vinext 1.0.0-beta.2 → 1.0.0-beta.4
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/README.md +6 -9
- package/dist/build/client-build-config.js +7 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +12 -2
- package/dist/check.js +4 -0
- package/dist/cli-args.d.ts +2 -1
- package/dist/cli-args.js +10 -0
- package/dist/cli.js +14 -8
- package/dist/client/navigation-runtime.d.ts +6 -0
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/config-matchers.js +4 -1
- package/dist/config/dotenv.d.ts +3 -4
- package/dist/config/dotenv.js +30 -22
- package/dist/config/next-config.d.ts +16 -5
- package/dist/config/next-config.js +7 -0
- package/dist/entries/app-browser-entry.d.ts +4 -10
- package/dist/entries/app-browser-entry.js +20 -4
- package/dist/entries/app-rsc-entry.js +21 -3
- package/dist/entries/app-rsc-manifest.js +19 -0
- package/dist/entries/pages-client-entry.js +0 -1
- package/dist/entries/pages-server-entry.js +13 -3
- package/dist/index.js +122 -49
- package/dist/init-cloudflare.d.ts +3 -1
- package/dist/init-cloudflare.js +59 -5
- package/dist/plugins/client-reference-dedup.js +7 -5
- package/dist/plugins/extensionless-dynamic-import.js +23 -18
- package/dist/plugins/ignore-dynamic-requests.js +3 -1
- package/dist/plugins/import-meta-url.js +17 -6
- package/dist/plugins/require-context.js +20 -15
- package/dist/plugins/sass.js +3 -4
- package/dist/plugins/transform-cache.d.ts +19 -0
- package/dist/plugins/transform-cache.js +36 -0
- package/dist/routing/app-route-graph.d.ts +14 -6
- package/dist/routing/app-route-graph.js +106 -16
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +7 -6
- package/dist/server/app-bfcache-identity.js +28 -2
- package/dist/server/app-browser-entry.js +175 -75
- package/dist/server/app-browser-navigation-controller.d.ts +23 -21
- package/dist/server/app-browser-navigation-controller.js +30 -5
- package/dist/server/app-browser-prefetch-response.d.ts +9 -0
- package/dist/server/app-browser-prefetch-response.js +32 -0
- package/dist/server/app-browser-state.d.ts +8 -3
- package/dist/server/app-browser-state.js +9 -3
- package/dist/server/app-page-cache-finalizer.js +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +16 -2
- package/dist/server/app-page-dispatch.d.ts +9 -1
- package/dist/server/app-page-dispatch.js +37 -8
- package/dist/server/app-page-element-builder.d.ts +4 -1
- package/dist/server/app-page-element-builder.js +34 -7
- package/dist/server/app-page-head.d.ts +3 -3
- package/dist/server/app-page-head.js +58 -13
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +2 -2
- package/dist/server/app-page-http-access-fallback-metadata.js +9 -1
- package/dist/server/app-page-probe.d.ts +4 -0
- package/dist/server/app-page-probe.js +6 -2
- package/dist/server/app-page-render.d.ts +1 -1
- package/dist/server/app-page-render.js +13 -3
- package/dist/server/app-page-request.d.ts +3 -1
- package/dist/server/app-page-request.js +4 -13
- package/dist/server/app-page-response.d.ts +2 -0
- package/dist/server/app-page-response.js +7 -2
- package/dist/server/app-page-route-wiring.d.ts +10 -2
- package/dist/server/app-page-route-wiring.js +269 -59
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +3 -1
- package/dist/server/app-route-handler-cache.js +4 -0
- package/dist/server/app-route-handler-dispatch.js +9 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +6 -0
- package/dist/server/app-route-module-loader.js +3 -0
- package/dist/server/app-router-entry.js +6 -3
- package/dist/server/app-rsc-cache-busting.d.ts +7 -0
- package/dist/server/app-rsc-cache-busting.js +6 -0
- package/dist/server/app-rsc-errors.js +10 -0
- package/dist/server/app-rsc-handler.d.ts +2 -0
- package/dist/server/app-rsc-handler.js +30 -13
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.js +65 -4
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +6 -0
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +4 -4
- package/dist/server/app-visited-response-cache.d.ts +6 -1
- package/dist/server/app-visited-response-cache.js +49 -1
- package/dist/server/cache-control.d.ts +2 -2
- package/dist/server/cache-control.js +2 -1
- package/dist/server/dev-server.d.ts +3 -1
- package/dist/server/dev-server.js +204 -348
- package/dist/server/edge-api-runtime.d.ts +10 -1
- package/dist/server/edge-api-runtime.js +29 -1
- package/dist/server/headers.d.ts +4 -2
- package/dist/server/headers.js +6 -3
- package/dist/server/isr-cache.d.ts +10 -33
- package/dist/server/isr-cache.js +33 -43
- package/dist/server/isr-decision.d.ts +2 -2
- package/dist/server/pages-api-route.d.ts +4 -0
- package/dist/server/pages-api-route.js +6 -3
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +6 -4
- package/dist/server/pages-dev-hydration.js +0 -1
- package/dist/server/pages-document-asset-props.d.ts +26 -0
- package/dist/server/pages-document-asset-props.js +69 -0
- package/dist/server/pages-get-initial-props.d.ts +1 -1
- package/dist/server/pages-get-initial-props.js +1 -4
- package/dist/server/pages-i18n.js +64 -16
- package/dist/server/pages-node-compat.d.ts +2 -0
- package/dist/server/pages-node-compat.js +10 -6
- package/dist/server/pages-page-data.d.ts +61 -9
- package/dist/server/pages-page-data.js +334 -74
- package/dist/server/pages-page-handler.d.ts +6 -1
- package/dist/server/pages-page-handler.js +119 -20
- package/dist/server/pages-page-response.d.ts +7 -3
- package/dist/server/pages-page-response.js +41 -33
- package/dist/server/pages-request-pipeline.d.ts +7 -0
- package/dist/server/pages-request-pipeline.js +5 -1
- package/dist/server/pages-revalidate.d.ts +1 -1
- package/dist/server/pages-revalidate.js +54 -8
- package/dist/server/pages-router-entry.d.ts +1 -0
- package/dist/server/pages-router-entry.js +10 -4
- package/dist/server/prerender-manifest.d.ts +1 -0
- package/dist/server/prod-server.d.ts +2 -1
- package/dist/server/prod-server.js +38 -13
- package/dist/server/revalidation-host.d.ts +11 -0
- package/dist/server/revalidation-host.js +19 -0
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/worker-revalidation-context.d.ts +13 -0
- package/dist/server/worker-revalidation-context.js +30 -0
- package/dist/shims/app-router-scroll-state.d.ts +2 -1
- package/dist/shims/app-router-scroll-state.js +7 -2
- package/dist/shims/cache-handler.d.ts +1 -1
- package/dist/shims/cache-handler.js +10 -7
- package/dist/shims/cache-runtime.d.ts +6 -0
- package/dist/shims/cache-runtime.js +4 -1
- package/dist/shims/cache.js +1 -1
- package/dist/shims/document.js +15 -2
- package/dist/shims/error.js +1 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-google-base.js +17 -8
- package/dist/shims/font-local.js +41 -10
- package/dist/shims/hash-scroll.d.ts +1 -1
- package/dist/shims/hash-scroll.js +2 -1
- package/dist/shims/headers.d.ts +10 -13
- package/dist/shims/headers.js +85 -36
- package/dist/shims/internal/cookie-serialize.d.ts +10 -9
- package/dist/shims/internal/cookie-serialize.js +9 -8
- package/dist/shims/internal/interpolate-as.d.ts +15 -1
- package/dist/shims/internal/interpolate-as.js +27 -2
- package/dist/shims/link.d.ts +2 -0
- package/dist/shims/link.js +77 -24
- package/dist/shims/metadata.d.ts +18 -34
- package/dist/shims/metadata.js +98 -56
- package/dist/shims/navigation.d.ts +18 -2
- package/dist/shims/navigation.js +70 -21
- package/dist/shims/request-context.d.ts +6 -2
- package/dist/shims/router.js +18 -7
- package/dist/shims/script.js +1 -1
- package/dist/shims/server.d.ts +7 -6
- package/dist/shims/server.js +156 -57
- package/dist/shims/slot.d.ts +2 -1
- package/dist/shims/slot.js +6 -2
- package/dist/shims/streamed-icons.d.ts +9 -0
- package/dist/shims/streamed-icons.js +33 -0
- package/dist/shims/unified-request-context.d.ts +21 -2
- package/dist/shims/unified-request-context.js +82 -1
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +5 -1
- package/dist/utils/html-limited-bots.js +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/package.json +1 -1
package/dist/shims/server.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { bindRequestContextSnapshot, getRequestContext, isInsideUnifiedScope, queueAfterCallback } from "./unified-request-context.js";
|
|
1
2
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
3
|
import { getRequestExecutionContext } from "./request-context.js";
|
|
3
4
|
import { MIDDLEWARE_SET_COOKIE_HEADER } from "../utils/protocol-headers.js";
|
|
4
5
|
import { MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER } from "../server/headers.js";
|
|
5
6
|
import { encodeMiddlewareRequestHeaders } from "../utils/middleware-request-headers.js";
|
|
6
|
-
import {
|
|
7
|
+
import { validateCookieAttributeValue, validateCookieName } from "./internal/cookie-serialize.js";
|
|
7
8
|
import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
|
|
8
9
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
9
10
|
//#region src/shims/server.ts
|
|
@@ -158,12 +159,8 @@ var NextResponse = class NextResponse extends Response {
|
|
|
158
159
|
* Create a JSON response.
|
|
159
160
|
*/
|
|
160
161
|
static json(body, init) {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
return new NextResponse(JSON.stringify(body), {
|
|
164
|
-
...init,
|
|
165
|
-
headers
|
|
166
|
-
});
|
|
162
|
+
const response = Response.json(body, init);
|
|
163
|
+
return new NextResponse(response.body, response);
|
|
167
164
|
}
|
|
168
165
|
/**
|
|
169
166
|
* Create a redirect response.
|
|
@@ -417,7 +414,7 @@ var NextURL = class NextURL {
|
|
|
417
414
|
};
|
|
418
415
|
if (this._trailingSlash) nextConfig.trailingSlash = true;
|
|
419
416
|
const config = {
|
|
420
|
-
basePath: this.
|
|
417
|
+
basePath: this._configBasePath,
|
|
421
418
|
nextConfig: Object.keys(nextConfig).length > 0 ? nextConfig : void 0
|
|
422
419
|
};
|
|
423
420
|
return new NextURL(this.href, void 0, config);
|
|
@@ -554,79 +551,54 @@ var ResponseCookies = class {
|
|
|
554
551
|
_parsed = /* @__PURE__ */ new Map();
|
|
555
552
|
constructor(headers) {
|
|
556
553
|
this._headers = headers;
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
const raw = header.slice(eq + 1, semi === -1 ? void 0 : semi);
|
|
563
|
-
let value;
|
|
564
|
-
try {
|
|
565
|
-
value = decodeURIComponent(raw);
|
|
566
|
-
} catch {
|
|
567
|
-
value = raw;
|
|
568
|
-
}
|
|
569
|
-
this._parsed.set(cookieName, {
|
|
570
|
-
serialized: header,
|
|
571
|
-
entry: {
|
|
572
|
-
name: cookieName,
|
|
573
|
-
value
|
|
574
|
-
}
|
|
575
|
-
});
|
|
554
|
+
const setCookie = headers.getSetCookie?.() ?? headers.get("set-cookie") ?? [];
|
|
555
|
+
const cookieStrings = Array.isArray(setCookie) ? setCookie : splitSetCookieString(setCookie);
|
|
556
|
+
for (const header of cookieStrings) {
|
|
557
|
+
const entry = parseSetCookieHeader(header);
|
|
558
|
+
if (entry) this._parsed.set(entry.name, entry);
|
|
576
559
|
}
|
|
577
560
|
}
|
|
578
561
|
set(...args) {
|
|
579
562
|
const [name, value, opts] = parseCookieSetArgs(args);
|
|
580
563
|
validateCookieName(name);
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
expires: typeof opts?.expires === "number" ? new Date(opts.expires) : opts?.expires,
|
|
585
|
-
sameSite
|
|
586
|
-
});
|
|
587
|
-
this._parsed.set(name, {
|
|
588
|
-
serialized,
|
|
589
|
-
entry: {
|
|
590
|
-
name,
|
|
591
|
-
value
|
|
592
|
-
}
|
|
593
|
-
});
|
|
564
|
+
const entry = normalizeResponseCookie(name, value, opts);
|
|
565
|
+
validateResponseCookieAttributes(entry);
|
|
566
|
+
this._parsed.set(name, entry);
|
|
594
567
|
this._syncHeaders();
|
|
595
568
|
return this;
|
|
596
569
|
}
|
|
597
570
|
get(...args) {
|
|
598
571
|
const key = typeof args[0] === "string" ? args[0] : args[0].name;
|
|
599
|
-
return this._parsed.get(key)
|
|
572
|
+
return this._parsed.get(key);
|
|
600
573
|
}
|
|
601
574
|
has(name) {
|
|
602
575
|
return this._parsed.has(name);
|
|
603
576
|
}
|
|
604
577
|
getAll(...args) {
|
|
605
|
-
const all = [...this._parsed.values()]
|
|
578
|
+
const all = [...this._parsed.values()];
|
|
606
579
|
if (args.length === 0) return all;
|
|
607
580
|
const key = typeof args[0] === "string" ? args[0] : args[0].name;
|
|
608
581
|
return all.filter((c) => c.name === key);
|
|
609
582
|
}
|
|
610
583
|
delete(...args) {
|
|
611
|
-
const [name,
|
|
584
|
+
const [name, options] = typeof args[0] === "string" ? [args[0], void 0] : [args[0].name, args[0]];
|
|
612
585
|
return this.set({
|
|
586
|
+
...options,
|
|
613
587
|
name,
|
|
614
588
|
value: "",
|
|
615
|
-
expires: /* @__PURE__ */ new Date(0)
|
|
616
|
-
path: opts?.path,
|
|
617
|
-
domain: opts?.domain,
|
|
618
|
-
httpOnly: opts?.httpOnly,
|
|
619
|
-
secure: opts?.secure,
|
|
620
|
-
sameSite: opts?.sameSite
|
|
589
|
+
expires: /* @__PURE__ */ new Date(0)
|
|
621
590
|
});
|
|
622
591
|
}
|
|
623
592
|
[Symbol.iterator]() {
|
|
624
|
-
return new Map([...this._parsed.values()].map((
|
|
593
|
+
return new Map([...this._parsed.values()].map((entry) => [entry.name, entry])).entries();
|
|
594
|
+
}
|
|
595
|
+
toString() {
|
|
596
|
+
return [...this._parsed.values()].map(stringifyResponseCookie).join("; ");
|
|
625
597
|
}
|
|
626
598
|
/** Delete all Set-Cookie headers and re-append from the internal map. */
|
|
627
599
|
_syncHeaders() {
|
|
628
600
|
this._headers.delete("Set-Cookie");
|
|
629
|
-
for (const
|
|
601
|
+
for (const entry of this._parsed.values()) this._headers.append("Set-Cookie", stringifyResponseCookie(entry));
|
|
630
602
|
}
|
|
631
603
|
};
|
|
632
604
|
var MiddlewareResponseCookies = class extends ResponseCookies {
|
|
@@ -654,6 +626,115 @@ var MiddlewareResponseCookies = class extends ResponseCookies {
|
|
|
654
626
|
this._responseHeaders.set(MIDDLEWARE_SET_COOKIE_HEADER, cookies.join(","));
|
|
655
627
|
}
|
|
656
628
|
};
|
|
629
|
+
function normalizeResponseCookie(name, value, options) {
|
|
630
|
+
const cookie = {
|
|
631
|
+
name,
|
|
632
|
+
value,
|
|
633
|
+
...options
|
|
634
|
+
};
|
|
635
|
+
if (typeof cookie.expires === "number") cookie.expires = new Date(cookie.expires);
|
|
636
|
+
if (cookie.maxAge) cookie.expires = new Date(Date.now() + cookie.maxAge * 1e3);
|
|
637
|
+
if (cookie.path == null) cookie.path = "/";
|
|
638
|
+
return cookie;
|
|
639
|
+
}
|
|
640
|
+
function parseSetCookieHeader(header) {
|
|
641
|
+
if (!header) return void 0;
|
|
642
|
+
const [[name, value], ...attributes] = parseResponseCookiePairs(header);
|
|
643
|
+
const { domain, expires, httponly, maxage, path, samesite, secure, partitioned, priority } = Object.fromEntries(attributes.map(([key, attributeValue]) => [key.toLowerCase().replaceAll("-", ""), attributeValue]));
|
|
644
|
+
return compactResponseCookie({
|
|
645
|
+
name,
|
|
646
|
+
value: decodeURIComponent(value),
|
|
647
|
+
domain,
|
|
648
|
+
...expires && { expires: new Date(expires) },
|
|
649
|
+
...httponly && { httpOnly: true },
|
|
650
|
+
...typeof maxage === "string" && { maxAge: Number(maxage) },
|
|
651
|
+
path,
|
|
652
|
+
...samesite && { sameSite: parseResponseCookieSameSite(samesite) },
|
|
653
|
+
...secure && { secure: true },
|
|
654
|
+
...priority && { priority: parseResponseCookiePriority(priority) },
|
|
655
|
+
...partitioned && { partitioned: true }
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
function parseResponseCookiePairs(cookie) {
|
|
659
|
+
const map = /* @__PURE__ */ new Map();
|
|
660
|
+
for (const pair of cookie.split(/; */)) {
|
|
661
|
+
if (!pair) continue;
|
|
662
|
+
const splitAt = pair.indexOf("=");
|
|
663
|
+
if (splitAt === -1) {
|
|
664
|
+
map.set(pair, "true");
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
const key = pair.slice(0, splitAt);
|
|
668
|
+
const value = pair.slice(splitAt + 1);
|
|
669
|
+
try {
|
|
670
|
+
map.set(key, decodeURIComponent(value ?? "true"));
|
|
671
|
+
} catch {}
|
|
672
|
+
}
|
|
673
|
+
return map;
|
|
674
|
+
}
|
|
675
|
+
function compactResponseCookie(cookie) {
|
|
676
|
+
const compact = {};
|
|
677
|
+
for (const key in cookie) if (cookie[key]) compact[key] = cookie[key];
|
|
678
|
+
return compact;
|
|
679
|
+
}
|
|
680
|
+
function parseResponseCookieSameSite(value) {
|
|
681
|
+
const sameSite = value.toLowerCase();
|
|
682
|
+
return sameSite === "strict" || sameSite === "lax" || sameSite === "none" ? sameSite : void 0;
|
|
683
|
+
}
|
|
684
|
+
function parseResponseCookiePriority(value) {
|
|
685
|
+
const priority = value.toLowerCase();
|
|
686
|
+
return priority === "low" || priority === "medium" || priority === "high" ? priority : void 0;
|
|
687
|
+
}
|
|
688
|
+
function validateResponseCookieAttributes(cookie) {
|
|
689
|
+
if (cookie.path) validateCookieAttributeValue(cookie.path, "Path");
|
|
690
|
+
if (cookie.domain) validateCookieAttributeValue(cookie.domain, "Domain");
|
|
691
|
+
}
|
|
692
|
+
function stringifyResponseCookie(cookie) {
|
|
693
|
+
const attributes = [
|
|
694
|
+
cookie.path && `Path=${cookie.path}`,
|
|
695
|
+
(cookie.expires || cookie.expires === 0) && `Expires=${(typeof cookie.expires === "number" ? new Date(cookie.expires) : cookie.expires).toUTCString()}`,
|
|
696
|
+
typeof cookie.maxAge === "number" && `Max-Age=${cookie.maxAge}`,
|
|
697
|
+
cookie.domain && `Domain=${cookie.domain}`,
|
|
698
|
+
cookie.secure && "Secure",
|
|
699
|
+
cookie.httpOnly && "HttpOnly",
|
|
700
|
+
cookie.sameSite && `SameSite=${cookie.sameSite}`,
|
|
701
|
+
cookie.partitioned && "Partitioned",
|
|
702
|
+
cookie.priority && `Priority=${cookie.priority}`
|
|
703
|
+
].filter(Boolean);
|
|
704
|
+
const stringified = `${cookie.name}=${encodeURIComponent(cookie.value ?? "")}`;
|
|
705
|
+
return attributes.length === 0 ? stringified : `${stringified}; ${attributes.join("; ")}`;
|
|
706
|
+
}
|
|
707
|
+
function splitSetCookieString(value) {
|
|
708
|
+
const cookies = [];
|
|
709
|
+
let position = 0;
|
|
710
|
+
let start = 0;
|
|
711
|
+
const skipWhitespace = () => {
|
|
712
|
+
while (position < value.length && /\s/.test(value.charAt(position))) position++;
|
|
713
|
+
return position < value.length;
|
|
714
|
+
};
|
|
715
|
+
while (position < value.length) {
|
|
716
|
+
start = position;
|
|
717
|
+
let separatorFound = false;
|
|
718
|
+
while (skipWhitespace()) {
|
|
719
|
+
if (value.charAt(position) !== ",") {
|
|
720
|
+
position++;
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
const lastComma = position++;
|
|
724
|
+
skipWhitespace();
|
|
725
|
+
const nextStart = position;
|
|
726
|
+
while (position < value.length && !"=;,".includes(value.charAt(position))) position++;
|
|
727
|
+
if (position < value.length && value.charAt(position) === "=") {
|
|
728
|
+
separatorFound = true;
|
|
729
|
+
position = nextStart;
|
|
730
|
+
cookies.push(value.substring(start, lastComma));
|
|
731
|
+
start = position;
|
|
732
|
+
} else position = lastComma + 1;
|
|
733
|
+
}
|
|
734
|
+
if (!separatorFound || position >= value.length) cookies.push(value.substring(start));
|
|
735
|
+
}
|
|
736
|
+
return cookies;
|
|
737
|
+
}
|
|
657
738
|
/**
|
|
658
739
|
* Parse the overloaded arguments for ResponseCookies.set():
|
|
659
740
|
* - (name, value, options?) — positional form
|
|
@@ -730,18 +811,36 @@ function userAgent({ headers }) {
|
|
|
730
811
|
*
|
|
731
812
|
* Uses the platform's `waitUntil` (via the per-request ExecutionContext) when
|
|
732
813
|
* available so the task survives past the response on Cloudflare Workers.
|
|
733
|
-
*
|
|
734
|
-
* context (e.g. Node.js dev server).
|
|
814
|
+
* Node.js dev drains callbacks from its response finish/close lifecycle.
|
|
735
815
|
*
|
|
736
816
|
* Throws when called inside a cached scope — request-specific
|
|
737
817
|
* side-effects must not leak into cached results.
|
|
738
818
|
*/
|
|
739
819
|
function after(task) {
|
|
740
820
|
_throwIfInsideCacheScope("after()");
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
821
|
+
const requestContext = isInsideUnifiedScope() ? getRequestContext() : null;
|
|
822
|
+
if (!requestContext) {
|
|
823
|
+
const executionContext = getRequestExecutionContext();
|
|
824
|
+
if (executionContext) {
|
|
825
|
+
if (typeof task !== "function" && (task == null || typeof task.then !== "function")) throw new TypeError("`after()`: Argument must be a promise or a function");
|
|
826
|
+
const promise = typeof task === "function" ? Promise.resolve().then(task) : task;
|
|
827
|
+
const guarded = Promise.resolve(promise).catch((error) => {
|
|
828
|
+
console.error("[vinext] after() task failed:", error);
|
|
829
|
+
});
|
|
830
|
+
executionContext.waitUntil(guarded);
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
throw new Error("`after()` was called outside a request scope");
|
|
834
|
+
}
|
|
835
|
+
if (typeof task !== "function") {
|
|
836
|
+
if (task == null || typeof task.then !== "function") throw new TypeError("`after()`: Argument must be a promise or a function");
|
|
837
|
+
const guarded = Promise.resolve(task).catch((error) => {
|
|
838
|
+
console.error("[vinext] after() task failed:", error);
|
|
839
|
+
});
|
|
840
|
+
getRequestExecutionContext()?.waitUntil(guarded);
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
queueAfterCallback(requestContext, bindRequestContextSnapshot(requestContext, task));
|
|
745
844
|
}
|
|
746
845
|
/**
|
|
747
846
|
* connection() — signals that the response requires a live connection
|
package/dist/shims/slot.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ type MergeElementsOptions = {
|
|
|
25
25
|
preservePreviousSlotIds?: readonly string[];
|
|
26
26
|
};
|
|
27
27
|
declare function updateBfcacheSlotEntryOrder(previousOrder: readonly string[], activeStateKey: string, maxEntries?: number): string[];
|
|
28
|
+
declare function getNonCacheComponentsSegmentKey(id: string, activeStateKey: string): string | undefined;
|
|
28
29
|
declare function mergeElements(prev: AppElements, next: AppElements, options?: MergeElementsOptions | boolean): AppElements;
|
|
29
30
|
declare function Slot({
|
|
30
31
|
id,
|
|
@@ -42,4 +43,4 @@ declare function ParallelSlot({
|
|
|
42
43
|
name: string;
|
|
43
44
|
}): string | number | bigint | boolean | Iterable<React$1.ReactNode> | Promise<string | number | bigint | boolean | Iterable<React$1.ReactNode> | React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>> | React$1.ReactPortal | null | undefined> | React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>> | null;
|
|
44
45
|
//#endregion
|
|
45
|
-
export { BfcacheSlotEntry, BfcacheStateKeyMapContext, Children, ChildrenContext, ElementsContext, ParallelSlot, ParallelSlotsContext, Slot, UNMATCHED_SLOT, mergeElements, updateBfcacheSlotEntryOrder };
|
|
46
|
+
export { BfcacheSlotEntry, BfcacheStateKeyMapContext, Children, ChildrenContext, ElementsContext, ParallelSlot, ParallelSlotsContext, Slot, UNMATCHED_SLOT, getNonCacheComponentsSegmentKey, mergeElements, updateBfcacheSlotEntryOrder };
|
package/dist/shims/slot.js
CHANGED
|
@@ -137,6 +137,10 @@ function BfcacheActivitySlotBoundary({ activeStateKey, content, elements, id, Se
|
|
|
137
137
|
})
|
|
138
138
|
}, entry.stateKey)) });
|
|
139
139
|
}
|
|
140
|
+
function getNonCacheComponentsSegmentKey(id, activeStateKey) {
|
|
141
|
+
const parsed = AppElementsWire.parseElementKey(id);
|
|
142
|
+
return parsed?.kind === "page" || parsed?.kind === "slot" && parsed.name === "children" ? activeStateKey : void 0;
|
|
143
|
+
}
|
|
140
144
|
function BfcacheSlotBoundary({ content, id }) {
|
|
141
145
|
const SegmentContext = BfcacheSegmentIdContext;
|
|
142
146
|
const elements = React$1.useContext(ElementsContext);
|
|
@@ -150,7 +154,7 @@ function BfcacheSlotBoundary({ content, id }) {
|
|
|
150
154
|
if (!isCacheComponentsEnabled()) return /* @__PURE__ */ jsx(SegmentContext.Provider, {
|
|
151
155
|
value: id,
|
|
152
156
|
children: content
|
|
153
|
-
});
|
|
157
|
+
}, getNonCacheComponentsSegmentKey(id, activeStateKey));
|
|
154
158
|
return /* @__PURE__ */ jsx(BfcacheActivitySlotBoundary, {
|
|
155
159
|
activeStateKey,
|
|
156
160
|
content,
|
|
@@ -224,4 +228,4 @@ function ParallelSlot({ name }) {
|
|
|
224
228
|
return React$1.useContext(ParallelSlotsContext)?.[name] ?? null;
|
|
225
229
|
}
|
|
226
230
|
//#endregion
|
|
227
|
-
export { BfcacheStateKeyMapContext, Children, ChildrenContext, ElementsContext, ParallelSlot, ParallelSlotsContext, Slot, UNMATCHED_SLOT, mergeElements, updateBfcacheSlotEntryOrder };
|
|
231
|
+
export { BfcacheStateKeyMapContext, Children, ChildrenContext, ElementsContext, ParallelSlot, ParallelSlotsContext, Slot, UNMATCHED_SLOT, getNonCacheComponentsSegmentKey, mergeElements, updateBfcacheSlotEntryOrder };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/shims/streamed-icons.d.ts
|
|
2
|
+
declare function reconcileStreamedIcons(metadataKey: string): void;
|
|
3
|
+
declare function StreamedIconsInsertion({
|
|
4
|
+
metadataKey
|
|
5
|
+
}: {
|
|
6
|
+
metadataKey: string;
|
|
7
|
+
}): null;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { StreamedIconsInsertion, reconcileStreamedIcons };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLayoutEffect } from "react";
|
|
3
|
+
//#region src/shims/streamed-icons.tsx
|
|
4
|
+
const STREAMED_ICON_ATTRIBUTE = "data-vinext-streamed-icon";
|
|
5
|
+
function getStreamedIconOrder(icon, metadataKey) {
|
|
6
|
+
const marker = icon.getAttribute(STREAMED_ICON_ATTRIBUTE);
|
|
7
|
+
const prefix = `${metadataKey}:`;
|
|
8
|
+
if (!marker?.startsWith(prefix)) return null;
|
|
9
|
+
const order = Number(marker.slice(prefix.length));
|
|
10
|
+
return Number.isInteger(order) && order >= 0 ? order : null;
|
|
11
|
+
}
|
|
12
|
+
function reconcileStreamedIcons(metadataKey) {
|
|
13
|
+
document.querySelectorAll(`body link[${STREAMED_ICON_ATTRIBUTE}]`).forEach((icon) => document.head.appendChild(icon));
|
|
14
|
+
const ownedIcons = [...document.querySelectorAll(`head link[${STREAMED_ICON_ATTRIBUTE}]`)];
|
|
15
|
+
const retainedIcons = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const icon of ownedIcons) {
|
|
17
|
+
const order = getStreamedIconOrder(icon, metadataKey);
|
|
18
|
+
if (order === null) {
|
|
19
|
+
icon.remove();
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const previousIcon = retainedIcons.get(order);
|
|
23
|
+
if (previousIcon) previousIcon.remove();
|
|
24
|
+
retainedIcons.set(order, icon);
|
|
25
|
+
}
|
|
26
|
+
for (const [, icon] of [...retainedIcons].sort(([leftOrder], [rightOrder]) => leftOrder - rightOrder)) document.head.appendChild(icon);
|
|
27
|
+
}
|
|
28
|
+
function StreamedIconsInsertion({ metadataKey }) {
|
|
29
|
+
useLayoutEffect(() => reconcileStreamedIcons(metadataKey), [metadataKey]);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { StreamedIconsInsertion, reconcileStreamedIcons };
|
|
@@ -18,13 +18,32 @@ import { NavigationState } from "./navigation-state.js";
|
|
|
18
18
|
*/
|
|
19
19
|
type UnifiedRequestContext = {
|
|
20
20
|
/** Cloudflare Workers ExecutionContext, or null on Node.js dev. */executionContext: ExecutionContextLike | null; /** Per-request cache for cacheForRequest(). Keyed by factory function reference. */
|
|
21
|
-
requestCache: WeakMap<(...args: any[]) => any, unknown>;
|
|
21
|
+
requestCache: WeakMap<(...args: any[]) => any, unknown>; /** Shared lifecycle state for work deferred until the response closes. */
|
|
22
|
+
afterContext: AfterRequestContext;
|
|
22
23
|
} & VinextHeadersShimState & I18nState & NavigationState & CacheState & PrivateCacheState & FetchCacheState & RouterState & HeadState & RootParamsState;
|
|
24
|
+
type AfterRequestContext = {
|
|
25
|
+
callbacks: Array<() => unknown>;
|
|
26
|
+
responseClosed: boolean;
|
|
27
|
+
pendingCallbacks: number;
|
|
28
|
+
completion: Promise<void> | null;
|
|
29
|
+
resolveCompletion: (() => void) | null;
|
|
30
|
+
};
|
|
23
31
|
/**
|
|
24
32
|
* Create a fresh `UnifiedRequestContext` with defaults for all fields.
|
|
25
33
|
* Pass partial overrides for the fields you need to pre-populate.
|
|
26
34
|
*/
|
|
27
35
|
declare function createRequestContext(opts?: Partial<UnifiedRequestContext>): UnifiedRequestContext;
|
|
36
|
+
/** Queue a callback until response close, or start it immediately once closed. */
|
|
37
|
+
declare function queueAfterCallback(ctx: UnifiedRequestContext, callback: () => unknown): void;
|
|
38
|
+
/** Bind a callback to every AsyncLocalStorage context active at registration. */
|
|
39
|
+
declare function bindRequestContextSnapshot<T>(ctx: UnifiedRequestContext, callback: () => T): () => T;
|
|
40
|
+
/**
|
|
41
|
+
* Release function-form `after()` work once the response body has closed.
|
|
42
|
+
* All queued callbacks start together, matching Next.js' unbounded PromiseQueue.
|
|
43
|
+
*/
|
|
44
|
+
declare function closeAfterResponse(ctx: UnifiedRequestContext): Promise<void>;
|
|
45
|
+
/** Wrap a response so deferred callbacks start on stream completion or cancellation. */
|
|
46
|
+
declare function closeAfterResponseWithBody(response: Response, ctx: UnifiedRequestContext): Response;
|
|
28
47
|
/**
|
|
29
48
|
* Run `fn` within a unified request context scope.
|
|
30
49
|
* All shim modules will read/write their state from `ctx` for the
|
|
@@ -65,4 +84,4 @@ declare function getRequestContext(): UnifiedRequestContext;
|
|
|
65
84
|
*/
|
|
66
85
|
declare function isInsideUnifiedScope(): boolean;
|
|
67
86
|
//#endregion
|
|
68
|
-
export { UnifiedRequestContext, createRequestContext, getRequestContext, isInsideUnifiedScope, runWithRequestContext, runWithUnifiedStateMutation };
|
|
87
|
+
export { AfterRequestContext, UnifiedRequestContext, bindRequestContextSnapshot, closeAfterResponse, closeAfterResponseWithBody, createRequestContext, getRequestContext, isInsideUnifiedScope, queueAfterCallback, runWithRequestContext, runWithUnifiedStateMutation };
|
|
@@ -43,6 +43,13 @@ function createRequestContext(opts) {
|
|
|
43
43
|
currentFetchDedupeEntries: /* @__PURE__ */ new Map(),
|
|
44
44
|
executionContext: _getInheritedExecutionContext(),
|
|
45
45
|
requestCache: /* @__PURE__ */ new WeakMap(),
|
|
46
|
+
afterContext: {
|
|
47
|
+
callbacks: [],
|
|
48
|
+
responseClosed: false,
|
|
49
|
+
pendingCallbacks: 0,
|
|
50
|
+
completion: null,
|
|
51
|
+
resolveCompletion: null
|
|
52
|
+
},
|
|
46
53
|
ssrContext: null,
|
|
47
54
|
ssrHeadChildren: [],
|
|
48
55
|
documentInitialHead: [],
|
|
@@ -50,6 +57,80 @@ function createRequestContext(opts) {
|
|
|
50
57
|
...opts
|
|
51
58
|
};
|
|
52
59
|
}
|
|
60
|
+
function ensureAfterCompletion(ctx) {
|
|
61
|
+
const state = ctx.afterContext;
|
|
62
|
+
if (state.resolveCompletion && state.completion) return;
|
|
63
|
+
let resolveCompletion;
|
|
64
|
+
const completion = new Promise((resolve) => {
|
|
65
|
+
resolveCompletion = resolve;
|
|
66
|
+
});
|
|
67
|
+
state.completion = completion;
|
|
68
|
+
state.resolveCompletion = resolveCompletion;
|
|
69
|
+
ctx.executionContext?.waitUntil(completion);
|
|
70
|
+
}
|
|
71
|
+
function finishAfterCallbacksIfIdle(ctx) {
|
|
72
|
+
const state = ctx.afterContext;
|
|
73
|
+
if (!state.responseClosed || state.pendingCallbacks !== 0 || state.callbacks.length !== 0 || !state.resolveCompletion) return;
|
|
74
|
+
const resolveCompletion = state.resolveCompletion;
|
|
75
|
+
state.resolveCompletion = null;
|
|
76
|
+
resolveCompletion();
|
|
77
|
+
}
|
|
78
|
+
function startAfterCallback(ctx, callback) {
|
|
79
|
+
const state = ctx.afterContext;
|
|
80
|
+
ensureAfterCompletion(ctx);
|
|
81
|
+
state.pendingCallbacks += 1;
|
|
82
|
+
Promise.resolve().then(callback).catch((error) => {
|
|
83
|
+
console.error("[vinext] after() task failed:", error);
|
|
84
|
+
}).finally(() => {
|
|
85
|
+
state.pendingCallbacks -= 1;
|
|
86
|
+
finishAfterCallbacksIfIdle(ctx);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Queue a callback until response close, or start it immediately once closed. */
|
|
90
|
+
function queueAfterCallback(ctx, callback) {
|
|
91
|
+
ensureAfterCompletion(ctx);
|
|
92
|
+
if (ctx.afterContext.responseClosed) startAfterCallback(ctx, callback);
|
|
93
|
+
else ctx.afterContext.callbacks.push(callback);
|
|
94
|
+
}
|
|
95
|
+
/** Bind a callback to every AsyncLocalStorage context active at registration. */
|
|
96
|
+
function bindRequestContextSnapshot(ctx, callback) {
|
|
97
|
+
const constructor = _als.constructor;
|
|
98
|
+
try {
|
|
99
|
+
const runInSnapshot = constructor.snapshot?.();
|
|
100
|
+
if (runInSnapshot) return () => runInSnapshot(callback);
|
|
101
|
+
} catch {}
|
|
102
|
+
return () => _als.run(ctx, callback);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Release function-form `after()` work once the response body has closed.
|
|
106
|
+
* All queued callbacks start together, matching Next.js' unbounded PromiseQueue.
|
|
107
|
+
*/
|
|
108
|
+
async function closeAfterResponse(ctx) {
|
|
109
|
+
const state = ctx.afterContext;
|
|
110
|
+
if (!state.responseClosed) {
|
|
111
|
+
state.responseClosed = true;
|
|
112
|
+
const callbacks = state.callbacks.splice(0);
|
|
113
|
+
for (const callback of callbacks) startAfterCallback(ctx, callback);
|
|
114
|
+
finishAfterCallbacksIfIdle(ctx);
|
|
115
|
+
}
|
|
116
|
+
return state.completion ?? Promise.resolve();
|
|
117
|
+
}
|
|
118
|
+
/** Wrap a response so deferred callbacks start on stream completion or cancellation. */
|
|
119
|
+
function closeAfterResponseWithBody(response, ctx) {
|
|
120
|
+
if (!response.body) {
|
|
121
|
+
queueMicrotask(() => void closeAfterResponse(ctx));
|
|
122
|
+
return response;
|
|
123
|
+
}
|
|
124
|
+
const passthrough = new TransformStream();
|
|
125
|
+
response.body.pipeTo(passthrough.writable).then(() => void closeAfterResponse(ctx), () => void closeAfterResponse(ctx));
|
|
126
|
+
const wrapped = new Response(passthrough.readable, {
|
|
127
|
+
status: response.status,
|
|
128
|
+
statusText: response.statusText,
|
|
129
|
+
headers: response.headers
|
|
130
|
+
});
|
|
131
|
+
wrapped.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
|
|
132
|
+
return wrapped;
|
|
133
|
+
}
|
|
53
134
|
function runWithRequestContext(ctx, fn) {
|
|
54
135
|
return _als.run(ctx, fn);
|
|
55
136
|
}
|
|
@@ -86,4 +167,4 @@ function isInsideUnifiedScope() {
|
|
|
86
167
|
return _als.getStore() != null;
|
|
87
168
|
}
|
|
88
169
|
//#endregion
|
|
89
|
-
export { createRequestContext, getRequestContext, isInsideUnifiedScope, runWithRequestContext, runWithUnifiedStateMutation };
|
|
170
|
+
export { bindRequestContextSnapshot, closeAfterResponse, closeAfterResponseWithBody, createRequestContext, getRequestContext, isInsideUnifiedScope, queueAfterCallback, runWithRequestContext, runWithUnifiedStateMutation };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/utils/cache-control-metadata.d.ts
|
|
2
2
|
declare function readCacheControlNumberField(ctx: Record<string, unknown> | undefined, field: string): number | undefined;
|
|
3
|
+
declare function readCacheControlRevalidateField(ctx: Record<string, unknown> | undefined): number | false | undefined;
|
|
3
4
|
//#endregion
|
|
4
|
-
export { readCacheControlNumberField };
|
|
5
|
+
export { readCacheControlNumberField, readCacheControlRevalidateField };
|
|
@@ -8,5 +8,9 @@ function readCacheControlNumberField(ctx, field) {
|
|
|
8
8
|
const value = readRecordField(ctx, "cacheControl")?.[field] ?? ctx?.[field];
|
|
9
9
|
return typeof value === "number" ? value : void 0;
|
|
10
10
|
}
|
|
11
|
+
function readCacheControlRevalidateField(ctx) {
|
|
12
|
+
const value = readRecordField(ctx, "cacheControl")?.revalidate ?? ctx?.revalidate;
|
|
13
|
+
return typeof value === "number" || value === false ? value : void 0;
|
|
14
|
+
}
|
|
11
15
|
//#endregion
|
|
12
|
-
export { readCacheControlNumberField };
|
|
16
|
+
export { readCacheControlNumberField, readCacheControlRevalidateField };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/utils/html-limited-bots.ts
|
|
2
|
-
const HTML_LIMITED_BOT_UA_RE_STRING = String.raw`[\w-]+-Google|Google-[\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight`;
|
|
2
|
+
const HTML_LIMITED_BOT_UA_RE_STRING = String.raw`[\w-]+-Google|Google-[\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|meta-externalagent|meta-externalfetcher|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight`;
|
|
3
3
|
const HEADLESS_BROWSER_BOT_UA_RE = /Googlebot(?!-)|Googlebot$/i;
|
|
4
4
|
const htmlLimitedBotRegexCache = /* @__PURE__ */ new Map();
|
|
5
5
|
function getHtmlLimitedBotRegex(htmlLimitedBots) {
|
|
@@ -7,6 +7,8 @@ declare const VINEXT_PRERENDER_SECRET_HEADER = "x-vinext-prerender-secret";
|
|
|
7
7
|
declare const VINEXT_PRERENDER_ROUTE_PARAMS_HEADER = "x-vinext-prerender-route-params";
|
|
8
8
|
/** Indicates a build-time prerender render is probing whether a route can be static. */
|
|
9
9
|
declare const VINEXT_PRERENDER_SPECULATIVE_HEADER = "x-vinext-prerender-speculative";
|
|
10
|
+
/** Logical hostname carried only by authenticated Node revalidation loopbacks. */
|
|
11
|
+
declare const VINEXT_REVALIDATE_HOST_HEADER = "x-vinext-revalidate-host";
|
|
10
12
|
/** Prefix for forwarded request headers (e.g. `x-middleware-request-cookie`). */
|
|
11
13
|
declare const MIDDLEWARE_REQUEST_HEADER_PREFIX = "x-middleware-request-";
|
|
12
14
|
/** Comma-separated list of header names that middleware wants to override. */
|
|
@@ -19,5 +21,9 @@ declare const MIDDLEWARE_CACHE_HEADER = "x-middleware-cache";
|
|
|
19
21
|
declare const MIDDLEWARE_SKIP_HEADER = "x-middleware-skip";
|
|
20
22
|
/** Generic prefix for all middleware internal headers. */
|
|
21
23
|
declare const MIDDLEWARE_HEADER_PREFIX = "x-middleware-";
|
|
24
|
+
/** Authenticates an internal Pages Router on-demand revalidation request. */
|
|
25
|
+
declare const PRERENDER_REVALIDATE_HEADER = "x-prerender-revalidate";
|
|
26
|
+
/** Restricts on-demand revalidation to paths that were already generated. */
|
|
27
|
+
declare const PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = "x-prerender-revalidate-if-generated";
|
|
22
28
|
//#endregion
|
|
23
|
-
export { MIDDLEWARE_CACHE_HEADER, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER };
|
|
29
|
+
export { MIDDLEWARE_CACHE_HEADER, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_REVALIDATE_HOST_HEADER };
|
|
@@ -7,6 +7,8 @@ const VINEXT_PRERENDER_SECRET_HEADER = "x-vinext-prerender-secret";
|
|
|
7
7
|
const VINEXT_PRERENDER_ROUTE_PARAMS_HEADER = "x-vinext-prerender-route-params";
|
|
8
8
|
/** Indicates a build-time prerender render is probing whether a route can be static. */
|
|
9
9
|
const VINEXT_PRERENDER_SPECULATIVE_HEADER = "x-vinext-prerender-speculative";
|
|
10
|
+
/** Logical hostname carried only by authenticated Node revalidation loopbacks. */
|
|
11
|
+
const VINEXT_REVALIDATE_HOST_HEADER = "x-vinext-revalidate-host";
|
|
10
12
|
/** Prefix for forwarded request headers (e.g. `x-middleware-request-cookie`). */
|
|
11
13
|
const MIDDLEWARE_REQUEST_HEADER_PREFIX = "x-middleware-request-";
|
|
12
14
|
/** Comma-separated list of header names that middleware wants to override. */
|
|
@@ -19,5 +21,9 @@ const MIDDLEWARE_CACHE_HEADER = "x-middleware-cache";
|
|
|
19
21
|
const MIDDLEWARE_SKIP_HEADER = "x-middleware-skip";
|
|
20
22
|
/** Generic prefix for all middleware internal headers. */
|
|
21
23
|
const MIDDLEWARE_HEADER_PREFIX = "x-middleware-";
|
|
24
|
+
/** Authenticates an internal Pages Router on-demand revalidation request. */
|
|
25
|
+
const PRERENDER_REVALIDATE_HEADER = "x-prerender-revalidate";
|
|
26
|
+
/** Restricts on-demand revalidation to paths that were already generated. */
|
|
27
|
+
const PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = "x-prerender-revalidate-if-generated";
|
|
22
28
|
//#endregion
|
|
23
|
-
export { MIDDLEWARE_CACHE_HEADER, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER };
|
|
29
|
+
export { MIDDLEWARE_CACHE_HEADER, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_REVALIDATE_HOST_HEADER };
|