vinext 1.2.1 → 1.3.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/README.md +12 -9
- package/dist/build/client-build-config.d.ts +64 -3
- package/dist/build/client-build-config.js +131 -4
- package/dist/build/client-reference-groups.d.ts +163 -0
- package/dist/build/client-reference-groups.js +534 -0
- package/dist/build/module-dependency-cache.d.ts +31 -0
- package/dist/build/module-dependency-cache.js +51 -1
- package/dist/build/next-client-runtime-manifests.d.ts +10 -1
- package/dist/build/next-client-runtime-manifests.js +19 -4
- package/dist/build/nitro-public-files.d.ts +24 -0
- package/dist/build/nitro-public-files.js +60 -0
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +5 -2
- package/dist/build/server-actions-encryption-key.d.ts +23 -0
- package/dist/build/server-actions-encryption-key.js +101 -0
- package/dist/build/ssr-manifest.d.ts +3 -0
- package/dist/build/ssr-manifest.js +10 -1
- package/dist/client/client-rewrite-params.d.ts +9 -0
- package/dist/client/client-rewrite-params.js +20 -0
- package/dist/client/dev-error-overlay.js +2 -1
- package/dist/client/navigation-runtime.d.ts +25 -2
- package/dist/client/navigation-runtime.js +42 -11
- package/dist/client/vinext-next-data.d.ts +0 -1
- package/dist/config/config-matchers.d.ts +15 -40
- package/dist/config/config-matchers.js +183 -255
- package/dist/config/config-source.d.ts +34 -0
- package/dist/config/config-source.js +141 -0
- package/dist/config/header-params.d.ts +29 -0
- package/dist/config/header-params.js +106 -0
- package/dist/config/next-config.d.ts +7 -5
- package/dist/config/next-config.js +120 -7
- package/dist/entries/app-browser-entry.d.ts +14 -1
- package/dist/entries/app-browser-entry.js +26 -36
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +92 -57
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +20 -1
- package/dist/entries/app-ssr-entry.d.ts +4 -1
- package/dist/entries/app-ssr-entry.js +9 -2
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +6 -6
- package/dist/entries/pages-server-entry.js +17 -14
- package/dist/index.d.ts +11 -0
- package/dist/index.js +239 -83
- package/dist/init.js +17 -0
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +106 -20
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/use-cache-callable.d.ts +5 -0
- package/dist/plugins/use-cache-callable.js +30 -8
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +1 -1
- package/dist/routing/app-route-graph.d.ts +1 -1
- package/dist/routing/browser-route-manifest.d.ts +43 -0
- package/dist/routing/browser-route-manifest.js +195 -0
- package/dist/routing/hashed-route-patterns.d.ts +4 -0
- package/dist/routing/hashed-route-patterns.js +22 -0
- package/dist/routing/optimistic-route-trie.d.ts +27 -0
- package/dist/routing/optimistic-route-trie.js +102 -0
- package/dist/routing/route-validation.d.ts +6 -1
- package/dist/routing/route-validation.js +26 -10
- package/dist/server/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +15 -1
- package/dist/server/app-browser-entry.js +147 -60
- package/dist/server/app-browser-error.d.ts +3 -1
- package/dist/server/app-browser-error.js +7 -2
- package/dist/server/app-browser-interception-context.d.ts +2 -2
- package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
- package/dist/server/app-browser-mpa-navigation.js +6 -5
- package/dist/server/app-browser-navigation-controller.d.ts +17 -6
- package/dist/server/app-browser-navigation-controller.js +88 -26
- package/dist/server/app-browser-state.d.ts +2 -2
- package/dist/server/app-browser-visible-commit.d.ts +4 -4
- package/dist/server/app-client-reference-preloader.d.ts +23 -0
- package/dist/server/app-client-reference-preloader.js +30 -7
- package/dist/server/app-fallback-renderer.js +2 -1
- package/dist/server/app-middleware.d.ts +6 -0
- package/dist/server/app-middleware.js +8 -10
- package/dist/server/app-optimistic-routing.d.ts +8 -10
- package/dist/server/app-optimistic-routing.js +4 -95
- package/dist/server/app-page-boundary-render.js +8 -1
- package/dist/server/app-page-cache-render.js +1 -0
- package/dist/server/app-page-dispatch.js +2 -0
- package/dist/server/app-page-render.js +3 -1
- package/dist/server/app-page-rsc-render-status.d.ts +1 -0
- package/dist/server/app-page-rsc-render-status.js +1 -0
- package/dist/server/app-page-search-params-observation.d.ts +1 -4
- package/dist/server/app-page-search-params-observation.js +8 -10
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +11 -7
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +2 -2
- package/dist/server/app-response-stage-entry.js +3 -3
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -0
- package/dist/server/app-route-handler-execution.js +9 -2
- package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
- package/dist/server/app-route-handler-middleware-context.js +3 -3
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +2 -2
- package/dist/server/app-route-handler-runtime.d.ts +2 -0
- package/dist/server/app-route-handler-runtime.js +20 -3
- package/dist/server/app-route-module-loader.js +7 -6
- package/dist/server/app-route-tree.d.ts +20 -0
- package/dist/server/app-route-tree.js +18 -0
- package/dist/server/app-router-entry.js +2 -2
- package/dist/server/app-rsc-combined-handler.js +8 -1
- package/dist/server/app-rsc-errors.d.ts +7 -0
- package/dist/server/app-rsc-errors.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +4 -1
- package/dist/server/app-rsc-handler.js +146 -130
- package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.js +3 -1
- package/dist/server/app-rsc-route-matching.d.ts +1 -0
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +23 -6
- package/dist/server/app-server-action-execution.js +50 -56
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +16 -7
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/config-headers.js +12 -3
- package/dist/server/isolate-shared-promise.d.ts +10 -0
- package/dist/server/isolate-shared-promise.js +33 -0
- package/dist/server/isr-cache.js +3 -2
- package/dist/server/middleware-matcher-pattern.d.ts +0 -1
- package/dist/server/middleware-matcher-pattern.js +11 -140
- package/dist/server/middleware-matcher.js +5 -6
- package/dist/server/middleware-response-headers.d.ts +31 -0
- package/dist/server/middleware-response-headers.js +57 -1
- package/dist/server/middleware-runtime.js +26 -13
- package/dist/server/navigation-planner.d.ts +2 -2
- package/dist/server/nitro-public-files-plugin.d.ts +38 -0
- package/dist/server/nitro-public-files-plugin.js +106 -0
- package/dist/server/nitro-public-files.d.ts +21 -0
- package/dist/server/nitro-public-files.js +39 -0
- package/dist/server/pages-asset-tags.d.ts +5 -0
- package/dist/server/pages-asset-tags.js +9 -2
- package/dist/server/pages-client-assets.d.ts +4 -1
- package/dist/server/pages-i18n.d.ts +18 -0
- package/dist/server/pages-i18n.js +18 -2
- package/dist/server/pages-node-compat.d.ts +5 -3
- package/dist/server/pages-node-compat.js +35 -16
- package/dist/server/pages-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +31 -35
- package/dist/server/pages-request-stage-entry.js +16 -6
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +1 -0
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +71 -33
- package/dist/server/proxy-trust.d.ts +6 -0
- package/dist/server/proxy-trust.js +12 -6
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +12 -1
- package/dist/server/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache-handler.js +3 -2
- package/dist/shims/cache-request-state.d.ts +40 -3
- package/dist/shims/cache-request-state.js +70 -5
- package/dist/shims/cache-runtime.js +47 -19
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +17 -8
- package/dist/shims/cdn-purge-routes.d.ts +24 -0
- package/dist/shims/cdn-purge-routes.js +77 -0
- package/dist/shims/dynamic.js +17 -4
- package/dist/shims/form.js +8 -3
- package/dist/shims/image-props.d.ts +93 -0
- package/dist/shims/image-props.js +323 -0
- package/dist/shims/image.d.ts +4 -18
- package/dist/shims/image.js +4 -319
- package/dist/shims/internal/headers-state.d.ts +7 -0
- package/dist/shims/internal/headers-state.js +14 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +31 -14
- package/dist/shims/internal/hybrid-client-route-owner.js +8 -8
- package/dist/shims/link.js +5 -3
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +17 -5
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +19 -40
- package/dist/shims/server.d.ts +31 -4
- package/dist/shims/server.js +58 -10
- package/dist/shims/thenable-params.d.ts +6 -1
- package/dist/shims/thenable-params.js +11 -2
- package/dist/shims/unified-request-context.d.ts +5 -0
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/utils/asset-prefix.d.ts +7 -0
- package/dist/utils/asset-prefix.js +10 -1
- package/dist/utils/client-build-manifest.js +12 -5
- package/dist/utils/client-runtime-metadata.d.ts +1 -0
- package/dist/utils/client-runtime-metadata.js +15 -2
- package/dist/utils/lazy-chunks.d.ts +4 -0
- package/dist/utils/manifest-paths.d.ts +14 -0
- package/dist/utils/manifest-paths.js +22 -1
- package/dist/utils/path-to-regexp.d.ts +21 -0
- package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
- package/dist/utils/plugin-react-version.d.ts +15 -0
- package/dist/utils/plugin-react-version.js +64 -0
- package/dist/utils/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/package.json +1 -1
- package/dist/server/middleware-path-to-regexp.d.ts +0 -13
- package/dist/utils/regex-safety.d.ts +0 -17
- package/dist/utils/regex-safety.js +0 -789
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { appendDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
2
2
|
import { createNonceAttribute } from "./html.js";
|
|
3
|
-
import { assetServingUrlFromBaseAnchored } from "../utils/manifest-paths.js";
|
|
3
|
+
import { SSR_MANIFEST_SHARED_CHUNKS_KEY, assetServingUrlFromBaseAnchored } from "../utils/manifest-paths.js";
|
|
4
4
|
import { getPagesClientAssets } from "./pages-client-assets.js";
|
|
5
5
|
//#region src/server/pages-asset-tags.ts
|
|
6
6
|
/**
|
|
@@ -55,7 +55,14 @@ function findModuleKey(manifest, moduleId) {
|
|
|
55
55
|
}
|
|
56
56
|
return matchedKey;
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Fallback for when no build-time `sharedChunks` list is registered. Prefers
|
|
60
|
+
* the chunk-name based list the build writes into the SSR manifest; the file
|
|
61
|
+
* name scan only matches `[name]-[hash]` names, not hash-only ones.
|
|
62
|
+
*/
|
|
58
63
|
function getSharedChunkFiles(manifest) {
|
|
64
|
+
const recorded = manifest[SSR_MANIFEST_SHARED_CHUNKS_KEY];
|
|
65
|
+
if (recorded) return recorded;
|
|
59
66
|
const cached = sharedChunkFiles.get(manifest);
|
|
60
67
|
if (cached) return cached;
|
|
61
68
|
const files = /* @__PURE__ */ new Set();
|
|
@@ -186,7 +193,7 @@ function collectAssetTags(options) {
|
|
|
186
193
|
const files = getManifestFilesForModule(m, id);
|
|
187
194
|
if (files) for (let fi = 0; fi < files.length; fi++) allFiles.push(files[fi]);
|
|
188
195
|
}
|
|
189
|
-
const sharedFiles =
|
|
196
|
+
const sharedFiles = runtimeAssets.sharedChunks ?? getSharedChunkFiles(m);
|
|
190
197
|
for (const file of sharedFiles) allFiles.push(file);
|
|
191
198
|
} else for (const akey in m) {
|
|
192
199
|
const avals = m[akey];
|
|
@@ -4,7 +4,10 @@ export type PagesClientAssets = {
|
|
|
4
4
|
clientEntry?: string;
|
|
5
5
|
appBootstrapPreinitModules?: string[];
|
|
6
6
|
ssrManifest?: Record<string, string[]>;
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Shared Pages chunk files (framework, vinext runtime, client entry) keyed on
|
|
9
|
+
* chunk names from this client build, in the SSR-manifest key-space.
|
|
10
|
+
*/
|
|
8
11
|
sharedChunks?: string[];
|
|
9
12
|
cssGraph?: Record<string, {
|
|
10
13
|
imports?: string[];
|
|
@@ -63,12 +63,30 @@ export declare function detectPathnameLocale(pathname: string, locales: readonly
|
|
|
63
63
|
* `:locale`. After normalisation the request looks like `/en/to-sv` and
|
|
64
64
|
* the rule matches with `:locale=en`.
|
|
65
65
|
*
|
|
66
|
+
* `restoreRootTrailingSlash` makes the root `/en/` rather than `/en`; header
|
|
67
|
+
* callers compute it with `shouldRestoreLocaleRootTrailingSlash`. Redirect
|
|
68
|
+
* and rewrite callers do not pass it yet.
|
|
69
|
+
*
|
|
66
70
|
* Ported from Next.js: packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
67
71
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
68
72
|
*/
|
|
69
73
|
export declare function normalizeDefaultLocalePathname(pathname: string, i18n: NextI18nConfig | null | undefined, options?: {
|
|
70
74
|
hostname?: string | null;
|
|
75
|
+
restoreRootTrailingSlash?: boolean;
|
|
71
76
|
}): string;
|
|
77
|
+
/**
|
|
78
|
+
* Whether Next.js re-adds the root's trailing slash after splicing in the
|
|
79
|
+
* default locale: the raw request pathname (basePath included, so `/docs`
|
|
80
|
+
* stays `/docs/en` while `/docs/` becomes `/docs/en/`) ends with `/`, and
|
|
81
|
+
* `trailingSlash` is on without `skipProxyUrlNormalize`.
|
|
82
|
+
*
|
|
83
|
+
* Ported from Next.js: packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
84
|
+
* (`hadTrailingSlash` + `maybeAddTrailingSlash`).
|
|
85
|
+
*/
|
|
86
|
+
export declare function shouldRestoreLocaleRootTrailingSlash(rawPathname: string, config: {
|
|
87
|
+
trailingSlash?: boolean;
|
|
88
|
+
skipProxyUrlNormalize?: boolean;
|
|
89
|
+
}): boolean;
|
|
72
90
|
/**
|
|
73
91
|
* Extract locale prefix from a URL path.
|
|
74
92
|
* e.g. /fr/about -> { locale: "fr", url: "/about", hadPrefix: true }
|
|
@@ -51,6 +51,10 @@ function detectPathnameLocale(pathname, locales) {
|
|
|
51
51
|
* `:locale`. After normalisation the request looks like `/en/to-sv` and
|
|
52
52
|
* the rule matches with `:locale=en`.
|
|
53
53
|
*
|
|
54
|
+
* `restoreRootTrailingSlash` makes the root `/en/` rather than `/en`; header
|
|
55
|
+
* callers compute it with `shouldRestoreLocaleRootTrailingSlash`. Redirect
|
|
56
|
+
* and rewrite callers do not pass it yet.
|
|
57
|
+
*
|
|
54
58
|
* Ported from Next.js: packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
55
59
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
56
60
|
*/
|
|
@@ -59,10 +63,22 @@ function normalizeDefaultLocalePathname(pathname, i18n, options = {}) {
|
|
|
59
63
|
if (pathname.startsWith("/_next/") || pathname.startsWith("/__vinext/")) return pathname;
|
|
60
64
|
if (detectPathnameLocale(pathname, i18n.locales)) return pathname;
|
|
61
65
|
const defaultLocale = detectDomainLocale(i18n.domains, options.hostname ?? void 0)?.defaultLocale ?? i18n.defaultLocale;
|
|
62
|
-
if (pathname === "/") return `/${defaultLocale}`;
|
|
66
|
+
if (pathname === "/") return options.restoreRootTrailingSlash ? `/${defaultLocale}/` : `/${defaultLocale}`;
|
|
63
67
|
return `/${defaultLocale}${pathname}`;
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
70
|
+
* Whether Next.js re-adds the root's trailing slash after splicing in the
|
|
71
|
+
* default locale: the raw request pathname (basePath included, so `/docs`
|
|
72
|
+
* stays `/docs/en` while `/docs/` becomes `/docs/en/`) ends with `/`, and
|
|
73
|
+
* `trailingSlash` is on without `skipProxyUrlNormalize`.
|
|
74
|
+
*
|
|
75
|
+
* Ported from Next.js: packages/next/src/server/lib/router-utils/resolve-routes.ts
|
|
76
|
+
* (`hadTrailingSlash` + `maybeAddTrailingSlash`).
|
|
77
|
+
*/
|
|
78
|
+
function shouldRestoreLocaleRootTrailingSlash(rawPathname, config) {
|
|
79
|
+
return Boolean(config.trailingSlash && !config.skipProxyUrlNormalize && rawPathname.endsWith("/"));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
66
82
|
* Extract locale prefix from a URL path.
|
|
67
83
|
* e.g. /fr/about -> { locale: "fr", url: "/about", hadPrefix: true }
|
|
68
84
|
* /about -> { locale: defaultLocale, url: "/about", hadPrefix: false }
|
|
@@ -243,4 +259,4 @@ function resolvePagesI18nRequest(url, i18nConfig, headers, hostname, basePath =
|
|
|
243
259
|
};
|
|
244
260
|
}
|
|
245
261
|
//#endregion
|
|
246
|
-
export { detectDomainLocale, detectLocaleFromAcceptLanguage, detectPathnameLocale, extractLocaleFromUrl, getLocaleRedirect, normalizeDefaultLocalePathname, parseCookieLocaleFromHeader, resolvePagesI18nRequest, stripI18nLocaleForApiRoute };
|
|
262
|
+
export { detectDomainLocale, detectLocaleFromAcceptLanguage, detectPathnameLocale, extractLocaleFromUrl, getLocaleRedirect, normalizeDefaultLocalePathname, parseCookieLocaleFromHeader, resolvePagesI18nRequest, shouldRestoreLocaleRootTrailingSlash, stripI18nLocaleForApiRoute };
|
|
@@ -15,15 +15,17 @@ export type PagesReqResRequest = Readable & {
|
|
|
15
15
|
draftMode?: true;
|
|
16
16
|
previewData: PagesPreviewData | false;
|
|
17
17
|
};
|
|
18
|
+
type PagesReqResHeaderValue = string | number | boolean | string[];
|
|
18
19
|
type PagesReqResHeaders = {
|
|
19
|
-
[key: string]:
|
|
20
|
+
[key: string]: PagesReqResHeaderValue;
|
|
20
21
|
};
|
|
21
22
|
export type PagesReqResResponse = Writable & {
|
|
22
23
|
statusCode: number;
|
|
23
24
|
readonly headersSent: boolean;
|
|
24
25
|
writeHead: (code: number, headers?: PagesReqResHeaders) => PagesReqResResponse;
|
|
25
|
-
setHeader: (name: string, value:
|
|
26
|
-
|
|
26
|
+
setHeader: (name: string, value: PagesReqResHeaderValue) => PagesReqResResponse;
|
|
27
|
+
appendHeader: (name: string, value: string | readonly string[]) => PagesReqResResponse;
|
|
28
|
+
getHeader: (name: string) => PagesReqResHeaderValue | undefined;
|
|
27
29
|
status: (code: number) => PagesReqResResponse;
|
|
28
30
|
json: (data: unknown) => void;
|
|
29
31
|
send: (data: unknown) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseCookieHeader } from "../utils/parse-cookie.js";
|
|
2
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
2
3
|
import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
|
|
3
4
|
import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT } from "./pages-body-parser-config.js";
|
|
4
5
|
import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
|
|
@@ -13,6 +14,18 @@ const NO_BODY_RESPONSE_STATUSES = /* @__PURE__ */ new Set([
|
|
|
13
14
|
205,
|
|
14
15
|
304
|
|
15
16
|
]);
|
|
17
|
+
const HTTP_TOKEN_PATTERN = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
|
|
18
|
+
const INVALID_HEADER_VALUE_CHAR_PATTERN = /[^\t\x20-\x7e\x80-\xff]/;
|
|
19
|
+
function createNodeTypeError(code, message) {
|
|
20
|
+
return Object.assign(new TypeError(message), { code });
|
|
21
|
+
}
|
|
22
|
+
function validateAppendedHeader(name, value) {
|
|
23
|
+
if (typeof name !== "string" || !name || !HTTP_TOKEN_PATTERN.test(name)) throw createNodeTypeError("ERR_INVALID_HTTP_TOKEN", `Header name must be a valid HTTP token ["${String(name)}"]`);
|
|
24
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
25
|
+
if (item === void 0) throw createNodeTypeError("ERR_HTTP_INVALID_HEADER_VALUE", `Invalid value "undefined" for header "${name}"`);
|
|
26
|
+
if (INVALID_HEADER_VALUE_CHAR_PATTERN.test(String(item))) throw createNodeTypeError("ERR_INVALID_CHAR", `Invalid character in header content ["${name}"]`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
16
29
|
async function readPagesRequestBodyWithLimit(request, maxBytes) {
|
|
17
30
|
if (!request.body) return "";
|
|
18
31
|
return readStreamAsTextWithLimit(request.body, maxBytes, () => {
|
|
@@ -120,9 +133,9 @@ var PagesResponseStream = class extends Writable {
|
|
|
120
133
|
resolveResponse;
|
|
121
134
|
rejectResponse;
|
|
122
135
|
resStatusCode = 200;
|
|
123
|
-
resHeaders =
|
|
124
|
-
setCookieHeaders = [];
|
|
136
|
+
resHeaders = Object.create(null);
|
|
125
137
|
resolved = false;
|
|
138
|
+
headWritten = false;
|
|
126
139
|
controller = null;
|
|
127
140
|
bufferedChunks = [];
|
|
128
141
|
streamEnded = false;
|
|
@@ -150,15 +163,21 @@ var PagesResponseStream = class extends Writable {
|
|
|
150
163
|
}
|
|
151
164
|
writeHead(code, headers) {
|
|
152
165
|
this.resStatusCode = code;
|
|
153
|
-
if (headers) for (const [key, value] of Object.entries(headers)) this.setHeaderValue(key, value, {
|
|
166
|
+
if (headers) for (const [key, value] of Object.entries(headers)) this.setHeaderValue(key, value, { append: false });
|
|
167
|
+
this.headWritten = true;
|
|
154
168
|
return this;
|
|
155
169
|
}
|
|
156
170
|
setHeader(name, value) {
|
|
157
|
-
this.setHeaderValue(name, value, {
|
|
171
|
+
this.setHeaderValue(name, value, { append: false });
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
appendHeader(name, value) {
|
|
175
|
+
if (this.headWritten || this.headersSent) throw Object.assign(/* @__PURE__ */ new Error("Cannot append headers after they are sent to the client"), { code: "ERR_HTTP_HEADERS_SENT" });
|
|
176
|
+
validateAppendedHeader(name, value);
|
|
177
|
+
this.setHeaderValue(name, value, { append: true });
|
|
158
178
|
return this;
|
|
159
179
|
}
|
|
160
180
|
getHeader(name) {
|
|
161
|
-
if (name.toLowerCase() === "set-cookie") return this.setCookieHeaders.length > 0 ? this.setCookieHeaders : void 0;
|
|
162
181
|
return this.resHeaders[name.toLowerCase()];
|
|
163
182
|
}
|
|
164
183
|
status(code) {
|
|
@@ -196,9 +215,7 @@ var PagesResponseStream = class extends Writable {
|
|
|
196
215
|
return this;
|
|
197
216
|
}
|
|
198
217
|
getHeaders() {
|
|
199
|
-
|
|
200
|
-
if (this.setCookieHeaders.length > 0) headers["set-cookie"] = this.setCookieHeaders;
|
|
201
|
-
return headers;
|
|
218
|
+
return { ...this.resHeaders };
|
|
202
219
|
}
|
|
203
220
|
setPreviewData(data, options = {}) {
|
|
204
221
|
setPagesPreviewData(this, data, options);
|
|
@@ -250,13 +267,15 @@ var PagesResponseStream = class extends Writable {
|
|
|
250
267
|
callback(error);
|
|
251
268
|
}
|
|
252
269
|
setHeaderValue(name, value, options) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
this.
|
|
270
|
+
const key = name.toLowerCase();
|
|
271
|
+
const existing = this.resHeaders[key];
|
|
272
|
+
if (!options.append || existing === void 0) {
|
|
273
|
+
this.resHeaders[key] = value;
|
|
257
274
|
return;
|
|
258
275
|
}
|
|
259
|
-
|
|
276
|
+
const values = Array.isArray(existing) ? existing : [existing];
|
|
277
|
+
values.push(...Array.isArray(value) ? value : [value]);
|
|
278
|
+
this.resHeaders[key] = values;
|
|
260
279
|
}
|
|
261
280
|
releasePendingWrite(error) {
|
|
262
281
|
const callback = this.pendingWrite;
|
|
@@ -267,8 +286,8 @@ var PagesResponseStream = class extends Writable {
|
|
|
267
286
|
if (this.resolved) return;
|
|
268
287
|
this.resolved = true;
|
|
269
288
|
const headers = new Headers();
|
|
270
|
-
for (const [key, value] of Object.entries(this.resHeaders)) headers.
|
|
271
|
-
|
|
289
|
+
for (const [key, value] of Object.entries(this.resHeaders)) if (Array.isArray(value)) for (const item of value) headers.append(key, String(item));
|
|
290
|
+
else headers.set(key, String(value));
|
|
272
291
|
if (NO_BODY_RESPONSE_STATUSES.has(this.resStatusCode)) {
|
|
273
292
|
this.discardBody = true;
|
|
274
293
|
this.bufferedChunks.length = 0;
|
|
@@ -359,10 +378,10 @@ function createPagesReqRes(options) {
|
|
|
359
378
|
*/
|
|
360
379
|
function createPagesApiReqRes(options) {
|
|
361
380
|
const { req, res, responsePromise } = createPagesReqRes(options);
|
|
362
|
-
const trustedRevalidateOrigin = options.trustedRevalidateOrigin ?? new URL(options.request.url).origin;
|
|
363
381
|
return {
|
|
364
382
|
req,
|
|
365
383
|
res: Object.assign(res, { async revalidate(urlPath, opts) {
|
|
384
|
+
const trustedRevalidateOrigin = options.trustedRevalidateOrigin ?? (getRequestExecutionContext()?.dispatchPagesRevalidate ? new URL(options.request.url).origin : void 0);
|
|
366
385
|
await performOnDemandRevalidate(options.request.headers, urlPath, opts, trustedRevalidateOrigin, options.allowedRevalidateHeaderKeys);
|
|
367
386
|
} }),
|
|
368
387
|
responsePromise
|
|
@@ -15,7 +15,7 @@ type PageRouteMatch = {
|
|
|
15
15
|
dataKind?: PagesRouteDataKind;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
-
export declare function fetchWorkerFilesystemRoute(request: Request, requestPathname: string, phase: FilesystemRoutePhase, fetchAsset: (request: Request) => Promise<Response>, publicFiles: ReadonlySet<string>, basePath?: string, assetPathPrefix?: string,
|
|
18
|
+
export declare function fetchWorkerFilesystemRoute(request: Request, requestPathname: string, phase: FilesystemRoutePhase, fetchAsset: (request: Request) => Promise<Response>, publicFiles: ReadonlySet<string>, basePath?: string, assetPathPrefix?: string, pathnameHasBasePath?: boolean): Promise<Response | false>;
|
|
19
19
|
export type MiddlewareResult = {
|
|
20
20
|
continue: boolean;
|
|
21
21
|
/** The pathname matches middleware, irrespective of request `has`/`missing` conditions. */
|
|
@@ -54,6 +54,11 @@ export type PagesPipelineDeps = {
|
|
|
54
54
|
recordCacheability?: boolean;
|
|
55
55
|
rawSearch?: string;
|
|
56
56
|
configMatchPathname?: string;
|
|
57
|
+
/**
|
|
58
|
+
* `shouldRestoreLocaleRootTrailingSlash` for the raw request pathname
|
|
59
|
+
* (basePath included), which the basePath-stripped request no longer shows.
|
|
60
|
+
*/
|
|
61
|
+
restoreLocaleRootTrailingSlash?: boolean;
|
|
57
62
|
/**
|
|
58
63
|
* Validate an on-demand revalidation credential using the runtime's
|
|
59
64
|
* authoritative build secret. Production adapters must inject the verifier
|
|
@@ -6,7 +6,7 @@ import { VINEXT_PRERENDER_REWRITTEN_HEADER } from "./headers.js";
|
|
|
6
6
|
import { methodNotAllowedResponse, notFoundStaticAssetResponse, sanitizeMethodNotAllowedHeaders } from "./http-error-responses.js";
|
|
7
7
|
import { cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
8
8
|
import { applyMiddlewareRequestHeaders, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
9
|
-
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
9
|
+
import { assetPrefixPathname, isAssetPrefixBuildAsset, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
10
10
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
11
11
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
12
12
|
import { detectPathnameLocale, normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
|
|
@@ -14,6 +14,7 @@ import { buildMiddlewarePrefetchSkipResponse } from "./pages-data-route.js";
|
|
|
14
14
|
import { markRouteCacheabilityDynamic } from "../shims/cacheability-classification.js";
|
|
15
15
|
import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
|
|
16
16
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
17
|
+
import { withExternalRewriteResponseHeaders } from "./middleware-response-headers.js";
|
|
17
18
|
import { setFrameworkRequestRoute } from "./request-tracing.js";
|
|
18
19
|
import { applyConfigHeadersToHeaderRecord } from "./config-headers.js";
|
|
19
20
|
import { finalizeMissingStaticAssetResponse, mergeHeaders } from "./worker-utils.js";
|
|
@@ -33,7 +34,7 @@ function headersFromRecord(record) {
|
|
|
33
34
|
else headers.set(name, value);
|
|
34
35
|
return headers;
|
|
35
36
|
}
|
|
36
|
-
async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset, publicFiles, basePath = "", assetPathPrefix = "",
|
|
37
|
+
async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset, publicFiles, basePath = "", assetPathPrefix = "", pathnameHasBasePath = true) {
|
|
37
38
|
const isRetrievalMethod = request.method === "GET" || request.method === "HEAD";
|
|
38
39
|
const assetUrl = new URL(request.url);
|
|
39
40
|
assetUrl.pathname = requestPathname;
|
|
@@ -46,7 +47,8 @@ async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetch
|
|
|
46
47
|
} catch {
|
|
47
48
|
return false;
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
if (!pathnameHasBasePath && !isAssetPrefixBuildAsset(decodedAssetUrl.pathname, assetPathPrefix)) return false;
|
|
51
|
+
const isPublicFile = pathnameHasBasePath && publicFiles.has(publicFileKey);
|
|
50
52
|
if (!isPublicFile && (requestPathname === "/api" || requestPathname.startsWith("/api/"))) return false;
|
|
51
53
|
if (phase === "direct" && isRetrievalMethod && !isPublicFile) return false;
|
|
52
54
|
if (!isPublicFile && !isNextStaticPath(decodedAssetUrl.pathname, basePath, assetPathPrefix)) return false;
|
|
@@ -118,6 +120,10 @@ async function runPagesRequest(request, deps) {
|
|
|
118
120
|
const reqCtx = requestContextFromRequest(request);
|
|
119
121
|
const requestHostname = i18nConfig ? url.hostname : "";
|
|
120
122
|
const requestConfigMatchPathname = i18nConfig ? normalizeDefaultLocalePathname(requestConfigPathname, i18nConfig, { hostname: requestHostname }) : requestConfigPathname;
|
|
123
|
+
const requestHeaderMatchPathname = i18nConfig ? normalizeDefaultLocalePathname(requestConfigPathname, i18nConfig, {
|
|
124
|
+
hostname: requestHostname,
|
|
125
|
+
restoreRootTrailingSlash: deps.restoreLocaleRootTrailingSlash
|
|
126
|
+
}) : requestConfigPathname;
|
|
121
127
|
if (configRedirects.length) {
|
|
122
128
|
const redirect = matchRedirect(requestConfigMatchPathname, configRedirects, reqCtx, basePathState, conditionalRedirectCacheability);
|
|
123
129
|
if (redirect) {
|
|
@@ -141,14 +147,16 @@ async function runPagesRequest(request, deps) {
|
|
|
141
147
|
hadBasePath: resolvedPathnameHasBasePath
|
|
142
148
|
});
|
|
143
149
|
const middlewareHeaders = {};
|
|
150
|
+
let middlewareCookies = [];
|
|
144
151
|
const mergeConfigHeadersIntoEarlyResponse = (response) => {
|
|
145
152
|
if (configHeaders.length === 0) return response;
|
|
146
153
|
const matchedConfigHeaders = {};
|
|
147
154
|
applyConfigHeadersToHeaderRecord(matchedConfigHeaders, {
|
|
148
155
|
configHeaders,
|
|
149
|
-
pathname:
|
|
156
|
+
pathname: requestHeaderMatchPathname,
|
|
150
157
|
requestContext: reqCtx,
|
|
151
158
|
basePathState,
|
|
159
|
+
middlewareHeaders: response.headers,
|
|
152
160
|
recordCacheability: deps.recordCacheability
|
|
153
161
|
});
|
|
154
162
|
return mergeHeaders(response, matchedConfigHeaders);
|
|
@@ -210,6 +218,8 @@ async function runPagesRequest(request, deps) {
|
|
|
210
218
|
else if (existing) middlewareHeaders[key] = [existing, value];
|
|
211
219
|
else middlewareHeaders[key] = [value];
|
|
212
220
|
} else middlewareHeaders[key] = value;
|
|
221
|
+
const stagedCookies = middlewareHeaders["set-cookie"];
|
|
222
|
+
if (Array.isArray(stagedCookies)) middlewareCookies = [...stagedCookies];
|
|
213
223
|
if (result.rewriteUrl) {
|
|
214
224
|
resolvedUrl = result.rewriteUrl;
|
|
215
225
|
resolvedPathnameIsRequestPathname = false;
|
|
@@ -249,26 +259,24 @@ async function runPagesRequest(request, deps) {
|
|
|
249
259
|
};
|
|
250
260
|
if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
|
|
251
261
|
configHeaders,
|
|
252
|
-
pathname:
|
|
262
|
+
pathname: requestHeaderMatchPathname,
|
|
253
263
|
requestContext: reqCtx,
|
|
254
264
|
basePathState,
|
|
255
265
|
recordCacheability: deps.recordCacheability
|
|
256
266
|
});
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
267
|
+
const proxyConfigRewrite = async (destination) => ({
|
|
268
|
+
type: "response",
|
|
269
|
+
response: withExternalRewriteResponseHeaders(await proxyExternal(request, destination), new Headers(), middlewareCookies)
|
|
270
|
+
});
|
|
271
|
+
if (isExternalUrl(resolvedUrl)) return {
|
|
272
|
+
type: "response",
|
|
273
|
+
response: withExternalRewriteResponseHeaders(await proxyExternal(request, resolvedUrl), headersFromRecord(middlewareHeaders), middlewareCookies)
|
|
274
|
+
};
|
|
264
275
|
let configRewriteFired = false;
|
|
265
276
|
for (const rewrite of configRewrites.beforeFiles ?? []) {
|
|
266
277
|
const rewritten = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), currentBasePathState(), configSourcePathname(), conditionalRewriteCacheability);
|
|
267
278
|
if (rewritten) {
|
|
268
|
-
if (isExternalUrl(rewritten)) return
|
|
269
|
-
type: "response",
|
|
270
|
-
response: await proxyExternal(request, rewritten)
|
|
271
|
-
};
|
|
279
|
+
if (isExternalUrl(rewritten)) return proxyConfigRewrite(rewritten);
|
|
272
280
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
|
|
273
281
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
274
282
|
resolvedPathnameIsRequestPathname = false;
|
|
@@ -279,13 +287,13 @@ async function runPagesRequest(request, deps) {
|
|
|
279
287
|
const initialFilesystemResult = await serveFilesystemRoute(resolvedPathname, resolvedPathnameIsRequestPathname ? "direct" : "beforeFiles");
|
|
280
288
|
if (initialFilesystemResult) return initialFilesystemResult;
|
|
281
289
|
const isMissingBuildAsset = () => isNextStaticPath(resolvedPathname, "", assetPrefixPathname(deps.assetPrefix ?? ""));
|
|
282
|
-
const isOutsideBasePathUnclaimed = () => basePath && !
|
|
290
|
+
const isOutsideBasePathUnclaimed = () => basePath && !resolvedPathnameHasBasePath;
|
|
283
291
|
const outOfBasePathNotFound = () => ({
|
|
284
292
|
type: "response",
|
|
285
|
-
response: isMissingBuildAsset() ? notFoundStaticAssetResponse(headersFromRecord(middlewareHeaders)) : new Response("This page could not be found", {
|
|
293
|
+
response: isMissingBuildAsset() ? notFoundStaticAssetResponse(headersFromRecord(middlewareHeaders)) : mergeHeaders(new Response("This page could not be found", {
|
|
286
294
|
status: 404,
|
|
287
295
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
288
|
-
})
|
|
296
|
+
}), middlewareHeaders)
|
|
289
297
|
});
|
|
290
298
|
const handleResolvedApiRoute = async () => {
|
|
291
299
|
if (isOutsideBasePathUnclaimed()) return null;
|
|
@@ -327,10 +335,7 @@ async function runPagesRequest(request, deps) {
|
|
|
327
335
|
if (!pageMatch || pageMatch.route.isDynamic) for (const rewrite of configRewrites.afterFiles ?? []) {
|
|
328
336
|
const rewritten = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), currentBasePathState(), configSourcePathname(), conditionalRewriteCacheability);
|
|
329
337
|
if (rewritten) {
|
|
330
|
-
if (isExternalUrl(rewritten)) return
|
|
331
|
-
type: "response",
|
|
332
|
-
response: await proxyExternal(request, rewritten)
|
|
333
|
-
};
|
|
338
|
+
if (isExternalUrl(rewritten)) return proxyConfigRewrite(rewritten);
|
|
334
339
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
|
|
335
340
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
336
341
|
resolvedPathnameIsRequestPathname = false;
|
|
@@ -355,10 +360,7 @@ async function runPagesRequest(request, deps) {
|
|
|
355
360
|
if ((isOutsideBasePathUnclaimed() || isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
356
361
|
const fallbackRewrite = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), currentBasePathState(), configSourcePathname(), conditionalRewriteCacheability);
|
|
357
362
|
if (!fallbackRewrite) continue;
|
|
358
|
-
if (isExternalUrl(fallbackRewrite)) return
|
|
359
|
-
type: "response",
|
|
360
|
-
response: await proxyExternal(request, fallbackRewrite)
|
|
361
|
-
};
|
|
363
|
+
if (isExternalUrl(fallbackRewrite)) return proxyConfigRewrite(fallbackRewrite);
|
|
362
364
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
363
365
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
364
366
|
resolvedPathnameIsRequestPathname = false;
|
|
@@ -384,10 +386,7 @@ async function runPagesRequest(request, deps) {
|
|
|
384
386
|
if (response.status === 404 && shouldDeferErrorPageOnMiss && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
385
387
|
const fallbackRewrite = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), currentBasePathState(), configSourcePathname(), conditionalRewriteCacheability);
|
|
386
388
|
if (!fallbackRewrite) continue;
|
|
387
|
-
if (isExternalUrl(fallbackRewrite)) return
|
|
388
|
-
type: "response",
|
|
389
|
-
response: await proxyExternal(request, fallbackRewrite)
|
|
390
|
-
};
|
|
389
|
+
if (isExternalUrl(fallbackRewrite)) return proxyConfigRewrite(fallbackRewrite);
|
|
391
390
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
392
391
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
393
392
|
resolvedPathnameIsRequestPathname = false;
|
|
@@ -437,10 +436,7 @@ async function runPagesRequest(request, deps) {
|
|
|
437
436
|
if (!devPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
438
437
|
const fallbackRewrite = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), currentBasePathState(), configSourcePathname(), conditionalRewriteCacheability);
|
|
439
438
|
if (!fallbackRewrite) continue;
|
|
440
|
-
if (isExternalUrl(fallbackRewrite)) return
|
|
441
|
-
type: "response",
|
|
442
|
-
response: await proxyExternal(request, fallbackRewrite)
|
|
443
|
-
};
|
|
439
|
+
if (isExternalUrl(fallbackRewrite)) return proxyConfigRewrite(fallbackRewrite);
|
|
444
440
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
445
441
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
446
442
|
resolvedPathnameIsRequestPathname = false;
|
|
@@ -7,7 +7,7 @@ import { attachRequestCfMetadata, cloneRequestWithHeaders, cloneRequestWithUrl,
|
|
|
7
7
|
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
8
8
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
9
9
|
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
10
|
-
import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
|
|
10
|
+
import { normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
|
|
11
11
|
import { isNextDataPathname } from "./pages-data-route.js";
|
|
12
12
|
import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
|
|
13
13
|
import { CACHEABILITY_REQUEST_STATE } from "../shims/cacheability-classification.js";
|
|
@@ -48,6 +48,10 @@ const pagesRequestStagePrerenderSecret = pagesEntry.prerenderSecret ?? null;
|
|
|
48
48
|
const basePath = vinextConfig?.basePath ?? "";
|
|
49
49
|
const assetPathPrefix = assetPrefixPathname(vinextConfig?.assetPrefix ?? "");
|
|
50
50
|
const trailingSlash = vinextConfig?.trailingSlash ?? false;
|
|
51
|
+
const localeRootTrailingSlashConfig = {
|
|
52
|
+
trailingSlash,
|
|
53
|
+
skipProxyUrlNormalize: vinextConfig?.skipProxyUrlNormalize
|
|
54
|
+
};
|
|
51
55
|
const skipTrailingSlashRedirect = vinextConfig?.skipTrailingSlashRedirect ?? false;
|
|
52
56
|
const i18nConfig = vinextConfig?.i18n ?? null;
|
|
53
57
|
const configRedirects = vinextConfig?.redirects ?? [];
|
|
@@ -88,7 +92,7 @@ function handleRequestStageLocally(request, env, ctx, dispatchResponseStage) {
|
|
|
88
92
|
function handleRequest(request, env, platformCtx, dispatchResponseStage, forceCacheBypass, defaultHostRuntime, assets) {
|
|
89
93
|
const url = new URL(request.url);
|
|
90
94
|
const trace = async () => {
|
|
91
|
-
await pagesEntry.__ensureInstrumentation?.();
|
|
95
|
+
await pagesEntry.__ensureInstrumentation?.(platformCtx);
|
|
92
96
|
return traceFrameworkRequest({
|
|
93
97
|
callback: () => handleRequestImpl(request, env, platformCtx, dispatchResponseStage, forceCacheBypass, defaultHostRuntime, assets),
|
|
94
98
|
getStatus: (response) => response?.status,
|
|
@@ -175,6 +179,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
175
179
|
}
|
|
176
180
|
const missingBuildAsset = isNextStaticPath(pathname, basePath, assetPathPrefix);
|
|
177
181
|
const hadBasePath = !basePath || hasBasePath(pathname, basePath);
|
|
182
|
+
const restoreLocaleRootTrailingSlash = shouldRestoreLocaleRootTrailingSlash(pathname, localeRootTrailingSlashConfig);
|
|
178
183
|
{
|
|
179
184
|
const stripped = stripBasePath(pathname, basePath);
|
|
180
185
|
if (stripped !== pathname) {
|
|
@@ -193,7 +198,10 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
193
198
|
request = dataNorm.request;
|
|
194
199
|
pathname = dataNorm.normalizedPathname;
|
|
195
200
|
}
|
|
196
|
-
const responseStagePolicyPathname = i18nConfig ? normalizeDefaultLocalePathname(pathname, i18nConfig, {
|
|
201
|
+
const responseStagePolicyPathname = i18nConfig ? normalizeDefaultLocalePathname(pathname, i18nConfig, {
|
|
202
|
+
hostname: url.hostname,
|
|
203
|
+
restoreRootTrailingSlash: restoreLocaleRootTrailingSlash
|
|
204
|
+
}) : pathname;
|
|
197
205
|
const responseStagePolicyHeaders = resolveResponseStageCachePolicy({
|
|
198
206
|
basePathState: {
|
|
199
207
|
basePath,
|
|
@@ -219,6 +227,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
219
227
|
hasMiddleware,
|
|
220
228
|
ctx,
|
|
221
229
|
recordCacheability: forceCacheBypass,
|
|
230
|
+
restoreLocaleRootTrailingSlash,
|
|
222
231
|
middlewareRequest: isDataReq && vinextConfig?.skipProxyUrlNormalize ? middlewareRequest : void 0,
|
|
223
232
|
dataNotFoundResponse: vinextConfig?.skipProxyUrlNormalize ? dataNorm.notFoundResponse : null,
|
|
224
233
|
authorizeOnDemandRevalidate: typeof authorizeOnDemandRevalidate === "function" ? authorizeOnDemandRevalidate : void 0,
|
|
@@ -320,7 +329,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
320
329
|
fetchPublicFile: (sourceRequest) => resolvePublicImageSource(sourceRequest, assets)
|
|
321
330
|
}), allowedWidths, imageConfig);
|
|
322
331
|
}
|
|
323
|
-
return fetchWorkerFilesystemRoute(filesystemRequest, requestPathname, phase, (assetRequest) => Promise.resolve(assets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix,
|
|
332
|
+
return fetchWorkerFilesystemRoute(filesystemRequest, requestPathname, phase, (assetRequest) => Promise.resolve(assets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix, resolvedPathnameHasBasePath);
|
|
324
333
|
}
|
|
325
334
|
};
|
|
326
335
|
const resolvePublicImageSource = async (sourceRequest, sourceAssets) => {
|
|
@@ -333,6 +342,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
333
342
|
const sourceResult = await runPagesRequest(attachRequestCfMetadata(new Request(new URL(sourcePathname + sourceUrl.search, sourceUrl), { signal: sourceRequest.signal }), sourceRequest), {
|
|
334
343
|
...deps,
|
|
335
344
|
hadBasePath: sourceHadBasePath,
|
|
345
|
+
restoreLocaleRootTrailingSlash: shouldRestoreLocaleRootTrailingSlash(sourceUrl.pathname, localeRootTrailingSlashConfig),
|
|
336
346
|
isDataReq: false,
|
|
337
347
|
isDataRequest: false,
|
|
338
348
|
middlewareRequest: void 0,
|
|
@@ -341,9 +351,9 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
341
351
|
runMiddleware: typeof runMiddleware === "function" ? wrapMiddlewareWithBasePath(runMiddleware, basePath, sourceHadBasePath) : null,
|
|
342
352
|
renderPage: null,
|
|
343
353
|
handleApi: null,
|
|
344
|
-
serveFilesystemRoute: async (candidate, _stagedHeaders, phase, _resolvedUrl, filesystemRequest) => {
|
|
354
|
+
serveFilesystemRoute: async (candidate, _stagedHeaders, phase, _resolvedUrl, filesystemRequest, candidateHasBasePath) => {
|
|
345
355
|
if (isImageOptimizationPath(candidate)) return false;
|
|
346
|
-
const asset = await fetchWorkerFilesystemRoute(filesystemRequest, candidate, phase, (assetRequest) => Promise.resolve(sourceAssets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix,
|
|
356
|
+
const asset = await fetchWorkerFilesystemRoute(filesystemRequest, candidate, phase, (assetRequest) => Promise.resolve(sourceAssets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix, candidateHasBasePath);
|
|
347
357
|
if (asset === false) return false;
|
|
348
358
|
sourceAsset = asset;
|
|
349
359
|
return new Response(null);
|
|
@@ -36,7 +36,7 @@ async function renderPagesResponse(request, env, platformCtx, props, stagedHeade
|
|
|
36
36
|
if (!isPagesResponseStageProps(props)) return new Response("Invalid vinext Pages response stage", { status: 400 });
|
|
37
37
|
if (props.buildId !== pagesEntry.buildId) return new Response("Vinext Pages response stage deployment mismatch", { status: 409 });
|
|
38
38
|
if (props.requestHost !== new URL(request.url).host) return new Response("Invalid vinext Pages response stage", { status: 400 });
|
|
39
|
-
await pagesEntry.__ensureInstrumentation?.();
|
|
39
|
+
await pagesEntry.__ensureInstrumentation?.(platformCtx);
|
|
40
40
|
registerConfiguredImageOptimizer(env);
|
|
41
41
|
const renderHeaders = new Headers(stagedHeaders ?? props.stagedHeaders ?? []);
|
|
42
42
|
renderHeaders.delete("Content-Length");
|
|
@@ -12,6 +12,7 @@ async function performOnDemandRevalidate(source, urlPath, opts = {}, trustedOrig
|
|
|
12
12
|
if (isSourceRevalidationRequest(source)) throw new Error(`Cannot revalidate ${urlPath} from an internal revalidation request`);
|
|
13
13
|
const executionContext = getRequestExecutionContext();
|
|
14
14
|
const dispatchRevalidate = executionContext?.dispatchPagesRevalidate;
|
|
15
|
+
if (!dispatchRevalidate && !trustedOrigin) throw new Error(`Cannot revalidate ${urlPath}: no in-process dispatcher or server-owned origin is available`);
|
|
15
16
|
const target = createRevalidateTarget(source, urlPath, trustedOrigin);
|
|
16
17
|
const headers = { [PRERENDER_REVALIDATE_HEADER]: getRevalidateSecret() };
|
|
17
18
|
if (trustedOrigin && !dispatchRevalidate) {
|
|
@@ -20,7 +20,7 @@ async function handleSingleStageRequest(request, env, platformCtx) {
|
|
|
20
20
|
let ctx = createWorkerPrerenderDiscoveryContext(ctxWithRevalidation, request, pagesRequestStagePrerenderSecret);
|
|
21
21
|
const readinessResponse = createWorkerPrerenderReadinessResponse(ctx, request);
|
|
22
22
|
if (readinessResponse) {
|
|
23
|
-
if (readinessResponse.status === 204) await Promise.all([__ensureInstrumentation(), __ensureInstrumentation$1()]);
|
|
23
|
+
if (readinessResponse.status === 204) await Promise.all([__ensureInstrumentation(ctx), __ensureInstrumentation$1(ctx)]);
|
|
24
24
|
return await validateCdnRequest(request) ?? readinessResponse;
|
|
25
25
|
}
|
|
26
26
|
const isClientBuildFile = isPagesClientBuildFileRequest(request, env, ctx);
|
|
@@ -3,7 +3,7 @@ import { negotiateEncoding } from "./accept-encoding.js";
|
|
|
3
3
|
import { StaticFileCache } from "./static-file-cache.js";
|
|
4
4
|
import { resolveRequestHost, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
5
5
|
import { COMPRESS_THRESHOLD, isCompressibleContentType } from "./response-compression.js";
|
|
6
|
-
import { IncomingMessage, ServerResponse } from "node:http";
|
|
6
|
+
import { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
7
7
|
//#region src/server/prod-server.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* Import a built server entry module (App Router RSC entry or Pages Router
|
|
@@ -127,7 +127,7 @@ declare function waitForNodeResponseCompletion(res: ServerResponse): Promise<voi
|
|
|
127
127
|
* Pages Router (dist/server/entry.js) and configures the appropriate handler.
|
|
128
128
|
*/
|
|
129
129
|
export declare function startProdServer(options?: ProdServerOptions): Promise<{
|
|
130
|
-
server:
|
|
130
|
+
server: Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
131
131
|
port: number;
|
|
132
132
|
}>;
|
|
133
133
|
type AppRouterPrerenderSeeder = (serverDir: string) => Promise<number>;
|