@cloudflare/pages-shared 0.11.29 → 0.11.31
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/asset-server/handler.ts
CHANGED
|
@@ -328,7 +328,10 @@ export async function generateHandler<
|
|
|
328
328
|
...Object.fromEntries(extraHeaders.entries()),
|
|
329
329
|
});
|
|
330
330
|
|
|
331
|
-
if (
|
|
331
|
+
if (
|
|
332
|
+
earlyHintsCache &&
|
|
333
|
+
isHTMLContentType(response.headers.get("Content-Type"))
|
|
334
|
+
) {
|
|
332
335
|
const preEarlyHintsHeaders = new Headers(headers);
|
|
333
336
|
|
|
334
337
|
// "Early Hints cache entries are keyed by request URI and ignore query strings."
|
|
@@ -347,65 +350,70 @@ export async function generateHandler<
|
|
|
347
350
|
}
|
|
348
351
|
} else {
|
|
349
352
|
if (setMetrics) setMetrics({ earlyHintsResult: "notused-miss" });
|
|
350
|
-
}
|
|
351
353
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
354
|
+
const clonedResponse = response.clone();
|
|
355
|
+
|
|
356
|
+
if (waitUntil) {
|
|
357
|
+
waitUntil(
|
|
358
|
+
(async () => {
|
|
359
|
+
try {
|
|
360
|
+
const links: { href: string; rel: string; as?: string }[] = [];
|
|
361
|
+
|
|
362
|
+
const transformedResponse = new HTMLRewriter()
|
|
363
|
+
.on("link[rel~=preconnect],link[rel~=preload]", {
|
|
364
|
+
element(element) {
|
|
365
|
+
for (const [attributeName] of element.attributes) {
|
|
366
|
+
if (
|
|
367
|
+
!ALLOWED_EARLY_HINT_LINK_ATTRIBUTES.includes(
|
|
368
|
+
attributeName.toLowerCase()
|
|
369
|
+
)
|
|
370
|
+
) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const href = element.getAttribute("href") || undefined;
|
|
376
|
+
const rel = element.getAttribute("rel") || undefined;
|
|
377
|
+
const as = element.getAttribute("as") || undefined;
|
|
378
|
+
if (href && !href.startsWith("data:") && rel) {
|
|
379
|
+
links.push({ href, rel, as });
|
|
370
380
|
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
381
|
+
},
|
|
382
|
+
})
|
|
383
|
+
.transform(clonedResponse);
|
|
384
|
+
|
|
385
|
+
// Needed to actually execute the HTMLRewriter handlers
|
|
386
|
+
await transformedResponse.text();
|
|
387
|
+
|
|
388
|
+
links.forEach(({ href, rel, as }) => {
|
|
389
|
+
let link = `<${href}>; rel="${rel}"`;
|
|
390
|
+
if (as) {
|
|
391
|
+
link += `; as=${as}`;
|
|
392
|
+
}
|
|
393
|
+
preEarlyHintsHeaders.append("Link", link);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
const linkHeader = preEarlyHintsHeaders.get("Link");
|
|
397
|
+
if (linkHeader) {
|
|
398
|
+
await earlyHintsCache.put(
|
|
399
|
+
earlyHintsCacheKey,
|
|
400
|
+
new Response(null, {
|
|
401
|
+
headers: {
|
|
402
|
+
Link: linkHeader,
|
|
403
|
+
"Cache-Control": "max-age=2592000", // 30 days
|
|
404
|
+
},
|
|
405
|
+
})
|
|
406
|
+
);
|
|
390
407
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
await earlyHintsCache.put(
|
|
397
|
-
earlyHintsCacheKey,
|
|
398
|
-
new Response(null, { headers: { Link: linkHeader } })
|
|
399
|
-
);
|
|
408
|
+
} catch (err) {
|
|
409
|
+
// Nbd if we fail here in the deferred 'waitUntil' work. We're probably trying to parse a malformed page or something.
|
|
410
|
+
// Totally fine to skip over any errors.
|
|
411
|
+
// If we need to debug something, you can uncomment the following:
|
|
412
|
+
// logError(err)
|
|
400
413
|
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
// If we need to debug something, you can uncomment the following:
|
|
405
|
-
// logError(err)
|
|
406
|
-
}
|
|
407
|
-
})()
|
|
408
|
-
);
|
|
414
|
+
})()
|
|
415
|
+
);
|
|
416
|
+
}
|
|
409
417
|
}
|
|
410
418
|
} else {
|
|
411
419
|
if (setMetrics) setMetrics({ earlyHintsResult: "disabled" });
|
|
@@ -553,7 +561,7 @@ export async function generateHandler<
|
|
|
553
561
|
}
|
|
554
562
|
|
|
555
563
|
if (
|
|
556
|
-
asset.contentType
|
|
564
|
+
isHTMLContentType(asset.contentType) &&
|
|
557
565
|
metadata.analytics?.version === ANALYTICS_VERSION
|
|
558
566
|
) {
|
|
559
567
|
return new HTMLRewriter()
|
|
@@ -653,3 +661,11 @@ function isPreview(url: URL): boolean {
|
|
|
653
661
|
}
|
|
654
662
|
return false;
|
|
655
663
|
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Whether or not the passed in string looks like an HTML
|
|
667
|
+
* Content-Type header
|
|
668
|
+
*/
|
|
669
|
+
function isHTMLContentType(contentType?: string | null) {
|
|
670
|
+
return contentType?.toLowerCase().startsWith("text/html") || false;
|
|
671
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { polyfill } from ".";
|
|
2
2
|
|
|
3
3
|
export default async () => {
|
|
4
|
+
const { HTMLRewriter } = await import("@miniflare/html-rewriter");
|
|
4
5
|
const mf = await import("miniflare");
|
|
5
6
|
polyfill({
|
|
6
7
|
fetch: mf.fetch,
|
|
7
8
|
Headers: mf.Headers,
|
|
8
9
|
Request: mf.Request,
|
|
9
10
|
Response: mf.Response,
|
|
11
|
+
HTMLRewriter: HTMLRewriter,
|
|
10
12
|
});
|
|
11
13
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudflare/pages-shared",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.31",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/cloudflare/workers-sdk.git",
|
|
@@ -13,14 +13,16 @@
|
|
|
13
13
|
"metadata-generator/**/*"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"miniflare": "3.
|
|
16
|
+
"miniflare": "3.20240419.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@
|
|
20
|
-
"@
|
|
19
|
+
"@miniflare/storage-memory": "^2.14.2",
|
|
20
|
+
"@cloudflare/workers-types": "^4.20240419.0",
|
|
21
|
+
"@miniflare/cache": "^2.14.2",
|
|
22
|
+
"@miniflare/core": "^2.14.2",
|
|
23
|
+
"@miniflare/html-rewriter": "^2.14.2",
|
|
21
24
|
"concurrently": "^7.3.0",
|
|
22
25
|
"glob": "^8.0.3",
|
|
23
|
-
"service-worker-mock": "^2.0.5",
|
|
24
26
|
"@cloudflare/workers-tsconfig": "0.0.0"
|
|
25
27
|
},
|
|
26
28
|
"workers-sdk": {
|