vinext 0.1.3 → 0.1.5
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/build/client-build-config.d.ts +11 -2
- package/dist/build/client-build-config.js +17 -6
- package/dist/build/css-url-assets.d.ts +1 -1
- package/dist/build/css-url-assets.js +9 -7
- package/dist/build/prerender.js +3 -1
- package/dist/cache/cache-adapters-virtual.js +1 -1
- package/dist/client/pages-router-link-navigation.d.ts +33 -7
- package/dist/client/pages-router-link-navigation.js +32 -2
- package/dist/client/vinext-next-data.js +2 -0
- package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +1 -1
- package/dist/config/config-matchers.d.ts +11 -1
- package/dist/config/config-matchers.js +14 -2
- package/dist/config/tsconfig-paths.js +14 -1
- package/dist/deploy.js +20 -13
- package/dist/entries/app-rsc-entry.js +27 -22
- package/dist/entries/pages-client-entry.js +14 -13
- package/dist/entries/pages-server-entry.js +8 -27
- package/dist/index.js +365 -147
- package/dist/plugins/css-data-url.js +30 -26
- package/dist/plugins/dynamic-preload-metadata.js +2 -4
- package/dist/plugins/extensionless-dynamic-import.js +27 -24
- package/dist/plugins/fonts.js +5 -4
- package/dist/plugins/import-meta-url.js +21 -15
- package/dist/plugins/instrumentation-client.js +1 -1
- package/dist/plugins/middleware-server-only.js +7 -6
- package/dist/plugins/og-assets.js +48 -46
- package/dist/plugins/optimize-imports.js +9 -3
- package/dist/plugins/remove-console.d.ts +7 -1
- package/dist/plugins/remove-console.js +4 -1
- package/dist/plugins/require-context.js +21 -20
- package/dist/plugins/strip-server-exports.d.ts +16 -8
- package/dist/plugins/strip-server-exports.js +496 -46
- package/dist/routing/app-route-graph.js +2 -2
- package/dist/server/app-bfcache-identity.d.ts +26 -0
- package/dist/server/app-bfcache-identity.js +127 -0
- package/dist/server/app-browser-action-result.js +1 -1
- package/dist/server/app-browser-entry.js +22 -12
- package/dist/server/app-browser-navigation-controller.d.ts +1 -1
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-state.d.ts +3 -22
- package/dist/server/app-browser-state.js +23 -139
- package/dist/server/app-browser-stream.js +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +1 -1
- package/dist/server/app-browser-visible-commit.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-layout-param-observation.js +1 -1
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -1
- package/dist/server/app-page-boundary.js +1 -1
- package/dist/server/app-page-cache-finalizer.d.ts +62 -0
- package/dist/server/app-page-cache-finalizer.js +122 -0
- package/dist/server/app-page-cache-render.d.ts +2 -2
- package/dist/server/app-page-cache-render.js +1 -1
- package/dist/server/app-page-cache.d.ts +2 -53
- package/dist/server/app-page-cache.js +5 -131
- package/dist/server/app-page-dispatch.d.ts +2 -2
- package/dist/server/app-page-dispatch.js +10 -8
- package/dist/server/app-page-probe.js +3 -2
- package/dist/server/app-page-render-observation.js +2 -2
- package/dist/server/app-page-render.d.ts +3 -3
- package/dist/server/app-page-render.js +3 -2
- package/dist/server/app-page-stream.d.ts +2 -9
- package/dist/server/app-page-stream.js +1 -35
- package/dist/server/app-pages-bridge.d.ts +5 -1
- package/dist/server/app-pages-bridge.js +5 -13
- package/dist/server/app-request-context.d.ts +1 -2
- package/dist/server/app-request-context.js +2 -1
- package/dist/server/app-route-handler-dispatch.js +3 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-handler-execution.js +1 -1
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-router-entry.js +2 -1
- package/dist/server/app-rsc-handler.d.ts +3 -0
- package/dist/server/app-rsc-handler.js +73 -31
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.js +6 -2
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-server-action-execution.js +10 -6
- package/dist/server/app-ssr-entry.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +12 -38
- package/dist/server/app-ssr-router-instance.d.ts +6 -0
- package/dist/server/app-ssr-router-instance.js +24 -0
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/artifact-compatibility.js +1 -1
- package/dist/server/before-interactive-head.d.ts +17 -0
- package/dist/server/before-interactive-head.js +35 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/csp.js +1 -4
- package/dist/server/defer-until-stream-consumed.d.ts +7 -0
- package/dist/server/defer-until-stream-consumed.js +34 -0
- package/dist/server/dev-server.js +82 -37
- package/dist/server/instrumentation.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/isr-decision.d.ts +1 -1
- package/dist/server/middleware-matcher.js +20 -9
- package/dist/server/middleware-runtime.d.ts +3 -4
- package/dist/server/middleware-runtime.js +4 -2
- package/dist/server/navigation-planner.d.ts +3 -12
- package/dist/server/navigation-planner.js +24 -0
- package/dist/server/navigation-trace.d.ts +2 -1
- package/dist/server/navigation-trace.js +1 -0
- package/dist/server/open-redirect.d.ts +12 -0
- package/dist/server/open-redirect.js +21 -0
- package/dist/server/operation-token.d.ts +40 -0
- package/dist/server/operation-token.js +85 -0
- package/dist/server/pages-data-route.d.ts +1 -1
- package/dist/server/pages-data-route.js +7 -4
- package/dist/server/pages-dev-module-url.d.ts +4 -0
- package/dist/server/pages-dev-module-url.js +15 -0
- package/dist/server/pages-document-initial-props.d.ts +4 -15
- package/dist/server/pages-document-initial-props.js +27 -56
- package/dist/server/pages-i18n.js +2 -2
- package/dist/server/pages-page-data.d.ts +1 -1
- package/dist/server/pages-page-data.js +3 -1
- package/dist/server/pages-page-handler.js +3 -1
- package/dist/server/pages-page-response.d.ts +3 -1
- package/dist/server/pages-page-response.js +6 -6
- package/dist/server/pages-readiness.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +7 -7
- package/dist/server/pages-request-pipeline.js +63 -21
- package/dist/server/prod-server.d.ts +3 -1
- package/dist/server/prod-server.js +43 -11
- package/dist/server/request-pipeline.d.ts +1 -24
- package/dist/server/request-pipeline.js +1 -33
- package/dist/server/seed-cache.d.ts +1 -1
- package/dist/server/static-file-cache.js +16 -4
- package/dist/shims/before-interactive-context.d.ts +14 -3
- package/dist/shims/cache-handler.d.ts +106 -0
- package/dist/shims/cache-handler.js +176 -0
- package/dist/shims/cache-request-state.d.ts +47 -0
- package/dist/shims/cache-request-state.js +126 -0
- package/dist/shims/cache-runtime.d.ts +2 -2
- package/dist/shims/cache-runtime.js +3 -14
- package/dist/shims/cache.d.ts +3 -231
- package/dist/shims/cache.js +17 -383
- package/dist/shims/cdn-cache.d.ts +1 -1
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/document.d.ts +15 -20
- package/dist/shims/document.js +5 -8
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +44 -0
- package/dist/shims/error-boundary.js +10 -8
- package/dist/shims/error.js +2 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/form.js +1 -1
- package/dist/shims/image.js +74 -9
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
- package/dist/shims/internal/app-page-props-cache-key.js +16 -0
- package/dist/shims/internal/navigation-untracked.js +2 -1
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
- package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
- package/dist/shims/internal/pages-data-target.js +1 -1
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/layout-segment-context.js +2 -1
- package/dist/shims/link.js +38 -17
- package/dist/shims/metadata.js +4 -4
- package/dist/shims/navigation-context-state.d.ts +40 -0
- package/dist/shims/navigation-context-state.js +116 -0
- package/dist/shims/navigation-errors.d.ts +55 -0
- package/dist/shims/navigation-errors.js +110 -0
- package/dist/shims/navigation-server.d.ts +3 -0
- package/dist/shims/navigation-server.js +3 -0
- package/dist/shims/navigation-state.d.ts +1 -2
- package/dist/shims/navigation-state.js +2 -1
- package/dist/shims/navigation.d.ts +3 -291
- package/dist/shims/navigation.js +16 -445
- package/dist/shims/navigation.react-server.d.ts +2 -2
- package/dist/shims/navigation.react-server.js +3 -1
- package/dist/shims/request-state-types.d.ts +3 -3
- package/dist/shims/router.d.ts +6 -2
- package/dist/shims/router.js +99 -20
- package/dist/shims/script.js +9 -5
- package/dist/shims/slot.js +3 -1
- package/dist/shims/unified-request-context.d.ts +2 -2
- package/dist/utils/has-trailing-comma.d.ts +24 -0
- package/dist/utils/has-trailing-comma.js +62 -0
- package/dist/utils/text-stream.d.ts +1 -1
- package/dist/utils/text-stream.js +2 -2
- package/dist/utils/virtual-module.d.ts +5 -0
- package/dist/utils/virtual-module.js +0 -0
- package/dist/utils/vite-version.d.ts +12 -1
- package/dist/utils/vite-version.js +9 -1
- package/package.json +5 -1
|
@@ -3,6 +3,7 @@ declare const NAVIGATION_TRACE_SCHEMA_VERSION = 0;
|
|
|
3
3
|
type NavigationTraceSchemaVersion = 0;
|
|
4
4
|
declare const NavigationTraceReasonCodes: {
|
|
5
5
|
cacheProofRejected: "NC_CACHE_REJECT";
|
|
6
|
+
cacheReuseTokenRejected: "NC_CACHE_TOKEN_REJECT";
|
|
6
7
|
commitCurrent: "NC_COMMIT";
|
|
7
8
|
crossDocumentFlight: "NC_CROSS_DOC_FLIGHT";
|
|
8
9
|
fetchFresh: "NC_FETCH_FRESH";
|
|
@@ -42,7 +43,7 @@ declare const NavigationTraceTransactionCodes: {
|
|
|
42
43
|
type NavigationTraceReasonCode = (typeof NavigationTraceReasonCodes)[keyof typeof NavigationTraceReasonCodes];
|
|
43
44
|
type NavigationTraceTransactionCode = (typeof NavigationTraceTransactionCodes)[keyof typeof NavigationTraceTransactionCodes];
|
|
44
45
|
type NavigationTraceCode = NavigationTraceReasonCode | NavigationTraceTransactionCode;
|
|
45
|
-
type NavigationTraceFieldName = "activeNavigationId" | "cacheProofCode" | "cacheProofMode" | "cacheProofReuseClass" | "cacheProofScope" | "currentRootLayoutTreePath" | "currentVisibleCommitVersion" | "nextRootLayoutTreePath" | "eventKind" | "fetchResultSource" | "freshFetchReason" | "operationLane" | "pendingOperationId" | "redirectDepth" | "redirectSignal" | "startedVisibleCommitVersion" | "startedNavigationId" | "targetHref" | "traverseDirection";
|
|
46
|
+
type NavigationTraceFieldName = "activeNavigationId" | "cacheProofCode" | "cacheProofMode" | "cacheProofReuseClass" | "cacheProofScope" | "cacheReuseTokenReason" | "currentRootLayoutTreePath" | "currentVisibleCommitVersion" | "nextRootLayoutTreePath" | "eventKind" | "fetchResultSource" | "freshFetchReason" | "operationLane" | "pendingOperationId" | "redirectDepth" | "redirectSignal" | "startedVisibleCommitVersion" | "startedNavigationId" | "targetHref" | "traverseDirection";
|
|
46
47
|
type NavigationTraceFieldValue = string | number | boolean | null;
|
|
47
48
|
type NavigationTraceFields = Readonly<Partial<Record<NavigationTraceFieldName, NavigationTraceFieldValue>>>;
|
|
48
49
|
type NavigationTraceEntry = Readonly<{
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const NAVIGATION_TRACE_SCHEMA_VERSION = 0;
|
|
3
3
|
const NavigationTraceReasonCodes = {
|
|
4
4
|
cacheProofRejected: "NC_CACHE_REJECT",
|
|
5
|
+
cacheReuseTokenRejected: "NC_CACHE_TOKEN_REJECT",
|
|
5
6
|
commitCurrent: "NC_COMMIT",
|
|
6
7
|
crossDocumentFlight: "NC_CROSS_DOC_FLIGHT",
|
|
7
8
|
fetchFresh: "NC_FETCH_FRESH",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/server/open-redirect.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if a request pathname looks like a protocol-relative open
|
|
4
|
+
* redirect, in either literal or percent-encoded form.
|
|
5
|
+
*
|
|
6
|
+
* A pathname is considered "open redirect shaped" when its first segment,
|
|
7
|
+
* after decoding backslashes and encoded delimiters, would cause a browser
|
|
8
|
+
* to resolve a `Location` containing the pathname as protocol-relative.
|
|
9
|
+
*/
|
|
10
|
+
declare function isOpenRedirectShaped(rawPathname: string): boolean;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { isOpenRedirectShaped };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/server/open-redirect.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if a request pathname looks like a protocol-relative open
|
|
4
|
+
* redirect, in either literal or percent-encoded form.
|
|
5
|
+
*
|
|
6
|
+
* A pathname is considered "open redirect shaped" when its first segment,
|
|
7
|
+
* after decoding backslashes and encoded delimiters, would cause a browser
|
|
8
|
+
* to resolve a `Location` containing the pathname as protocol-relative.
|
|
9
|
+
*/
|
|
10
|
+
function isOpenRedirectShaped(rawPathname) {
|
|
11
|
+
if (!rawPathname.startsWith("/")) return false;
|
|
12
|
+
const afterSlash = rawPathname.slice(1);
|
|
13
|
+
if (afterSlash.startsWith("/") || afterSlash.startsWith("\\")) return true;
|
|
14
|
+
if (afterSlash.length >= 3 && afterSlash[0] === "%") {
|
|
15
|
+
const encoded = afterSlash.slice(0, 3).toLowerCase();
|
|
16
|
+
if (encoded === "%5c" || encoded === "%2f") return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { isOpenRedirectShaped };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/server/operation-token.d.ts
|
|
2
|
+
type OperationLane = "hmr" | "navigation" | "prefetch" | "refresh" | "server-action" | "traverse";
|
|
3
|
+
type OperationToken = {
|
|
4
|
+
operationId: number;
|
|
5
|
+
lane: OperationLane;
|
|
6
|
+
navigationId: number;
|
|
7
|
+
baseVisibleCommitVersion: number;
|
|
8
|
+
graphVersion: string | null;
|
|
9
|
+
deploymentVersion: string | null;
|
|
10
|
+
targetSnapshotFingerprint: string;
|
|
11
|
+
cacheVariantFingerprint?: string;
|
|
12
|
+
};
|
|
13
|
+
declare const verifiedOperationTokenBrand: unique symbol;
|
|
14
|
+
type VerifiedOperationToken = OperationToken & {
|
|
15
|
+
readonly [verifiedOperationTokenBrand]: true;
|
|
16
|
+
};
|
|
17
|
+
type OperationTokenAuthority = {
|
|
18
|
+
activeNavigationId: number;
|
|
19
|
+
visibleCommitVersion: number;
|
|
20
|
+
graphVersion: string | null;
|
|
21
|
+
installedCacheVariantFingerprint: string | null;
|
|
22
|
+
};
|
|
23
|
+
type OperationTokenDimension = "navigation" | "visibleCommit" | "graphVersion" | "cacheVariant";
|
|
24
|
+
type OperationTokenRejectionReason = "staleNavigation" | "staleVisibleCommit" | "graphVersionMismatch" | "graphVersionMissing" | "cacheVariantMismatch" | "cacheVariantMissing";
|
|
25
|
+
type OperationTokenVerdict = {
|
|
26
|
+
readonly authorized: true;
|
|
27
|
+
readonly token: VerifiedOperationToken;
|
|
28
|
+
} | {
|
|
29
|
+
readonly authorized: false;
|
|
30
|
+
readonly reason: OperationTokenRejectionReason;
|
|
31
|
+
};
|
|
32
|
+
type OperationTokenVerificationPolicy = {
|
|
33
|
+
check: readonly OperationTokenDimension[];
|
|
34
|
+
require: readonly OperationTokenDimension[];
|
|
35
|
+
};
|
|
36
|
+
declare function verifyOperationToken(token: OperationToken, authority: OperationTokenAuthority, policy: OperationTokenVerificationPolicy): OperationTokenVerdict;
|
|
37
|
+
declare function verifyOperationTokenForCommit(token: OperationToken, authority: Pick<OperationTokenAuthority, "activeNavigationId" | "visibleCommitVersion">): OperationTokenVerdict;
|
|
38
|
+
declare function verifyOperationTokenForCacheReuse(token: OperationToken, authority: Pick<OperationTokenAuthority, "graphVersion" | "installedCacheVariantFingerprint">): OperationTokenVerdict;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { OperationLane, OperationToken, OperationTokenAuthority, OperationTokenRejectionReason, OperationTokenVerdict, OperationTokenVerificationPolicy, VerifiedOperationToken, verifyOperationToken, verifyOperationTokenForCacheReuse, verifyOperationTokenForCommit };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
//#region src/server/operation-token.ts
|
|
2
|
+
const DIMENSION_ORDER = [
|
|
3
|
+
"navigation",
|
|
4
|
+
"visibleCommit",
|
|
5
|
+
"graphVersion",
|
|
6
|
+
"cacheVariant"
|
|
7
|
+
];
|
|
8
|
+
function evaluateDimension(dimension, token, authority) {
|
|
9
|
+
switch (dimension) {
|
|
10
|
+
case "navigation": return token.navigationId === authority.activeNavigationId ? { kind: "satisfied" } : {
|
|
11
|
+
kind: "mismatch",
|
|
12
|
+
reason: "staleNavigation"
|
|
13
|
+
};
|
|
14
|
+
case "visibleCommit": return token.baseVisibleCommitVersion === authority.visibleCommitVersion ? { kind: "satisfied" } : {
|
|
15
|
+
kind: "mismatch",
|
|
16
|
+
reason: "staleVisibleCommit"
|
|
17
|
+
};
|
|
18
|
+
case "graphVersion":
|
|
19
|
+
if (token.graphVersion === null || authority.graphVersion === null) return {
|
|
20
|
+
kind: "absent",
|
|
21
|
+
missingReason: "graphVersionMissing"
|
|
22
|
+
};
|
|
23
|
+
return token.graphVersion === authority.graphVersion ? { kind: "satisfied" } : {
|
|
24
|
+
kind: "mismatch",
|
|
25
|
+
reason: "graphVersionMismatch"
|
|
26
|
+
};
|
|
27
|
+
case "cacheVariant": {
|
|
28
|
+
const tokenVariant = token.cacheVariantFingerprint;
|
|
29
|
+
const installedVariant = authority.installedCacheVariantFingerprint;
|
|
30
|
+
if (tokenVariant === void 0 || installedVariant === null) return {
|
|
31
|
+
kind: "absent",
|
|
32
|
+
missingReason: "cacheVariantMissing"
|
|
33
|
+
};
|
|
34
|
+
return tokenVariant === installedVariant ? { kind: "satisfied" } : {
|
|
35
|
+
kind: "mismatch",
|
|
36
|
+
reason: "cacheVariantMismatch"
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
default: throw new Error("[vinext] Unknown operation-token dimension: " + String(dimension));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function verifyOperationToken(token, authority, policy) {
|
|
43
|
+
const required = new Set(policy.require);
|
|
44
|
+
const evaluated = new Set([...policy.check, ...policy.require]);
|
|
45
|
+
for (const dimension of DIMENSION_ORDER) {
|
|
46
|
+
if (!evaluated.has(dimension)) continue;
|
|
47
|
+
const status = evaluateDimension(dimension, token, authority);
|
|
48
|
+
if (status.kind === "mismatch") return {
|
|
49
|
+
authorized: false,
|
|
50
|
+
reason: status.reason
|
|
51
|
+
};
|
|
52
|
+
if (status.kind === "absent" && required.has(dimension)) return {
|
|
53
|
+
authorized: false,
|
|
54
|
+
reason: status.missingReason
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
authorized: true,
|
|
59
|
+
token
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function verifyOperationTokenForCommit(token, authority) {
|
|
63
|
+
return verifyOperationToken(token, {
|
|
64
|
+
activeNavigationId: authority.activeNavigationId,
|
|
65
|
+
visibleCommitVersion: authority.visibleCommitVersion,
|
|
66
|
+
graphVersion: token.graphVersion,
|
|
67
|
+
installedCacheVariantFingerprint: token.cacheVariantFingerprint ?? null
|
|
68
|
+
}, {
|
|
69
|
+
check: ["navigation", "visibleCommit"],
|
|
70
|
+
require: ["navigation", "visibleCommit"]
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function verifyOperationTokenForCacheReuse(token, authority) {
|
|
74
|
+
return verifyOperationToken(token, {
|
|
75
|
+
activeNavigationId: token.navigationId,
|
|
76
|
+
visibleCommitVersion: token.baseVisibleCommitVersion,
|
|
77
|
+
graphVersion: authority.graphVersion,
|
|
78
|
+
installedCacheVariantFingerprint: authority.installedCacheVariantFingerprint
|
|
79
|
+
}, {
|
|
80
|
+
check: ["graphVersion", "cacheVariant"],
|
|
81
|
+
require: []
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { verifyOperationToken, verifyOperationTokenForCacheReuse, verifyOperationTokenForCommit };
|
|
@@ -116,6 +116,6 @@ type NormalizePagesDataRequestResult = {
|
|
|
116
116
|
* Extracted from `entries/pages-server-entry.ts` so both `renderPage` and
|
|
117
117
|
* `runMiddleware` share a single implementation.
|
|
118
118
|
*/
|
|
119
|
-
declare function normalizePagesDataRequest(request: Request, buildId: string | null): NormalizePagesDataRequestResult;
|
|
119
|
+
declare function normalizePagesDataRequest(request: Request, buildId: string | null, basePath?: string): NormalizePagesDataRequestResult;
|
|
120
120
|
//#endregion
|
|
121
121
|
export { buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
1
2
|
import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
2
3
|
//#region src/server/pages-data-route.ts
|
|
3
4
|
/**
|
|
@@ -123,16 +124,18 @@ function buildNextDataNotFoundResponse() {
|
|
|
123
124
|
* Extracted from `entries/pages-server-entry.ts` so both `renderPage` and
|
|
124
125
|
* `runMiddleware` share a single implementation.
|
|
125
126
|
*/
|
|
126
|
-
function normalizePagesDataRequest(request, buildId) {
|
|
127
|
+
function normalizePagesDataRequest(request, buildId, basePath = "") {
|
|
127
128
|
const reqUrl = new URL(request.url);
|
|
128
|
-
|
|
129
|
+
const hadBasePath = !!basePath && hasBasePath(reqUrl.pathname, basePath);
|
|
130
|
+
const dataPathname = basePath ? stripBasePath(reqUrl.pathname, basePath) : reqUrl.pathname;
|
|
131
|
+
if (!isNextDataPathname(dataPathname)) return {
|
|
129
132
|
isDataReq: false,
|
|
130
133
|
request,
|
|
131
134
|
normalizedPathname: null,
|
|
132
135
|
search: "",
|
|
133
136
|
notFoundResponse: null
|
|
134
137
|
};
|
|
135
|
-
const dataMatch = buildId ? parseNextDataPathname(
|
|
138
|
+
const dataMatch = buildId ? parseNextDataPathname(dataPathname, buildId) : null;
|
|
136
139
|
if (!dataMatch) return {
|
|
137
140
|
isDataReq: false,
|
|
138
141
|
request,
|
|
@@ -141,7 +144,7 @@ function normalizePagesDataRequest(request, buildId) {
|
|
|
141
144
|
notFoundResponse: buildNextDataNotFoundResponse()
|
|
142
145
|
};
|
|
143
146
|
const normalizedUrl = new URL(reqUrl);
|
|
144
|
-
normalizedUrl.pathname = dataMatch.pagePathname;
|
|
147
|
+
normalizedUrl.pathname = hadBasePath ? addBasePathToPathname(dataMatch.pagePathname, basePath) : dataMatch.pagePathname;
|
|
145
148
|
return {
|
|
146
149
|
isDataReq: true,
|
|
147
150
|
request: new Request(normalizedUrl, request),
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
//#region src/server/pages-dev-module-url.ts
|
|
3
|
+
function normalizeBase(base) {
|
|
4
|
+
if (!base || base === "/") return "/";
|
|
5
|
+
return `/${base.replace(/^\/+|\/+$/g, "")}/`;
|
|
6
|
+
}
|
|
7
|
+
function encodeModulePath(modulePath) {
|
|
8
|
+
return encodeURI(modulePath).replace(/%5B/gi, "[").replace(/%5D/gi, "]").replace(/\?/g, "%3F").replace(/#/g, "%23");
|
|
9
|
+
}
|
|
10
|
+
function createPagesDevModuleUrl(viteRoot, moduleFilePath, viteBase) {
|
|
11
|
+
const relativePath = (/^[A-Za-z]:[\\/]/.test(viteRoot) ? path.win32 : path).relative(viteRoot, moduleFilePath).replace(/\\/g, "/");
|
|
12
|
+
return normalizeBase(viteBase) + encodeModulePath(relativePath);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { createPagesDevModuleUrl };
|
|
@@ -45,12 +45,6 @@ type DocumentRenderPageInput = {
|
|
|
45
45
|
* the head nodes returned by `getInitialProps` (forward them to
|
|
46
46
|
* `setDocumentInitialHead()` — do NOT call
|
|
47
47
|
* `callDocumentGetInitialProps()` as well).
|
|
48
|
-
* - `consumed` — `getInitialProps` WAS invoked but no body was produced
|
|
49
|
-
* (it never called `renderPage`, returned no `{ html }`, or
|
|
50
|
-
* threw). Callers must NOT re-invoke `getInitialProps` (that
|
|
51
|
-
* would call it a second time) — render the streaming body,
|
|
52
|
-
* spread `docProps` (possibly empty) onto `<Document>`, and
|
|
53
|
-
* forward `head` to `setDocumentInitialHead()`.
|
|
54
48
|
*/
|
|
55
49
|
type RunDocumentRenderPageResult = {
|
|
56
50
|
status: "skipped";
|
|
@@ -60,10 +54,6 @@ type RunDocumentRenderPageResult = {
|
|
|
60
54
|
stylesHTML: string;
|
|
61
55
|
docProps: Record<string, unknown>;
|
|
62
56
|
head: ReactNode[];
|
|
63
|
-
} | {
|
|
64
|
-
status: "consumed";
|
|
65
|
-
docProps: Record<string, unknown>;
|
|
66
|
-
head: ReactNode[];
|
|
67
57
|
};
|
|
68
58
|
/**
|
|
69
59
|
* Run a user `_document.getInitialProps()` with a `ctx.renderPage()` that
|
|
@@ -75,11 +65,10 @@ type RunDocumentRenderPageResult = {
|
|
|
75
65
|
* prod (`pages-page-response.ts`) and dev (`dev-server.ts`) SSR pipelines so
|
|
76
66
|
* the `getInitialProps` + `renderPage` contract lives in one place.
|
|
77
67
|
*
|
|
78
|
-
* `getInitialProps` is invoked at most once here. When this returns `
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* this contract guarantees).
|
|
68
|
+
* `getInitialProps` is invoked at most once here. When this returns `rendered`,
|
|
69
|
+
* callers MUST treat that as the single invocation and must not call
|
|
70
|
+
* `loadUserDocumentInitialProps` again. Errors intentionally propagate to the
|
|
71
|
+
* Pages Router's normal error-page pipeline, matching Next.js.
|
|
83
72
|
*
|
|
84
73
|
* @see .nextjs-ref/packages/next/src/server/render.tsx (search `renderPage`)
|
|
85
74
|
*/
|
|
@@ -19,19 +19,19 @@ import React from "react";
|
|
|
19
19
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/server/render.tsx
|
|
20
20
|
* (search for `loadDocumentInitialProps` and `documentElement`).
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* `runDocumentRenderPage()` supplies `renderPage`, `defaultGetInitialProps`,
|
|
23
|
+
* and the request pathname/query/asPath fields needed by the common upstream
|
|
24
|
+
* pattern:
|
|
25
25
|
*
|
|
26
26
|
* static async getInitialProps(ctx) {
|
|
27
27
|
* const initialProps = await Document.getInitialProps(ctx)
|
|
28
28
|
* return { ...initialProps, docValue }
|
|
29
29
|
* }
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* The standalone `loadUserDocumentInitialProps()` compatibility path supplies
|
|
32
|
+
* an empty default render result because it is only used after the body has
|
|
33
|
+
* already been produced. Request-only fields such as req/res remain outside
|
|
34
|
+
* that compatibility helper.
|
|
35
35
|
*
|
|
36
36
|
* Returns `null` when the user did not override the base shim (the static
|
|
37
37
|
* `getInitialProps` reference still points at the shim's stub) so callers
|
|
@@ -47,7 +47,7 @@ async function loadUserDocumentInitialProps(DocumentComponent) {
|
|
|
47
47
|
const getInitialProps = DocumentComponent.getInitialProps;
|
|
48
48
|
if (typeof getInitialProps !== "function") return null;
|
|
49
49
|
if (getInitialProps === BASE_GET_INITIAL_PROPS) return null;
|
|
50
|
-
const result = await getInitialProps({});
|
|
50
|
+
const result = await getInitialProps({ defaultGetInitialProps: async () => ({ html: "" }) });
|
|
51
51
|
return result && typeof result === "object" ? result : null;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
@@ -60,11 +60,10 @@ async function loadUserDocumentInitialProps(DocumentComponent) {
|
|
|
60
60
|
* prod (`pages-page-response.ts`) and dev (`dev-server.ts`) SSR pipelines so
|
|
61
61
|
* the `getInitialProps` + `renderPage` contract lives in one place.
|
|
62
62
|
*
|
|
63
|
-
* `getInitialProps` is invoked at most once here. When this returns `
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* this contract guarantees).
|
|
63
|
+
* `getInitialProps` is invoked at most once here. When this returns `rendered`,
|
|
64
|
+
* callers MUST treat that as the single invocation and must not call
|
|
65
|
+
* `loadUserDocumentInitialProps` again. Errors intentionally propagate to the
|
|
66
|
+
* Pages Router's normal error-page pipeline, matching Next.js.
|
|
68
67
|
*
|
|
69
68
|
* @see .nextjs-ref/packages/next/src/server/render.tsx (search `renderPage`)
|
|
70
69
|
*/
|
|
@@ -74,58 +73,30 @@ async function runDocumentRenderPage(input) {
|
|
|
74
73
|
if (DocCtor.getInitialProps === BASE_GET_INITIAL_PROPS) return { status: "skipped" };
|
|
75
74
|
if (!input.enhancePageElement) return { status: "skipped" };
|
|
76
75
|
const enhancePageElement = input.enhancePageElement;
|
|
77
|
-
let renderPageCalled = false;
|
|
78
76
|
const renderPage = async (opts = {}) => {
|
|
79
|
-
|
|
80
|
-
const wrapped = withScriptNonce(enhancePageElement(opts), input.scriptNonce);
|
|
77
|
+
const wrapped = withScriptNonce(enhancePageElement(typeof opts === "function" ? { enhanceComponent: opts } : opts), input.scriptNonce);
|
|
81
78
|
return {
|
|
82
79
|
html: await readStreamAsText(await input.renderToReadableStream(wrapped)),
|
|
83
80
|
head: []
|
|
84
81
|
};
|
|
85
82
|
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
renderPage,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
...input.context
|
|
99
|
-
});
|
|
100
|
-
} catch (err) {
|
|
101
|
-
console.error("[vinext] _document.getInitialProps() threw:", err);
|
|
102
|
-
return {
|
|
103
|
-
status: "consumed",
|
|
104
|
-
docProps: {},
|
|
105
|
-
head: []
|
|
106
|
-
};
|
|
107
|
-
}
|
|
83
|
+
const docInitialProps = await DocCtor.getInitialProps({
|
|
84
|
+
renderPage,
|
|
85
|
+
defaultGetInitialProps: async (ctx) => {
|
|
86
|
+
const result = await ctx.renderPage({ enhanceApp: (App) => (props) => React.createElement(App, props) });
|
|
87
|
+
return {
|
|
88
|
+
html: result.html,
|
|
89
|
+
head: result.head ?? [],
|
|
90
|
+
styles: void 0
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
...input.context
|
|
94
|
+
});
|
|
108
95
|
const { html: _html, head: rawHead, styles: _styles, ...docProps } = docInitialProps ?? {};
|
|
109
96
|
const head = Array.isArray(rawHead) ? rawHead : [];
|
|
110
|
-
if (!
|
|
111
|
-
status: "consumed",
|
|
112
|
-
docProps,
|
|
113
|
-
head
|
|
114
|
-
};
|
|
115
|
-
if (!docInitialProps || typeof docInitialProps.html !== "string") {
|
|
116
|
-
console.error(`[vinext] "${DocCtor.displayName ?? DocCtor.name ?? "Document"}.getInitialProps()" did not return an object with a string "html" prop`);
|
|
117
|
-
return {
|
|
118
|
-
status: "consumed",
|
|
119
|
-
docProps,
|
|
120
|
-
head
|
|
121
|
-
};
|
|
122
|
-
}
|
|
97
|
+
if (!docInitialProps || typeof docInitialProps.html !== "string") throw new Error(`"${DocCtor.displayName ?? DocCtor.name ?? "Document"}.getInitialProps()" should resolve to an object with a "html" prop set with a valid html string`);
|
|
123
98
|
let stylesHTML = "";
|
|
124
|
-
if (docInitialProps.styles != null)
|
|
125
|
-
stylesHTML = await input.renderStylesToString(React.createElement(React.Fragment, null, docInitialProps.styles));
|
|
126
|
-
} catch (err) {
|
|
127
|
-
console.error("[vinext] Failed to render _document.getInitialProps() styles:", err);
|
|
128
|
-
}
|
|
99
|
+
if (docInitialProps.styles != null) stylesHTML = await input.renderStylesToString(React.createElement(React.Fragment, null, docInitialProps.styles));
|
|
129
100
|
return {
|
|
130
101
|
status: "rendered",
|
|
131
102
|
bodyHtml: docInitialProps.html,
|
|
@@ -127,8 +127,8 @@ function parseCookieLocaleFromHeader(cookieHeader, i18nConfig) {
|
|
|
127
127
|
} catch {
|
|
128
128
|
return null;
|
|
129
129
|
}
|
|
130
|
-
|
|
131
|
-
return null;
|
|
130
|
+
const lowerValue = value.toLowerCase();
|
|
131
|
+
return i18nConfig.locales.find((locale) => locale.toLowerCase() === lowerValue) ?? null;
|
|
132
132
|
}
|
|
133
133
|
function formatLocalizedRootPath(locale, defaultLocale, basePath = "", trailingSlash = false, search = "") {
|
|
134
134
|
if (locale.toLowerCase() === defaultLocale.toLowerCase()) return void 0;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Route } from "../routing/pages-router.js";
|
|
2
2
|
import { VinextNextData } from "../client/vinext-next-data.js";
|
|
3
|
-
import { CachedPagesValue } from "../shims/cache.js";
|
|
3
|
+
import { CachedPagesValue } from "../shims/cache-handler.js";
|
|
4
4
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
5
5
|
import { PagesGsspResponse, PagesI18nRenderContext, PagesNextDataExtras } from "./pages-page-response.js";
|
|
6
6
|
import { ReactNode } from "react";
|
|
@@ -198,7 +198,9 @@ function applyBotETagAndCheck(cachedResponse, html, options) {
|
|
|
198
198
|
function rewritePagesCachedHtml(cachedHtml, freshBody, nextDataScript) {
|
|
199
199
|
const bodyStart = cachedHtml.indexOf("<div id=\"__next\">");
|
|
200
200
|
const contentStart = bodyStart >= 0 ? bodyStart + 17 : -1;
|
|
201
|
-
const
|
|
201
|
+
const canonicalNextDataStart = cachedHtml.search(/<script\b(?=[^>]*\bid=["']__NEXT_DATA__["'])(?=[^>]*\btype=["']application\/json["'])[^>]*>/);
|
|
202
|
+
const legacyNextDataStart = cachedHtml.indexOf("<script>window.__NEXT_DATA__");
|
|
203
|
+
const nextDataStart = canonicalNextDataStart >= 0 ? canonicalNextDataStart : legacyNextDataStart;
|
|
202
204
|
if (contentStart >= 0 && nextDataStart >= 0) {
|
|
203
205
|
const region = cachedHtml.slice(contentStart, nextDataStart);
|
|
204
206
|
const lastCloseDiv = region.lastIndexOf("</div>");
|
|
@@ -184,7 +184,7 @@ function createPagesPageHandler(opts) {
|
|
|
184
184
|
const pagesResolvedUrl = (new URL(routeUrl, originalRequestUrl).pathname || "/") + originalRequestUrl.search;
|
|
185
185
|
const pageDataResult = await resolvePagesPageData({
|
|
186
186
|
isDataReq,
|
|
187
|
-
err,
|
|
187
|
+
err: err instanceof Error ? err : void 0,
|
|
188
188
|
applyRequestContexts: applySSRContext,
|
|
189
189
|
buildId,
|
|
190
190
|
deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
|
|
@@ -327,6 +327,7 @@ function createPagesPageHandler(opts) {
|
|
|
327
327
|
return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
|
|
328
328
|
},
|
|
329
329
|
DocumentComponent,
|
|
330
|
+
err: err instanceof Error ? err : void 0,
|
|
330
331
|
flushPreloads: typeof flushPreloads === "function" ? flushPreloads : void 0,
|
|
331
332
|
fontLinkHeader,
|
|
332
333
|
fontPreloads: allFontPreloads,
|
|
@@ -344,6 +345,7 @@ function createPagesPageHandler(opts) {
|
|
|
344
345
|
pageProps,
|
|
345
346
|
props: renderProps,
|
|
346
347
|
params,
|
|
348
|
+
query,
|
|
347
349
|
renderDocumentToString(element) {
|
|
348
350
|
return renderToStringAsync(element);
|
|
349
351
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VinextNextData } from "../client/vinext-next-data.js";
|
|
2
|
-
import { CachedPagesValue } from "../shims/cache.js";
|
|
2
|
+
import { CachedPagesValue } from "../shims/cache-handler.js";
|
|
3
3
|
import { RenderPageEnhancers } from "./pages-document-initial-props.js";
|
|
4
4
|
import { ComponentType, ReactNode } from "react";
|
|
5
5
|
|
|
@@ -66,6 +66,7 @@ type RenderPagesPageResponseOptions = {
|
|
|
66
66
|
*/
|
|
67
67
|
enhancePageElement?: ((opts: RenderPageEnhancers) => ReactNode) | undefined;
|
|
68
68
|
DocumentComponent: ComponentType | null;
|
|
69
|
+
err?: Error;
|
|
69
70
|
flushPreloads?: (() => Promise<void> | void) | undefined;
|
|
70
71
|
fontLinkHeader: string;
|
|
71
72
|
fontPreloads: PagesFontPreload[];
|
|
@@ -95,6 +96,7 @@ type RenderPagesPageResponseOptions = {
|
|
|
95
96
|
pageProps: Record<string, unknown>;
|
|
96
97
|
props?: Record<string, unknown>;
|
|
97
98
|
params: Record<string, unknown>;
|
|
99
|
+
query?: Record<string, unknown>;
|
|
98
100
|
renderDocumentToString: (element: ReactNode) => Promise<string>;
|
|
99
101
|
renderToReadableStream: (element: ReactNode) => Promise<ReadableStream<Uint8Array>>;
|
|
100
102
|
resetSSRHead?: (() => void) | undefined;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
2
2
|
import { reportRequestError } from "./instrumentation.js";
|
|
3
3
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
4
|
-
import { fnv1a52 } from "../utils/hash.js";
|
|
5
|
-
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
6
4
|
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
|
|
7
5
|
import { buildMissIsrCacheControl } from "./isr-decision.js";
|
|
6
|
+
import { fnv1a52 } from "../utils/hash.js";
|
|
7
|
+
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
8
8
|
import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
9
9
|
import { withScriptNonce } from "../shims/script-nonce-context.js";
|
|
10
|
-
import {
|
|
10
|
+
import { createNonceAttribute, escapeHtmlAttr } from "./html.js";
|
|
11
11
|
import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
|
|
12
12
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
13
13
|
import { loadUserDocumentInitialProps, runDocumentRenderPage } from "./pages-document-initial-props.js";
|
|
@@ -89,8 +89,7 @@ function buildPagesNextDataScript(options) {
|
|
|
89
89
|
...options.nextData?.__vinext,
|
|
90
90
|
...options.vinext
|
|
91
91
|
};
|
|
92
|
-
|
|
93
|
-
return createInlineScriptTag(`window.__NEXT_DATA__ = ${options.safeJsonStringify(nextDataPayload)}${localeGlobals}`, options.scriptNonce);
|
|
92
|
+
return `<script id="__NEXT_DATA__" type="application/json"${createNonceAttribute(options.scriptNonce)}>${options.safeJsonStringify(nextDataPayload)}<\/script>`;
|
|
94
93
|
}
|
|
95
94
|
async function buildPagesShellHtml(bodyMarker, fontHeadHTML, nextDataScript, options) {
|
|
96
95
|
if (options.DocumentComponent) {
|
|
@@ -197,8 +196,9 @@ async function renderPagesPageResponse(options) {
|
|
|
197
196
|
renderStylesToString: async (element) => readStreamAsText(await options.renderToReadableStream(element)),
|
|
198
197
|
scriptNonce: options.scriptNonce,
|
|
199
198
|
context: {
|
|
199
|
+
err: options.err,
|
|
200
200
|
pathname: options.routePattern,
|
|
201
|
-
query: options.params,
|
|
201
|
+
query: options.query ?? options.params,
|
|
202
202
|
asPath: options.routeUrl
|
|
203
203
|
}
|
|
204
204
|
});
|
|
@@ -10,7 +10,7 @@ function buildPagesReadinessNextData(options) {
|
|
|
10
10
|
const hasAppGip = typeof options.appComponent?.getInitialProps === "function";
|
|
11
11
|
return {
|
|
12
12
|
gssp: hasPageGssp,
|
|
13
|
-
gsp: hasPageGsp,
|
|
13
|
+
gsp: hasPageGsp ? true : void 0,
|
|
14
14
|
gip: hasPageGip,
|
|
15
15
|
appGip: hasAppGip,
|
|
16
16
|
autoExport: !hasPageGssp && !hasPageGsp && !hasPageGip && !hasAppGip,
|
|
@@ -7,6 +7,8 @@ type PagesRenderOptions = {
|
|
|
7
7
|
renderErrorPageOnMiss?: boolean;
|
|
8
8
|
originalUrl?: string;
|
|
9
9
|
};
|
|
10
|
+
type FilesystemRoutePhase = "direct" | "beforeFiles" | "afterFiles" | "fallback";
|
|
11
|
+
declare function fetchWorkerFilesystemRoute(request: Request, requestPathname: string, phase: FilesystemRoutePhase, fetchAsset: (request: Request) => Promise<Response>): Promise<Response | false>;
|
|
10
12
|
type MiddlewareResult = {
|
|
11
13
|
continue: boolean;
|
|
12
14
|
redirectUrl?: string;
|
|
@@ -53,15 +55,13 @@ type PagesPipelineDeps = {
|
|
|
53
55
|
*/
|
|
54
56
|
proxyExternal?: ((currentRequest: Request, externalUrl: string) => Promise<Response>) | null;
|
|
55
57
|
/**
|
|
56
|
-
* Optional
|
|
58
|
+
* Optional filesystem/static-asset probe supplied by each runtime adapter.
|
|
57
59
|
* Called post-middleware (so middleware can intercept/redirect public files) with the
|
|
58
60
|
* original basePath-stripped pathname and the staged middleware response headers.
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* to fall through to rewrites/render. Worker/dev adapters omit this — their public files
|
|
62
|
-
* are served by the asset binding / Vite respectively.
|
|
61
|
+
* Node may write directly to `res` and return true; dev/Workers return a Response.
|
|
62
|
+
* Resolves false to continue through rewrites, API routes, and page rendering.
|
|
63
63
|
*/
|
|
64
|
-
|
|
64
|
+
serveFilesystemRoute?: ((requestPathname: string, stagedHeaders: HeaderRecord, phase: FilesystemRoutePhase) => Promise<boolean | Response>) | null;
|
|
65
65
|
};
|
|
66
66
|
/**
|
|
67
67
|
* Wrap an adapter's `runMiddleware` callback so middleware receives the original
|
|
@@ -111,4 +111,4 @@ type PagesPipelineResult = {
|
|
|
111
111
|
*/
|
|
112
112
|
declare function runPagesRequest(request: Request, deps: PagesPipelineDeps): Promise<PagesPipelineResult>;
|
|
113
113
|
//#endregion
|
|
114
|
-
export { MiddlewareResult, PagesPipelineDeps, PagesPipelineResult, PagesRenderOptions, runPagesRequest, wrapMiddlewareWithBasePath };
|
|
114
|
+
export { FilesystemRoutePhase, MiddlewareResult, PagesPipelineDeps, PagesPipelineResult, PagesRenderOptions, fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath };
|