vinext 0.0.44 → 0.0.46
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/google-fonts/build-url.d.ts +10 -0
- package/dist/build/google-fonts/build-url.js +30 -0
- package/dist/build/google-fonts/build-url.js.map +1 -0
- package/dist/build/google-fonts/font-data.js +24985 -0
- package/dist/build/google-fonts/font-data.js.map +1 -0
- package/dist/build/google-fonts/font-metadata.d.ts +17 -0
- package/dist/build/google-fonts/font-metadata.js +7 -0
- package/dist/build/google-fonts/font-metadata.js.map +1 -0
- package/dist/build/google-fonts/get-axes.d.ts +7 -0
- package/dist/build/google-fonts/get-axes.js +39 -0
- package/dist/build/google-fonts/get-axes.js.map +1 -0
- package/dist/build/google-fonts/sort-variants.d.ts +5 -0
- package/dist/build/google-fonts/sort-variants.js +14 -0
- package/dist/build/google-fonts/sort-variants.js.map +1 -0
- package/dist/build/google-fonts/validate.d.ts +28 -0
- package/dist/build/google-fonts/validate.js +56 -0
- package/dist/build/google-fonts/validate.js.map +1 -0
- package/dist/build/layout-classification.d.ts +1 -1
- package/dist/build/layout-classification.js.map +1 -1
- package/dist/build/nitro-route-rules.d.ts +1 -1
- package/dist/build/nitro-route-rules.js.map +1 -1
- package/dist/build/precompress.d.ts +1 -1
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +1 -7
- package/dist/build/prerender.js +17 -6
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/run-prerender.d.ts +1 -13
- package/dist/build/run-prerender.js +5 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/standalone.d.ts +1 -1
- package/dist/build/standalone.js +4 -3
- package/dist/build/standalone.js.map +1 -1
- package/dist/check.js +30 -18
- package/dist/check.js.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/cloudflare/kv-cache-handler.d.ts +5 -0
- package/dist/cloudflare/kv-cache-handler.js +56 -35
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.d.ts +1 -16
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.js +1 -0
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.d.ts +1 -1
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +38 -2
- package/dist/config/next-config.js +24 -0
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts +1 -1
- package/dist/deploy.js +18 -23
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-rsc-entry.js +387 -1718
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +24 -0
- package/dist/entries/app-rsc-manifest.js +153 -0
- package/dist/entries/app-rsc-manifest.js.map +1 -0
- package/dist/entries/pages-server-entry.js +13 -103
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/index.js +59 -34
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.js.map +1 -1
- package/dist/plugins/async-hooks-stub.d.ts +1 -2
- package/dist/plugins/async-hooks-stub.js +2 -2
- package/dist/plugins/async-hooks-stub.js.map +1 -1
- package/dist/plugins/fonts.d.ts +1 -20
- package/dist/plugins/fonts.js +42 -21
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/rsc-client-shim-excludes.d.ts +6 -0
- package/dist/plugins/rsc-client-shim-excludes.js +27 -0
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -0
- package/dist/plugins/server-externals-manifest.d.ts +1 -11
- package/dist/plugins/server-externals-manifest.js +1 -1
- package/dist/plugins/server-externals-manifest.js.map +1 -1
- package/dist/routing/app-router.d.ts +14 -5
- package/dist/routing/app-router.js +82 -5
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +1 -3
- package/dist/routing/file-matcher.js +1 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/route-pattern.d.ts +9 -0
- package/dist/routing/route-pattern.js +90 -0
- package/dist/routing/route-pattern.js.map +1 -0
- package/dist/routing/route-trie.js +10 -11
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/utils.d.ts +1 -29
- package/dist/routing/utils.js +1 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/app-browser-entry.js +63 -5
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-state.d.ts +1 -1
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +1 -1
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-elements.d.ts +1 -2
- package/dist/server/app-elements.js +1 -1
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-middleware.d.ts +32 -0
- package/dist/server/app-middleware.js +147 -0
- package/dist/server/app-middleware.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +5 -1
- package/dist/server/app-page-boundary-render.js +52 -30
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +13 -1
- package/dist/server/app-page-boundary.js +37 -17
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +4 -1
- package/dist/server/app-page-cache.js +38 -2
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +120 -0
- package/dist/server/app-page-dispatch.js +332 -0
- package/dist/server/app-page-dispatch.js.map +1 -0
- package/dist/server/app-page-execution.d.ts +6 -3
- package/dist/server/app-page-execution.js +22 -10
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +55 -0
- package/dist/server/app-page-head.js +196 -0
- package/dist/server/app-page-head.js.map +1 -0
- package/dist/server/app-page-method.d.ts +16 -0
- package/dist/server/app-page-method.js +30 -0
- package/dist/server/app-page-method.js.map +1 -0
- package/dist/server/app-page-params.d.ts +7 -0
- package/dist/server/app-page-params.js +28 -0
- package/dist/server/app-page-params.js.map +1 -0
- package/dist/server/app-page-probe.d.ts +1 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +4 -3
- package/dist/server/app-page-render.js +54 -8
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +5 -5
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +1 -1
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +15 -11
- package/dist/server/app-page-route-wiring.js +31 -9
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +12 -1
- package/dist/server/app-page-stream.js +10 -4
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-prerender-endpoints.d.ts +19 -0
- package/dist/server/app-prerender-endpoints.js +96 -0
- package/dist/server/app-prerender-endpoints.js.map +1 -0
- package/dist/server/app-prerender-static-params.d.ts +16 -0
- package/dist/server/app-prerender-static-params.js +14 -0
- package/dist/server/app-prerender-static-params.js.map +1 -0
- package/dist/server/app-route-handler-cache.d.ts +4 -1
- package/dist/server/app-route-handler-cache.js +6 -2
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +42 -0
- package/dist/server/app-route-handler-dispatch.js +147 -0
- package/dist/server/app-route-handler-dispatch.js.map +1 -0
- package/dist/server/app-route-handler-execution.d.ts +7 -3
- package/dist/server/app-route-handler-execution.js +32 -6
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-policy.d.ts +6 -2
- package/dist/server/app-route-handler-policy.js +8 -3
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +44 -4
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.d.ts +5 -2
- package/dist/server/app-route-handler-runtime.js +108 -2
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-errors.d.ts +27 -0
- package/dist/server/app-rsc-errors.js +42 -0
- package/dist/server/app-rsc-errors.js.map +1 -0
- package/dist/server/app-rsc-route-matching.d.ts +40 -0
- package/dist/server/app-rsc-route-matching.js +66 -0
- package/dist/server/app-rsc-route-matching.js.map +1 -0
- package/dist/server/app-server-action-execution.d.ts +120 -0
- package/dist/server/app-server-action-execution.js +355 -0
- package/dist/server/app-server-action-execution.js.map +1 -0
- package/dist/server/app-ssr-entry.d.ts +7 -0
- package/dist/server/app-ssr-entry.js +30 -9
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +5 -3
- package/dist/server/app-ssr-stream.js +29 -2
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.d.ts +15 -0
- package/dist/server/app-static-generation.js +20 -0
- package/dist/server/app-static-generation.js.map +1 -0
- package/dist/server/csp.d.ts +1 -2
- package/dist/server/csp.js +1 -1
- package/dist/server/csp.js.map +1 -1
- package/dist/server/dev-module-runner.d.ts +1 -1
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-route-files.d.ts +7 -0
- package/dist/server/dev-route-files.js +73 -0
- package/dist/server/dev-route-files.js.map +1 -0
- package/dist/server/dev-server.js +4 -0
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.d.ts +17 -0
- package/dist/server/file-based-metadata.js +356 -0
- package/dist/server/file-based-metadata.js.map +1 -0
- package/dist/server/implicit-tags.d.ts +6 -0
- package/dist/server/implicit-tags.js +42 -0
- package/dist/server/implicit-tags.js.map +1 -0
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +20 -2
- package/dist/server/isr-cache.js +58 -7
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-build-data.d.ts +25 -0
- package/dist/server/metadata-route-build-data.js +150 -0
- package/dist/server/metadata-route-build-data.js.map +1 -0
- package/dist/server/metadata-route-response.d.ts +17 -0
- package/dist/server/metadata-route-response.js +187 -0
- package/dist/server/metadata-route-response.js.map +1 -0
- package/dist/server/metadata-routes.d.ts +42 -4
- package/dist/server/metadata-routes.js +127 -11
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.d.ts +15 -0
- package/dist/server/middleware-matcher.js +102 -0
- package/dist/server/middleware-matcher.js.map +1 -0
- package/dist/server/middleware-request-headers.d.ts +1 -3
- package/dist/server/middleware-request-headers.js +5 -4
- package/dist/server/middleware-request-headers.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +39 -0
- package/dist/server/middleware-runtime.js +159 -0
- package/dist/server/middleware-runtime.js.map +1 -0
- package/dist/server/middleware.d.ts +5 -37
- package/dist/server/middleware.js +18 -228
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/pages-api-route.d.ts +1 -1
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-i18n.d.ts +2 -3
- package/dist/server/pages-i18n.js +1 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-node-compat.d.ts +1 -2
- package/dist/server/pages-node-compat.js +1 -1
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +6 -2
- package/dist/server/pages-page-data.js +4 -0
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +1 -1
- package/dist/server/pages-page-response.js +2 -1
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prerender-work-unit-setup.d.ts +7 -0
- package/dist/server/prerender-work-unit-setup.js +30 -0
- package/dist/server/prerender-work-unit-setup.js.map +1 -0
- package/dist/server/prod-server.js +12 -14
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +46 -5
- package/dist/server/request-pipeline.js +84 -5
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/rsc-stream-hints.d.ts +5 -0
- package/dist/server/rsc-stream-hints.js +35 -0
- package/dist/server/rsc-stream-hints.js.map +1 -0
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.d.ts +9 -0
- package/dist/server/server-action-not-found.js +40 -0
- package/dist/server/server-action-not-found.js.map +1 -0
- package/dist/server/socket-error-backstop.d.ts +17 -0
- package/dist/server/socket-error-backstop.js +129 -0
- package/dist/server/socket-error-backstop.js.map +1 -0
- package/dist/server/static-file-cache.d.ts +1 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/shims/cache-runtime.js +16 -3
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +27 -2
- package/dist/shims/cache.js +135 -24
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +49 -4
- package/dist/shims/error-boundary.js +76 -4
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +10 -1
- package/dist/shims/fetch-cache.js +24 -4
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +21 -22
- package/dist/shims/font-google-base.js +86 -29
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/form.js +1 -1
- package/dist/shims/headers.d.ts +14 -2
- package/dist/shims/headers.js +127 -17
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.js +26 -8
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/make-hanging-promise.d.ts +16 -0
- package/dist/shims/internal/make-hanging-promise.js +46 -0
- package/dist/shims/internal/make-hanging-promise.js.map +1 -0
- package/dist/shims/internal/work-unit-async-storage.d.ts +26 -3
- package/dist/shims/internal/work-unit-async-storage.js +6 -3
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
- package/dist/shims/link.js +1 -1
- package/dist/shims/metadata.d.ts +38 -26
- package/dist/shims/metadata.js +75 -45
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +17 -4
- package/dist/shims/navigation.js +29 -6
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.d.ts +2 -2
- package/dist/shims/navigation.react-server.js +2 -2
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/offline.d.ts +5 -0
- package/dist/shims/offline.js +17 -0
- package/dist/shims/offline.js.map +1 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/root-params.d.ts +11 -0
- package/dist/shims/root-params.js +24 -0
- package/dist/shims/root-params.js.map +1 -0
- package/dist/shims/router.js +1 -1
- package/dist/shims/server.d.ts +5 -1
- package/dist/shims/server.js +101 -10
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/thenable-params.d.ts +5 -0
- package/dist/shims/thenable-params.js +37 -0
- package/dist/shims/thenable-params.js.map +1 -0
- package/dist/shims/unified-request-context.d.ts +2 -1
- package/dist/shims/unified-request-context.js +4 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/url-safety.d.ts +3 -1
- package/dist/shims/url-safety.js +5 -1
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/utils/error-cause.d.ts +5 -0
- package/dist/utils/error-cause.js +97 -0
- package/dist/utils/error-cause.js.map +1 -0
- package/dist/utils/lazy-chunks.d.ts +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/package.json +6 -1
- package/dist/server/middleware-codegen.d.ts +0 -54
- package/dist/server/middleware-codegen.js +0 -414
- package/dist/server/middleware-codegen.js.map +0 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { resolveEntryPath } from "./runtime-entry-module.js";
|
|
2
2
|
import { isProxyFile } from "../server/middleware.js";
|
|
3
|
-
import {
|
|
3
|
+
import { buildAppRscManifestCode } from "./app-rsc-manifest.js";
|
|
4
4
|
import { generateDevOriginCheckCode } from "../server/dev-origin-check.js";
|
|
5
|
-
import fs from "node:fs";
|
|
6
5
|
//#region src/entries/app-rsc-entry.ts
|
|
7
6
|
/**
|
|
8
7
|
* App Router RSC entry generator.
|
|
@@ -15,25 +14,33 @@ import fs from "node:fs";
|
|
|
15
14
|
*/
|
|
16
15
|
const configMatchersPath = resolveEntryPath("../config/config-matchers.js", import.meta.url);
|
|
17
16
|
const requestPipelinePath = resolveEntryPath("../server/request-pipeline.js", import.meta.url);
|
|
17
|
+
const appMiddlewarePath = resolveEntryPath("../server/app-middleware.js", import.meta.url);
|
|
18
18
|
const middlewareRequestHeadersPath = resolveEntryPath("../server/middleware-request-headers.js", import.meta.url);
|
|
19
19
|
const requestContextShimPath = resolveEntryPath("../shims/request-context.js", import.meta.url);
|
|
20
20
|
const normalizePathModulePath = resolveEntryPath("../server/normalize-path.js", import.meta.url);
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
21
|
+
const routingUtilsPath = resolveEntryPath("../routing/utils.js", import.meta.url);
|
|
22
|
+
const appRouteHandlerDispatchPath = resolveEntryPath("../server/app-route-handler-dispatch.js", import.meta.url);
|
|
23
|
+
const appServerActionExecutionPath = resolveEntryPath("../server/app-server-action-execution.js", import.meta.url);
|
|
24
|
+
const appRscErrorsPath = resolveEntryPath("../server/app-rsc-errors.js", import.meta.url);
|
|
25
|
+
const implicitTagsPath = resolveEntryPath("../server/implicit-tags.js", import.meta.url);
|
|
26
26
|
const appPageExecutionPath = resolveEntryPath("../server/app-page-execution.js", import.meta.url);
|
|
27
27
|
const appPageBoundaryRenderPath = resolveEntryPath("../server/app-page-boundary-render.js", import.meta.url);
|
|
28
28
|
const appElementsPath = resolveEntryPath("../server/app-elements.js", import.meta.url);
|
|
29
29
|
const appPageRouteWiringPath = resolveEntryPath("../server/app-page-route-wiring.js", import.meta.url);
|
|
30
|
-
const
|
|
30
|
+
const appPageHeadPath = resolveEntryPath("../server/app-page-head.js", import.meta.url);
|
|
31
|
+
const appPageParamsPath = resolveEntryPath("../server/app-page-params.js", import.meta.url);
|
|
31
32
|
const appPageResponsePath = resolveEntryPath("../server/app-page-response.js", import.meta.url);
|
|
33
|
+
const appPageDispatchPath = resolveEntryPath("../server/app-page-dispatch.js", import.meta.url);
|
|
32
34
|
const cspPath = resolveEntryPath("../server/csp.js", import.meta.url);
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
35
|
+
const appRscRouteMatchingPath = resolveEntryPath("../server/app-rsc-route-matching.js", import.meta.url);
|
|
36
|
+
const appPrerenderEndpointsPath = resolveEntryPath("../server/app-prerender-endpoints.js", import.meta.url);
|
|
37
|
+
const prerenderWorkUnitSetupPath = resolveEntryPath("../server/prerender-work-unit-setup.js", import.meta.url);
|
|
38
|
+
const rscStreamHintsPath = resolveEntryPath("../server/rsc-stream-hints.js", import.meta.url);
|
|
39
|
+
const isrCachePath = resolveEntryPath("../server/isr-cache.js", import.meta.url);
|
|
40
|
+
const rootParamsShimPath = resolveEntryPath("../shims/root-params.js", import.meta.url);
|
|
41
|
+
const thenableParamsShimPath = resolveEntryPath("../shims/thenable-params.js", import.meta.url);
|
|
42
|
+
const metadataRouteResponsePath = resolveEntryPath("../server/metadata-route-response.js", import.meta.url);
|
|
43
|
+
const errorCausePath = resolveEntryPath("../utils/error-cause.js", import.meta.url);
|
|
37
44
|
/**
|
|
38
45
|
* Generate the virtual RSC entry module.
|
|
39
46
|
*
|
|
@@ -56,201 +63,64 @@ function generateRscEntry(appDir, routes, middlewarePath, metadataRoutes, global
|
|
|
56
63
|
const i18nConfig = config?.i18n ?? null;
|
|
57
64
|
const hasPagesDir = config?.hasPagesDir ?? false;
|
|
58
65
|
const publicFiles = config?.publicFiles ?? [];
|
|
59
|
-
const imports =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (importMap.has(filePath)) return importMap.get(filePath);
|
|
64
|
-
const varName = `mod_${importIdx++}`;
|
|
65
|
-
const absPath = filePath.replace(/\\/g, "/");
|
|
66
|
-
imports.push(`import * as ${varName} from ${JSON.stringify(absPath)};`);
|
|
67
|
-
importMap.set(filePath, varName);
|
|
68
|
-
return varName;
|
|
69
|
-
}
|
|
70
|
-
for (const route of routes) {
|
|
71
|
-
if (route.pagePath) getImportVar(route.pagePath);
|
|
72
|
-
if (route.routePath) getImportVar(route.routePath);
|
|
73
|
-
for (const layout of route.layouts) getImportVar(layout);
|
|
74
|
-
for (const tmpl of route.templates) getImportVar(tmpl);
|
|
75
|
-
if (route.loadingPath) getImportVar(route.loadingPath);
|
|
76
|
-
if (route.errorPath) getImportVar(route.errorPath);
|
|
77
|
-
if (route.layoutErrorPaths) {
|
|
78
|
-
for (const ep of route.layoutErrorPaths) if (ep) getImportVar(ep);
|
|
79
|
-
}
|
|
80
|
-
if (route.notFoundPath) getImportVar(route.notFoundPath);
|
|
81
|
-
for (const nfp of route.notFoundPaths || []) if (nfp) getImportVar(nfp);
|
|
82
|
-
if (route.forbiddenPath) getImportVar(route.forbiddenPath);
|
|
83
|
-
if (route.unauthorizedPath) getImportVar(route.unauthorizedPath);
|
|
84
|
-
for (const slot of route.parallelSlots) {
|
|
85
|
-
if (slot.pagePath) getImportVar(slot.pagePath);
|
|
86
|
-
if (slot.defaultPath) getImportVar(slot.defaultPath);
|
|
87
|
-
if (slot.layoutPath) getImportVar(slot.layoutPath);
|
|
88
|
-
if (slot.loadingPath) getImportVar(slot.loadingPath);
|
|
89
|
-
if (slot.errorPath) getImportVar(slot.errorPath);
|
|
90
|
-
for (const ir of slot.interceptingRoutes) {
|
|
91
|
-
getImportVar(ir.pagePath);
|
|
92
|
-
for (const layoutPath of ir.layoutPaths) getImportVar(layoutPath);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const routeEntries = routes.map((route, routeIdx) => {
|
|
97
|
-
const layoutVars = route.layouts.map((l) => getImportVar(l));
|
|
98
|
-
const templateVars = route.templates.map((t) => getImportVar(t));
|
|
99
|
-
const notFoundVars = (route.notFoundPaths || []).map((nf) => nf ? getImportVar(nf) : "null");
|
|
100
|
-
const slotEntries = route.parallelSlots.map((slot) => {
|
|
101
|
-
const interceptEntries = slot.interceptingRoutes.map((ir) => ` {
|
|
102
|
-
convention: ${JSON.stringify(ir.convention)},
|
|
103
|
-
targetPattern: ${JSON.stringify(ir.targetPattern)},
|
|
104
|
-
interceptLayouts: [${ir.layoutPaths.map((layoutPath) => getImportVar(layoutPath)).join(", ")}],
|
|
105
|
-
page: ${getImportVar(ir.pagePath)},
|
|
106
|
-
params: ${JSON.stringify(ir.params)},
|
|
107
|
-
}`);
|
|
108
|
-
return ` ${JSON.stringify(slot.key)}: {
|
|
109
|
-
name: ${JSON.stringify(slot.name)},
|
|
110
|
-
page: ${slot.pagePath ? getImportVar(slot.pagePath) : "null"},
|
|
111
|
-
default: ${slot.defaultPath ? getImportVar(slot.defaultPath) : "null"},
|
|
112
|
-
layout: ${slot.layoutPath ? getImportVar(slot.layoutPath) : "null"},
|
|
113
|
-
loading: ${slot.loadingPath ? getImportVar(slot.loadingPath) : "null"},
|
|
114
|
-
error: ${slot.errorPath ? getImportVar(slot.errorPath) : "null"},
|
|
115
|
-
layoutIndex: ${slot.layoutIndex},
|
|
116
|
-
routeSegments: ${JSON.stringify(slot.routeSegments)},
|
|
117
|
-
intercepts: [
|
|
118
|
-
${interceptEntries.join(",\n")}
|
|
119
|
-
],
|
|
120
|
-
}`;
|
|
121
|
-
});
|
|
122
|
-
const layoutErrorVars = (route.layoutErrorPaths || []).map((ep) => ep ? getImportVar(ep) : "null");
|
|
123
|
-
return ` {
|
|
124
|
-
__buildTimeClassifications: __VINEXT_CLASS(${routeIdx}), // evaluated once at module load
|
|
125
|
-
__buildTimeReasons: __classDebug ? __VINEXT_CLASS_REASONS(${routeIdx}) : null,
|
|
126
|
-
pattern: ${JSON.stringify(route.pattern)},
|
|
127
|
-
patternParts: ${JSON.stringify(route.patternParts)},
|
|
128
|
-
isDynamic: ${route.isDynamic},
|
|
129
|
-
params: ${JSON.stringify(route.params)},
|
|
130
|
-
page: ${route.pagePath ? getImportVar(route.pagePath) : "null"},
|
|
131
|
-
routeHandler: ${route.routePath ? getImportVar(route.routePath) : "null"},
|
|
132
|
-
layouts: [${layoutVars.join(", ")}],
|
|
133
|
-
routeSegments: ${JSON.stringify(route.routeSegments)},
|
|
134
|
-
templateTreePositions: ${JSON.stringify(route.templateTreePositions)},
|
|
135
|
-
layoutTreePositions: ${JSON.stringify(route.layoutTreePositions)},
|
|
136
|
-
templates: [${templateVars.join(", ")}],
|
|
137
|
-
errors: [${layoutErrorVars.join(", ")}],
|
|
138
|
-
slots: {
|
|
139
|
-
${slotEntries.join(",\n")}
|
|
140
|
-
},
|
|
141
|
-
loading: ${route.loadingPath ? getImportVar(route.loadingPath) : "null"},
|
|
142
|
-
error: ${route.errorPath ? getImportVar(route.errorPath) : "null"},
|
|
143
|
-
notFound: ${route.notFoundPath ? getImportVar(route.notFoundPath) : "null"},
|
|
144
|
-
notFounds: [${notFoundVars.join(", ")}],
|
|
145
|
-
forbidden: ${route.forbiddenPath ? getImportVar(route.forbiddenPath) : "null"},
|
|
146
|
-
unauthorized: ${route.unauthorizedPath ? getImportVar(route.unauthorizedPath) : "null"},
|
|
147
|
-
}`;
|
|
148
|
-
});
|
|
149
|
-
const rootRoute = routes.find((r) => r.pattern === "/");
|
|
150
|
-
const rootNotFoundVar = rootRoute?.notFoundPath ? getImportVar(rootRoute.notFoundPath) : null;
|
|
151
|
-
const rootForbiddenVar = rootRoute?.forbiddenPath ? getImportVar(rootRoute.forbiddenPath) : null;
|
|
152
|
-
const rootUnauthorizedVar = rootRoute?.unauthorizedPath ? getImportVar(rootRoute.unauthorizedPath) : null;
|
|
153
|
-
const rootLayoutVars = rootRoute ? rootRoute.layouts.map((l) => getImportVar(l)) : [];
|
|
154
|
-
const globalErrorVar = globalErrorPath ? getImportVar(globalErrorPath) : null;
|
|
155
|
-
const effectiveMetaRoutes = metadataRoutes ?? [];
|
|
156
|
-
const dynamicMetaRoutes = effectiveMetaRoutes.filter((r) => r.isDynamic);
|
|
157
|
-
for (const mr of dynamicMetaRoutes) getImportVar(mr.filePath);
|
|
158
|
-
const metaRouteEntries = effectiveMetaRoutes.map((mr) => {
|
|
159
|
-
const patternParts = mr.isDynamic && mr.servedUrl.includes("[") ? JSON.stringify(mr.servedUrl.split("/").filter(Boolean).map((seg) => {
|
|
160
|
-
if (seg.startsWith("[[...") && seg.endsWith("]]")) return ":" + seg.slice(5, -2) + "*";
|
|
161
|
-
if (seg.startsWith("[...") && seg.endsWith("]")) return ":" + seg.slice(4, -1) + "+";
|
|
162
|
-
if (seg.startsWith("[") && seg.endsWith("]")) return ":" + seg.slice(1, -1);
|
|
163
|
-
return seg;
|
|
164
|
-
})) : null;
|
|
165
|
-
if (mr.isDynamic) return ` {
|
|
166
|
-
type: ${JSON.stringify(mr.type)},
|
|
167
|
-
isDynamic: true,
|
|
168
|
-
servedUrl: ${JSON.stringify(mr.servedUrl)},
|
|
169
|
-
contentType: ${JSON.stringify(mr.contentType)},
|
|
170
|
-
module: ${getImportVar(mr.filePath)},${patternParts ? `\n patternParts: ${patternParts},` : ""}
|
|
171
|
-
}`;
|
|
172
|
-
let fileDataBase64 = "";
|
|
173
|
-
try {
|
|
174
|
-
fileDataBase64 = fs.readFileSync(mr.filePath).toString("base64");
|
|
175
|
-
} catch {}
|
|
176
|
-
return ` {
|
|
177
|
-
type: ${JSON.stringify(mr.type)},
|
|
178
|
-
isDynamic: false,
|
|
179
|
-
servedUrl: ${JSON.stringify(mr.servedUrl)},
|
|
180
|
-
contentType: ${JSON.stringify(mr.contentType)},
|
|
181
|
-
fileDataBase64: ${JSON.stringify(fileDataBase64)},
|
|
182
|
-
}`;
|
|
66
|
+
const { imports, routeEntries, metaRouteEntries, generateStaticParamsEntries, rootNotFoundVar, rootForbiddenVar, rootUnauthorizedVar, rootLayoutVars, globalErrorVar } = buildAppRscManifestCode({
|
|
67
|
+
routes,
|
|
68
|
+
metadataRoutes,
|
|
69
|
+
globalErrorPath
|
|
183
70
|
});
|
|
71
|
+
const loadPrerenderPagesRoutesCode = hasPagesDir ? `
|
|
72
|
+
async function __loadPrerenderPagesRoutes() {
|
|
73
|
+
const __gspSsrEntry = await import.meta.viteRsc.loadModule("ssr", "index");
|
|
74
|
+
return __gspSsrEntry.pageRoutes;
|
|
75
|
+
}
|
|
76
|
+
` : "";
|
|
77
|
+
const prerenderPagesLoaderOption = hasPagesDir ? " loadPagesRoutes: __loadPrerenderPagesRoutes,\n" : "";
|
|
184
78
|
return `
|
|
185
79
|
import {
|
|
186
80
|
renderToReadableStream as _renderToReadableStream,
|
|
81
|
+
decodeAction,
|
|
187
82
|
decodeReply,
|
|
188
83
|
loadServerAction,
|
|
189
84
|
createTemporaryReferenceSet,
|
|
190
85
|
} from "@vitejs/plugin-rsc/rsc";
|
|
191
86
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
192
87
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
// Flight lines are newline-delimited, so we buffer partial lines across chunks
|
|
198
|
-
// to guarantee the regex never sees a split hint.
|
|
88
|
+
import {
|
|
89
|
+
normalizeReactFlightPreloadHints as __normalizeReactFlightPreloadHints,
|
|
90
|
+
} from ${JSON.stringify(rscStreamHintsPath)};
|
|
91
|
+
|
|
199
92
|
function renderToReadableStream(model, options) {
|
|
200
|
-
|
|
201
|
-
const stream = _renderToReadableStream(model, options);
|
|
202
|
-
const decoder = new TextDecoder();
|
|
203
|
-
const encoder = new TextEncoder();
|
|
204
|
-
let carry = "";
|
|
205
|
-
return stream.pipeThrough(new TransformStream({
|
|
206
|
-
transform(chunk, controller) {
|
|
207
|
-
const text = carry + decoder.decode(chunk, { stream: true });
|
|
208
|
-
const lastNl = text.lastIndexOf("\\n");
|
|
209
|
-
if (lastNl === -1) {
|
|
210
|
-
carry = text;
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
carry = text.slice(lastNl + 1);
|
|
214
|
-
controller.enqueue(encoder.encode(text.slice(0, lastNl + 1).replace(_hlFixRe, '$1,"style"$2')));
|
|
215
|
-
},
|
|
216
|
-
flush(controller) {
|
|
217
|
-
const text = carry + decoder.decode();
|
|
218
|
-
if (text) controller.enqueue(encoder.encode(text.replace(_hlFixRe, '$1,"style"$2')));
|
|
219
|
-
}
|
|
220
|
-
}));
|
|
93
|
+
return __normalizeReactFlightPreloadHints(_renderToReadableStream(model, options));
|
|
221
94
|
}
|
|
222
95
|
import { createElement } from "react";
|
|
223
96
|
import { setNavigationContext as _setNavigationContextOrig, getNavigationContext as _getNavigationContext } from "next/navigation";
|
|
224
|
-
import { setHeadersContext, headersContextFromRequest, getDraftModeCookieHeader, getAndClearPendingCookies, consumeDynamicUsage,
|
|
225
|
-
import { NextRequest, NextFetchEvent } from "next/server";
|
|
97
|
+
import { setHeadersContext, headersContextFromRequest, getDraftModeCookieHeader, getAndClearPendingCookies, consumeDynamicUsage, consumeInvalidDynamicUsageError, markDynamicUsage, getHeadersContext, setHeadersAccessPhase } from "next/headers";
|
|
226
98
|
import { mergeMetadata, resolveModuleMetadata, mergeViewport, resolveModuleViewport } from "vinext/metadata";
|
|
227
99
|
${middlewarePath ? `import * as middlewareModule from ${JSON.stringify(middlewarePath.replace(/\\/g, "/"))};` : ""}
|
|
228
100
|
${instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(instrumentationPath.replace(/\\/g, "/"))};` : ""}
|
|
229
|
-
|
|
230
|
-
import { requestContextFromRequest, normalizeHost, matchRedirect, matchRewrite,
|
|
231
|
-
import { decodePathParams as __decodePathParams } from ${JSON.stringify(normalizePathModulePath)};
|
|
101
|
+
import { handleMetadataRouteRequest as __handleMetadataRouteRequest } from ${JSON.stringify(metadataRouteResponsePath)};
|
|
102
|
+
import { requestContextFromRequest, normalizeHost, matchRedirect, matchRewrite, isExternalUrl, proxyExternalRequest, sanitizeDestination } from ${JSON.stringify(configMatchersPath)};
|
|
103
|
+
import { decodePathParams as __decodePathParams, normalizePath as __normalizePath } from ${JSON.stringify(normalizePathModulePath)};
|
|
104
|
+
import { normalizePathnameForRouteMatch as __normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict as __normalizePathnameForRouteMatchStrict } from ${JSON.stringify(routingUtilsPath)};
|
|
232
105
|
import { buildRequestHeadersFromMiddlewareResponse as __buildRequestHeadersFromMiddlewareResponse } from ${JSON.stringify(middlewareRequestHeadersPath)};
|
|
233
|
-
import {
|
|
106
|
+
import { applyConfigHeadersToResponse, resolvePublicFileRoute, validateImageUrl, guardProtocolRelativeUrl, hasBasePath, stripBasePath, normalizeTrailingSlash } from ${JSON.stringify(requestPipelinePath)};
|
|
107
|
+
import { applyAppMiddleware as __applyAppMiddleware } from ${JSON.stringify(appMiddlewarePath)};
|
|
234
108
|
import {
|
|
235
|
-
|
|
236
|
-
} from ${JSON.stringify(
|
|
109
|
+
dispatchAppRouteHandler as __dispatchAppRouteHandler,
|
|
110
|
+
} from ${JSON.stringify(appRouteHandlerDispatchPath)};
|
|
237
111
|
import {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
} from ${JSON.stringify(
|
|
112
|
+
handleProgressiveServerActionRequest as __handleProgressiveServerActionRequest,
|
|
113
|
+
handleServerActionRscRequest as __handleServerActionRscRequest,
|
|
114
|
+
readActionBodyWithLimit as __readBodyWithLimit,
|
|
115
|
+
readActionFormDataWithLimit as __readFormDataWithLimit,
|
|
116
|
+
} from ${JSON.stringify(appServerActionExecutionPath)};
|
|
243
117
|
import {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
import { readAppPageCacheResponse as __readAppPageCacheResponse } from ${JSON.stringify(appPageCachePath)};
|
|
118
|
+
createRscOnErrorHandler as __createRscOnErrorHandler,
|
|
119
|
+
sanitizeErrorForClient as __sanitizeErrorForClient,
|
|
120
|
+
} from ${JSON.stringify(appRscErrorsPath)};
|
|
248
121
|
import {
|
|
249
122
|
buildAppPageFontLinkHeader as __buildAppPageFontLinkHeader,
|
|
250
|
-
buildAppPageSpecialErrorResponse as __buildAppPageSpecialErrorResponse,
|
|
251
|
-
readAppPageTextStream as __readAppPageTextStream,
|
|
252
123
|
resolveAppPageSpecialError as __resolveAppPageSpecialError,
|
|
253
|
-
teeAppPageRscStreamForCapture as __teeAppPageRscStreamForCapture,
|
|
254
124
|
} from ${JSON.stringify(appPageExecutionPath)};
|
|
255
125
|
import {
|
|
256
126
|
renderAppPageErrorBoundary as __renderAppPageErrorBoundary,
|
|
@@ -266,34 +136,51 @@ import {
|
|
|
266
136
|
resolveAppPageChildSegments as __resolveAppPageChildSegments,
|
|
267
137
|
} from ${JSON.stringify(appPageRouteWiringPath)};
|
|
268
138
|
import {
|
|
269
|
-
|
|
270
|
-
} from ${JSON.stringify(
|
|
139
|
+
resolveAppPageSegmentParams as __resolveAppPageSegmentParams,
|
|
140
|
+
} from ${JSON.stringify(appPageParamsPath)};
|
|
141
|
+
import {
|
|
142
|
+
collectAppPageSearchParams as __collectAppPageSearchParams,
|
|
143
|
+
resolveActiveParallelRouteHeadInputs as __resolveActiveParallelRouteHeadInputs,
|
|
144
|
+
resolveAppPageHead as __resolveAppPageHead,
|
|
145
|
+
} from ${JSON.stringify(appPageHeadPath)};
|
|
271
146
|
import {
|
|
272
147
|
mergeMiddlewareResponseHeaders as __mergeMiddlewareResponseHeaders,
|
|
273
148
|
} from ${JSON.stringify(appPageResponsePath)};
|
|
149
|
+
import {
|
|
150
|
+
dispatchAppPage as __dispatchAppPage,
|
|
151
|
+
} from ${JSON.stringify(appPageDispatchPath)};
|
|
274
152
|
import { getScriptNonceFromHeaderSources as __getScriptNonceFromHeaderSources } from ${JSON.stringify(cspPath)};
|
|
153
|
+
import { buildPageCacheTags } from ${JSON.stringify(implicitTagsPath)};
|
|
154
|
+
import { getRequestExecutionContext as _getRequestExecutionContext } from ${JSON.stringify(requestContextShimPath)};
|
|
155
|
+
import { setRootParams as __setRootParams, pickRootParams as __pickRootParams } from ${JSON.stringify(rootParamsShimPath)};
|
|
156
|
+
import { makeThenableParams } from ${JSON.stringify(thenableParamsShimPath)};
|
|
157
|
+
import { ensureFetchPatch as _ensureFetchPatch, setCurrentFetchSoftTags } from "vinext/fetch-cache";
|
|
275
158
|
import {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
resolveAppPageIntercept as __resolveAppPageIntercept,
|
|
279
|
-
validateAppPageDynamicParams as __validateAppPageDynamicParams,
|
|
280
|
-
} from ${JSON.stringify(appPageRequestPath)};
|
|
159
|
+
createAppRscRouteMatcher as __createAppRscRouteMatcher,
|
|
160
|
+
} from ${JSON.stringify(appRscRouteMatchingPath)};
|
|
281
161
|
import {
|
|
282
|
-
|
|
283
|
-
} from ${JSON.stringify(
|
|
284
|
-
import {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
162
|
+
handleAppPrerenderEndpoint as __handleAppPrerenderEndpoint,
|
|
163
|
+
} from ${JSON.stringify(appPrerenderEndpointsPath)};
|
|
164
|
+
import {
|
|
165
|
+
appIsrHtmlKey as __isrHtmlKey,
|
|
166
|
+
appIsrRscKey as __isrRscKey,
|
|
167
|
+
appIsrRouteKey as __isrRouteKey,
|
|
168
|
+
isrGet as __isrGet,
|
|
169
|
+
isrSet as __isrSet,
|
|
170
|
+
normalizeMountedSlotsHeader as __normalizeMountedSlotsHeader,
|
|
171
|
+
triggerBackgroundRegeneration as __triggerBackgroundRegeneration,
|
|
172
|
+
} from ${JSON.stringify(isrCachePath)};
|
|
288
173
|
// Import server-only state module to register ALS-backed accessors.
|
|
289
174
|
import "vinext/navigation-state";
|
|
175
|
+
import { runWithPrerenderWorkUnit as __runWithPrerenderWorkUnit } from ${JSON.stringify(prerenderWorkUnitSetupPath)};
|
|
290
176
|
import { runWithRequestContext as _runWithUnifiedCtx, createRequestContext as _createUnifiedCtx } from "vinext/unified-request-context";
|
|
291
177
|
import { reportRequestError as _reportRequestError } from "vinext/instrumentation";
|
|
178
|
+
import { flattenErrorCauses as __flattenErrorCauses } from ${JSON.stringify(errorCausePath)};
|
|
292
179
|
import { getSSRFontLinks as _getSSRFontLinks, getSSRFontStyles as _getSSRFontStylesGoogle, getSSRFontPreloads as _getSSRFontPreloadsGoogle } from "next/font/google";
|
|
293
180
|
import { getSSRFontStyles as _getSSRFontStylesLocal, getSSRFontPreloads as _getSSRFontPreloadsLocal } from "next/font/local";
|
|
294
181
|
function _getSSRFontStyles() { return [..._getSSRFontStylesGoogle(), ..._getSSRFontStylesLocal()]; }
|
|
295
182
|
function _getSSRFontPreloads() { return [..._getSSRFontPreloadsGoogle(), ..._getSSRFontPreloadsLocal()]; }
|
|
296
|
-
${hasPagesDir ? `//
|
|
183
|
+
${hasPagesDir ? `// Pages Router routes are loaded lazily from the SSR environment for internal prerender requests.` : ""}
|
|
297
184
|
|
|
298
185
|
// ALS used to suppress the expected "Invalid hook call" dev warning when
|
|
299
186
|
// layout/page components are probed outside React's render cycle. Patching
|
|
@@ -316,48 +203,15 @@ console.error = (...args) => {
|
|
|
316
203
|
// it in a module-level variable (that would leak between concurrent requests).
|
|
317
204
|
function setNavigationContext(ctx) {
|
|
318
205
|
_setNavigationContextOrig(ctx);
|
|
206
|
+
if (ctx === null) __setRootParams(null);
|
|
319
207
|
}
|
|
320
208
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
// These helpers are inlined instead of imported from isr-cache.js because
|
|
327
|
-
// the virtual RSC entry module runs in the RSC Vite environment which
|
|
328
|
-
// cannot use dynamic imports at the module-evaluation level for server-only
|
|
329
|
-
// modules, and direct imports must use the pre-computed absolute paths.
|
|
330
|
-
async function __isrGet(key) {
|
|
331
|
-
const handler = getCacheHandler();
|
|
332
|
-
const result = await handler.get(key);
|
|
333
|
-
if (!result || !result.value) return null;
|
|
334
|
-
return { value: result, isStale: result.cacheState === "stale" };
|
|
335
|
-
}
|
|
336
|
-
async function __isrSet(key, data, revalidateSeconds, tags) {
|
|
337
|
-
const handler = getCacheHandler();
|
|
338
|
-
await handler.set(key, data, { revalidate: revalidateSeconds, tags: Array.isArray(tags) ? tags : [] });
|
|
339
|
-
}
|
|
340
|
-
function __pageCacheTags(pathname, extraTags) {
|
|
341
|
-
const tags = [pathname, "_N_T_" + pathname];
|
|
342
|
-
// Layout hierarchy tags — matches Next.js getDerivedTags.
|
|
343
|
-
tags.push("_N_T_/layout");
|
|
344
|
-
const segments = pathname.split("/");
|
|
345
|
-
let built = "";
|
|
346
|
-
for (let i = 1; i < segments.length; i++) {
|
|
347
|
-
if (segments[i]) {
|
|
348
|
-
built += "/" + segments[i];
|
|
349
|
-
tags.push("_N_T_" + built + "/layout");
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
// Leaf page tag — revalidatePath(path, "page") targets this.
|
|
353
|
-
tags.push("_N_T_" + built + "/page");
|
|
354
|
-
if (Array.isArray(extraTags)) {
|
|
355
|
-
for (const tag of extraTags) {
|
|
356
|
-
if (!tags.includes(tag)) tags.push(tag);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
return tags;
|
|
209
|
+
function __clearRequestContext() {
|
|
210
|
+
setHeadersContext(null);
|
|
211
|
+
setNavigationContext(null);
|
|
212
|
+
// setNavigationContext(null) already clears root params internally
|
|
360
213
|
}
|
|
214
|
+
|
|
361
215
|
// Note: cache entries are written with \`headers: undefined\`. Next.js stores
|
|
362
216
|
// response headers (e.g. set-cookie from cookies().set() during render) in the
|
|
363
217
|
// cache entry so they can be replayed on HIT. We don't do this because:
|
|
@@ -368,68 +222,6 @@ function __pageCacheTags(pathname, extraTags) {
|
|
|
368
222
|
// In practice this means ISR-cached responses won't replay render-time set-cookie
|
|
369
223
|
// headers — but that case is already prevented by the dynamic-usage opt-out.
|
|
370
224
|
// TODO: capture render-time response headers for full Next.js parity.
|
|
371
|
-
const __pendingRegenerations = new Map();
|
|
372
|
-
function __triggerBackgroundRegeneration(key, renderFn) {
|
|
373
|
-
if (__pendingRegenerations.has(key)) return;
|
|
374
|
-
const promise = renderFn()
|
|
375
|
-
.catch((err) => console.error("[vinext] ISR regen failed for " + key + ":", err))
|
|
376
|
-
.finally(() => __pendingRegenerations.delete(key));
|
|
377
|
-
__pendingRegenerations.set(key, promise);
|
|
378
|
-
const ctx = _getRequestExecutionContext();
|
|
379
|
-
if (ctx && typeof ctx.waitUntil === "function") ctx.waitUntil(promise);
|
|
380
|
-
}
|
|
381
|
-
// HTML and RSC are stored under separate keys — matching Next.js's file-system
|
|
382
|
-
// layout (.html / .rsc) — so each request type reads and writes its own key
|
|
383
|
-
// independently with no races or partial-entry sentinels.
|
|
384
|
-
//
|
|
385
|
-
// Key format: "app:<buildId>:<pathname>:<suffix>"
|
|
386
|
-
// Long-pathname fallback: "app:<buildId>:__hash:<fnv1a64(pathname)>:<suffix>"
|
|
387
|
-
// Without buildId (should not happen in production): "app:<pathname>:<suffix>"
|
|
388
|
-
// The 200-char threshold keeps the full key well under Cloudflare KV's 512-byte limit
|
|
389
|
-
// even after adding the build ID and suffix. FNV-1a 64 is used for the hash (two
|
|
390
|
-
// 32-bit rounds) to give a ~64-bit output with negligible collision probability for
|
|
391
|
-
// realistic pathname lengths.
|
|
392
|
-
// Keep prefix construction and hashing logic in sync with isrCacheKey() in server/isr-cache.ts.
|
|
393
|
-
function __isrFnv1a64(s) {
|
|
394
|
-
// h1 uses the standard FNV-1a 32-bit offset basis (0x811c9dc5).
|
|
395
|
-
let h1 = 0x811c9dc5;
|
|
396
|
-
for (let i = 0; i < s.length; i++) { h1 ^= s.charCodeAt(i); h1 = (h1 * 0x01000193) >>> 0; }
|
|
397
|
-
// h2 uses a different seed (0x050c5d1f — the FNV-1a hash of the string "vinext")
|
|
398
|
-
// so the two rounds are independently seeded and their outputs are decorrelated.
|
|
399
|
-
// Concatenating two independently-seeded 32-bit FNV-1a hashes gives an effective
|
|
400
|
-
// 64-bit hash. A random non-standard seed would also work; we derive it from a
|
|
401
|
-
// fixed string so the choice is auditable and deterministic across rebuilds.
|
|
402
|
-
let h2 = 0x050c5d1f;
|
|
403
|
-
for (let i = 0; i < s.length; i++) { h2 ^= s.charCodeAt(i); h2 = (h2 * 0x01000193) >>> 0; }
|
|
404
|
-
return h1.toString(36) + h2.toString(36);
|
|
405
|
-
}
|
|
406
|
-
function __isrCacheKey(pathname, suffix) {
|
|
407
|
-
const normalized = pathname === "/" ? "/" : pathname.replace(/\\/$/, "");
|
|
408
|
-
// __VINEXT_BUILD_ID is replaced at compile time by Vite's define plugin.
|
|
409
|
-
const buildId = process.env.__VINEXT_BUILD_ID;
|
|
410
|
-
const prefix = buildId ? "app:" + buildId : "app";
|
|
411
|
-
const key = prefix + ":" + normalized + ":" + suffix;
|
|
412
|
-
if (key.length <= 200) return key;
|
|
413
|
-
// Pathname too long — hash it to keep under KV's 512-byte key limit.
|
|
414
|
-
return prefix + ":__hash:" + __isrFnv1a64(normalized) + ":" + suffix;
|
|
415
|
-
}
|
|
416
|
-
function __isrHtmlKey(pathname) { return __isrCacheKey(pathname, "html"); }
|
|
417
|
-
function __isrRscKey(pathname, mountedSlotsHeader) {
|
|
418
|
-
if (!mountedSlotsHeader) return __isrCacheKey(pathname, "rsc");
|
|
419
|
-
return __isrCacheKey(pathname, "rsc:" + __isrFnv1a64(mountedSlotsHeader));
|
|
420
|
-
}
|
|
421
|
-
function __normalizeMountedSlotsHeader(raw) {
|
|
422
|
-
if (!raw) return null;
|
|
423
|
-
const normalized = Array.from(
|
|
424
|
-
new Set(
|
|
425
|
-
raw
|
|
426
|
-
.split(/\\s+/)
|
|
427
|
-
.filter(Boolean),
|
|
428
|
-
),
|
|
429
|
-
).sort().join(" ");
|
|
430
|
-
return normalized || null;
|
|
431
|
-
}
|
|
432
|
-
function __isrRouteKey(pathname) { return __isrCacheKey(pathname, "route"); }
|
|
433
225
|
// Verbose cache logging — opt in with NEXT_PRIVATE_DEBUG_CACHE=1.
|
|
434
226
|
// Matches the env var Next.js uses for its own cache debug output so operators
|
|
435
227
|
// have a single knob for all cache tracing.
|
|
@@ -447,124 +239,6 @@ const __classDebug = process.env.VINEXT_DEBUG_CLASSIFICATION
|
|
|
447
239
|
}
|
|
448
240
|
: undefined;
|
|
449
241
|
|
|
450
|
-
// Normalize null-prototype objects from matchPattern() into thenable objects
|
|
451
|
-
// that work both as Promises (for Next.js 15+ async params) and as plain
|
|
452
|
-
// objects with synchronous property access (for pre-15 code like params.id).
|
|
453
|
-
//
|
|
454
|
-
// matchPattern() uses Object.create(null), producing objects without
|
|
455
|
-
// Object.prototype. The RSC serializer rejects these. Spreading ({...obj})
|
|
456
|
-
// restores a normal prototype. Object.assign onto the Promise preserves
|
|
457
|
-
// synchronous property access (params.id, params.slug) that existing
|
|
458
|
-
// components and test fixtures rely on.
|
|
459
|
-
function makeThenableParams(obj) {
|
|
460
|
-
const plain = { ...obj };
|
|
461
|
-
return Object.assign(Promise.resolve(plain), plain);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// djb2 hash — matches Next.js's stringHash for digest generation.
|
|
465
|
-
// Produces a stable numeric string from error message + stack.
|
|
466
|
-
function __errorDigest(str) {
|
|
467
|
-
let hash = 5381;
|
|
468
|
-
for (let i = str.length - 1; i >= 0; i--) {
|
|
469
|
-
hash = (hash * 33) ^ str.charCodeAt(i);
|
|
470
|
-
}
|
|
471
|
-
return (hash >>> 0).toString();
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// Sanitize an error for client consumption. In production, replaces the error
|
|
475
|
-
// with a generic Error that only carries a digest hash (matching Next.js
|
|
476
|
-
// behavior). In development, returns the original error for debugging.
|
|
477
|
-
// Navigation errors (redirect, notFound, etc.) are always passed through
|
|
478
|
-
// unchanged since their digests are used for client-side routing.
|
|
479
|
-
function __sanitizeErrorForClient(error) {
|
|
480
|
-
// Navigation errors must pass through with their digest intact
|
|
481
|
-
if (__resolveAppPageSpecialError(error)) {
|
|
482
|
-
return error;
|
|
483
|
-
}
|
|
484
|
-
// In development, pass through the original error for debugging
|
|
485
|
-
if (process.env.NODE_ENV !== "production") {
|
|
486
|
-
return error;
|
|
487
|
-
}
|
|
488
|
-
// In production, create a sanitized error with only a digest hash
|
|
489
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
490
|
-
const stack = error instanceof Error ? (error.stack || "") : "";
|
|
491
|
-
const sanitized = new Error(
|
|
492
|
-
"An error occurred in the Server Components render. " +
|
|
493
|
-
"The specific message is omitted in production builds to avoid leaking sensitive details. " +
|
|
494
|
-
"A digest property is included on this error instance which may provide additional details about the nature of the error."
|
|
495
|
-
);
|
|
496
|
-
sanitized.digest = __errorDigest(msg + stack);
|
|
497
|
-
return sanitized;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// onError callback for renderToReadableStream — preserves the digest for
|
|
501
|
-
// Next.js navigation errors (redirect, notFound, forbidden, unauthorized)
|
|
502
|
-
// thrown during RSC streaming (e.g. inside Suspense boundaries).
|
|
503
|
-
// For non-navigation errors in production, generates a digest hash so the
|
|
504
|
-
// error can be correlated with server logs without leaking details.
|
|
505
|
-
function rscOnError(error, requestInfo, errorContext) {
|
|
506
|
-
if (error && typeof error === "object" && "digest" in error) {
|
|
507
|
-
return String(error.digest);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// In dev, detect the "Only plain objects" RSC serialization error and emit
|
|
511
|
-
// an actionable hint. This error occurs when a Server Component passes a
|
|
512
|
-
// class instance, ES module namespace object, or null-prototype object as a
|
|
513
|
-
// prop to a Client Component.
|
|
514
|
-
//
|
|
515
|
-
// Root cause: Vite bundles modules as true ESM (module namespace objects
|
|
516
|
-
// have a null-like internal slot), while Next.js's webpack build produces
|
|
517
|
-
// plain CJS-wrapped objects with __esModule:true. React's RSC serializer
|
|
518
|
-
// accepts the latter as plain objects but rejects the former — which means
|
|
519
|
-
// code that accidentally passes "import * as X" works in webpack/Next.js
|
|
520
|
-
// but correctly fails in vinext.
|
|
521
|
-
//
|
|
522
|
-
// Common triggers:
|
|
523
|
-
// - "import * as utils from './utils'" passed as a prop
|
|
524
|
-
// - class instances (new Foo()) passed as props
|
|
525
|
-
// - Date / Map / Set instances passed as props
|
|
526
|
-
// - Objects with Object.create(null) (null prototype)
|
|
527
|
-
if (
|
|
528
|
-
process.env.NODE_ENV !== "production" &&
|
|
529
|
-
error instanceof Error &&
|
|
530
|
-
error.message.includes("Only plain objects, and a few built-ins, can be passed to Client Components")
|
|
531
|
-
) {
|
|
532
|
-
console.error(
|
|
533
|
-
"[vinext] RSC serialization error: a non-plain object was passed from a Server Component to a Client Component.\\n" +
|
|
534
|
-
"\\n" +
|
|
535
|
-
"Common causes:\\n" +
|
|
536
|
-
" * Passing a module namespace (import * as X) directly as a prop.\\n" +
|
|
537
|
-
" Unlike Next.js (webpack), Vite produces real ESM module namespace objects\\n" +
|
|
538
|
-
" which are not serializable. Fix: pass individual values instead,\\n" +
|
|
539
|
-
" e.g. <Comp value={module.value} />\\n" +
|
|
540
|
-
" * Passing a class instance (new Foo()) as a prop.\\n" +
|
|
541
|
-
" Fix: convert to a plain object, e.g. { id: foo.id, name: foo.name }\\n" +
|
|
542
|
-
" * Passing a Date, Map, or Set. Use .toISOString(), [...map.entries()], etc.\\n" +
|
|
543
|
-
" * Passing Object.create(null). Use { ...obj } to restore a prototype.\\n" +
|
|
544
|
-
"\\n" +
|
|
545
|
-
"Original error:",
|
|
546
|
-
error.message,
|
|
547
|
-
);
|
|
548
|
-
return undefined;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
if (requestInfo && errorContext && error) {
|
|
552
|
-
_reportRequestError(
|
|
553
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
554
|
-
requestInfo,
|
|
555
|
-
errorContext,
|
|
556
|
-
);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// In production, generate a digest hash for non-navigation errors
|
|
560
|
-
if (process.env.NODE_ENV === "production" && error) {
|
|
561
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
562
|
-
const stack = error instanceof Error ? (error.stack || "") : "";
|
|
563
|
-
return __errorDigest(msg + stack);
|
|
564
|
-
}
|
|
565
|
-
return undefined;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
242
|
function createRscOnErrorHandler(request, pathname, routePath) {
|
|
569
243
|
const requestInfo = {
|
|
570
244
|
path: pathname,
|
|
@@ -576,9 +250,11 @@ function createRscOnErrorHandler(request, pathname, routePath) {
|
|
|
576
250
|
routePath: routePath || pathname,
|
|
577
251
|
routeType: "render",
|
|
578
252
|
};
|
|
579
|
-
return
|
|
580
|
-
|
|
581
|
-
|
|
253
|
+
return __createRscOnErrorHandler({
|
|
254
|
+
errorContext,
|
|
255
|
+
reportRequestError: _reportRequestError,
|
|
256
|
+
requestInfo,
|
|
257
|
+
});
|
|
582
258
|
}
|
|
583
259
|
|
|
584
260
|
${imports.join("\n")}
|
|
@@ -636,7 +312,7 @@ function __VINEXT_CLASS_REASONS(routeIdx) {
|
|
|
636
312
|
const routes = [
|
|
637
313
|
${routeEntries.join(",\n")}
|
|
638
314
|
];
|
|
639
|
-
const
|
|
315
|
+
const __routeMatcher = __createAppRscRouteMatcher(routes);
|
|
640
316
|
|
|
641
317
|
const metadataRoutes = [
|
|
642
318
|
${metaRouteEntries.join(",\n")}
|
|
@@ -646,6 +322,7 @@ const rootNotFoundModule = ${rootNotFoundVar ? rootNotFoundVar : "null"};
|
|
|
646
322
|
const rootForbiddenModule = ${rootForbiddenVar ? rootForbiddenVar : "null"};
|
|
647
323
|
const rootUnauthorizedModule = ${rootUnauthorizedVar ? rootUnauthorizedVar : "null"};
|
|
648
324
|
const rootLayouts = [${rootLayoutVars.join(", ")}];
|
|
325
|
+
const __APP_PAGE_EMPTY_MW_CTX = { headers: null, status: null };
|
|
649
326
|
|
|
650
327
|
/**
|
|
651
328
|
* Render an HTTP access fallback page (not-found/forbidden/unauthorized) with layouts and noindex meta.
|
|
@@ -654,13 +331,12 @@ const rootLayouts = [${rootLayoutVars.join(", ")}];
|
|
|
654
331
|
* @param opts.boundaryComponent - Override the boundary component (for layout-level notFound)
|
|
655
332
|
* @param opts.layouts - Override the layouts to wrap with (for layout-level notFound, excludes the throwing layout)
|
|
656
333
|
*/
|
|
657
|
-
async function renderHTTPAccessFallbackPage(route, statusCode, isRscRequest, request, opts, scriptNonce) {
|
|
334
|
+
async function renderHTTPAccessFallbackPage(route, statusCode, isRscRequest, request, opts, scriptNonce, middlewareContext) {
|
|
658
335
|
return __renderAppPageHttpAccessFallback({
|
|
659
336
|
boundaryComponent: opts?.boundaryComponent ?? null,
|
|
660
337
|
buildFontLinkHeader: __buildAppPageFontLinkHeader,
|
|
661
338
|
clearRequestContext() {
|
|
662
|
-
|
|
663
|
-
setNavigationContext(null);
|
|
339
|
+
__clearRequestContext();
|
|
664
340
|
},
|
|
665
341
|
createRscOnErrorHandler(pathname, routePath) {
|
|
666
342
|
return createRscOnErrorHandler(request, pathname, routePath);
|
|
@@ -677,6 +353,8 @@ async function renderHTTPAccessFallbackPage(route, statusCode, isRscRequest, req
|
|
|
677
353
|
},
|
|
678
354
|
makeThenableParams,
|
|
679
355
|
matchedParams: opts?.matchedParams ?? route?.params ?? {},
|
|
356
|
+
middlewareContext: middlewareContext ?? __APP_PAGE_EMPTY_MW_CTX,
|
|
357
|
+
metadataRoutes,
|
|
680
358
|
requestUrl: request.url,
|
|
681
359
|
resolveChildSegments: __resolveAppPageChildSegments,
|
|
682
360
|
rootForbiddenModule: rootForbiddenModule,
|
|
@@ -691,8 +369,8 @@ async function renderHTTPAccessFallbackPage(route, statusCode, isRscRequest, req
|
|
|
691
369
|
}
|
|
692
370
|
|
|
693
371
|
/** Convenience: render a not-found page (404) */
|
|
694
|
-
async function renderNotFoundPage(route, isRscRequest, request, matchedParams, scriptNonce) {
|
|
695
|
-
return renderHTTPAccessFallbackPage(route, 404, isRscRequest, request, { matchedParams }, scriptNonce);
|
|
372
|
+
async function renderNotFoundPage(route, isRscRequest, request, matchedParams, scriptNonce, middlewareContext) {
|
|
373
|
+
return renderHTTPAccessFallbackPage(route, 404, isRscRequest, request, { matchedParams }, scriptNonce, middlewareContext);
|
|
696
374
|
}
|
|
697
375
|
|
|
698
376
|
/**
|
|
@@ -702,12 +380,11 @@ async function renderNotFoundPage(route, isRscRequest, request, matchedParams, s
|
|
|
702
380
|
* Next.js returns HTTP 200 when error.tsx catches an error (the error is "handled"
|
|
703
381
|
* by the boundary). This matches that behavior intentionally.
|
|
704
382
|
*/
|
|
705
|
-
async function renderErrorBoundaryPage(route, error, isRscRequest, request, matchedParams, scriptNonce) {
|
|
383
|
+
async function renderErrorBoundaryPage(route, error, isRscRequest, request, matchedParams, scriptNonce, middlewareContext) {
|
|
706
384
|
return __renderAppPageErrorBoundary({
|
|
707
385
|
buildFontLinkHeader: __buildAppPageFontLinkHeader,
|
|
708
386
|
clearRequestContext() {
|
|
709
|
-
|
|
710
|
-
setNavigationContext(null);
|
|
387
|
+
__clearRequestContext();
|
|
711
388
|
},
|
|
712
389
|
createRscOnErrorHandler(pathname, routePath) {
|
|
713
390
|
return createRscOnErrorHandler(request, pathname, routePath);
|
|
@@ -724,6 +401,8 @@ async function renderErrorBoundaryPage(route, error, isRscRequest, request, matc
|
|
|
724
401
|
},
|
|
725
402
|
makeThenableParams,
|
|
726
403
|
matchedParams: matchedParams ?? route?.params ?? {},
|
|
404
|
+
middlewareContext: middlewareContext ?? __APP_PAGE_EMPTY_MW_CTX,
|
|
405
|
+
metadataRoutes,
|
|
727
406
|
requestUrl: request.url,
|
|
728
407
|
resolveChildSegments: __resolveAppPageChildSegments,
|
|
729
408
|
rootLayouts: rootLayouts,
|
|
@@ -735,84 +414,7 @@ async function renderErrorBoundaryPage(route, error, isRscRequest, request, matc
|
|
|
735
414
|
}
|
|
736
415
|
|
|
737
416
|
function matchRoute(url) {
|
|
738
|
-
|
|
739
|
-
let normalizedUrl = pathname === "/" ? "/" : pathname.replace(/\\/$/, "");
|
|
740
|
-
// NOTE: Do NOT decodeURIComponent here. The caller is responsible for decoding
|
|
741
|
-
// the pathname exactly once at the request entry point. Decoding again here
|
|
742
|
-
// would cause inconsistent path matching between middleware and routing.
|
|
743
|
-
const urlParts = normalizedUrl.split("/").filter(Boolean);
|
|
744
|
-
return _trieMatch(_routeTrie, urlParts);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
function __createStaticFileSignal(pathname, _mwCtx) {
|
|
748
|
-
const headers = new Headers({
|
|
749
|
-
"x-vinext-static-file": encodeURIComponent(pathname),
|
|
750
|
-
});
|
|
751
|
-
if (_mwCtx.headers) {
|
|
752
|
-
for (const [key, value] of _mwCtx.headers) {
|
|
753
|
-
headers.append(key, value);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return new Response(null, {
|
|
757
|
-
status: _mwCtx.status ?? 200,
|
|
758
|
-
headers,
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// matchPattern is kept for findIntercept (linear scan over small interceptLookup array).
|
|
763
|
-
function matchPattern(urlParts, patternParts) {
|
|
764
|
-
const params = Object.create(null);
|
|
765
|
-
for (let i = 0; i < patternParts.length; i++) {
|
|
766
|
-
const pp = patternParts[i];
|
|
767
|
-
if (pp.endsWith("+")) {
|
|
768
|
-
if (i !== patternParts.length - 1) return null;
|
|
769
|
-
const paramName = pp.slice(1, -1);
|
|
770
|
-
const remaining = urlParts.slice(i);
|
|
771
|
-
if (remaining.length === 0) return null;
|
|
772
|
-
params[paramName] = remaining;
|
|
773
|
-
return params;
|
|
774
|
-
}
|
|
775
|
-
if (pp.endsWith("*")) {
|
|
776
|
-
if (i !== patternParts.length - 1) return null;
|
|
777
|
-
const paramName = pp.slice(1, -1);
|
|
778
|
-
params[paramName] = urlParts.slice(i);
|
|
779
|
-
return params;
|
|
780
|
-
}
|
|
781
|
-
if (pp.startsWith(":")) {
|
|
782
|
-
if (i >= urlParts.length) return null;
|
|
783
|
-
params[pp.slice(1)] = urlParts[i];
|
|
784
|
-
continue;
|
|
785
|
-
}
|
|
786
|
-
if (i >= urlParts.length || urlParts[i] !== pp) return null;
|
|
787
|
-
}
|
|
788
|
-
if (urlParts.length !== patternParts.length) return null;
|
|
789
|
-
return params;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
function mergeMatchedParams(sourceParams, targetParams) {
|
|
793
|
-
return Object.assign(Object.create(null), sourceParams, targetParams);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// Build a global intercepting route lookup for RSC navigation.
|
|
797
|
-
// Maps target URL patterns to { sourceRouteIndex, slotKey, interceptPage, interceptLayouts, params }.
|
|
798
|
-
const interceptLookup = [];
|
|
799
|
-
for (let ri = 0; ri < routes.length; ri++) {
|
|
800
|
-
const r = routes[ri];
|
|
801
|
-
if (!r.slots) continue;
|
|
802
|
-
for (const [slotKey, slotMod] of Object.entries(r.slots)) {
|
|
803
|
-
if (!slotMod.intercepts) continue;
|
|
804
|
-
for (const intercept of slotMod.intercepts) {
|
|
805
|
-
interceptLookup.push({
|
|
806
|
-
sourceRouteIndex: ri,
|
|
807
|
-
slotKey,
|
|
808
|
-
targetPattern: intercept.targetPattern,
|
|
809
|
-
targetPatternParts: intercept.targetPattern.split("/").filter(Boolean),
|
|
810
|
-
interceptLayouts: intercept.interceptLayouts,
|
|
811
|
-
page: intercept.page,
|
|
812
|
-
params: intercept.params,
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
}
|
|
417
|
+
return __routeMatcher.matchRoute(url);
|
|
816
418
|
}
|
|
817
419
|
|
|
818
420
|
/**
|
|
@@ -820,25 +422,7 @@ for (let ri = 0; ri < routes.length; ri++) {
|
|
|
820
422
|
* Returns the match info or null.
|
|
821
423
|
*/
|
|
822
424
|
function findIntercept(pathname, sourcePathname = null) {
|
|
823
|
-
|
|
824
|
-
for (const entry of interceptLookup) {
|
|
825
|
-
const params = matchPattern(urlParts, entry.targetPatternParts);
|
|
826
|
-
if (params !== null) {
|
|
827
|
-
let sourceParams = Object.create(null);
|
|
828
|
-
if (sourcePathname !== null) {
|
|
829
|
-
const sourceRoute = routes[entry.sourceRouteIndex];
|
|
830
|
-
const sourceParts = sourcePathname.split("/").filter(Boolean);
|
|
831
|
-
const matchedSourceParams = sourceRoute
|
|
832
|
-
? matchPattern(sourceParts, sourceRoute.patternParts)
|
|
833
|
-
: null;
|
|
834
|
-
if (matchedSourceParams !== null) {
|
|
835
|
-
sourceParams = matchedSourceParams;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
return { ...entry, matchedParams: mergeMatchedParams(sourceParams, params) };
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
return null;
|
|
425
|
+
return __routeMatcher.findIntercept(pathname, sourcePathname);
|
|
842
426
|
}
|
|
843
427
|
|
|
844
428
|
async function buildPageElements(route, params, routePath, pageRequest) {
|
|
@@ -869,83 +453,30 @@ async function buildPageElements(route, params, routePath, pageRequest) {
|
|
|
869
453
|
};
|
|
870
454
|
}
|
|
871
455
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
const layoutMods = route.layouts.filter(Boolean);
|
|
897
|
-
|
|
898
|
-
// Convert URLSearchParams → plain object for page generateMetadata() and
|
|
899
|
-
// pageProps.searchParams. Built before the layout loop so the page metadata
|
|
900
|
-
// call (below) and pageProps can reference the same object.
|
|
901
|
-
// NOTE: Layouts do NOT receive searchParams in generateMetadata() — only
|
|
902
|
-
// pages do. This matches Next.js behavior (resolve-metadata.ts:777).
|
|
903
|
-
const spObj = Object.create(null);
|
|
904
|
-
let hasSearchParams = false;
|
|
905
|
-
if (searchParams && searchParams.forEach) {
|
|
906
|
-
searchParams.forEach(function(v, k) {
|
|
907
|
-
hasSearchParams = true;
|
|
908
|
-
if (k in spObj) {
|
|
909
|
-
spObj[k] = Array.isArray(spObj[k]) ? spObj[k].concat(v) : [spObj[k], v];
|
|
910
|
-
} else {
|
|
911
|
-
spObj[k] = v;
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
// Build the parent promise chain and kick off metadata resolution in one pass.
|
|
917
|
-
// Each layout module is called exactly once. layoutMetaPromises[i] is the
|
|
918
|
-
// promise for layout[i]'s own metadata result.
|
|
919
|
-
//
|
|
920
|
-
// All calls are kicked off immediately (concurrent I/O), but each layout's
|
|
921
|
-
// "parent" promise only resolves after the preceding layout's metadata is done.
|
|
922
|
-
const layoutMetaPromises = [];
|
|
923
|
-
let accumulatedMetaPromise = Promise.resolve({});
|
|
924
|
-
for (let i = 0; i < layoutMods.length; i++) {
|
|
925
|
-
const parentForThisLayout = accumulatedMetaPromise;
|
|
926
|
-
// Kick off this layout's metadata resolution now (concurrent with others).
|
|
927
|
-
const metaPromise = resolveModuleMetadata(layoutMods[i], params, undefined, parentForThisLayout)
|
|
928
|
-
.catch((err) => { console.error("[vinext] Layout generateMetadata() failed:", err); return null; });
|
|
929
|
-
layoutMetaPromises.push(metaPromise);
|
|
930
|
-
// Advance accumulator: resolves to merged(layouts[0..i]) once layout[i] is done.
|
|
931
|
-
accumulatedMetaPromise = metaPromise.then(async (result) =>
|
|
932
|
-
result ? mergeMetadata([await parentForThisLayout, result]) : await parentForThisLayout
|
|
933
|
-
);
|
|
934
|
-
}
|
|
935
|
-
// Page's parent is the fully-accumulated layout metadata.
|
|
936
|
-
const pageParentPromise = accumulatedMetaPromise;
|
|
937
|
-
|
|
938
|
-
const [layoutMetaResults, layoutVpResults, pageMeta, pageVp] = await Promise.all([
|
|
939
|
-
Promise.all(layoutMetaPromises),
|
|
940
|
-
Promise.all(layoutMods.map((mod) => resolveModuleViewport(mod, params).catch((err) => { console.error("[vinext] Layout generateViewport() failed:", err); return null; }))),
|
|
941
|
-
route.page ? resolveModuleMetadata(route.page, params, spObj, pageParentPromise) : Promise.resolve(null),
|
|
942
|
-
route.page ? resolveModuleViewport(route.page, params) : Promise.resolve(null),
|
|
943
|
-
]);
|
|
944
|
-
|
|
945
|
-
const metadataList = [...layoutMetaResults.filter(Boolean), ...(pageMeta ? [pageMeta] : [])];
|
|
946
|
-
const viewportList = [...layoutVpResults.filter(Boolean), ...(pageVp ? [pageVp] : [])];
|
|
947
|
-
const resolvedMetadata = metadataList.length > 0 ? mergeMetadata(metadataList) : null;
|
|
948
|
-
const resolvedViewport = mergeViewport(viewportList);
|
|
456
|
+
const {
|
|
457
|
+
hasSearchParams,
|
|
458
|
+
metadata: resolvedMetadata,
|
|
459
|
+
pageSearchParams,
|
|
460
|
+
viewport: resolvedViewport,
|
|
461
|
+
} = await __resolveAppPageHead({
|
|
462
|
+
layoutModules: route.layouts,
|
|
463
|
+
layoutTreePositions: route.layoutTreePositions,
|
|
464
|
+
metadataRoutes,
|
|
465
|
+
pageModule: route.page,
|
|
466
|
+
parallelRoutes: __resolveActiveParallelRouteHeadInputs({
|
|
467
|
+
interceptLayouts: opts?.interceptLayouts ?? null,
|
|
468
|
+
interceptPage: opts?.interceptPage ?? null,
|
|
469
|
+
interceptParams: opts?.interceptParams ?? null,
|
|
470
|
+
interceptSlotKey: opts?.interceptSlotKey ?? null,
|
|
471
|
+
params,
|
|
472
|
+
routeSegments: route.routeSegments,
|
|
473
|
+
slots: route.slots,
|
|
474
|
+
}),
|
|
475
|
+
params,
|
|
476
|
+
routePath: route.pattern,
|
|
477
|
+
routeSegments: route.routeSegments,
|
|
478
|
+
searchParams,
|
|
479
|
+
});
|
|
949
480
|
|
|
950
481
|
// Build the route tree from the leaf page, then delegate the boundary/layout/
|
|
951
482
|
// template/segment wiring to a typed runtime helper so the generated entry
|
|
@@ -955,7 +486,7 @@ async function buildPageElements(route, params, routePath, pageRequest) {
|
|
|
955
486
|
// Always provide searchParams prop when the URL object is available, even
|
|
956
487
|
// when the query string is empty -- pages that do "await searchParams" need
|
|
957
488
|
// it to be a thenable rather than undefined.
|
|
958
|
-
pageProps.searchParams = makeThenableParams(
|
|
489
|
+
pageProps.searchParams = makeThenableParams(pageSearchParams);
|
|
959
490
|
// If the URL has query parameters, mark the page as dynamic.
|
|
960
491
|
// In Next.js, only accessing the searchParams prop signals dynamic usage,
|
|
961
492
|
// but a Proxy-based approach doesn't work here because React's RSC debug
|
|
@@ -986,6 +517,8 @@ async function buildPageElements(route, params, routePath, pageRequest) {
|
|
|
986
517
|
interceptionContext: opts?.interceptionContext ?? null,
|
|
987
518
|
routePath,
|
|
988
519
|
rootNotFoundModule: ${rootNotFoundVar ? rootNotFoundVar : "null"},
|
|
520
|
+
rootForbiddenModule: ${rootForbiddenVar ? rootForbiddenVar : "null"},
|
|
521
|
+
rootUnauthorizedModule: ${rootUnauthorizedVar ? rootUnauthorizedVar : "null"},
|
|
989
522
|
route,
|
|
990
523
|
slotOverrides:
|
|
991
524
|
opts && opts.interceptSlotKey && opts.interceptPage
|
|
@@ -1000,8 +533,6 @@ async function buildPageElements(route, params, routePath, pageRequest) {
|
|
|
1000
533
|
});
|
|
1001
534
|
}
|
|
1002
535
|
|
|
1003
|
-
${middlewarePath ? generateMiddlewareMatcherCode("modern") : ""}
|
|
1004
|
-
|
|
1005
536
|
const __basePath = ${JSON.stringify(bp)};
|
|
1006
537
|
const __trailingSlash = ${JSON.stringify(ts)};
|
|
1007
538
|
const __i18nConfig = ${JSON.stringify(i18nConfig)};
|
|
@@ -1013,13 +544,6 @@ const __allowedOrigins = ${JSON.stringify(allowedOrigins)};
|
|
|
1013
544
|
|
|
1014
545
|
${generateDevOriginCheckCode(config?.allowedDevOrigins)}
|
|
1015
546
|
|
|
1016
|
-
// ── ReDoS-safe regex compilation (still needed for middleware matching) ──
|
|
1017
|
-
${generateSafeRegExpCode("modern")}
|
|
1018
|
-
|
|
1019
|
-
// ── Path normalization ──────────────────────────────────────────────────
|
|
1020
|
-
${generateNormalizePathCode("modern")}
|
|
1021
|
-
${generateRouteMatchNormalizationCode("modern")}
|
|
1022
|
-
|
|
1023
547
|
// ── Config pattern matching, redirects, rewrites, headers, CSRF validation,
|
|
1024
548
|
// external URL proxy, cookie parsing, and request context are imported from
|
|
1025
549
|
// config-matchers.ts and request-pipeline.ts (see import statements above).
|
|
@@ -1058,63 +582,6 @@ function __buildPostMwRequestContext(request) {
|
|
|
1058
582
|
*/
|
|
1059
583
|
var __MAX_ACTION_BODY_SIZE = ${JSON.stringify(bodySizeLimit)};
|
|
1060
584
|
|
|
1061
|
-
/**
|
|
1062
|
-
* Read a request body as text with a size limit.
|
|
1063
|
-
* Enforces the limit on the actual byte stream to prevent bypasses
|
|
1064
|
-
* via chunked transfer-encoding where Content-Length is absent or spoofed.
|
|
1065
|
-
*/
|
|
1066
|
-
async function __readBodyWithLimit(request, maxBytes) {
|
|
1067
|
-
if (!request.body) return "";
|
|
1068
|
-
var reader = request.body.getReader();
|
|
1069
|
-
var decoder = new TextDecoder();
|
|
1070
|
-
var chunks = [];
|
|
1071
|
-
var totalSize = 0;
|
|
1072
|
-
for (;;) {
|
|
1073
|
-
var result = await reader.read();
|
|
1074
|
-
if (result.done) break;
|
|
1075
|
-
totalSize += result.value.byteLength;
|
|
1076
|
-
if (totalSize > maxBytes) {
|
|
1077
|
-
reader.cancel();
|
|
1078
|
-
throw new Error("Request body too large");
|
|
1079
|
-
}
|
|
1080
|
-
chunks.push(decoder.decode(result.value, { stream: true }));
|
|
1081
|
-
}
|
|
1082
|
-
chunks.push(decoder.decode());
|
|
1083
|
-
return chunks.join("");
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
/**
|
|
1087
|
-
* Read a request body as FormData with a size limit.
|
|
1088
|
-
* Consumes the body stream with a byte counter and then parses the
|
|
1089
|
-
* collected bytes as multipart form data via the Response constructor.
|
|
1090
|
-
*/
|
|
1091
|
-
async function __readFormDataWithLimit(request, maxBytes) {
|
|
1092
|
-
if (!request.body) return new FormData();
|
|
1093
|
-
var reader = request.body.getReader();
|
|
1094
|
-
var chunks = [];
|
|
1095
|
-
var totalSize = 0;
|
|
1096
|
-
for (;;) {
|
|
1097
|
-
var result = await reader.read();
|
|
1098
|
-
if (result.done) break;
|
|
1099
|
-
totalSize += result.value.byteLength;
|
|
1100
|
-
if (totalSize > maxBytes) {
|
|
1101
|
-
reader.cancel();
|
|
1102
|
-
throw new Error("Request body too large");
|
|
1103
|
-
}
|
|
1104
|
-
chunks.push(result.value);
|
|
1105
|
-
}
|
|
1106
|
-
// Reconstruct a Response with the original Content-Type so that
|
|
1107
|
-
// the FormData parser can handle multipart boundaries correctly.
|
|
1108
|
-
var combined = new Uint8Array(totalSize);
|
|
1109
|
-
var offset = 0;
|
|
1110
|
-
for (var chunk of chunks) {
|
|
1111
|
-
combined.set(chunk, offset);
|
|
1112
|
-
offset += chunk.byteLength;
|
|
1113
|
-
}
|
|
1114
|
-
var contentType = request.headers.get("content-type") || "";
|
|
1115
|
-
return new Response(combined, { headers: { "Content-Type": contentType } }).formData();
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
585
|
// Map from route pattern to generateStaticParams function.
|
|
1119
586
|
// Used by the prerender phase to enumerate dynamic route URLs without
|
|
1120
587
|
// loading route modules via the dev server.
|
|
@@ -1124,7 +591,10 @@ export const generateStaticParamsMap = {
|
|
|
1124
591
|
// to provide parent params for nested dynamic routes, but they don't have a pagePath
|
|
1125
592
|
// so they are excluded here. Supporting layout-level generateStaticParams requires
|
|
1126
593
|
// scanning layout.tsx files separately and including them in this map.
|
|
1127
|
-
${
|
|
594
|
+
${generateStaticParamsEntries.join("\n")}
|
|
595
|
+
};${loadPrerenderPagesRoutesCode}
|
|
596
|
+
const rootParamNamesMap = {
|
|
597
|
+
${routes.filter((r) => r.isDynamic && r.pagePath && r.rootParamNames && r.rootParamNames.length > 0).map((r) => ` ${JSON.stringify(r.pattern)}: ${JSON.stringify(r.rootParamNames)},`).join("\n")}
|
|
1128
598
|
};
|
|
1129
599
|
|
|
1130
600
|
export default async function handler(request, ctx) {
|
|
@@ -1139,15 +609,33 @@ export default async function handler(request, ctx) {
|
|
|
1139
609
|
const __uCtx = _createUnifiedCtx({
|
|
1140
610
|
headersContext: headersCtx,
|
|
1141
611
|
executionContext: ctx ?? _getRequestExecutionContext() ?? null,
|
|
612
|
+
unstableCacheRevalidation: "background",
|
|
1142
613
|
});
|
|
1143
|
-
return _runWithUnifiedCtx(__uCtx,
|
|
614
|
+
return _runWithUnifiedCtx(__uCtx, () =>
|
|
615
|
+
__runWithPrerenderWorkUnit(async () => {
|
|
1144
616
|
_ensureFetchPatch();
|
|
1145
617
|
const __reqCtx = requestContextFromRequest(request);
|
|
1146
618
|
// Per-request container for middleware state. Passed into
|
|
1147
619
|
// _handleRequest which fills in .headers and .status;
|
|
1148
620
|
// avoids module-level variables that race on Workers.
|
|
1149
621
|
const _mwCtx = { headers: null, requestHeaders: null, status: null };
|
|
1150
|
-
|
|
622
|
+
let response;
|
|
623
|
+
try {
|
|
624
|
+
response = await _handleRequest(request, __reqCtx, _mwCtx);
|
|
625
|
+
} catch (err) {
|
|
626
|
+
// Dev only: embed err.cause chain into err.message/err.stack so Vite's
|
|
627
|
+
// dev-server "Internal server error:" logger (which builds output from
|
|
628
|
+
// message + stack only) reveals the underlying root cause (ECONNREFUSED,
|
|
629
|
+
// role missing, workerd socket error, etc.) instead of dropping it.
|
|
630
|
+
// Skipped in production because Node's util.inspect / workerd's logger
|
|
631
|
+
// already render .cause natively, so flattening would double-print it.
|
|
632
|
+
// NODE_ENV is build-time-replaced by Vite, so the prod bundle compiles
|
|
633
|
+
// this branch out entirely.
|
|
634
|
+
if (process.env.NODE_ENV !== "production") {
|
|
635
|
+
__flattenErrorCauses(err);
|
|
636
|
+
}
|
|
637
|
+
throw err;
|
|
638
|
+
}
|
|
1151
639
|
// Apply custom headers from next.config.js to non-redirect responses.
|
|
1152
640
|
// Skip redirects (3xx) because Response.redirect() creates immutable headers,
|
|
1153
641
|
// and Next.js doesn't apply custom headers to redirects anyway.
|
|
@@ -1157,25 +645,16 @@ export default async function handler(request, ctx) {
|
|
|
1157
645
|
let pathname;
|
|
1158
646
|
try { pathname = __normalizePath(__normalizePathnameForRouteMatch(url.pathname)); } catch { pathname = url.pathname; }
|
|
1159
647
|
${bp ? `if (pathname.startsWith(${JSON.stringify(bp)})) pathname = pathname.slice(${JSON.stringify(bp)}.length) || "/";` : ""}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
// for correct CDN caching behavior.
|
|
1166
|
-
const lk = h.key.toLowerCase();
|
|
1167
|
-
if (lk === "vary" || lk === "set-cookie") {
|
|
1168
|
-
response.headers.append(h.key, h.value);
|
|
1169
|
-
} else if (!response.headers.has(lk)) {
|
|
1170
|
-
// Middleware headers take precedence: skip config keys already
|
|
1171
|
-
// set by middleware so middleware headers always win.
|
|
1172
|
-
response.headers.set(h.key, h.value);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
648
|
+
applyConfigHeadersToResponse(response.headers, {
|
|
649
|
+
configHeaders: __configHeaders,
|
|
650
|
+
pathname,
|
|
651
|
+
requestContext: __reqCtx,
|
|
652
|
+
});
|
|
1175
653
|
}
|
|
1176
654
|
}
|
|
1177
655
|
return response;
|
|
1178
|
-
|
|
656
|
+
}, { route: () => new URL(request.url).pathname })
|
|
657
|
+
);
|
|
1179
658
|
}
|
|
1180
659
|
|
|
1181
660
|
async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
@@ -1214,74 +693,16 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1214
693
|
pathname = stripBasePath(pathname, __basePath);
|
|
1215
694
|
` : ""}
|
|
1216
695
|
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
return new Response("Not Found", { status: 404 });
|
|
1228
|
-
}
|
|
1229
|
-
const pattern = url.searchParams.get("pattern");
|
|
1230
|
-
if (!pattern) return new Response("missing pattern", { status: 400 });
|
|
1231
|
-
const fn = generateStaticParamsMap[pattern];
|
|
1232
|
-
if (typeof fn !== "function") return new Response("null", { status: 200, headers: { "content-type": "application/json" } });
|
|
1233
|
-
try {
|
|
1234
|
-
const parentParams = url.searchParams.get("parentParams");
|
|
1235
|
-
const raw = parentParams ? JSON.parse(parentParams) : {};
|
|
1236
|
-
// Ensure params is a plain object — reject primitives, arrays, and null
|
|
1237
|
-
// so user-authored generateStaticParams always receives { params: {} }
|
|
1238
|
-
// rather than { params: 5 } or similar if input is malformed.
|
|
1239
|
-
const params = (typeof raw === "object" && raw !== null && !Array.isArray(raw)) ? raw : {};
|
|
1240
|
-
const result = await fn({ params });
|
|
1241
|
-
return new Response(JSON.stringify(result), { status: 200, headers: { "content-type": "application/json" } });
|
|
1242
|
-
} catch (e) {
|
|
1243
|
-
return new Response(JSON.stringify({ error: String(e) }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
${hasPagesDir ? `
|
|
1248
|
-
// ── Prerender: pages-static-paths endpoint ───────────────────────────
|
|
1249
|
-
// Internal endpoint used by prerenderPages() during a CF Workers hybrid
|
|
1250
|
-
// build to call getStaticPaths() for dynamic Pages Router routes via
|
|
1251
|
-
// wrangler unstable_startWorker. Returns JSON-serialised getStaticPaths result.
|
|
1252
|
-
// Gated on VINEXT_PRERENDER=1 to prevent exposure in normal deployments.
|
|
1253
|
-
// See static-params endpoint above for process.env vs CF vars notes.
|
|
1254
|
-
//
|
|
1255
|
-
// pageRoutes lives in the SSR environment (virtual:vinext-server-entry).
|
|
1256
|
-
// We load it lazily via import.meta.viteRsc.loadModule — the same pattern
|
|
1257
|
-
// used by handleSsr() elsewhere in this template. At build time, Vite's RSC
|
|
1258
|
-
// plugin transforms this call into a bundled cross-environment import, so it
|
|
1259
|
-
// works correctly in the CF Workers production bundle running in Miniflare.
|
|
1260
|
-
if (pathname === "/__vinext/prerender/pages-static-paths") {
|
|
1261
|
-
if (process.env.VINEXT_PRERENDER !== "1") {
|
|
1262
|
-
return new Response("Not Found", { status: 404 });
|
|
1263
|
-
}
|
|
1264
|
-
const __gspPattern = url.searchParams.get("pattern");
|
|
1265
|
-
if (!__gspPattern) return new Response("missing pattern", { status: 400 });
|
|
1266
|
-
try {
|
|
1267
|
-
const __gspSsrEntry = await import.meta.viteRsc.loadModule("ssr", "index");
|
|
1268
|
-
const __pagesRoutes = __gspSsrEntry.pageRoutes;
|
|
1269
|
-
const __gspRoute = Array.isArray(__pagesRoutes)
|
|
1270
|
-
? __pagesRoutes.find((r) => r.pattern === __gspPattern)
|
|
1271
|
-
: undefined;
|
|
1272
|
-
if (!__gspRoute || typeof __gspRoute.module?.getStaticPaths !== "function") {
|
|
1273
|
-
return new Response("null", { status: 200, headers: { "content-type": "application/json" } });
|
|
1274
|
-
}
|
|
1275
|
-
const __localesParam = url.searchParams.get("locales");
|
|
1276
|
-
const __locales = __localesParam ? JSON.parse(__localesParam) : [];
|
|
1277
|
-
const __defaultLocale = url.searchParams.get("defaultLocale") ?? "";
|
|
1278
|
-
const __gspResult = await __gspRoute.module.getStaticPaths({ locales: __locales, defaultLocale: __defaultLocale });
|
|
1279
|
-
return new Response(JSON.stringify(__gspResult), { status: 200, headers: { "content-type": "application/json" } });
|
|
1280
|
-
} catch (e) {
|
|
1281
|
-
return new Response(JSON.stringify({ error: String(e) }), { status: 500, headers: { "content-type": "application/json" } });
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
` : ""}
|
|
696
|
+
const __prerenderEndpointResponse = await __handleAppPrerenderEndpoint(request, {
|
|
697
|
+
isPrerenderEnabled() {
|
|
698
|
+
return process.env.VINEXT_PRERENDER === "1";
|
|
699
|
+
},
|
|
700
|
+
${prerenderPagesLoaderOption}
|
|
701
|
+
pathname,
|
|
702
|
+
rootParamNamesByPattern: rootParamNamesMap,
|
|
703
|
+
staticParamsMap: generateStaticParamsMap,
|
|
704
|
+
});
|
|
705
|
+
if (__prerenderEndpointResponse) return __prerenderEndpointResponse;
|
|
1285
706
|
|
|
1286
707
|
// Trailing slash normalization (redirect to canonical form)
|
|
1287
708
|
const __tsRedirect = normalizeTrailingSlash(pathname, __basePath, __trailingSlash, url.search);
|
|
@@ -1325,142 +746,19 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1325
746
|
// every response path without module-level state that races on Workers.
|
|
1326
747
|
|
|
1327
748
|
${middlewarePath ? `
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
// Note: h may include x-middleware-request-* internal headers so
|
|
1342
|
-
// applyMiddlewareRequestHeaders() can unpack them below.
|
|
1343
|
-
// processMiddlewareHeaders() strips them before any response.
|
|
1344
|
-
_mwCtx.headers = new Headers();
|
|
1345
|
-
for (const [key, value] of __mwCtxData.h) {
|
|
1346
|
-
_mwCtx.headers.append(key, value);
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
if (__mwCtxData.s != null) {
|
|
1350
|
-
_mwCtx.status = __mwCtxData.s;
|
|
1351
|
-
}
|
|
1352
|
-
// Apply forwarded middleware rewrite so routing uses the rewritten path.
|
|
1353
|
-
// The RSC plugin constructs its Request from the original HTTP request,
|
|
1354
|
-
// not from req.url, so the connect handler's req.url rewrite is invisible.
|
|
1355
|
-
if (__mwCtxData.r) {
|
|
1356
|
-
const __rewriteParsed = new URL(__mwCtxData.r, request.url);
|
|
1357
|
-
cleanPathname = __rewriteParsed.pathname;
|
|
1358
|
-
url.search = __rewriteParsed.search;
|
|
1359
|
-
}
|
|
1360
|
-
// Flag set after full context application — if any step fails (e.g. malformed
|
|
1361
|
-
// rewrite URL), we fall back to re-running middleware as a safety net.
|
|
1362
|
-
__mwCtxApplied = true;
|
|
1363
|
-
} catch (e) {
|
|
1364
|
-
console.error("[vinext] Failed to parse forwarded middleware context:", e);
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
if (!__mwCtxApplied) {
|
|
1369
|
-
// Run proxy/middleware if present and path matches.
|
|
1370
|
-
// Validate exports match the file type (proxy.ts vs middleware.ts), matching Next.js behavior.
|
|
1371
|
-
// https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts
|
|
1372
|
-
const _isProxy = ${JSON.stringify(isProxyFile(middlewarePath))};
|
|
1373
|
-
const middlewareFn = _isProxy
|
|
1374
|
-
? (middlewareModule.proxy ?? middlewareModule.default)
|
|
1375
|
-
: (middlewareModule.middleware ?? middlewareModule.default);
|
|
1376
|
-
if (typeof middlewareFn !== "function") {
|
|
1377
|
-
const _fileType = _isProxy ? "Proxy" : "Middleware";
|
|
1378
|
-
const _expectedExport = _isProxy ? "proxy" : "middleware";
|
|
1379
|
-
throw new Error("The " + _fileType + " file must export a function named \`" + _expectedExport + "\` or a \`default\` function.");
|
|
1380
|
-
}
|
|
1381
|
-
const middlewareMatcher = middlewareModule.config?.matcher;
|
|
1382
|
-
if (matchesMiddleware(cleanPathname, middlewareMatcher, request, __i18nConfig)) {
|
|
1383
|
-
try {
|
|
1384
|
-
// Wrap in NextRequest so middleware gets .nextUrl, .cookies, .geo, .ip, etc.
|
|
1385
|
-
// Always construct a new Request with the fully decoded + normalized pathname
|
|
1386
|
-
// so middleware and the router see the same canonical path.
|
|
1387
|
-
const mwUrl = new URL(request.url);
|
|
1388
|
-
mwUrl.pathname = cleanPathname;
|
|
1389
|
-
const mwRequest = new Request(mwUrl, request);
|
|
1390
|
-
const __mwNextConfig = (__basePath || __i18nConfig) ? { basePath: __basePath, i18n: __i18nConfig ?? undefined } : undefined;
|
|
1391
|
-
const nextRequest = mwRequest instanceof NextRequest ? mwRequest : new NextRequest(mwRequest, __mwNextConfig ? { nextConfig: __mwNextConfig } : undefined);
|
|
1392
|
-
const mwFetchEvent = new NextFetchEvent({ page: cleanPathname });
|
|
1393
|
-
let mwResponse;
|
|
1394
|
-
try {
|
|
1395
|
-
mwResponse = await middlewareFn(nextRequest, mwFetchEvent);
|
|
1396
|
-
} finally {
|
|
1397
|
-
const _mwWaitUntil = mwFetchEvent.drainWaitUntil();
|
|
1398
|
-
const _mwExecCtx = _getRequestExecutionContext();
|
|
1399
|
-
if (_mwExecCtx && typeof _mwExecCtx.waitUntil === "function") { _mwExecCtx.waitUntil(_mwWaitUntil); }
|
|
1400
|
-
}
|
|
1401
|
-
if (mwResponse) {
|
|
1402
|
-
// Check for x-middleware-next (continue)
|
|
1403
|
-
if (mwResponse.headers.get("x-middleware-next") === "1") {
|
|
1404
|
-
// Middleware wants to continue — collect all headers except the two
|
|
1405
|
-
// control headers we've already consumed. x-middleware-request-*
|
|
1406
|
-
// headers are kept so applyMiddlewareRequestHeaders() can unpack them;
|
|
1407
|
-
// the blanket strip loop after that call removes every remaining
|
|
1408
|
-
// x-middleware-* header before the set is merged into the response.
|
|
1409
|
-
_mwCtx.headers = new Headers();
|
|
1410
|
-
for (const [key, value] of mwResponse.headers) {
|
|
1411
|
-
if (key !== "x-middleware-next" && key !== "x-middleware-rewrite") {
|
|
1412
|
-
_mwCtx.headers.append(key, value);
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
} else {
|
|
1416
|
-
// Check for redirect
|
|
1417
|
-
if (mwResponse.status >= 300 && mwResponse.status < 400) {
|
|
1418
|
-
return mwResponse;
|
|
1419
|
-
}
|
|
1420
|
-
// Check for rewrite
|
|
1421
|
-
const rewriteUrl = mwResponse.headers.get("x-middleware-rewrite");
|
|
1422
|
-
if (rewriteUrl) {
|
|
1423
|
-
const rewriteParsed = new URL(rewriteUrl, request.url);
|
|
1424
|
-
cleanPathname = rewriteParsed.pathname;
|
|
1425
|
-
// Carry over query params from the rewrite URL so that
|
|
1426
|
-
// searchParams props, useSearchParams(), and navigation context
|
|
1427
|
-
// reflect the rewrite destination, not the original request.
|
|
1428
|
-
url.search = rewriteParsed.search;
|
|
1429
|
-
// Capture custom status code from rewrite (e.g. NextResponse.rewrite(url, { status: 403 }))
|
|
1430
|
-
if (mwResponse.status !== 200) {
|
|
1431
|
-
_mwCtx.status = mwResponse.status;
|
|
1432
|
-
}
|
|
1433
|
-
// Also save any other headers from the rewrite response
|
|
1434
|
-
_mwCtx.headers = new Headers();
|
|
1435
|
-
for (const [key, value] of mwResponse.headers) {
|
|
1436
|
-
if (key !== "x-middleware-next" && key !== "x-middleware-rewrite") {
|
|
1437
|
-
_mwCtx.headers.append(key, value);
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
} else {
|
|
1441
|
-
// Middleware returned a custom response
|
|
1442
|
-
return mwResponse;
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
}
|
|
1446
|
-
} catch (err) {
|
|
1447
|
-
console.error("[vinext] Middleware error:", err);
|
|
1448
|
-
return new Response("Internal Server Error", { status: 500 });
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
} // end of if (!__mwCtxApplied)
|
|
1452
|
-
|
|
1453
|
-
// Unpack x-middleware-request-* headers into the request context so that
|
|
1454
|
-
// headers() returns the middleware-modified headers instead of the original
|
|
1455
|
-
// request headers. Strip ALL x-middleware-* headers from the set that will
|
|
1456
|
-
// be merged into the outgoing HTTP response — this prefix is reserved for
|
|
1457
|
-
// internal routing signals and must never reach clients.
|
|
1458
|
-
if (_mwCtx.headers) {
|
|
1459
|
-
// Preserve the pre-strip header set so route handlers can reconstruct
|
|
1460
|
-
// a request object with middleware header overrides applied.
|
|
1461
|
-
_mwCtx.requestHeaders = new Headers(_mwCtx.headers);
|
|
1462
|
-
applyMiddlewareRequestHeaders(_mwCtx.headers);
|
|
1463
|
-
processMiddlewareHeaders(_mwCtx.headers);
|
|
749
|
+
const __mwResult = await __applyAppMiddleware({
|
|
750
|
+
basePath: __basePath,
|
|
751
|
+
cleanPathname,
|
|
752
|
+
context: _mwCtx,
|
|
753
|
+
i18nConfig: __i18nConfig,
|
|
754
|
+
isProxy: ${JSON.stringify(isProxyFile(middlewarePath))},
|
|
755
|
+
module: middlewareModule,
|
|
756
|
+
request,
|
|
757
|
+
});
|
|
758
|
+
if (__mwResult.kind === "response") return __mwResult.response;
|
|
759
|
+
cleanPathname = __mwResult.cleanPathname;
|
|
760
|
+
if (__mwResult.search !== null) {
|
|
761
|
+
url.search = __mwResult.search;
|
|
1464
762
|
}
|
|
1465
763
|
` : ""}
|
|
1466
764
|
|
|
@@ -1479,8 +777,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1479
777
|
const __rewritten = matchRewrite(cleanPathname, __configRewrites.beforeFiles, __postMwReqCtx);
|
|
1480
778
|
if (__rewritten) {
|
|
1481
779
|
if (isExternalUrl(__rewritten)) {
|
|
1482
|
-
|
|
1483
|
-
setNavigationContext(null);
|
|
780
|
+
__clearRequestContext();
|
|
1484
781
|
return proxyExternalRequest(request, __rewritten);
|
|
1485
782
|
}
|
|
1486
783
|
cleanPathname = __rewritten;
|
|
@@ -1495,91 +792,25 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1495
792
|
return Response.redirect(new URL(__imgResult, url.origin).href, 302);
|
|
1496
793
|
}
|
|
1497
794
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
metaRoute.type === "sitemap" &&
|
|
1505
|
-
metaRoute.isDynamic &&
|
|
1506
|
-
typeof metaRoute.module.generateSitemaps === "function"
|
|
1507
|
-
) {
|
|
1508
|
-
const sitemapPrefix = metaRoute.servedUrl.slice(0, -4); // strip ".xml"
|
|
1509
|
-
// Match exactly /{prefix}/{id}.xml — one segment only (no slashes in id)
|
|
1510
|
-
if (cleanPathname.startsWith(sitemapPrefix + "/") && cleanPathname.endsWith(".xml")) {
|
|
1511
|
-
const rawId = cleanPathname.slice(sitemapPrefix.length + 1, -4);
|
|
1512
|
-
if (rawId.includes("/")) continue; // multi-segment — not a paginated sitemap
|
|
1513
|
-
const sitemaps = await metaRoute.module.generateSitemaps();
|
|
1514
|
-
const matched = sitemaps.find(function(s) { return String(s.id) === rawId; });
|
|
1515
|
-
if (!matched) return new Response("Not Found", { status: 404 });
|
|
1516
|
-
// Pass the original typed id from generateSitemaps() so numeric IDs stay numeric.
|
|
1517
|
-
// TODO: wrap with makeThenableParams-style Promise when upgrading to Next.js 16
|
|
1518
|
-
// full-Promise param semantics (id becomes Promise<string> in v16).
|
|
1519
|
-
const result = await metaRoute.module.default({ id: matched.id });
|
|
1520
|
-
if (result instanceof Response) return result;
|
|
1521
|
-
return new Response(sitemapToXml(result), {
|
|
1522
|
-
headers: { "Content-Type": metaRoute.contentType },
|
|
1523
|
-
});
|
|
1524
|
-
}
|
|
1525
|
-
// Skip — the base servedUrl is not served when generateSitemaps exists
|
|
1526
|
-
continue;
|
|
1527
|
-
}
|
|
1528
|
-
// Match metadata route — use pattern matching for dynamic segments,
|
|
1529
|
-
// strict equality for static paths.
|
|
1530
|
-
var _metaParams = null;
|
|
1531
|
-
if (metaRoute.patternParts) {
|
|
1532
|
-
var _metaUrlParts = cleanPathname.split("/").filter(Boolean);
|
|
1533
|
-
_metaParams = matchPattern(_metaUrlParts, metaRoute.patternParts);
|
|
1534
|
-
if (!_metaParams) continue;
|
|
1535
|
-
} else if (cleanPathname !== metaRoute.servedUrl) {
|
|
1536
|
-
continue;
|
|
1537
|
-
}
|
|
1538
|
-
if (metaRoute.isDynamic) {
|
|
1539
|
-
// Dynamic metadata route — call the default export and serialize
|
|
1540
|
-
const metaFn = metaRoute.module.default;
|
|
1541
|
-
if (typeof metaFn === "function") {
|
|
1542
|
-
const result = await metaFn({ params: makeThenableParams(_metaParams || {}) });
|
|
1543
|
-
let body;
|
|
1544
|
-
// If it's already a Response (e.g., ImageResponse), return directly
|
|
1545
|
-
if (result instanceof Response) return result;
|
|
1546
|
-
// Serialize based on type
|
|
1547
|
-
if (metaRoute.type === "sitemap") body = sitemapToXml(result);
|
|
1548
|
-
else if (metaRoute.type === "robots") body = robotsToText(result);
|
|
1549
|
-
else if (metaRoute.type === "manifest") body = manifestToJson(result);
|
|
1550
|
-
else body = JSON.stringify(result);
|
|
1551
|
-
return new Response(body, {
|
|
1552
|
-
headers: { "Content-Type": metaRoute.contentType },
|
|
1553
|
-
});
|
|
1554
|
-
}
|
|
1555
|
-
} else {
|
|
1556
|
-
// Static metadata file — decode from embedded base64 data
|
|
1557
|
-
try {
|
|
1558
|
-
const binary = atob(metaRoute.fileDataBase64);
|
|
1559
|
-
const bytes = new Uint8Array(binary.length);
|
|
1560
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
1561
|
-
return new Response(bytes, {
|
|
1562
|
-
headers: {
|
|
1563
|
-
"Content-Type": metaRoute.contentType,
|
|
1564
|
-
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
1565
|
-
},
|
|
1566
|
-
});
|
|
1567
|
-
} catch {
|
|
1568
|
-
return new Response("Not Found", { status: 404 });
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
795
|
+
const metadataRouteResponse = await __handleMetadataRouteRequest({
|
|
796
|
+
metadataRoutes,
|
|
797
|
+
cleanPathname,
|
|
798
|
+
makeThenableParams,
|
|
799
|
+
});
|
|
800
|
+
if (metadataRouteResponse) return metadataRouteResponse;
|
|
1572
801
|
|
|
1573
802
|
// Serve public/ files as filesystem routes after middleware and before
|
|
1574
803
|
// afterFiles/fallback rewrites, matching Next.js routing semantics.
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
804
|
+
const __publicFileResponse = resolvePublicFileRoute({
|
|
805
|
+
cleanPathname,
|
|
806
|
+
middlewareContext: _mwCtx,
|
|
807
|
+
pathname,
|
|
808
|
+
publicFiles: __publicFiles,
|
|
809
|
+
request,
|
|
810
|
+
});
|
|
811
|
+
if (__publicFileResponse) {
|
|
812
|
+
__clearRequestContext();
|
|
813
|
+
return __publicFileResponse;
|
|
1583
814
|
}
|
|
1584
815
|
|
|
1585
816
|
// Set navigation context for Server Components.
|
|
@@ -1591,242 +822,119 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1591
822
|
});
|
|
1592
823
|
|
|
1593
824
|
// Handle server action POST requests
|
|
1594
|
-
const actionId = request.headers.get("x-rsc-action");
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
const args = await decodeReply(body, { temporaryReferences });
|
|
1636
|
-
const action = await loadServerAction(actionId);
|
|
1637
|
-
let returnValue;
|
|
1638
|
-
let actionRedirect = null;
|
|
1639
|
-
const previousHeadersPhase = setHeadersAccessPhase("action");
|
|
1640
|
-
try {
|
|
1641
|
-
try {
|
|
1642
|
-
const data = await action.apply(null, args);
|
|
1643
|
-
returnValue = { ok: true, data };
|
|
1644
|
-
} catch (e) {
|
|
1645
|
-
// Detect redirect() / permanentRedirect() called inside the action.
|
|
1646
|
-
// These throw errors with digest "NEXT_REDIRECT;replace;url[;status]".
|
|
1647
|
-
// The URL is encodeURIComponent-encoded to prevent semicolons in the URL
|
|
1648
|
-
// from corrupting the delimiter-based digest format.
|
|
1649
|
-
if (e && typeof e === "object" && "digest" in e) {
|
|
1650
|
-
const digest = String(e.digest);
|
|
1651
|
-
if (digest.startsWith("NEXT_REDIRECT;")) {
|
|
1652
|
-
const parts = digest.split(";");
|
|
1653
|
-
actionRedirect = {
|
|
1654
|
-
url: decodeURIComponent(parts[2]),
|
|
1655
|
-
type: parts[1] || "push", // "push" or "replace"
|
|
1656
|
-
status: parts[3] ? parseInt(parts[3], 10) : 307,
|
|
1657
|
-
};
|
|
1658
|
-
returnValue = { ok: true, data: undefined };
|
|
1659
|
-
} else if (digest === "NEXT_NOT_FOUND" || digest.startsWith("NEXT_HTTP_ERROR_FALLBACK;")) {
|
|
1660
|
-
// notFound() / forbidden() / unauthorized() in action — package as error
|
|
1661
|
-
returnValue = { ok: false, data: e };
|
|
1662
|
-
} else {
|
|
1663
|
-
// Non-navigation digest error — sanitize in production to avoid
|
|
1664
|
-
// leaking internal details (connection strings, paths, etc.)
|
|
1665
|
-
console.error("[vinext] Server action error:", e);
|
|
1666
|
-
returnValue = { ok: false, data: __sanitizeErrorForClient(e) };
|
|
1667
|
-
}
|
|
1668
|
-
} else {
|
|
1669
|
-
// Unhandled error — sanitize in production to avoid leaking
|
|
1670
|
-
// internal details (database errors, file paths, stack traces, etc.)
|
|
1671
|
-
console.error("[vinext] Server action error:", e);
|
|
1672
|
-
returnValue = { ok: false, data: __sanitizeErrorForClient(e) };
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
} finally {
|
|
1676
|
-
setHeadersAccessPhase(previousHeadersPhase);
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
// If the action called redirect(), signal the client to navigate.
|
|
1680
|
-
// We can't use a real HTTP redirect (the fetch would follow it automatically
|
|
1681
|
-
// and receive a page HTML instead of RSC stream). Instead, we return a 200
|
|
1682
|
-
// with x-action-redirect header that the client entry detects and handles.
|
|
1683
|
-
if (actionRedirect) {
|
|
1684
|
-
const actionPendingCookies = getAndClearPendingCookies();
|
|
1685
|
-
const actionDraftCookie = getDraftModeCookieHeader();
|
|
1686
|
-
setHeadersContext(null);
|
|
1687
|
-
setNavigationContext(null);
|
|
1688
|
-
const redirectHeaders = new Headers({
|
|
1689
|
-
"Content-Type": "text/x-component; charset=utf-8",
|
|
1690
|
-
"Vary": "RSC, Accept",
|
|
1691
|
-
});
|
|
1692
|
-
__mergeMiddlewareResponseHeaders(redirectHeaders, _mwCtx.headers);
|
|
1693
|
-
redirectHeaders.set("x-action-redirect", actionRedirect.url);
|
|
1694
|
-
redirectHeaders.set("x-action-redirect-type", actionRedirect.type);
|
|
1695
|
-
redirectHeaders.set("x-action-redirect-status", String(actionRedirect.status));
|
|
1696
|
-
for (const cookie of actionPendingCookies) {
|
|
1697
|
-
redirectHeaders.append("Set-Cookie", cookie);
|
|
1698
|
-
}
|
|
1699
|
-
if (actionDraftCookie) redirectHeaders.append("Set-Cookie", actionDraftCookie);
|
|
1700
|
-
// Send an empty RSC-like body (client will navigate instead of parsing)
|
|
1701
|
-
return new Response("", { status: 200, headers: redirectHeaders });
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
// After the action, re-render the current page so the client
|
|
1705
|
-
// gets an updated React tree reflecting any mutations.
|
|
1706
|
-
//
|
|
1707
|
-
// When the original request came from inside an intercepted modal
|
|
1708
|
-
// (X-Vinext-Interception-Context present + source route still
|
|
1709
|
-
// matches), rebuild the intercepted tree — otherwise the modal would
|
|
1710
|
-
// unmount and the direct route would render in its place. Mirrors
|
|
1711
|
-
// the interception resolution used by the GET path.
|
|
1712
|
-
const match = matchRoute(cleanPathname);
|
|
1713
|
-
let element;
|
|
1714
|
-
let errorPattern = match ? match.route.pattern : cleanPathname;
|
|
1715
|
-
if (match) {
|
|
1716
|
-
const { route: actionRoute, params: actionParams } = match;
|
|
1717
|
-
const __actionRerenderTarget = __resolveAppPageActionRerenderTarget({
|
|
1718
|
-
cleanPathname,
|
|
1719
|
-
currentParams: actionParams,
|
|
1720
|
-
currentRoute: actionRoute,
|
|
1721
|
-
findIntercept(pathname) {
|
|
1722
|
-
return findIntercept(pathname, interceptionContextHeader);
|
|
1723
|
-
},
|
|
1724
|
-
getRouteParamNames(sourceRoute) {
|
|
1725
|
-
return sourceRoute.params;
|
|
1726
|
-
},
|
|
1727
|
-
getSourceRoute(sourceRouteIndex) {
|
|
1728
|
-
return routes[sourceRouteIndex];
|
|
1729
|
-
},
|
|
1730
|
-
isRscRequest,
|
|
1731
|
-
toInterceptOpts(intercept) {
|
|
1732
|
-
return {
|
|
1733
|
-
interceptionContext: interceptionContextHeader,
|
|
1734
|
-
interceptLayouts: intercept.interceptLayouts,
|
|
1735
|
-
interceptSlotKey: intercept.slotKey,
|
|
1736
|
-
interceptPage: intercept.page,
|
|
1737
|
-
interceptParams: intercept.matchedParams,
|
|
1738
|
-
};
|
|
1739
|
-
},
|
|
1740
|
-
});
|
|
1741
|
-
|
|
1742
|
-
setNavigationContext({
|
|
1743
|
-
pathname: cleanPathname,
|
|
1744
|
-
searchParams: url.searchParams,
|
|
1745
|
-
params: __actionRerenderTarget.navigationParams,
|
|
1746
|
-
});
|
|
1747
|
-
element = buildPageElements(
|
|
1748
|
-
__actionRerenderTarget.route,
|
|
1749
|
-
__actionRerenderTarget.params,
|
|
1750
|
-
cleanPathname,
|
|
1751
|
-
{
|
|
1752
|
-
opts: __actionRerenderTarget.interceptOpts,
|
|
1753
|
-
searchParams: url.searchParams,
|
|
1754
|
-
isRscRequest,
|
|
1755
|
-
request,
|
|
1756
|
-
mountedSlotsHeader: __mountedSlotsHeader,
|
|
1757
|
-
},
|
|
1758
|
-
);
|
|
1759
|
-
errorPattern = __actionRerenderTarget.route.pattern;
|
|
1760
|
-
} else {
|
|
1761
|
-
const _actionRouteId = __createAppPayloadRouteId(cleanPathname, null);
|
|
1762
|
-
element = {
|
|
1763
|
-
[__APP_INTERCEPTION_CONTEXT_KEY]: null,
|
|
1764
|
-
__route: _actionRouteId,
|
|
1765
|
-
__rootLayout: null,
|
|
1766
|
-
[_actionRouteId]: createElement("div", null, "Page not found"),
|
|
1767
|
-
};
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
|
-
const onRenderError = createRscOnErrorHandler(
|
|
1771
|
-
request,
|
|
1772
|
-
cleanPathname,
|
|
1773
|
-
errorPattern,
|
|
1774
|
-
);
|
|
1775
|
-
const rscStream = renderToReadableStream(
|
|
1776
|
-
{ root: element, returnValue },
|
|
1777
|
-
{ temporaryReferences, onError: onRenderError },
|
|
1778
|
-
);
|
|
1779
|
-
|
|
1780
|
-
// Collect cookies set during the action synchronously (before stream is consumed).
|
|
1781
|
-
// Do NOT clear headers/navigation context here — the RSC stream is consumed lazily
|
|
1782
|
-
// by the client, and async server components that run during consumption need the
|
|
1783
|
-
// context to still be live. The AsyncLocalStorage scope from runWithRequestContext
|
|
1784
|
-
// handles cleanup naturally when all async continuations complete.
|
|
1785
|
-
const actionPendingCookies = getAndClearPendingCookies();
|
|
1786
|
-
const actionDraftCookie = getDraftModeCookieHeader();
|
|
1787
|
-
|
|
1788
|
-
const actionHeaders = new Headers({
|
|
1789
|
-
"Content-Type": "text/x-component; charset=utf-8",
|
|
1790
|
-
"Vary": "RSC, Accept",
|
|
1791
|
-
});
|
|
1792
|
-
__mergeMiddlewareResponseHeaders(actionHeaders, _mwCtx.headers);
|
|
1793
|
-
const actionResponse = new Response(rscStream, {
|
|
1794
|
-
status: _mwCtx.status ?? 200,
|
|
1795
|
-
headers: actionHeaders,
|
|
825
|
+
const actionId = request.headers.get("x-rsc-action") ?? request.headers.get("next-action");
|
|
826
|
+
const actionContentType = request.headers.get("content-type") || "";
|
|
827
|
+
const progressiveActionResponse = await __handleProgressiveServerActionRequest({
|
|
828
|
+
actionId,
|
|
829
|
+
allowedOrigins: __allowedOrigins,
|
|
830
|
+
cleanPathname,
|
|
831
|
+
clearRequestContext() {
|
|
832
|
+
__clearRequestContext();
|
|
833
|
+
},
|
|
834
|
+
contentType: actionContentType,
|
|
835
|
+
decodeAction,
|
|
836
|
+
getAndClearPendingCookies,
|
|
837
|
+
getDraftModeCookieHeader,
|
|
838
|
+
maxActionBodySize: __MAX_ACTION_BODY_SIZE,
|
|
839
|
+
middlewareHeaders: _mwCtx.headers,
|
|
840
|
+
readFormDataWithLimit: __readFormDataWithLimit,
|
|
841
|
+
reportRequestError: _reportRequestError,
|
|
842
|
+
request,
|
|
843
|
+
setHeadersAccessPhase,
|
|
844
|
+
});
|
|
845
|
+
if (progressiveActionResponse) return progressiveActionResponse;
|
|
846
|
+
|
|
847
|
+
const serverActionResponse = await __handleServerActionRscRequest({
|
|
848
|
+
actionId,
|
|
849
|
+
allowedOrigins: __allowedOrigins,
|
|
850
|
+
buildPageElement({
|
|
851
|
+
route: actionRoute,
|
|
852
|
+
params: actionParams,
|
|
853
|
+
cleanPathname: actionCleanPathname,
|
|
854
|
+
interceptOpts,
|
|
855
|
+
searchParams,
|
|
856
|
+
isRscRequest: actionIsRscRequest,
|
|
857
|
+
request: actionRequest,
|
|
858
|
+
mountedSlotsHeader,
|
|
859
|
+
}) {
|
|
860
|
+
return buildPageElements(actionRoute, actionParams, actionCleanPathname, {
|
|
861
|
+
opts: interceptOpts,
|
|
862
|
+
searchParams,
|
|
863
|
+
isRscRequest: actionIsRscRequest,
|
|
864
|
+
request: actionRequest,
|
|
865
|
+
mountedSlotsHeader,
|
|
1796
866
|
});
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
867
|
+
},
|
|
868
|
+
cleanPathname,
|
|
869
|
+
clearRequestContext() {
|
|
870
|
+
__clearRequestContext();
|
|
871
|
+
},
|
|
872
|
+
contentType: actionContentType,
|
|
873
|
+
createNotFoundElement(actionRouteId) {
|
|
874
|
+
return {
|
|
875
|
+
[__APP_INTERCEPTION_CONTEXT_KEY]: null,
|
|
876
|
+
__route: actionRouteId,
|
|
877
|
+
__rootLayout: null,
|
|
878
|
+
[actionRouteId]: createElement("div", null, "Page not found"),
|
|
879
|
+
};
|
|
880
|
+
},
|
|
881
|
+
createPayloadRouteId(pathnameToRender, interceptionContext) {
|
|
882
|
+
return __createAppPayloadRouteId(pathnameToRender, interceptionContext);
|
|
883
|
+
},
|
|
884
|
+
createRscOnErrorHandler(actionRequest, actionPathname, routePattern) {
|
|
885
|
+
return createRscOnErrorHandler(actionRequest, actionPathname, routePattern);
|
|
886
|
+
},
|
|
887
|
+
createTemporaryReferenceSet,
|
|
888
|
+
decodeReply,
|
|
889
|
+
findIntercept(pathnameToMatch) {
|
|
890
|
+
return findIntercept(pathnameToMatch, interceptionContextHeader);
|
|
891
|
+
},
|
|
892
|
+
getAndClearPendingCookies,
|
|
893
|
+
getDraftModeCookieHeader,
|
|
894
|
+
getRouteParamNames(sourceRoute) {
|
|
895
|
+
return sourceRoute.params;
|
|
896
|
+
},
|
|
897
|
+
getSourceRoute(sourceRouteIndex) {
|
|
898
|
+
return routes[sourceRouteIndex];
|
|
899
|
+
},
|
|
900
|
+
isRscRequest,
|
|
901
|
+
loadServerAction,
|
|
902
|
+
matchRoute(pathnameToMatch) {
|
|
903
|
+
return matchRoute(pathnameToMatch);
|
|
904
|
+
},
|
|
905
|
+
maxActionBodySize: __MAX_ACTION_BODY_SIZE,
|
|
906
|
+
middlewareHeaders: _mwCtx.headers,
|
|
907
|
+
middlewareStatus: _mwCtx.status,
|
|
908
|
+
mountedSlotsHeader: __mountedSlotsHeader,
|
|
909
|
+
readBodyWithLimit: __readBodyWithLimit,
|
|
910
|
+
readFormDataWithLimit: __readFormDataWithLimit,
|
|
911
|
+
renderToReadableStream,
|
|
912
|
+
reportRequestError: _reportRequestError,
|
|
913
|
+
request,
|
|
914
|
+
sanitizeErrorForClient(error) {
|
|
915
|
+
return __sanitizeErrorForClient(error);
|
|
916
|
+
},
|
|
917
|
+
searchParams: url.searchParams,
|
|
918
|
+
setHeadersAccessPhase,
|
|
919
|
+
setNavigationContext,
|
|
920
|
+
toInterceptOpts(intercept) {
|
|
921
|
+
return {
|
|
922
|
+
interceptionContext: interceptionContextHeader,
|
|
923
|
+
interceptLayouts: intercept.interceptLayouts,
|
|
924
|
+
interceptSlotKey: intercept.slotKey,
|
|
925
|
+
interceptPage: intercept.page,
|
|
926
|
+
interceptParams: intercept.matchedParams,
|
|
927
|
+
};
|
|
928
|
+
},
|
|
929
|
+
});
|
|
930
|
+
if (serverActionResponse) return serverActionResponse;
|
|
1822
931
|
|
|
1823
932
|
// ── Apply afterFiles rewrites from next.config.js ──────────────────────
|
|
1824
933
|
if (__configRewrites.afterFiles && __configRewrites.afterFiles.length) {
|
|
1825
934
|
const __afterRewritten = matchRewrite(cleanPathname, __configRewrites.afterFiles, __postMwReqCtx);
|
|
1826
935
|
if (__afterRewritten) {
|
|
1827
936
|
if (isExternalUrl(__afterRewritten)) {
|
|
1828
|
-
|
|
1829
|
-
setNavigationContext(null);
|
|
937
|
+
__clearRequestContext();
|
|
1830
938
|
return proxyExternalRequest(request, __afterRewritten);
|
|
1831
939
|
}
|
|
1832
940
|
cleanPathname = __afterRewritten;
|
|
@@ -1840,8 +948,7 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1840
948
|
const __fallbackRewritten = matchRewrite(cleanPathname, __configRewrites.fallback, __postMwReqCtx);
|
|
1841
949
|
if (__fallbackRewritten) {
|
|
1842
950
|
if (isExternalUrl(__fallbackRewritten)) {
|
|
1843
|
-
|
|
1844
|
-
setNavigationContext(null);
|
|
951
|
+
__clearRequestContext();
|
|
1845
952
|
return proxyExternalRequest(request, __fallbackRewritten);
|
|
1846
953
|
}
|
|
1847
954
|
cleanPathname = __fallbackRewritten;
|
|
@@ -1882,19 +989,19 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1882
989
|
// (non-404). A 404 means the path isn't a Pages route either,
|
|
1883
990
|
// so fall through to the App Router not-found page below.
|
|
1884
991
|
if (__pagesRes.status !== 404) {
|
|
1885
|
-
|
|
1886
|
-
setNavigationContext(null);
|
|
992
|
+
__clearRequestContext();
|
|
1887
993
|
return __pagesRes;
|
|
1888
994
|
}
|
|
1889
995
|
}
|
|
1890
996
|
}
|
|
1891
997
|
` : ""}
|
|
1892
998
|
// Render custom not-found page if available, otherwise plain 404
|
|
1893
|
-
const notFoundResponse = await renderNotFoundPage(null, isRscRequest, request, undefined, _scriptNonce);
|
|
999
|
+
const notFoundResponse = await renderNotFoundPage(null, isRscRequest, request, undefined, _scriptNonce, _mwCtx);
|
|
1894
1000
|
if (notFoundResponse) return notFoundResponse;
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1001
|
+
__clearRequestContext();
|
|
1002
|
+
const notFoundHeaders = new Headers();
|
|
1003
|
+
__mergeMiddlewareResponseHeaders(notFoundHeaders, _mwCtx.headers);
|
|
1004
|
+
return new Response("Not Found", { status: 404, headers: notFoundHeaders });
|
|
1898
1005
|
}
|
|
1899
1006
|
|
|
1900
1007
|
const { route, params } = match;
|
|
@@ -1905,568 +1012,130 @@ async function _handleRequest(request, __reqCtx, _mwCtx) {
|
|
|
1905
1012
|
searchParams: url.searchParams,
|
|
1906
1013
|
params,
|
|
1907
1014
|
});
|
|
1015
|
+
__setRootParams(__pickRootParams(params, route.rootParamNames));
|
|
1908
1016
|
|
|
1909
1017
|
// Handle route.ts API handlers
|
|
1910
1018
|
if (route.routeHandler) {
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
const revalidateSeconds = __getAppRouteHandlerRevalidateSeconds(handler);
|
|
1914
|
-
if (__hasAppRouteHandlerDefaultExport(handler) && process.env.NODE_ENV === "development") {
|
|
1915
|
-
console.error(
|
|
1916
|
-
"[vinext] Detected default export in route handler " + route.pattern + ". Export a named export for each HTTP method instead.",
|
|
1917
|
-
);
|
|
1918
|
-
}
|
|
1919
|
-
|
|
1920
|
-
const {
|
|
1921
|
-
allowHeaderForOptions,
|
|
1922
|
-
handlerFn,
|
|
1923
|
-
isAutoHead,
|
|
1924
|
-
shouldAutoRespondToOptions,
|
|
1925
|
-
} = __resolveAppRouteHandlerMethod(handler, method);
|
|
1926
|
-
|
|
1927
|
-
if (shouldAutoRespondToOptions) {
|
|
1928
|
-
setHeadersContext(null);
|
|
1929
|
-
setNavigationContext(null);
|
|
1930
|
-
return __applyRouteHandlerMiddlewareContext(
|
|
1931
|
-
new Response(null, {
|
|
1932
|
-
status: 204,
|
|
1933
|
-
headers: { "Allow": allowHeaderForOptions },
|
|
1934
|
-
}),
|
|
1935
|
-
_mwCtx,
|
|
1936
|
-
);
|
|
1937
|
-
}
|
|
1938
|
-
|
|
1939
|
-
// ISR cache read for route handlers (production only).
|
|
1940
|
-
// Only GET/HEAD (auto-HEAD) with finite revalidate > 0 are ISR-eligible.
|
|
1941
|
-
// Known-dynamic handlers skip the read entirely so stale cache entries
|
|
1942
|
-
// from earlier requests do not replay once the process has learned they
|
|
1943
|
-
// access request-specific data.
|
|
1944
|
-
if (
|
|
1945
|
-
__shouldReadAppRouteHandlerCache({
|
|
1946
|
-
dynamicConfig: handler.dynamic,
|
|
1947
|
-
handlerFn,
|
|
1948
|
-
isAutoHead,
|
|
1949
|
-
isKnownDynamic: __isKnownDynamicAppRoute(route.pattern),
|
|
1950
|
-
isProduction: process.env.NODE_ENV === "production",
|
|
1951
|
-
method,
|
|
1952
|
-
revalidateSeconds,
|
|
1953
|
-
})
|
|
1954
|
-
) {
|
|
1955
|
-
const __cachedRouteResponse = await __readAppRouteHandlerCacheResponse({
|
|
1956
|
-
basePath: __basePath,
|
|
1957
|
-
buildPageCacheTags: __pageCacheTags,
|
|
1958
|
-
cleanPathname,
|
|
1959
|
-
clearRequestContext: function() {
|
|
1960
|
-
setHeadersContext(null);
|
|
1961
|
-
setNavigationContext(null);
|
|
1962
|
-
},
|
|
1963
|
-
consumeDynamicUsage,
|
|
1964
|
-
getCollectedFetchTags,
|
|
1965
|
-
handlerFn,
|
|
1966
|
-
i18n: __i18nConfig,
|
|
1967
|
-
isAutoHead,
|
|
1968
|
-
isrDebug: __isrDebug,
|
|
1969
|
-
isrGet: __isrGet,
|
|
1970
|
-
isrRouteKey: __isrRouteKey,
|
|
1971
|
-
isrSet: __isrSet,
|
|
1972
|
-
markDynamicUsage,
|
|
1973
|
-
middlewareContext: _mwCtx,
|
|
1974
|
-
params,
|
|
1975
|
-
requestUrl: request.url,
|
|
1976
|
-
revalidateSearchParams: url.searchParams,
|
|
1977
|
-
revalidateSeconds,
|
|
1978
|
-
routePattern: route.pattern,
|
|
1979
|
-
runInRevalidationContext: async function(renderFn) {
|
|
1980
|
-
const __revalHeadCtx = { headers: new Headers(), cookies: new Map() };
|
|
1981
|
-
const __revalUCtx = _createUnifiedCtx({
|
|
1982
|
-
headersContext: __revalHeadCtx,
|
|
1983
|
-
executionContext: _getRequestExecutionContext(),
|
|
1984
|
-
});
|
|
1985
|
-
await _runWithUnifiedCtx(__revalUCtx, async () => {
|
|
1986
|
-
_ensureFetchPatch();
|
|
1987
|
-
await renderFn();
|
|
1988
|
-
});
|
|
1989
|
-
},
|
|
1990
|
-
scheduleBackgroundRegeneration: __triggerBackgroundRegeneration,
|
|
1991
|
-
setNavigationContext,
|
|
1992
|
-
});
|
|
1993
|
-
if (__cachedRouteResponse) {
|
|
1994
|
-
return __cachedRouteResponse;
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
if (typeof handlerFn === "function") {
|
|
1999
|
-
return __executeAppRouteHandler({
|
|
2000
|
-
basePath: __basePath,
|
|
2001
|
-
buildPageCacheTags: __pageCacheTags,
|
|
2002
|
-
cleanPathname,
|
|
2003
|
-
clearRequestContext: function() {
|
|
2004
|
-
setHeadersContext(null);
|
|
2005
|
-
setNavigationContext(null);
|
|
2006
|
-
},
|
|
2007
|
-
consumeDynamicUsage,
|
|
2008
|
-
executionContext: _getRequestExecutionContext(),
|
|
2009
|
-
getAndClearPendingCookies,
|
|
2010
|
-
getCollectedFetchTags,
|
|
2011
|
-
getDraftModeCookieHeader,
|
|
2012
|
-
handler,
|
|
2013
|
-
handlerFn,
|
|
2014
|
-
i18n: __i18nConfig,
|
|
2015
|
-
isAutoHead,
|
|
2016
|
-
isProduction: process.env.NODE_ENV === "production",
|
|
2017
|
-
isrDebug: __isrDebug,
|
|
2018
|
-
isrRouteKey: __isrRouteKey,
|
|
2019
|
-
isrSet: __isrSet,
|
|
2020
|
-
markDynamicUsage,
|
|
2021
|
-
method,
|
|
2022
|
-
middlewareContext: _mwCtx,
|
|
2023
|
-
middlewareRequestHeaders: _mwCtx.requestHeaders,
|
|
2024
|
-
params: makeThenableParams(params),
|
|
2025
|
-
reportRequestError: _reportRequestError,
|
|
2026
|
-
request,
|
|
2027
|
-
revalidateSeconds,
|
|
2028
|
-
routePattern: route.pattern,
|
|
2029
|
-
setHeadersAccessPhase,
|
|
2030
|
-
});
|
|
2031
|
-
}
|
|
2032
|
-
setHeadersContext(null);
|
|
2033
|
-
setNavigationContext(null);
|
|
2034
|
-
return __applyRouteHandlerMiddlewareContext(
|
|
2035
|
-
new Response(null, {
|
|
2036
|
-
status: 405,
|
|
2037
|
-
}),
|
|
2038
|
-
_mwCtx,
|
|
1019
|
+
setCurrentFetchSoftTags(
|
|
1020
|
+
buildPageCacheTags(cleanPathname, [], route.routeSegments, "route"),
|
|
2039
1021
|
);
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
// Build the component tree: layouts wrapping the page
|
|
2043
|
-
const hasPageModule = !!route.page;
|
|
2044
|
-
const PageComponent = route.page?.default;
|
|
2045
|
-
if (hasPageModule && !PageComponent) {
|
|
2046
|
-
setHeadersContext(null);
|
|
2047
|
-
setNavigationContext(null);
|
|
2048
|
-
return new Response("Page has no default export", { status: 500 });
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
// Read route segment config from page module exports
|
|
2052
|
-
let revalidateSeconds = typeof route.page?.revalidate === "number" ? route.page.revalidate : null;
|
|
2053
|
-
const dynamicConfig = route.page?.dynamic; // 'auto' | 'force-dynamic' | 'force-static' | 'error'
|
|
2054
|
-
const dynamicParamsConfig = route.page?.dynamicParams; // true (default) | false
|
|
2055
|
-
const isForceStatic = dynamicConfig === "force-static";
|
|
2056
|
-
const isDynamicError = dynamicConfig === "error";
|
|
2057
|
-
|
|
2058
|
-
// force-static: replace headers/cookies context with empty values and
|
|
2059
|
-
// clear searchParams so dynamic APIs return defaults instead of real data
|
|
2060
|
-
if (isForceStatic) {
|
|
2061
|
-
setHeadersContext({ headers: new Headers(), cookies: new Map() });
|
|
2062
|
-
setNavigationContext({
|
|
2063
|
-
pathname: cleanPathname,
|
|
2064
|
-
searchParams: new URLSearchParams(),
|
|
2065
|
-
params,
|
|
2066
|
-
});
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
// dynamic = 'error': install an access error so request APIs fail with the
|
|
2070
|
-
// static-generation message even for legacy sync property access.
|
|
2071
|
-
if (isDynamicError) {
|
|
2072
|
-
const errorMsg = 'Page with \`dynamic = "error"\` used a dynamic API. ' +
|
|
2073
|
-
'This page was expected to be fully static, but headers(), cookies(), ' +
|
|
2074
|
-
'or searchParams was accessed. Remove the dynamic API usage or change ' +
|
|
2075
|
-
'the dynamic config to "auto" or "force-dynamic".';
|
|
2076
|
-
setHeadersContext({
|
|
2077
|
-
headers: new Headers(),
|
|
2078
|
-
cookies: new Map(),
|
|
2079
|
-
accessError: new Error(errorMsg),
|
|
2080
|
-
});
|
|
2081
|
-
setNavigationContext({
|
|
2082
|
-
pathname: cleanPathname,
|
|
2083
|
-
searchParams: new URLSearchParams(),
|
|
2084
|
-
params,
|
|
2085
|
-
});
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
|
-
// force-dynamic: set no-store Cache-Control
|
|
2089
|
-
const isForceDynamic = dynamicConfig === "force-dynamic";
|
|
2090
|
-
|
|
2091
|
-
// ── ISR cache read (production only) ─────────────────────────────────────
|
|
2092
|
-
// Read from cache BEFORE generateStaticParams and all rendering work.
|
|
2093
|
-
// This is the critical performance optimization: on a cache hit we skip
|
|
2094
|
-
// ALL expensive work (generateStaticParams, buildPageElement, layout probe,
|
|
2095
|
-
// page probe, renderToReadableStream, SSR). Both HTML and RSC requests
|
|
2096
|
-
// (client-side navigation / prefetch) are served from cache.
|
|
2097
|
-
//
|
|
2098
|
-
// HTML and RSC are stored under separate keys (matching Next.js's .html/.rsc
|
|
2099
|
-
// file layout) so each request type reads and writes independently — no races,
|
|
2100
|
-
// no partial-entry sentinels, no read-before-write hacks needed.
|
|
2101
|
-
//
|
|
2102
|
-
// force-static and dynamic='error' are compatible with ISR — they control
|
|
2103
|
-
// how dynamic APIs behave during rendering, not whether results are cached.
|
|
2104
|
-
// Only force-dynamic truly bypasses the ISR cache.
|
|
2105
|
-
if (
|
|
2106
|
-
process.env.NODE_ENV === "production" &&
|
|
2107
|
-
!isForceDynamic &&
|
|
2108
|
-
(isRscRequest || !_scriptNonce) &&
|
|
2109
|
-
revalidateSeconds !== null && revalidateSeconds > 0 && revalidateSeconds !== Infinity
|
|
2110
|
-
) {
|
|
2111
|
-
const __cachedPageResponse = await __readAppPageCacheResponse({
|
|
1022
|
+
return __dispatchAppRouteHandler({
|
|
1023
|
+
basePath: __basePath,
|
|
2112
1024
|
cleanPathname,
|
|
2113
1025
|
clearRequestContext: function() {
|
|
2114
|
-
|
|
2115
|
-
setNavigationContext(null);
|
|
1026
|
+
__clearRequestContext();
|
|
2116
1027
|
},
|
|
2117
|
-
|
|
1028
|
+
i18n: __i18nConfig,
|
|
2118
1029
|
isrDebug: __isrDebug,
|
|
2119
1030
|
isrGet: __isrGet,
|
|
2120
|
-
|
|
2121
|
-
isrRscKey: __isrRscKey,
|
|
1031
|
+
isrRouteKey: __isrRouteKey,
|
|
2122
1032
|
isrSet: __isrSet,
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
const __revalUCtx = _createUnifiedCtx({
|
|
2132
|
-
headersContext: __revalHeadCtx,
|
|
2133
|
-
executionContext: _getRequestExecutionContext(),
|
|
2134
|
-
});
|
|
2135
|
-
return _runWithUnifiedCtx(__revalUCtx, async () => {
|
|
2136
|
-
_ensureFetchPatch();
|
|
2137
|
-
setNavigationContext({ pathname: cleanPathname, searchParams: new URLSearchParams(), params });
|
|
2138
|
-
// Slot context (X-Vinext-Mounted-Slots) is inherited from the
|
|
2139
|
-
// triggering request so the regen result is cached under the
|
|
2140
|
-
// correct slot-variant key.
|
|
2141
|
-
const __revalElement = await buildPageElements(
|
|
2142
|
-
route,
|
|
2143
|
-
params,
|
|
2144
|
-
cleanPathname,
|
|
2145
|
-
{
|
|
2146
|
-
opts: undefined,
|
|
2147
|
-
searchParams: new URLSearchParams(),
|
|
2148
|
-
isRscRequest,
|
|
2149
|
-
request,
|
|
2150
|
-
mountedSlotsHeader: __mountedSlotsHeader,
|
|
2151
|
-
},
|
|
2152
|
-
);
|
|
2153
|
-
const __revalOnError = createRscOnErrorHandler(request, cleanPathname, route.pattern);
|
|
2154
|
-
const __revalRscStream = renderToReadableStream(__revalElement, { onError: __revalOnError });
|
|
2155
|
-
const __revalRscCapture = __teeAppPageRscStreamForCapture(__revalRscStream, true);
|
|
2156
|
-
const __revalFontData = { links: _getSSRFontLinks(), styles: _getSSRFontStyles(), preloads: _getSSRFontPreloads() };
|
|
2157
|
-
const __revalSsrEntry = await import.meta.viteRsc.loadModule("ssr", "index");
|
|
2158
|
-
const __revalHtmlStream = await __revalSsrEntry.handleSsr(
|
|
2159
|
-
__revalRscCapture.responseStream,
|
|
2160
|
-
_getNavigationContext(),
|
|
2161
|
-
__revalFontData,
|
|
2162
|
-
);
|
|
2163
|
-
setHeadersContext(null);
|
|
2164
|
-
setNavigationContext(null);
|
|
2165
|
-
const __freshHtml = await __readAppPageTextStream(__revalHtmlStream);
|
|
2166
|
-
const __freshRscData = await __revalRscCapture.capturedRscDataPromise;
|
|
2167
|
-
const __pageTags = __pageCacheTags(cleanPathname, getCollectedFetchTags());
|
|
2168
|
-
return { html: __freshHtml, rscData: __freshRscData, tags: __pageTags };
|
|
2169
|
-
});
|
|
1033
|
+
middlewareContext: _mwCtx,
|
|
1034
|
+
middlewareRequestHeaders: _mwCtx.requestHeaders,
|
|
1035
|
+
params,
|
|
1036
|
+
request,
|
|
1037
|
+
route: {
|
|
1038
|
+
pattern: route.pattern,
|
|
1039
|
+
routeHandler: route.routeHandler,
|
|
1040
|
+
routeSegments: route.routeSegments,
|
|
2170
1041
|
},
|
|
2171
1042
|
scheduleBackgroundRegeneration: __triggerBackgroundRegeneration,
|
|
1043
|
+
searchParams: url.searchParams,
|
|
2172
1044
|
});
|
|
2173
|
-
if (__cachedPageResponse) {
|
|
2174
|
-
return __cachedPageResponse;
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
// dynamicParams = false: only params from generateStaticParams are allowed.
|
|
2179
|
-
// This runs AFTER the ISR cache read so that a cache hit skips this work entirely.
|
|
2180
|
-
const __dynamicParamsResponse = await __validateAppPageDynamicParams({
|
|
2181
|
-
clearRequestContext() {
|
|
2182
|
-
setHeadersContext(null);
|
|
2183
|
-
setNavigationContext(null);
|
|
2184
|
-
},
|
|
2185
|
-
enforceStaticParamsOnly: dynamicParamsConfig === false,
|
|
2186
|
-
generateStaticParams: route.page?.generateStaticParams,
|
|
2187
|
-
isDynamicRoute: route.isDynamic,
|
|
2188
|
-
logGenerateStaticParamsError(err) {
|
|
2189
|
-
console.error("[vinext] generateStaticParams error:", err);
|
|
2190
|
-
},
|
|
2191
|
-
params,
|
|
2192
|
-
});
|
|
2193
|
-
if (__dynamicParamsResponse) {
|
|
2194
|
-
return __dynamicParamsResponse;
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
|
-
// Check for intercepting routes on RSC requests (client-side navigation).
|
|
2198
|
-
// If the target URL matches an intercepting route in a parallel slot,
|
|
2199
|
-
// render the source route with the intercepting page in the slot.
|
|
2200
|
-
const __interceptResult = await __resolveAppPageIntercept({
|
|
2201
|
-
buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams) {
|
|
2202
|
-
return buildPageElements(
|
|
2203
|
-
interceptRoute,
|
|
2204
|
-
interceptParams,
|
|
2205
|
-
cleanPathname,
|
|
2206
|
-
{
|
|
2207
|
-
opts: interceptOpts,
|
|
2208
|
-
searchParams: interceptSearchParams,
|
|
2209
|
-
isRscRequest,
|
|
2210
|
-
request,
|
|
2211
|
-
mountedSlotsHeader: __mountedSlotsHeader,
|
|
2212
|
-
},
|
|
2213
|
-
);
|
|
2214
|
-
},
|
|
2215
|
-
cleanPathname,
|
|
2216
|
-
currentRoute: route,
|
|
2217
|
-
findIntercept(pathname) {
|
|
2218
|
-
return findIntercept(pathname, interceptionContextHeader);
|
|
2219
|
-
},
|
|
2220
|
-
getRouteParamNames(sourceRoute) {
|
|
2221
|
-
return sourceRoute.params;
|
|
2222
|
-
},
|
|
2223
|
-
getSourceRoute(sourceRouteIndex) {
|
|
2224
|
-
return routes[sourceRouteIndex];
|
|
2225
|
-
},
|
|
2226
|
-
isRscRequest,
|
|
2227
|
-
renderInterceptResponse(sourceRoute, interceptElement) {
|
|
2228
|
-
const interceptOnError = createRscOnErrorHandler(
|
|
2229
|
-
request,
|
|
2230
|
-
cleanPathname,
|
|
2231
|
-
sourceRoute.pattern,
|
|
2232
|
-
);
|
|
2233
|
-
const interceptStream = renderToReadableStream(interceptElement, {
|
|
2234
|
-
onError: interceptOnError,
|
|
2235
|
-
});
|
|
2236
|
-
// Do NOT clear headers/navigation context here — the RSC stream is consumed lazily
|
|
2237
|
-
// by the client, and async server components that run during consumption need the
|
|
2238
|
-
// context to still be live. The AsyncLocalStorage scope from runWithRequestContext
|
|
2239
|
-
// handles cleanup naturally when all async continuations complete.
|
|
2240
|
-
const interceptHeaders = new Headers({
|
|
2241
|
-
"Content-Type": "text/x-component; charset=utf-8",
|
|
2242
|
-
"Vary": "RSC, Accept",
|
|
2243
|
-
});
|
|
2244
|
-
__mergeMiddlewareResponseHeaders(interceptHeaders, _mwCtx.headers);
|
|
2245
|
-
return new Response(interceptStream, {
|
|
2246
|
-
status: _mwCtx.status ?? 200,
|
|
2247
|
-
headers: interceptHeaders,
|
|
2248
|
-
});
|
|
2249
|
-
},
|
|
2250
|
-
searchParams: url.searchParams,
|
|
2251
|
-
setNavigationContext,
|
|
2252
|
-
toInterceptOpts(intercept) {
|
|
2253
|
-
return {
|
|
2254
|
-
interceptionContext: interceptionContextHeader,
|
|
2255
|
-
interceptLayouts: intercept.interceptLayouts,
|
|
2256
|
-
interceptSlotKey: intercept.slotKey,
|
|
2257
|
-
interceptPage: intercept.page,
|
|
2258
|
-
interceptParams: intercept.matchedParams,
|
|
2259
|
-
};
|
|
2260
|
-
},
|
|
2261
|
-
});
|
|
2262
|
-
if (__interceptResult.response) {
|
|
2263
|
-
return __interceptResult.response;
|
|
2264
1045
|
}
|
|
2265
|
-
const interceptOpts = __interceptResult.interceptOpts;
|
|
2266
1046
|
|
|
2267
|
-
const
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
1047
|
+
const PageComponent = route.page?.default;
|
|
1048
|
+
const _asyncRouteParams = makeThenableParams(params);
|
|
1049
|
+
return __dispatchAppPage({
|
|
1050
|
+
buildPageElement(targetRoute, targetParams, targetOpts, targetSearchParams) {
|
|
1051
|
+
return buildPageElements(targetRoute, targetParams, cleanPathname, {
|
|
1052
|
+
opts: targetOpts,
|
|
1053
|
+
searchParams: targetSearchParams,
|
|
2272
1054
|
isRscRequest,
|
|
2273
1055
|
request,
|
|
2274
1056
|
mountedSlotsHeader: __mountedSlotsHeader,
|
|
2275
1057
|
});
|
|
2276
1058
|
},
|
|
2277
|
-
renderErrorBoundaryPage(buildErr) {
|
|
2278
|
-
return renderErrorBoundaryPage(route, buildErr, isRscRequest, request, params, _scriptNonce);
|
|
2279
|
-
},
|
|
2280
|
-
renderSpecialError(__buildSpecialError) {
|
|
2281
|
-
return __buildAppPageSpecialErrorResponse({
|
|
2282
|
-
clearRequestContext() {
|
|
2283
|
-
setHeadersContext(null);
|
|
2284
|
-
setNavigationContext(null);
|
|
2285
|
-
},
|
|
2286
|
-
renderFallbackPage(statusCode) {
|
|
2287
|
-
return renderHTTPAccessFallbackPage(
|
|
2288
|
-
route,
|
|
2289
|
-
statusCode,
|
|
2290
|
-
isRscRequest,
|
|
2291
|
-
request,
|
|
2292
|
-
{
|
|
2293
|
-
matchedParams: params,
|
|
2294
|
-
},
|
|
2295
|
-
_scriptNonce,
|
|
2296
|
-
);
|
|
2297
|
-
},
|
|
2298
|
-
requestUrl: request.url,
|
|
2299
|
-
specialError: __buildSpecialError,
|
|
2300
|
-
});
|
|
2301
|
-
},
|
|
2302
|
-
resolveSpecialError: __resolveAppPageSpecialError,
|
|
2303
|
-
});
|
|
2304
|
-
if (__pageBuildResult.response) {
|
|
2305
|
-
return __pageBuildResult.response;
|
|
2306
|
-
}
|
|
2307
|
-
const element = __pageBuildResult.element;
|
|
2308
|
-
|
|
2309
|
-
// Note: CSS is automatically injected by @vitejs/plugin-rsc's
|
|
2310
|
-
// rscCssTransform — no manual loadCss() call needed.
|
|
2311
|
-
const _hasLoadingBoundary = !!(route.loading && route.loading.default);
|
|
2312
|
-
const _asyncLayoutParams = makeThenableParams(params);
|
|
2313
|
-
return __renderAppPageLifecycle({
|
|
2314
1059
|
cleanPathname,
|
|
2315
1060
|
clearRequestContext() {
|
|
2316
|
-
|
|
2317
|
-
setNavigationContext(null);
|
|
1061
|
+
__clearRequestContext();
|
|
2318
1062
|
},
|
|
2319
|
-
consumeDynamicUsage,
|
|
2320
1063
|
createRscOnErrorHandler(pathname, routePath) {
|
|
2321
1064
|
return createRscOnErrorHandler(request, pathname, routePath);
|
|
2322
1065
|
},
|
|
2323
|
-
|
|
2324
|
-
|
|
1066
|
+
debugClassification: __classDebug,
|
|
1067
|
+
dynamicConfig: route.page?.dynamic,
|
|
1068
|
+
dynamicParamsConfig: route.page?.dynamicParams,
|
|
1069
|
+
findIntercept(pathname) {
|
|
1070
|
+
return findIntercept(pathname, interceptionContextHeader);
|
|
1071
|
+
},
|
|
1072
|
+
generateStaticParams: route.page?.generateStaticParams,
|
|
2325
1073
|
getFontLinks: _getSSRFontLinks,
|
|
2326
1074
|
getFontPreloads: _getSSRFontPreloads,
|
|
2327
1075
|
getFontStyles: _getSSRFontStyles,
|
|
2328
1076
|
getNavigationContext: _getNavigationContext,
|
|
2329
|
-
|
|
2330
|
-
return
|
|
2331
|
-
},
|
|
2332
|
-
getRequestCacheLife() {
|
|
2333
|
-
return _consumeRequestScopedCacheLife();
|
|
1077
|
+
getSourceRoute(sourceRouteIndex) {
|
|
1078
|
+
return routes[sourceRouteIndex];
|
|
2334
1079
|
},
|
|
1080
|
+
hasGenerateStaticParams: typeof route.page?.generateStaticParams === "function",
|
|
1081
|
+
hasPageDefaultExport: !!PageComponent,
|
|
1082
|
+
hasPageModule: !!route.page,
|
|
2335
1083
|
handlerStart: __reqStart,
|
|
2336
|
-
|
|
2337
|
-
isDynamicError,
|
|
2338
|
-
isForceDynamic,
|
|
2339
|
-
isForceStatic,
|
|
1084
|
+
interceptionContext: interceptionContextHeader,
|
|
2340
1085
|
isProduction: process.env.NODE_ENV === "production",
|
|
2341
1086
|
isRscRequest,
|
|
2342
1087
|
isrDebug: __isrDebug,
|
|
1088
|
+
isrGet: __isrGet,
|
|
2343
1089
|
isrHtmlKey: __isrHtmlKey,
|
|
2344
1090
|
isrRscKey: __isrRscKey,
|
|
2345
1091
|
isrSet: __isrSet,
|
|
2346
|
-
layoutCount: route.layouts?.length ?? 0,
|
|
2347
1092
|
loadSsrHandler() {
|
|
2348
1093
|
return import.meta.viteRsc.loadModule("ssr", "index");
|
|
2349
1094
|
},
|
|
2350
1095
|
middlewareContext: _mwCtx,
|
|
1096
|
+
mountedSlotsHeader: __mountedSlotsHeader,
|
|
2351
1097
|
params,
|
|
2352
1098
|
probeLayoutAt(li) {
|
|
2353
1099
|
const LayoutComp = route.layouts[li]?.default;
|
|
2354
1100
|
if (!LayoutComp) return null;
|
|
2355
|
-
return LayoutComp({
|
|
1101
|
+
return LayoutComp({
|
|
1102
|
+
params: makeThenableParams(__resolveAppPageSegmentParams(
|
|
1103
|
+
route.routeSegments,
|
|
1104
|
+
route.layoutTreePositions?.[li] ?? 0,
|
|
1105
|
+
params,
|
|
1106
|
+
)),
|
|
1107
|
+
children: null,
|
|
1108
|
+
});
|
|
2356
1109
|
},
|
|
2357
1110
|
probePage() {
|
|
2358
1111
|
if (!PageComponent) return null;
|
|
2359
|
-
const
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
? _probeSearchObj[k].concat(v)
|
|
2364
|
-
: [_probeSearchObj[k], v];
|
|
2365
|
-
} else {
|
|
2366
|
-
_probeSearchObj[k] = v;
|
|
2367
|
-
}
|
|
2368
|
-
});
|
|
2369
|
-
const _asyncSearchParams = makeThenableParams(_probeSearchObj);
|
|
2370
|
-
return PageComponent({ params: _asyncLayoutParams, searchParams: _asyncSearchParams });
|
|
2371
|
-
},
|
|
2372
|
-
classification: {
|
|
2373
|
-
getLayoutId(index) {
|
|
2374
|
-
const tp = route.layoutTreePositions?.[index] ?? 0;
|
|
2375
|
-
return "layout:" + __createAppPageTreePath(route.routeSegments, tp);
|
|
2376
|
-
},
|
|
2377
|
-
buildTimeClassifications: route.__buildTimeClassifications,
|
|
2378
|
-
buildTimeReasons: route.__buildTimeReasons,
|
|
2379
|
-
debugClassification: __classDebug,
|
|
2380
|
-
async runWithIsolatedDynamicScope(fn) {
|
|
2381
|
-
const priorDynamic = consumeDynamicUsage();
|
|
2382
|
-
try {
|
|
2383
|
-
const result = await fn();
|
|
2384
|
-
const dynamicDetected = consumeDynamicUsage();
|
|
2385
|
-
return { result, dynamicDetected };
|
|
2386
|
-
} finally {
|
|
2387
|
-
consumeDynamicUsage();
|
|
2388
|
-
if (priorDynamic) markDynamicUsage();
|
|
2389
|
-
}
|
|
2390
|
-
},
|
|
2391
|
-
},
|
|
2392
|
-
revalidateSeconds,
|
|
2393
|
-
mountedSlotsHeader: __mountedSlotsHeader,
|
|
2394
|
-
renderErrorBoundaryResponse(renderErr) {
|
|
2395
|
-
return renderErrorBoundaryPage(route, renderErr, isRscRequest, request, params, _scriptNonce);
|
|
1112
|
+
const _asyncSearchParams = makeThenableParams(
|
|
1113
|
+
__collectAppPageSearchParams(url.searchParams).searchParamsObject,
|
|
1114
|
+
);
|
|
1115
|
+
return PageComponent({ params: _asyncRouteParams, searchParams: _asyncSearchParams });
|
|
2396
1116
|
},
|
|
2397
|
-
|
|
2398
|
-
return
|
|
2399
|
-
clearRequestContext() {
|
|
2400
|
-
setHeadersContext(null);
|
|
2401
|
-
setNavigationContext(null);
|
|
2402
|
-
},
|
|
2403
|
-
renderFallbackPage(statusCode) {
|
|
2404
|
-
// Find the not-found component from the parent level (the boundary that
|
|
2405
|
-
// would catch this in Next.js). Walk up from the throwing layout to find
|
|
2406
|
-
// the nearest not-found at a parent layout's directory.
|
|
2407
|
-
let parentNotFound = null;
|
|
2408
|
-
if (route.notFounds) {
|
|
2409
|
-
for (let pi = li - 1; pi >= 0; pi--) {
|
|
2410
|
-
if (route.notFounds[pi]?.default) {
|
|
2411
|
-
parentNotFound = route.notFounds[pi].default;
|
|
2412
|
-
break;
|
|
2413
|
-
}
|
|
2414
|
-
}
|
|
2415
|
-
}
|
|
2416
|
-
if (!parentNotFound) parentNotFound = ${rootNotFoundVar ? `${rootNotFoundVar}?.default` : "null"};
|
|
2417
|
-
const parentLayouts = route.layouts.slice(0, li);
|
|
2418
|
-
return renderHTTPAccessFallbackPage(
|
|
2419
|
-
route,
|
|
2420
|
-
statusCode,
|
|
2421
|
-
isRscRequest,
|
|
2422
|
-
request,
|
|
2423
|
-
{
|
|
2424
|
-
boundaryComponent: parentNotFound,
|
|
2425
|
-
layouts: parentLayouts,
|
|
2426
|
-
matchedParams: params,
|
|
2427
|
-
},
|
|
2428
|
-
_scriptNonce,
|
|
2429
|
-
);
|
|
2430
|
-
},
|
|
2431
|
-
requestUrl: request.url,
|
|
2432
|
-
specialError: __layoutSpecialError,
|
|
2433
|
-
});
|
|
1117
|
+
renderErrorBoundaryPage(renderErr) {
|
|
1118
|
+
return renderErrorBoundaryPage(route, renderErr, isRscRequest, request, params, _scriptNonce, _mwCtx);
|
|
2434
1119
|
},
|
|
2435
|
-
|
|
2436
|
-
return
|
|
2437
|
-
clearRequestContext() {
|
|
2438
|
-
setHeadersContext(null);
|
|
2439
|
-
setNavigationContext(null);
|
|
2440
|
-
},
|
|
2441
|
-
renderFallbackPage(statusCode) {
|
|
2442
|
-
return renderHTTPAccessFallbackPage(
|
|
2443
|
-
route,
|
|
2444
|
-
statusCode,
|
|
2445
|
-
isRscRequest,
|
|
2446
|
-
request,
|
|
2447
|
-
{
|
|
2448
|
-
matchedParams: params,
|
|
2449
|
-
},
|
|
2450
|
-
_scriptNonce,
|
|
2451
|
-
);
|
|
2452
|
-
},
|
|
2453
|
-
requestUrl: request.url,
|
|
2454
|
-
specialError,
|
|
2455
|
-
});
|
|
1120
|
+
renderHttpAccessFallbackPage(statusCode, opts, middlewareContext) {
|
|
1121
|
+
return renderHTTPAccessFallbackPage(route, statusCode, isRscRequest, request, opts, _scriptNonce, middlewareContext);
|
|
2456
1122
|
},
|
|
2457
1123
|
renderToReadableStream,
|
|
2458
|
-
|
|
2459
|
-
|
|
1124
|
+
request,
|
|
1125
|
+
revalidateSeconds: typeof route.page?.revalidate === "number" ? route.page.revalidate : null,
|
|
1126
|
+
rootForbiddenModule,
|
|
1127
|
+
rootNotFoundModule,
|
|
1128
|
+
rootUnauthorizedModule,
|
|
1129
|
+
route,
|
|
2460
1130
|
runWithSuppressedHookWarning(probe) {
|
|
2461
|
-
// Run inside ALS context so the module-level console.error patch suppresses
|
|
2462
|
-
// "Invalid hook call" only for this request's probe — concurrent requests
|
|
2463
|
-
// each have their own ALS store and are unaffected.
|
|
2464
1131
|
return _suppressHookWarningAls.run(true, probe);
|
|
2465
1132
|
},
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
_getRequestExecutionContext()?.waitUntil(__cachePromise);
|
|
1133
|
+
scheduleBackgroundRegeneration(key, renderFn, errorContext) {
|
|
1134
|
+
__triggerBackgroundRegeneration(key, renderFn, errorContext);
|
|
2469
1135
|
},
|
|
1136
|
+
scriptNonce: _scriptNonce,
|
|
1137
|
+
searchParams: url.searchParams,
|
|
1138
|
+
setNavigationContext,
|
|
2470
1139
|
});
|
|
2471
1140
|
}
|
|
2472
1141
|
|