-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.js
More file actions
125 lines (109 loc) · 4.68 KB
/
Copy pathmiddleware.js
File metadata and controls
125 lines (109 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* BunnyCDN Edge Script Middleware for Ghost Cache Invalidation.
*
* When a response is not served from the cache, inspects the origin response
* for an 'x-cache-invalidate' header and triggers a cache purge via BunnyCDN API call if found.
* Uses the specific /purge?url=... format.
*
* Required Environment Variables in BunnyCDN Edge Rule:
* - BUNNY_API_KEY: Your BunnyCDN account API key.
*
* Optional Environment Variables:
* - GHOST_PUBLIC_URL: Your blog's public base URL (e.g., https://yourdomain.com). Used to prefix relative paths.
*/
import * as BunnySDK from "https://esm.sh/@bunny.net/edgescript-sdk@0.12.0";
import process from "node:process";
/**
* Parses the invalidation pattern from Ghost's x-cache-invalidate header.
* Mimics the logic needed to correctly interpret paths for purging.
*
* @param {string} pattern - The pattern string (e.g., "/$/", "/post-slug", "/page/*").
* @param {string | undefined} ghostPublicUrl - Optional base public URL from env.
* @returns {{ urls: string[], purgeAll: boolean, pattern: string, timestamp: string }} - Parsed data.
*/
function parseInvalidationPattern(pattern, ghostPublicUrl) {
const purgeAll = pattern === "/$/" || pattern === "/*";
const baseUrls = purgeAll
? [`${ghostPublicUrl || ""}/*`] // Use /* directly if purging all
: pattern.split(",").map((url) => url.trim());
const urls = baseUrls.map((url) => {
if (url === "/*") return ghostPublicUrl ? `${ghostPublicUrl}/*` : "/*";
if (url.startsWith("http")) return url;
return ghostPublicUrl ? `${ghostPublicUrl}${url}` : url; // Return relative if no public URL
});
return {
urls,
purgeAll,
pattern,
timestamp: new Date().toISOString(),
};
}
async function onOriginResponse(context) {
const invalidationHeader =
context.response.headers.get("x-cache-invalidate");
if (invalidationHeader) {
// Log detection only if header is found
console.log(
`EdgeScript: Detected x-cache-invalidate header: ${invalidationHeader}`
);
// --- Configuration from Environment Variables ---
const ghostPublicUrl = process.env.GHOST_PUBLIC_URL;
const apiKey = process.env.BUNNY_API_KEY;
// --- End Configuration ---
if (!apiKey) {
// Log essential error
console.error(
"EdgeScript: BUNNY_API_KEY environment variable is not set. Cannot trigger purge."
);
return context.response; // Return original response
}
try {
const invalidationData = parseInvalidationPattern(
invalidationHeader,
ghostPublicUrl
);
const basePurgeUrl = "https://api.bunny.net/purge";
// Trigger purge for each URL individually
for (const urlToPurge of invalidationData.urls) {
// Use async=false to wait for purge confirmation, change to true if preferred
const apiUrl = `${basePurgeUrl}?url=${encodeURIComponent(
urlToPurge
)}&async=false`;
const options = {
method: "POST",
headers: {
AccessKey: apiKey,
},
};
try {
const purgeResponse = await fetch(apiUrl, options);
if (!purgeResponse.ok) {
const errorText = await purgeResponse.text();
// Log essential failure details
console.error(
`EdgeScript: Purge API request FAILED for ${urlToPurge}: ${purgeResponse.status} ${purgeResponse.statusText} - ${errorText}`
);
} else {
// Log essential success (simplified)
console.log(
`EdgeScript: Purge API request SUCCESSFUL for ${urlToPurge}: ${purgeResponse.status}`
);
}
} catch (fetchError) {
// Log essential network error
console.error(
`EdgeScript: Network error during purge request for ${urlToPurge}: ${fetchError.message}`
);
}
}
} catch (error) {
// Log essential processing error
console.error(
`EdgeScript: Error processing invalidation or calling purge API: ${error.message}`,
error.stack
);
}
}
return context.response;
}
BunnySDK.net.http.servePullZone().onOriginResponse(onOriginResponse);