@netlify/cache 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs +246 -0
- package/dist/main.d.cts +8 -1
- package/dist/main.d.ts +8 -1
- package/dist/main.js +246 -0
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -16,6 +16,24 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var __accessCheck = (obj, member, msg) => {
|
|
20
|
+
if (!member.has(obj))
|
|
21
|
+
throw TypeError("Cannot " + msg);
|
|
22
|
+
};
|
|
23
|
+
var __privateGet = (obj, member, getter) => {
|
|
24
|
+
__accessCheck(obj, member, "read from private field");
|
|
25
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
26
|
+
};
|
|
27
|
+
var __privateAdd = (obj, member, value) => {
|
|
28
|
+
if (member.has(obj))
|
|
29
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
30
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
31
|
+
};
|
|
32
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
33
|
+
__accessCheck(obj, member, "write to private field");
|
|
34
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
35
|
+
return value;
|
|
36
|
+
};
|
|
19
37
|
|
|
20
38
|
// src/main.ts
|
|
21
39
|
var main_exports = {};
|
|
@@ -25,18 +43,245 @@ __export(main_exports, {
|
|
|
25
43
|
MINUTE: () => MINUTE,
|
|
26
44
|
WEEK: () => WEEK,
|
|
27
45
|
YEAR: () => YEAR,
|
|
46
|
+
caches: () => caches,
|
|
28
47
|
fetchWithCache: () => fetchWithCache,
|
|
29
48
|
getCacheStatus: () => getCacheStatus,
|
|
30
49
|
setCacheHeaders: () => setCacheHeaders
|
|
31
50
|
});
|
|
32
51
|
module.exports = __toCommonJS(main_exports);
|
|
33
52
|
|
|
53
|
+
// src/bootstrap/errors.ts
|
|
54
|
+
var ERROR_CODES = {
|
|
55
|
+
invalid_vary: "Responses must not use unsupported directives of the `Netlify-Vary` header (https://ntl.fyi/cache_api_invalid_vary).",
|
|
56
|
+
no_cache: "Responses must not set cache control headers with the `private`, `no-cache` or `no-store` directives (https://ntl.fyi/cache_api_no_cache).",
|
|
57
|
+
low_ttl: "Responses must have a cache control header with a `max-age` or `s-maxage` directive (https://ntl.fyi/cache_api_low_ttl).",
|
|
58
|
+
no_directive: "Responses must have a cache control header with caching directives (https://ntl.fyi/cache_api_no_directive).",
|
|
59
|
+
no_ttl: "Responses must have a cache control header with a `max-age` or `s-maxage` directive (https://ntl.fyi/cache_api_no_ttl).",
|
|
60
|
+
no_status: "Responses must specify a status code (https://ntl.fyi/cache_api_no_status).",
|
|
61
|
+
invalid_directive: "Responses must have a cache control header with caching directives (https://ntl.fyi/cache_api_invalid_directive).",
|
|
62
|
+
status: "Responses must have a status code between 200 and 299 (https://ntl.fyi/cache_api_status)."
|
|
63
|
+
};
|
|
64
|
+
var GENERIC_ERROR = "The server has returned an unexpected error (https://ntl.fyi/cache_api_error).";
|
|
65
|
+
|
|
34
66
|
// src/headers.ts
|
|
35
67
|
var CacheStatus = "cache-status";
|
|
36
68
|
var NetlifyCacheId = "netlify-cache-id";
|
|
37
69
|
var NetlifyCacheTag = "netlify-cache-tag";
|
|
38
70
|
var NetlifyCdnCacheControl = "netlify-cdn-cache-control";
|
|
39
71
|
var NetlifyVary = "netlify-vary";
|
|
72
|
+
var ErrorDetail = "netlify-programmable-error";
|
|
73
|
+
var ResourceHeaders = "netlify-programmable-headers";
|
|
74
|
+
var ResourceStatus = "netlify-programmable-status";
|
|
75
|
+
var ResourceStore = "netlify-programmable-store";
|
|
76
|
+
var NetlifyForwardedHost = "netlify-forwarded-host";
|
|
77
|
+
var UserAgent = "user-agent";
|
|
78
|
+
|
|
79
|
+
// src/bootstrap/cache.ts
|
|
80
|
+
var allowedProtocols = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
81
|
+
var discardedHeaders = /* @__PURE__ */ new Set(["cookie", "content-encoding", "content-length"]);
|
|
82
|
+
var getInternalHeaders = Symbol("getInternalHeaders");
|
|
83
|
+
var serializeResourceHeaders = Symbol("serializeResourceHeaders");
|
|
84
|
+
var _base64Encode, _getContext, _name, _userAgent;
|
|
85
|
+
var NetlifyCache = class {
|
|
86
|
+
constructor({ base64Encode, getContext, name, userAgent }) {
|
|
87
|
+
__privateAdd(this, _base64Encode, void 0);
|
|
88
|
+
__privateAdd(this, _getContext, void 0);
|
|
89
|
+
__privateAdd(this, _name, void 0);
|
|
90
|
+
__privateAdd(this, _userAgent, void 0);
|
|
91
|
+
__privateSet(this, _base64Encode, base64Encode);
|
|
92
|
+
__privateSet(this, _getContext, getContext);
|
|
93
|
+
__privateSet(this, _name, name);
|
|
94
|
+
__privateSet(this, _userAgent, userAgent);
|
|
95
|
+
}
|
|
96
|
+
[getInternalHeaders](requestContext) {
|
|
97
|
+
const { host, token } = requestContext;
|
|
98
|
+
const headers = {
|
|
99
|
+
Authorization: `Bearer ${token}`,
|
|
100
|
+
[ResourceStore]: __privateGet(this, _name)
|
|
101
|
+
};
|
|
102
|
+
if (host) {
|
|
103
|
+
headers[NetlifyForwardedHost] = host;
|
|
104
|
+
}
|
|
105
|
+
if (__privateGet(this, _userAgent)) {
|
|
106
|
+
headers[UserAgent] = __privateGet(this, _userAgent);
|
|
107
|
+
}
|
|
108
|
+
return headers;
|
|
109
|
+
}
|
|
110
|
+
[serializeResourceHeaders](headers) {
|
|
111
|
+
const headersMap = {};
|
|
112
|
+
headers.forEach((value, key) => {
|
|
113
|
+
if (discardedHeaders.has(key)) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (key === "set-cookie") {
|
|
117
|
+
headersMap[key] = headersMap[key] || [];
|
|
118
|
+
headersMap[key].push(value);
|
|
119
|
+
} else {
|
|
120
|
+
headersMap[key] = value.split(",");
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return __privateGet(this, _base64Encode).call(this, JSON.stringify(headersMap));
|
|
124
|
+
}
|
|
125
|
+
async add(request) {
|
|
126
|
+
await this.put(new Request(request), await fetch(request));
|
|
127
|
+
}
|
|
128
|
+
async addAll(requests) {
|
|
129
|
+
await Promise.allSettled(requests.map((request) => this.add(request)));
|
|
130
|
+
}
|
|
131
|
+
// eslint-disable-next-line class-methods-use-this, require-await, @typescript-eslint/no-unused-vars
|
|
132
|
+
async delete(request) {
|
|
133
|
+
const context = __privateGet(this, _getContext).call(this, { operation: "delete" /* Delete */ });
|
|
134
|
+
if (context) {
|
|
135
|
+
const resourceURL = extractAndValidateURL(request);
|
|
136
|
+
await fetch(`${context.url}/${toCacheKey(resourceURL)}`, {
|
|
137
|
+
headers: this[getInternalHeaders](context),
|
|
138
|
+
method: "DELETE"
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
// eslint-disable-next-line class-methods-use-this, require-await, @typescript-eslint/no-unused-vars
|
|
144
|
+
async keys(_request) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
async match(request) {
|
|
148
|
+
try {
|
|
149
|
+
const context = __privateGet(this, _getContext).call(this, { operation: "read" /* Read */ });
|
|
150
|
+
if (!context) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const resourceURL = extractAndValidateURL(request);
|
|
154
|
+
const cacheURL = `${context.url}/${toCacheKey(resourceURL)}`;
|
|
155
|
+
const response = await fetch(cacheURL, {
|
|
156
|
+
headers: this[getInternalHeaders](context),
|
|
157
|
+
method: "GET"
|
|
158
|
+
});
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
return response;
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
167
|
+
async matchAll(request, _options) {
|
|
168
|
+
if (!request) {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
const res = await this.match(request);
|
|
172
|
+
return res ? [res] : [];
|
|
173
|
+
}
|
|
174
|
+
async put(request, response) {
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
throw new TypeError(`Cannot cache response with status ${response.status}.`);
|
|
177
|
+
}
|
|
178
|
+
if (request instanceof Request && request.method !== "GET") {
|
|
179
|
+
throw new TypeError(`Cannot cache response to ${request.method} request.`);
|
|
180
|
+
}
|
|
181
|
+
if (response.status === 206) {
|
|
182
|
+
throw new TypeError("Cannot cache response to a range request (206 Partial Content).");
|
|
183
|
+
}
|
|
184
|
+
if (response.headers.get("vary")?.includes("*")) {
|
|
185
|
+
throw new TypeError("Cannot cache response with 'Vary: *' header.");
|
|
186
|
+
}
|
|
187
|
+
const context = __privateGet(this, _getContext).call(this, { operation: "write" /* Write */ });
|
|
188
|
+
if (!context) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const resourceURL = extractAndValidateURL(request);
|
|
192
|
+
const cacheResponse = await fetch(`${context.url}/${toCacheKey(resourceURL)}`, {
|
|
193
|
+
body: response.body,
|
|
194
|
+
headers: {
|
|
195
|
+
...this[getInternalHeaders](context),
|
|
196
|
+
[ResourceHeaders]: this[serializeResourceHeaders](response.headers),
|
|
197
|
+
[ResourceStatus]: response.status.toString()
|
|
198
|
+
},
|
|
199
|
+
// @ts-expect-error https://github.com/whatwg/fetch/pull/1457
|
|
200
|
+
duplex: "half",
|
|
201
|
+
method: "POST"
|
|
202
|
+
});
|
|
203
|
+
if (!cacheResponse.ok) {
|
|
204
|
+
const errorDetail = cacheResponse.headers.get(ErrorDetail) ?? "";
|
|
205
|
+
const errorMessage = ERROR_CODES[errorDetail] || GENERIC_ERROR;
|
|
206
|
+
context.logger?.(`Failed to write to the cache: ${errorMessage}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
_base64Encode = new WeakMap();
|
|
211
|
+
_getContext = new WeakMap();
|
|
212
|
+
_name = new WeakMap();
|
|
213
|
+
_userAgent = new WeakMap();
|
|
214
|
+
var extractAndValidateURL = (input) => {
|
|
215
|
+
let url;
|
|
216
|
+
if (input instanceof Request) {
|
|
217
|
+
url = new URL(input.url);
|
|
218
|
+
} else {
|
|
219
|
+
try {
|
|
220
|
+
url = new URL(String(input));
|
|
221
|
+
} catch {
|
|
222
|
+
throw new TypeError(`${input} is not a valid URL.`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (!allowedProtocols.has(url.protocol)) {
|
|
226
|
+
throw new TypeError(
|
|
227
|
+
`Cannot cache response for URL with unsupported protocol (${url.protocol}). Supported protocols are ${[
|
|
228
|
+
...allowedProtocols
|
|
229
|
+
].join(", ")}.`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
return url;
|
|
233
|
+
};
|
|
234
|
+
var toCacheKey = (url) => encodeURIComponent(url.toString());
|
|
235
|
+
|
|
236
|
+
// src/bootstrap/cachestorage.ts
|
|
237
|
+
var _environmentOptions, _stores;
|
|
238
|
+
var NetlifyCacheStorage = class {
|
|
239
|
+
constructor(environmentOptions) {
|
|
240
|
+
__privateAdd(this, _environmentOptions, void 0);
|
|
241
|
+
__privateAdd(this, _stores, void 0);
|
|
242
|
+
__privateSet(this, _environmentOptions, environmentOptions);
|
|
243
|
+
__privateSet(this, _stores, /* @__PURE__ */ new Map());
|
|
244
|
+
}
|
|
245
|
+
open(name) {
|
|
246
|
+
let store = __privateGet(this, _stores).get(name);
|
|
247
|
+
if (!store) {
|
|
248
|
+
store = new NetlifyCache({
|
|
249
|
+
...__privateGet(this, _environmentOptions),
|
|
250
|
+
name
|
|
251
|
+
});
|
|
252
|
+
__privateGet(this, _stores).set(name, store);
|
|
253
|
+
}
|
|
254
|
+
return Promise.resolve(store);
|
|
255
|
+
}
|
|
256
|
+
has(name) {
|
|
257
|
+
return Promise.resolve(__privateGet(this, _stores).has(name));
|
|
258
|
+
}
|
|
259
|
+
delete(name) {
|
|
260
|
+
return Promise.resolve(__privateGet(this, _stores).delete(name));
|
|
261
|
+
}
|
|
262
|
+
keys() {
|
|
263
|
+
return Promise.resolve([...__privateGet(this, _stores).keys()]);
|
|
264
|
+
}
|
|
265
|
+
async match(request, options) {
|
|
266
|
+
if (options?.cacheName) {
|
|
267
|
+
return __privateGet(this, _stores).get(options.cacheName)?.match(request);
|
|
268
|
+
}
|
|
269
|
+
for (const store of __privateGet(this, _stores).values()) {
|
|
270
|
+
const response = await store.match(request);
|
|
271
|
+
if (response === void 0) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
_environmentOptions = new WeakMap();
|
|
278
|
+
_stores = new WeakMap();
|
|
279
|
+
|
|
280
|
+
// src/polyfill.ts
|
|
281
|
+
var caches = globalThis.caches ?? new NetlifyCacheStorage({
|
|
282
|
+
base64Encode: () => "",
|
|
283
|
+
getContext: () => null
|
|
284
|
+
});
|
|
40
285
|
|
|
41
286
|
// src/cache-headers/validation.ts
|
|
42
287
|
var ensureArray = (value) => Array.isArray(value) ? value : [value];
|
|
@@ -309,6 +554,7 @@ var YEAR = 365 * DAY;
|
|
|
309
554
|
MINUTE,
|
|
310
555
|
WEEK,
|
|
311
556
|
YEAR,
|
|
557
|
+
caches,
|
|
312
558
|
fetchWithCache,
|
|
313
559
|
getCacheStatus,
|
|
314
560
|
setCacheHeaders
|
package/dist/main.d.cts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { N as NetlifyCache } from './cache-7af07baa.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Polyfill for local development environments where `globalThis.caches` is not
|
|
5
|
+
* available. This is a no-op cache, which will automatically work with the
|
|
6
|
+
* real one in production.
|
|
7
|
+
*/
|
|
8
|
+
declare const caches: CacheStorage;
|
|
9
|
+
|
|
3
10
|
interface CacheSettings {
|
|
4
11
|
/**
|
|
5
12
|
* Persist the response in the durable cache, shared across all CDN nodes.
|
|
@@ -174,4 +181,4 @@ declare const WEEK: number;
|
|
|
174
181
|
*/
|
|
175
182
|
declare const YEAR: number;
|
|
176
183
|
|
|
177
|
-
export { DAY, HOUR, MINUTE, WEEK, YEAR, fetchWithCache, getCacheStatus, setCacheHeaders };
|
|
184
|
+
export { DAY, HOUR, MINUTE, WEEK, YEAR, caches, fetchWithCache, getCacheStatus, setCacheHeaders };
|
package/dist/main.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { N as NetlifyCache } from './cache-7af07baa.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Polyfill for local development environments where `globalThis.caches` is not
|
|
5
|
+
* available. This is a no-op cache, which will automatically work with the
|
|
6
|
+
* real one in production.
|
|
7
|
+
*/
|
|
8
|
+
declare const caches: CacheStorage;
|
|
9
|
+
|
|
3
10
|
interface CacheSettings {
|
|
4
11
|
/**
|
|
5
12
|
* Persist the response in the durable cache, shared across all CDN nodes.
|
|
@@ -174,4 +181,4 @@ declare const WEEK: number;
|
|
|
174
181
|
*/
|
|
175
182
|
declare const YEAR: number;
|
|
176
183
|
|
|
177
|
-
export { DAY, HOUR, MINUTE, WEEK, YEAR, fetchWithCache, getCacheStatus, setCacheHeaders };
|
|
184
|
+
export { DAY, HOUR, MINUTE, WEEK, YEAR, caches, fetchWithCache, getCacheStatus, setCacheHeaders };
|
package/dist/main.js
CHANGED
|
@@ -1,9 +1,254 @@
|
|
|
1
|
+
var __accessCheck = (obj, member, msg) => {
|
|
2
|
+
if (!member.has(obj))
|
|
3
|
+
throw TypeError("Cannot " + msg);
|
|
4
|
+
};
|
|
5
|
+
var __privateGet = (obj, member, getter) => {
|
|
6
|
+
__accessCheck(obj, member, "read from private field");
|
|
7
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
8
|
+
};
|
|
9
|
+
var __privateAdd = (obj, member, value) => {
|
|
10
|
+
if (member.has(obj))
|
|
11
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
12
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
+
};
|
|
14
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
15
|
+
__accessCheck(obj, member, "write to private field");
|
|
16
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/bootstrap/errors.ts
|
|
21
|
+
var ERROR_CODES = {
|
|
22
|
+
invalid_vary: "Responses must not use unsupported directives of the `Netlify-Vary` header (https://ntl.fyi/cache_api_invalid_vary).",
|
|
23
|
+
no_cache: "Responses must not set cache control headers with the `private`, `no-cache` or `no-store` directives (https://ntl.fyi/cache_api_no_cache).",
|
|
24
|
+
low_ttl: "Responses must have a cache control header with a `max-age` or `s-maxage` directive (https://ntl.fyi/cache_api_low_ttl).",
|
|
25
|
+
no_directive: "Responses must have a cache control header with caching directives (https://ntl.fyi/cache_api_no_directive).",
|
|
26
|
+
no_ttl: "Responses must have a cache control header with a `max-age` or `s-maxage` directive (https://ntl.fyi/cache_api_no_ttl).",
|
|
27
|
+
no_status: "Responses must specify a status code (https://ntl.fyi/cache_api_no_status).",
|
|
28
|
+
invalid_directive: "Responses must have a cache control header with caching directives (https://ntl.fyi/cache_api_invalid_directive).",
|
|
29
|
+
status: "Responses must have a status code between 200 and 299 (https://ntl.fyi/cache_api_status)."
|
|
30
|
+
};
|
|
31
|
+
var GENERIC_ERROR = "The server has returned an unexpected error (https://ntl.fyi/cache_api_error).";
|
|
32
|
+
|
|
1
33
|
// src/headers.ts
|
|
2
34
|
var CacheStatus = "cache-status";
|
|
3
35
|
var NetlifyCacheId = "netlify-cache-id";
|
|
4
36
|
var NetlifyCacheTag = "netlify-cache-tag";
|
|
5
37
|
var NetlifyCdnCacheControl = "netlify-cdn-cache-control";
|
|
6
38
|
var NetlifyVary = "netlify-vary";
|
|
39
|
+
var ErrorDetail = "netlify-programmable-error";
|
|
40
|
+
var ResourceHeaders = "netlify-programmable-headers";
|
|
41
|
+
var ResourceStatus = "netlify-programmable-status";
|
|
42
|
+
var ResourceStore = "netlify-programmable-store";
|
|
43
|
+
var NetlifyForwardedHost = "netlify-forwarded-host";
|
|
44
|
+
var UserAgent = "user-agent";
|
|
45
|
+
|
|
46
|
+
// src/bootstrap/cache.ts
|
|
47
|
+
var allowedProtocols = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
48
|
+
var discardedHeaders = /* @__PURE__ */ new Set(["cookie", "content-encoding", "content-length"]);
|
|
49
|
+
var getInternalHeaders = Symbol("getInternalHeaders");
|
|
50
|
+
var serializeResourceHeaders = Symbol("serializeResourceHeaders");
|
|
51
|
+
var _base64Encode, _getContext, _name, _userAgent;
|
|
52
|
+
var NetlifyCache = class {
|
|
53
|
+
constructor({ base64Encode, getContext, name, userAgent }) {
|
|
54
|
+
__privateAdd(this, _base64Encode, void 0);
|
|
55
|
+
__privateAdd(this, _getContext, void 0);
|
|
56
|
+
__privateAdd(this, _name, void 0);
|
|
57
|
+
__privateAdd(this, _userAgent, void 0);
|
|
58
|
+
__privateSet(this, _base64Encode, base64Encode);
|
|
59
|
+
__privateSet(this, _getContext, getContext);
|
|
60
|
+
__privateSet(this, _name, name);
|
|
61
|
+
__privateSet(this, _userAgent, userAgent);
|
|
62
|
+
}
|
|
63
|
+
[getInternalHeaders](requestContext) {
|
|
64
|
+
const { host, token } = requestContext;
|
|
65
|
+
const headers = {
|
|
66
|
+
Authorization: `Bearer ${token}`,
|
|
67
|
+
[ResourceStore]: __privateGet(this, _name)
|
|
68
|
+
};
|
|
69
|
+
if (host) {
|
|
70
|
+
headers[NetlifyForwardedHost] = host;
|
|
71
|
+
}
|
|
72
|
+
if (__privateGet(this, _userAgent)) {
|
|
73
|
+
headers[UserAgent] = __privateGet(this, _userAgent);
|
|
74
|
+
}
|
|
75
|
+
return headers;
|
|
76
|
+
}
|
|
77
|
+
[serializeResourceHeaders](headers) {
|
|
78
|
+
const headersMap = {};
|
|
79
|
+
headers.forEach((value, key) => {
|
|
80
|
+
if (discardedHeaders.has(key)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (key === "set-cookie") {
|
|
84
|
+
headersMap[key] = headersMap[key] || [];
|
|
85
|
+
headersMap[key].push(value);
|
|
86
|
+
} else {
|
|
87
|
+
headersMap[key] = value.split(",");
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return __privateGet(this, _base64Encode).call(this, JSON.stringify(headersMap));
|
|
91
|
+
}
|
|
92
|
+
async add(request) {
|
|
93
|
+
await this.put(new Request(request), await fetch(request));
|
|
94
|
+
}
|
|
95
|
+
async addAll(requests) {
|
|
96
|
+
await Promise.allSettled(requests.map((request) => this.add(request)));
|
|
97
|
+
}
|
|
98
|
+
// eslint-disable-next-line class-methods-use-this, require-await, @typescript-eslint/no-unused-vars
|
|
99
|
+
async delete(request) {
|
|
100
|
+
const context = __privateGet(this, _getContext).call(this, { operation: "delete" /* Delete */ });
|
|
101
|
+
if (context) {
|
|
102
|
+
const resourceURL = extractAndValidateURL(request);
|
|
103
|
+
await fetch(`${context.url}/${toCacheKey(resourceURL)}`, {
|
|
104
|
+
headers: this[getInternalHeaders](context),
|
|
105
|
+
method: "DELETE"
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
// eslint-disable-next-line class-methods-use-this, require-await, @typescript-eslint/no-unused-vars
|
|
111
|
+
async keys(_request) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
async match(request) {
|
|
115
|
+
try {
|
|
116
|
+
const context = __privateGet(this, _getContext).call(this, { operation: "read" /* Read */ });
|
|
117
|
+
if (!context) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const resourceURL = extractAndValidateURL(request);
|
|
121
|
+
const cacheURL = `${context.url}/${toCacheKey(resourceURL)}`;
|
|
122
|
+
const response = await fetch(cacheURL, {
|
|
123
|
+
headers: this[getInternalHeaders](context),
|
|
124
|
+
method: "GET"
|
|
125
|
+
});
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
return response;
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
134
|
+
async matchAll(request, _options) {
|
|
135
|
+
if (!request) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
const res = await this.match(request);
|
|
139
|
+
return res ? [res] : [];
|
|
140
|
+
}
|
|
141
|
+
async put(request, response) {
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
throw new TypeError(`Cannot cache response with status ${response.status}.`);
|
|
144
|
+
}
|
|
145
|
+
if (request instanceof Request && request.method !== "GET") {
|
|
146
|
+
throw new TypeError(`Cannot cache response to ${request.method} request.`);
|
|
147
|
+
}
|
|
148
|
+
if (response.status === 206) {
|
|
149
|
+
throw new TypeError("Cannot cache response to a range request (206 Partial Content).");
|
|
150
|
+
}
|
|
151
|
+
if (response.headers.get("vary")?.includes("*")) {
|
|
152
|
+
throw new TypeError("Cannot cache response with 'Vary: *' header.");
|
|
153
|
+
}
|
|
154
|
+
const context = __privateGet(this, _getContext).call(this, { operation: "write" /* Write */ });
|
|
155
|
+
if (!context) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const resourceURL = extractAndValidateURL(request);
|
|
159
|
+
const cacheResponse = await fetch(`${context.url}/${toCacheKey(resourceURL)}`, {
|
|
160
|
+
body: response.body,
|
|
161
|
+
headers: {
|
|
162
|
+
...this[getInternalHeaders](context),
|
|
163
|
+
[ResourceHeaders]: this[serializeResourceHeaders](response.headers),
|
|
164
|
+
[ResourceStatus]: response.status.toString()
|
|
165
|
+
},
|
|
166
|
+
// @ts-expect-error https://github.com/whatwg/fetch/pull/1457
|
|
167
|
+
duplex: "half",
|
|
168
|
+
method: "POST"
|
|
169
|
+
});
|
|
170
|
+
if (!cacheResponse.ok) {
|
|
171
|
+
const errorDetail = cacheResponse.headers.get(ErrorDetail) ?? "";
|
|
172
|
+
const errorMessage = ERROR_CODES[errorDetail] || GENERIC_ERROR;
|
|
173
|
+
context.logger?.(`Failed to write to the cache: ${errorMessage}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
_base64Encode = new WeakMap();
|
|
178
|
+
_getContext = new WeakMap();
|
|
179
|
+
_name = new WeakMap();
|
|
180
|
+
_userAgent = new WeakMap();
|
|
181
|
+
var extractAndValidateURL = (input) => {
|
|
182
|
+
let url;
|
|
183
|
+
if (input instanceof Request) {
|
|
184
|
+
url = new URL(input.url);
|
|
185
|
+
} else {
|
|
186
|
+
try {
|
|
187
|
+
url = new URL(String(input));
|
|
188
|
+
} catch {
|
|
189
|
+
throw new TypeError(`${input} is not a valid URL.`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (!allowedProtocols.has(url.protocol)) {
|
|
193
|
+
throw new TypeError(
|
|
194
|
+
`Cannot cache response for URL with unsupported protocol (${url.protocol}). Supported protocols are ${[
|
|
195
|
+
...allowedProtocols
|
|
196
|
+
].join(", ")}.`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
return url;
|
|
200
|
+
};
|
|
201
|
+
var toCacheKey = (url) => encodeURIComponent(url.toString());
|
|
202
|
+
|
|
203
|
+
// src/bootstrap/cachestorage.ts
|
|
204
|
+
var _environmentOptions, _stores;
|
|
205
|
+
var NetlifyCacheStorage = class {
|
|
206
|
+
constructor(environmentOptions) {
|
|
207
|
+
__privateAdd(this, _environmentOptions, void 0);
|
|
208
|
+
__privateAdd(this, _stores, void 0);
|
|
209
|
+
__privateSet(this, _environmentOptions, environmentOptions);
|
|
210
|
+
__privateSet(this, _stores, /* @__PURE__ */ new Map());
|
|
211
|
+
}
|
|
212
|
+
open(name) {
|
|
213
|
+
let store = __privateGet(this, _stores).get(name);
|
|
214
|
+
if (!store) {
|
|
215
|
+
store = new NetlifyCache({
|
|
216
|
+
...__privateGet(this, _environmentOptions),
|
|
217
|
+
name
|
|
218
|
+
});
|
|
219
|
+
__privateGet(this, _stores).set(name, store);
|
|
220
|
+
}
|
|
221
|
+
return Promise.resolve(store);
|
|
222
|
+
}
|
|
223
|
+
has(name) {
|
|
224
|
+
return Promise.resolve(__privateGet(this, _stores).has(name));
|
|
225
|
+
}
|
|
226
|
+
delete(name) {
|
|
227
|
+
return Promise.resolve(__privateGet(this, _stores).delete(name));
|
|
228
|
+
}
|
|
229
|
+
keys() {
|
|
230
|
+
return Promise.resolve([...__privateGet(this, _stores).keys()]);
|
|
231
|
+
}
|
|
232
|
+
async match(request, options) {
|
|
233
|
+
if (options?.cacheName) {
|
|
234
|
+
return __privateGet(this, _stores).get(options.cacheName)?.match(request);
|
|
235
|
+
}
|
|
236
|
+
for (const store of __privateGet(this, _stores).values()) {
|
|
237
|
+
const response = await store.match(request);
|
|
238
|
+
if (response === void 0) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
_environmentOptions = new WeakMap();
|
|
245
|
+
_stores = new WeakMap();
|
|
246
|
+
|
|
247
|
+
// src/polyfill.ts
|
|
248
|
+
var caches = globalThis.caches ?? new NetlifyCacheStorage({
|
|
249
|
+
base64Encode: () => "",
|
|
250
|
+
getContext: () => null
|
|
251
|
+
});
|
|
7
252
|
|
|
8
253
|
// src/cache-headers/validation.ts
|
|
9
254
|
var ensureArray = (value) => Array.isArray(value) ? value : [value];
|
|
@@ -275,6 +520,7 @@ export {
|
|
|
275
520
|
MINUTE,
|
|
276
521
|
WEEK,
|
|
277
522
|
YEAR,
|
|
523
|
+
caches,
|
|
278
524
|
fetchWithCache,
|
|
279
525
|
getCacheStatus,
|
|
280
526
|
setCacheHeaders
|