vinext 0.0.46 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/build/layout-classification.js +3 -1
- package/dist/build/layout-classification.js.map +1 -1
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +80 -24
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +9 -5
- package/dist/build/report.js +17 -7
- package/dist/build/report.js.map +1 -1
- package/dist/build/route-classification-injector.d.ts +35 -0
- package/dist/build/route-classification-injector.js +61 -0
- package/dist/build/route-classification-injector.js.map +1 -0
- package/dist/build/route-classification-manifest.d.ts +1 -1
- package/dist/build/run-prerender.d.ts +5 -0
- package/dist/build/run-prerender.js +4 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/server-manifest.js +2 -7
- package/dist/build/server-manifest.js.map +1 -1
- package/dist/build/standalone.js +3 -5
- package/dist/build/standalone.js.map +1 -1
- package/dist/build/static-export.d.ts +1 -1
- package/dist/check.js +45 -29
- package/dist/check.js.map +1 -1
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.js +121 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli.js +11 -20
- package/dist/cli.js.map +1 -1
- package/dist/cloudflare/kv-cache-handler.js +29 -9
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/config/config-matchers.js +46 -37
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +4 -2
- package/dist/config/next-config.js +3 -0
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts +18 -2
- package/dist/deploy.js +47 -4
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +4 -3
- package/dist/entries/app-rsc-entry.js +379 -858
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +1 -1
- package/dist/entries/app-rsc-manifest.js +6 -1
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.js +3 -2
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +19 -61
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +12 -3
- package/dist/entries/runtime-entry-module.js +15 -4
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +40 -58
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.js +54 -32
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/og-assets.js +15 -16
- package/dist/plugins/og-assets.js.map +1 -1
- package/dist/plugins/rsc-client-shim-excludes.d.ts +2 -1
- package/dist/plugins/rsc-client-shim-excludes.js +11 -1
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +195 -0
- package/dist/routing/app-route-graph.js +1022 -0
- package/dist/routing/app-route-graph.js.map +1 -0
- package/dist/routing/app-router.d.ts +14 -88
- package/dist/routing/app-router.js +21 -712
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +3 -1
- package/dist/routing/file-matcher.js +6 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.js +10 -19
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-matching.d.ts +28 -0
- package/dist/routing/route-matching.js +44 -0
- package/dist/routing/route-matching.js.map +1 -0
- package/dist/routing/route-pattern.js +4 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/routing/route-trie.d.ts +8 -0
- package/dist/routing/route-trie.js +12 -1
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/route-validation.js +3 -4
- package/dist/routing/route-validation.js.map +1 -1
- package/dist/routing/utils.d.ts +8 -1
- package/dist/routing/utils.js +25 -2
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/app-browser-entry.js +145 -294
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-error.d.ts +3 -4
- package/dist/server/app-browser-error.js +8 -4
- package/dist/server/app-browser-error.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +75 -0
- package/dist/server/app-browser-navigation-controller.js +290 -0
- package/dist/server/app-browser-navigation-controller.js.map +1 -0
- package/dist/server/app-browser-state.d.ts +33 -15
- package/dist/server/app-browser-state.js +52 -59
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +68 -0
- package/dist/server/app-browser-visible-commit.js +182 -0
- package/dist/server/app-browser-visible-commit.js.map +1 -0
- package/dist/server/app-client-reference-preloader.d.ts +15 -0
- package/dist/server/app-client-reference-preloader.js +46 -0
- package/dist/server/app-client-reference-preloader.js.map +1 -0
- package/dist/server/app-elements-wire.d.ts +130 -0
- package/dist/server/app-elements-wire.js +205 -0
- package/dist/server/app-elements-wire.js.map +1 -0
- package/dist/server/app-elements.d.ts +2 -84
- package/dist/server/app-elements.js +4 -107
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +57 -0
- package/dist/server/app-fallback-renderer.js +79 -0
- package/dist/server/app-fallback-renderer.js.map +1 -0
- package/dist/server/app-hook-warning-suppression.d.ts +7 -0
- package/dist/server/app-hook-warning-suppression.js +12 -0
- package/dist/server/app-hook-warning-suppression.js.map +1 -0
- package/dist/server/app-middleware.d.ts +2 -1
- package/dist/server/app-middleware.js +34 -11
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-mounted-slots-header.d.ts +17 -0
- package/dist/server/app-mounted-slots-header.js +21 -0
- package/dist/server/app-mounted-slots-header.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +3 -3
- package/dist/server/app-page-boundary-render.js +8 -5
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +19 -4
- package/dist/server/app-page-cache.js +60 -22
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +9 -5
- package/dist/server/app-page-dispatch.js +41 -17
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +61 -0
- package/dist/server/app-page-element-builder.js +142 -0
- package/dist/server/app-page-element-builder.js.map +1 -0
- package/dist/server/app-page-execution.d.ts +23 -5
- package/dist/server/app-page-execution.js +39 -24
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.js +2 -1
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-method.js +2 -5
- package/dist/server/app-page-method.js.map +1 -1
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +3 -3
- package/dist/server/app-page-params.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +1 -1
- package/dist/server/app-page-probe.js +5 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +6 -2
- package/dist/server/app-page-render.js +118 -30
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +19 -5
- package/dist/server/app-page-request.js +49 -7
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +1 -0
- package/dist/server/app-page-response.js +6 -9
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +20 -4
- package/dist/server/app-page-route-wiring.js +15 -12
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +9 -2
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-post-middleware-context.d.ts +16 -0
- package/dist/server/app-post-middleware-context.js +28 -0
- package/dist/server/app-post-middleware-context.js.map +1 -0
- package/dist/server/app-prerender-endpoints.js +3 -2
- package/dist/server/app-prerender-endpoints.js.map +1 -1
- package/dist/server/app-request-context.d.ts +22 -0
- package/dist/server/app-request-context.js +30 -0
- package/dist/server/app-request-context.js.map +1 -0
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +7 -2
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +8 -5
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -1
- package/dist/server/app-route-handler-execution.js +2 -2
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-policy.js +13 -13
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.d.ts +4 -2
- package/dist/server/app-route-handler-response.js +9 -7
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.d.ts +9 -1
- package/dist/server/app-route-handler-runtime.js +11 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js +9 -4
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +34 -0
- package/dist/server/app-rsc-cache-busting.js +137 -0
- package/dist/server/app-rsc-cache-busting.js.map +1 -0
- package/dist/server/app-rsc-error-handler.d.ts +21 -0
- package/dist/server/app-rsc-error-handler.js +30 -0
- package/dist/server/app-rsc-error-handler.js.map +1 -0
- package/dist/server/app-rsc-handler.d.ts +117 -0
- package/dist/server/app-rsc-handler.js +271 -0
- package/dist/server/app-rsc-handler.js.map +1 -0
- package/dist/server/app-rsc-request-normalization.d.ts +42 -0
- package/dist/server/app-rsc-request-normalization.js +67 -0
- package/dist/server/app-rsc-request-normalization.js.map +1 -0
- package/dist/server/app-rsc-response-finalizer.d.ts +30 -0
- package/dist/server/app-rsc-response-finalizer.js +38 -0
- package/dist/server/app-rsc-response-finalizer.js.map +1 -0
- package/dist/server/app-rsc-route-matching.js +8 -4
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-segment-config.d.ts +33 -0
- package/dist/server/app-segment-config.js +90 -0
- package/dist/server/app-segment-config.js.map +1 -0
- package/dist/server/app-server-action-execution.d.ts +2 -0
- package/dist/server/app-server-action-execution.js +45 -51
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.js +21 -20
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +44 -0
- package/dist/server/artifact-compatibility.js +82 -0
- package/dist/server/artifact-compatibility.js.map +1 -0
- package/dist/server/cache-control.d.ts +24 -0
- package/dist/server/cache-control.js +33 -0
- package/dist/server/cache-control.js.map +1 -0
- package/dist/server/cache-proof.d.ts +200 -0
- package/dist/server/cache-proof.js +342 -0
- package/dist/server/cache-proof.js.map +1 -0
- package/dist/server/dev-error-overlay-store.d.ts +23 -0
- package/dist/server/dev-error-overlay-store.js +67 -0
- package/dist/server/dev-error-overlay-store.js.map +1 -0
- package/dist/server/dev-error-overlay.d.ts +15 -0
- package/dist/server/dev-error-overlay.js +548 -0
- package/dist/server/dev-error-overlay.js.map +1 -0
- package/dist/server/dev-origin-check.js +8 -4
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-server.js +1 -6
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +67 -0
- package/dist/server/http-error-responses.js +77 -0
- package/dist/server/http-error-responses.js.map +1 -0
- package/dist/server/image-optimization.js +2 -1
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/instrumentation-runtime.d.ts +44 -0
- package/dist/server/instrumentation-runtime.js +29 -0
- package/dist/server/instrumentation-runtime.js.map +1 -0
- package/dist/server/isr-cache.d.ts +2 -7
- package/dist/server/isr-cache.js +7 -10
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-response.js +6 -5
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.d.ts +1 -0
- package/dist/server/metadata-routes.js +6 -0
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.js +2 -2
- package/dist/server/middleware-matcher.js.map +1 -1
- package/dist/server/middleware-response-headers.js +21 -0
- package/dist/server/middleware-response-headers.js.map +1 -1
- package/dist/server/middleware-runtime.js +3 -3
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +33 -0
- package/dist/server/navigation-trace.js +35 -0
- package/dist/server/navigation-trace.js.map +1 -0
- package/dist/server/next-error-digest.d.ts +44 -0
- package/dist/server/next-error-digest.js +40 -0
- package/dist/server/next-error-digest.js.map +1 -0
- package/dist/server/pages-api-route.js +2 -1
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-node-compat.js +4 -16
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +2 -1
- package/dist/server/pages-page-data.js +6 -5
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +3 -8
- package/dist/server/pages-page-response.js +46 -15
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prod-server.d.ts +6 -0
- package/dist/server/prod-server.js +28 -21
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +42 -1
- package/dist/server/request-pipeline.js +97 -17
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/rsc-stream-hints.d.ts +3 -1
- package/dist/server/rsc-stream-hints.js +4 -1
- package/dist/server/rsc-stream-hints.js.map +1 -1
- package/dist/server/seed-cache.js +19 -8
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +2 -2
- package/dist/shims/cache-runtime.js +31 -17
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +15 -3
- package/dist/shims/cache.js +45 -20
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +17 -1
- package/dist/shims/error-boundary.js +31 -1
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +4 -1
- package/dist/shims/fetch-cache.js +57 -16
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/head-state.js +2 -3
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/headers.js +4 -44
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-state.js +2 -3
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/image.js +93 -5
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/als-registry.d.ts +15 -0
- package/dist/shims/internal/als-registry.js +55 -0
- package/dist/shims/internal/als-registry.js.map +1 -0
- package/dist/shims/internal/cookie-serialize.d.ts +46 -0
- package/dist/shims/internal/cookie-serialize.js +51 -0
- package/dist/shims/internal/cookie-serialize.js.map +1 -0
- package/dist/shims/link.js +31 -26
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +26 -1
- package/dist/shims/metadata.js +94 -4
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.js +2 -3
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +2 -7
- package/dist/shims/navigation.js +44 -36
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/request-context.js +2 -4
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/router-state.js +2 -3
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.js +2 -2
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/server.js +5 -30
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +1 -1
- package/dist/shims/slot.js +5 -4
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/thenable-params.d.ts +5 -2
- package/dist/shims/thenable-params.js +26 -6
- package/dist/shims/thenable-params.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +3 -14
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/use-merged-ref.d.ts +7 -0
- package/dist/shims/use-merged-ref.js +40 -0
- package/dist/shims/use-merged-ref.js.map +1 -0
- package/dist/utils/base-path.d.ts +7 -1
- package/dist/utils/base-path.js +12 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/cache-control-metadata.d.ts +6 -0
- package/dist/utils/cache-control-metadata.js +16 -0
- package/dist/utils/cache-control-metadata.js.map +1 -0
- package/dist/utils/safe-json-file.d.ts +18 -0
- package/dist/utils/safe-json-file.js +25 -0
- package/dist/utils/safe-json-file.js.map +1 -0
- package/dist/utils/text-stream.d.ts +29 -0
- package/dist/utils/text-stream.js +66 -0
- package/dist/utils/text-stream.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
|
|
2
|
+
import { MiddlewareModule } from "./middleware-runtime.js";
|
|
3
|
+
import { AppMiddlewareContext } from "./app-middleware.js";
|
|
4
|
+
import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
|
|
5
|
+
import { handleMetadataRouteRequest } from "./metadata-route-response.js";
|
|
6
|
+
|
|
7
|
+
//#region src/server/app-rsc-handler.d.ts
|
|
8
|
+
type AppPageParams = Record<string, string | string[]>;
|
|
9
|
+
type MetadataRoutes = Parameters<typeof handleMetadataRouteRequest>[0]["metadataRoutes"];
|
|
10
|
+
type MakeThenableParams = Parameters<typeof handleMetadataRouteRequest>[0]["makeThenableParams"];
|
|
11
|
+
type StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["staticParamsMap"];
|
|
12
|
+
type RootParamNamesMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["rootParamNamesByPattern"];
|
|
13
|
+
type AppRscMiddlewareContext = AppMiddlewareContext;
|
|
14
|
+
type AppRscHandlerRoute = {
|
|
15
|
+
page?: unknown;
|
|
16
|
+
pattern: string;
|
|
17
|
+
rootParamNames?: readonly string[];
|
|
18
|
+
routeHandler?: unknown;
|
|
19
|
+
routeSegments: readonly string[];
|
|
20
|
+
};
|
|
21
|
+
type AppRscRouteMatch<TRoute> = {
|
|
22
|
+
params: AppPageParams;
|
|
23
|
+
route: TRoute;
|
|
24
|
+
};
|
|
25
|
+
type DispatchMatchedPageOptions<TRoute> = {
|
|
26
|
+
cleanPathname: string;
|
|
27
|
+
handlerStart: number;
|
|
28
|
+
interceptionContext: string | null;
|
|
29
|
+
isRscRequest: boolean;
|
|
30
|
+
middlewareContext: AppRscMiddlewareContext;
|
|
31
|
+
mountedSlotsHeader: string | null;
|
|
32
|
+
params: AppPageParams;
|
|
33
|
+
request: Request;
|
|
34
|
+
route: TRoute;
|
|
35
|
+
scriptNonce?: string;
|
|
36
|
+
searchParams: URLSearchParams;
|
|
37
|
+
};
|
|
38
|
+
type DispatchMatchedRouteHandlerOptions<TRoute> = {
|
|
39
|
+
cleanPathname: string;
|
|
40
|
+
middlewareContext: AppRscMiddlewareContext;
|
|
41
|
+
params: AppPageParams;
|
|
42
|
+
request: Request;
|
|
43
|
+
route: TRoute;
|
|
44
|
+
searchParams: URLSearchParams;
|
|
45
|
+
};
|
|
46
|
+
type HandleProgressiveActionRequestOptions = {
|
|
47
|
+
actionId: string | null;
|
|
48
|
+
cleanPathname: string;
|
|
49
|
+
contentType: string;
|
|
50
|
+
middlewareContext: AppRscMiddlewareContext;
|
|
51
|
+
request: Request;
|
|
52
|
+
};
|
|
53
|
+
type HandleServerActionRequestOptions = {
|
|
54
|
+
actionId: string | null;
|
|
55
|
+
cleanPathname: string;
|
|
56
|
+
contentType: string;
|
|
57
|
+
interceptionContext: string | null;
|
|
58
|
+
isRscRequest: boolean;
|
|
59
|
+
middlewareContext: AppRscMiddlewareContext;
|
|
60
|
+
mountedSlotsHeader: string | null;
|
|
61
|
+
request: Request;
|
|
62
|
+
searchParams: URLSearchParams;
|
|
63
|
+
};
|
|
64
|
+
type RenderNotFoundOptions<TRoute> = {
|
|
65
|
+
isRscRequest: boolean;
|
|
66
|
+
matchedParams?: AppPageParams;
|
|
67
|
+
middlewareContext: AppRscMiddlewareContext;
|
|
68
|
+
request: Request;
|
|
69
|
+
route: TRoute | null;
|
|
70
|
+
scriptNonce?: string;
|
|
71
|
+
};
|
|
72
|
+
type RenderPagesFallbackOptions = {
|
|
73
|
+
isRscRequest: boolean;
|
|
74
|
+
middlewareContext: AppRscMiddlewareContext;
|
|
75
|
+
request: Request;
|
|
76
|
+
url: URL;
|
|
77
|
+
};
|
|
78
|
+
type NavigationContextValue = {
|
|
79
|
+
params: AppPageParams;
|
|
80
|
+
pathname: string;
|
|
81
|
+
searchParams: URLSearchParams;
|
|
82
|
+
};
|
|
83
|
+
type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
|
|
84
|
+
basePath: string;
|
|
85
|
+
clearRequestContext: () => void;
|
|
86
|
+
configHeaders: NextHeader[];
|
|
87
|
+
configRedirects: NextRedirect[];
|
|
88
|
+
configRewrites: {
|
|
89
|
+
afterFiles: NextRewrite[];
|
|
90
|
+
beforeFiles: NextRewrite[];
|
|
91
|
+
fallback: NextRewrite[];
|
|
92
|
+
};
|
|
93
|
+
dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;
|
|
94
|
+
dispatchMatchedRouteHandler: (options: DispatchMatchedRouteHandlerOptions<TRoute>) => Promise<Response>;
|
|
95
|
+
ensureInstrumentation?: () => Promise<void>;
|
|
96
|
+
handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | null>;
|
|
97
|
+
handleServerActionRequest: (options: HandleServerActionRequestOptions) => Promise<Response | null>;
|
|
98
|
+
i18nConfig: NextI18nConfig | null;
|
|
99
|
+
isMiddlewareProxy: boolean;
|
|
100
|
+
loadPrerenderPagesRoutes?: () => Promise<unknown>;
|
|
101
|
+
makeThenableParams: MakeThenableParams;
|
|
102
|
+
matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;
|
|
103
|
+
metadataRoutes: MetadataRoutes;
|
|
104
|
+
middlewareModule: MiddlewareModule | null;
|
|
105
|
+
publicFiles: ReadonlySet<string>;
|
|
106
|
+
renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;
|
|
107
|
+
renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;
|
|
108
|
+
rootParamNamesByPattern?: RootParamNamesMap;
|
|
109
|
+
setNavigationContext: (context: NavigationContextValue) => void;
|
|
110
|
+
staticParamsMap: StaticParamsMap;
|
|
111
|
+
trailingSlash: boolean;
|
|
112
|
+
validateDevRequestOrigin?: (request: Request) => Response | null;
|
|
113
|
+
};
|
|
114
|
+
declare function createAppRscHandler<TRoute extends AppRscHandlerRoute>(options: CreateAppRscHandlerOptions<TRoute>): (request: Request, ctx: unknown) => Promise<Response>;
|
|
115
|
+
//#endregion
|
|
116
|
+
export { createAppRscHandler };
|
|
117
|
+
//# sourceMappingURL=app-rsc-handler.d.ts.map
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
|
+
import { hasBasePath } from "../utils/base-path.js";
|
|
3
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
|
+
import { isExternalUrl, matchRedirect, matchRewrite, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
5
|
+
import { notFoundResponse } from "./http-error-responses.js";
|
|
6
|
+
import { cloneRequestWithHeaders, filterInternalHeaders, normalizeTrailingSlash, resolvePublicFileRoute, validateImageUrl } from "./request-pipeline.js";
|
|
7
|
+
import { headersContextFromRequest } from "../shims/headers.js";
|
|
8
|
+
import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
9
|
+
import { createRscRedirectLocation, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
10
|
+
import { getScriptNonceFromHeaderSources } from "./csp.js";
|
|
11
|
+
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
12
|
+
import { applyAppMiddleware } from "./app-middleware.js";
|
|
13
|
+
import "./app-page-response.js";
|
|
14
|
+
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
15
|
+
import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
|
|
16
|
+
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
17
|
+
import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
|
|
18
|
+
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
19
|
+
import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
|
|
20
|
+
import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
|
|
21
|
+
import { handleMetadataRouteRequest } from "./metadata-route-response.js";
|
|
22
|
+
import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
|
|
23
|
+
//#region src/server/app-rsc-handler.ts
|
|
24
|
+
function hasProperty(value, key) {
|
|
25
|
+
return key in value;
|
|
26
|
+
}
|
|
27
|
+
function isExecutionContextLike(value) {
|
|
28
|
+
if (!value || typeof value !== "object") return false;
|
|
29
|
+
return hasProperty(value, "waitUntil") && typeof value.waitUntil === "function";
|
|
30
|
+
}
|
|
31
|
+
function redirectDestinationWithBasePath(destination, basePath) {
|
|
32
|
+
if (!basePath || isExternalUrl(destination) || hasBasePath(destination, basePath)) return destination;
|
|
33
|
+
return basePath + destination;
|
|
34
|
+
}
|
|
35
|
+
async function applyRewrite(options, cleanPathname) {
|
|
36
|
+
if (!options.rewrites.length) return null;
|
|
37
|
+
const rewritten = matchRewrite(cleanPathname, options.rewrites, options.requestContext);
|
|
38
|
+
if (!rewritten) return null;
|
|
39
|
+
if (isExternalUrl(rewritten)) {
|
|
40
|
+
options.clearRequestContext();
|
|
41
|
+
return proxyExternalRequest(options.request, rewritten);
|
|
42
|
+
}
|
|
43
|
+
return rewritten;
|
|
44
|
+
}
|
|
45
|
+
async function handleAppRscRequest(options, request, preMiddlewareRequestContext) {
|
|
46
|
+
const handlerStart = process.env.NODE_ENV !== "production" ? performance.now() : 0;
|
|
47
|
+
if (process.env.NODE_ENV !== "production") {
|
|
48
|
+
const originBlock = options.validateDevRequestOrigin?.(request);
|
|
49
|
+
if (originBlock) return originBlock;
|
|
50
|
+
}
|
|
51
|
+
const normalized = normalizeRscRequest(request, options.basePath);
|
|
52
|
+
if (normalized instanceof Response) return normalized;
|
|
53
|
+
const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader } = normalized;
|
|
54
|
+
let { pathname, cleanPathname } = normalized;
|
|
55
|
+
const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {
|
|
56
|
+
isPrerenderEnabled() {
|
|
57
|
+
return process.env.VINEXT_PRERENDER === "1";
|
|
58
|
+
},
|
|
59
|
+
loadPagesRoutes: options.loadPrerenderPagesRoutes,
|
|
60
|
+
pathname,
|
|
61
|
+
rootParamNamesByPattern: options.rootParamNamesByPattern,
|
|
62
|
+
staticParamsMap: options.staticParamsMap
|
|
63
|
+
});
|
|
64
|
+
if (prerenderEndpointResponse) return prerenderEndpointResponse;
|
|
65
|
+
const trailingSlashRedirect = normalizeTrailingSlash(pathname, options.basePath, options.trailingSlash, url.search);
|
|
66
|
+
if (trailingSlashRedirect) return trailingSlashRedirect;
|
|
67
|
+
const redirect = matchRedirect(stripRscSuffix(pathname), options.configRedirects, preMiddlewareRequestContext);
|
|
68
|
+
if (redirect) {
|
|
69
|
+
const destination = sanitizeDestination(redirectDestinationWithBasePath(redirect.destination, options.basePath));
|
|
70
|
+
const location = isRscRequest && request.headers.get("RSC") === "1" ? await createRscRedirectLocation(destination, request) : destination;
|
|
71
|
+
return new Response(null, {
|
|
72
|
+
status: redirect.permanent ? 308 : 307,
|
|
73
|
+
headers: { Location: location }
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const rscCacheBustingRedirect = await resolveInvalidRscCacheBustingRequest({
|
|
77
|
+
isRscRequest,
|
|
78
|
+
request
|
|
79
|
+
});
|
|
80
|
+
if (rscCacheBustingRedirect) return rscCacheBustingRedirect;
|
|
81
|
+
const middlewareContext = {
|
|
82
|
+
headers: null,
|
|
83
|
+
requestHeaders: null,
|
|
84
|
+
status: null
|
|
85
|
+
};
|
|
86
|
+
if (options.middlewareModule) {
|
|
87
|
+
const middlewareResult = await applyAppMiddleware({
|
|
88
|
+
basePath: options.basePath,
|
|
89
|
+
cleanPathname,
|
|
90
|
+
context: middlewareContext,
|
|
91
|
+
i18nConfig: options.i18nConfig,
|
|
92
|
+
isProxy: options.isMiddlewareProxy,
|
|
93
|
+
module: options.middlewareModule,
|
|
94
|
+
request
|
|
95
|
+
});
|
|
96
|
+
if (middlewareResult.kind === "response") return middlewareResult.response;
|
|
97
|
+
cleanPathname = middlewareResult.cleanPathname;
|
|
98
|
+
if (middlewareResult.search !== null) url.search = middlewareResult.search;
|
|
99
|
+
}
|
|
100
|
+
const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareContext.headers);
|
|
101
|
+
const postMiddlewareRequestContext = buildPostMwRequestContext(request);
|
|
102
|
+
const beforeFilesRewrite = await applyRewrite({
|
|
103
|
+
clearRequestContext: options.clearRequestContext,
|
|
104
|
+
request,
|
|
105
|
+
requestContext: postMiddlewareRequestContext,
|
|
106
|
+
rewrites: options.configRewrites.beforeFiles
|
|
107
|
+
}, cleanPathname);
|
|
108
|
+
if (beforeFilesRewrite instanceof Response) return beforeFilesRewrite;
|
|
109
|
+
if (beforeFilesRewrite) cleanPathname = beforeFilesRewrite;
|
|
110
|
+
if (cleanPathname === "/_vinext/image") {
|
|
111
|
+
const imageUrlResult = validateImageUrl(url.searchParams.get("url"), request.url);
|
|
112
|
+
if (imageUrlResult instanceof Response) return imageUrlResult;
|
|
113
|
+
return Response.redirect(new URL(imageUrlResult, url.origin).href, 302);
|
|
114
|
+
}
|
|
115
|
+
const metadataRouteResponse = await handleMetadataRouteRequest({
|
|
116
|
+
metadataRoutes: options.metadataRoutes,
|
|
117
|
+
cleanPathname,
|
|
118
|
+
makeThenableParams: options.makeThenableParams
|
|
119
|
+
});
|
|
120
|
+
if (metadataRouteResponse) return metadataRouteResponse;
|
|
121
|
+
const publicFileResponse = resolvePublicFileRoute({
|
|
122
|
+
cleanPathname,
|
|
123
|
+
middlewareContext,
|
|
124
|
+
pathname,
|
|
125
|
+
publicFiles: options.publicFiles,
|
|
126
|
+
request
|
|
127
|
+
});
|
|
128
|
+
if (publicFileResponse) {
|
|
129
|
+
options.clearRequestContext();
|
|
130
|
+
return publicFileResponse;
|
|
131
|
+
}
|
|
132
|
+
if (isRscRequest) stripRscCacheBustingSearchParam(url);
|
|
133
|
+
options.setNavigationContext({
|
|
134
|
+
pathname: cleanPathname,
|
|
135
|
+
searchParams: url.searchParams,
|
|
136
|
+
params: {}
|
|
137
|
+
});
|
|
138
|
+
const actionId = request.headers.get("x-rsc-action") ?? request.headers.get("next-action");
|
|
139
|
+
const contentType = request.headers.get("content-type") || "";
|
|
140
|
+
const progressiveActionResponse = await options.handleProgressiveActionRequest({
|
|
141
|
+
actionId,
|
|
142
|
+
cleanPathname,
|
|
143
|
+
contentType,
|
|
144
|
+
middlewareContext,
|
|
145
|
+
request
|
|
146
|
+
});
|
|
147
|
+
if (progressiveActionResponse) return progressiveActionResponse;
|
|
148
|
+
const serverActionResponse = await options.handleServerActionRequest({
|
|
149
|
+
actionId,
|
|
150
|
+
cleanPathname,
|
|
151
|
+
contentType,
|
|
152
|
+
interceptionContext: interceptionContextHeader,
|
|
153
|
+
isRscRequest,
|
|
154
|
+
middlewareContext,
|
|
155
|
+
mountedSlotsHeader,
|
|
156
|
+
request,
|
|
157
|
+
searchParams: url.searchParams
|
|
158
|
+
});
|
|
159
|
+
if (serverActionResponse) return serverActionResponse;
|
|
160
|
+
const afterFilesRewrite = await applyRewrite({
|
|
161
|
+
clearRequestContext: options.clearRequestContext,
|
|
162
|
+
request,
|
|
163
|
+
requestContext: postMiddlewareRequestContext,
|
|
164
|
+
rewrites: options.configRewrites.afterFiles
|
|
165
|
+
}, cleanPathname);
|
|
166
|
+
if (afterFilesRewrite instanceof Response) return afterFilesRewrite;
|
|
167
|
+
if (afterFilesRewrite) cleanPathname = afterFilesRewrite;
|
|
168
|
+
let match = options.matchRoute(cleanPathname);
|
|
169
|
+
if (!match) {
|
|
170
|
+
const fallbackRewrite = await applyRewrite({
|
|
171
|
+
clearRequestContext: options.clearRequestContext,
|
|
172
|
+
request,
|
|
173
|
+
requestContext: postMiddlewareRequestContext,
|
|
174
|
+
rewrites: options.configRewrites.fallback
|
|
175
|
+
}, cleanPathname);
|
|
176
|
+
if (fallbackRewrite instanceof Response) return fallbackRewrite;
|
|
177
|
+
if (fallbackRewrite) {
|
|
178
|
+
cleanPathname = fallbackRewrite;
|
|
179
|
+
match = options.matchRoute(cleanPathname);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (!match) {
|
|
183
|
+
const pagesFallbackResponse = await options.renderPagesFallback?.({
|
|
184
|
+
isRscRequest,
|
|
185
|
+
middlewareContext,
|
|
186
|
+
request,
|
|
187
|
+
url
|
|
188
|
+
});
|
|
189
|
+
if (pagesFallbackResponse) {
|
|
190
|
+
options.clearRequestContext();
|
|
191
|
+
return pagesFallbackResponse;
|
|
192
|
+
}
|
|
193
|
+
const renderedNotFoundResponse = await options.renderNotFound({
|
|
194
|
+
isRscRequest,
|
|
195
|
+
middlewareContext,
|
|
196
|
+
request,
|
|
197
|
+
route: null,
|
|
198
|
+
scriptNonce
|
|
199
|
+
});
|
|
200
|
+
if (renderedNotFoundResponse) return renderedNotFoundResponse;
|
|
201
|
+
options.clearRequestContext();
|
|
202
|
+
const headers = new Headers();
|
|
203
|
+
mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
|
|
204
|
+
return notFoundResponse({ headers });
|
|
205
|
+
}
|
|
206
|
+
const { route, params } = match;
|
|
207
|
+
options.setNavigationContext({
|
|
208
|
+
pathname: cleanPathname,
|
|
209
|
+
searchParams: url.searchParams,
|
|
210
|
+
params
|
|
211
|
+
});
|
|
212
|
+
setRootParams(pickRootParams(params, route.rootParamNames));
|
|
213
|
+
if (route.routeHandler) {
|
|
214
|
+
setCurrentFetchSoftTags(buildPageCacheTags(cleanPathname, [], [...route.routeSegments], "route"));
|
|
215
|
+
return options.dispatchMatchedRouteHandler({
|
|
216
|
+
cleanPathname,
|
|
217
|
+
middlewareContext,
|
|
218
|
+
params,
|
|
219
|
+
request,
|
|
220
|
+
route,
|
|
221
|
+
searchParams: url.searchParams
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return options.dispatchMatchedPage({
|
|
225
|
+
cleanPathname,
|
|
226
|
+
handlerStart,
|
|
227
|
+
interceptionContext: interceptionContextHeader,
|
|
228
|
+
isRscRequest,
|
|
229
|
+
middlewareContext,
|
|
230
|
+
mountedSlotsHeader,
|
|
231
|
+
params,
|
|
232
|
+
request,
|
|
233
|
+
route,
|
|
234
|
+
scriptNonce,
|
|
235
|
+
searchParams: url.searchParams
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function createAppRscHandler(options) {
|
|
239
|
+
return async function appRscHandler(rawRequest, ctx) {
|
|
240
|
+
await options.ensureInstrumentation?.();
|
|
241
|
+
const mwCtx = rawRequest.headers.get("x-vinext-mw-ctx");
|
|
242
|
+
const filteredHeaders = filterInternalHeaders(rawRequest.headers);
|
|
243
|
+
if (mwCtx !== null) filteredHeaders.set("x-vinext-mw-ctx", mwCtx);
|
|
244
|
+
const request = cloneRequestWithHeaders(rawRequest, filteredHeaders);
|
|
245
|
+
const executionContext = isExecutionContextLike(ctx) ? ctx : getRequestExecutionContext() ?? null;
|
|
246
|
+
return runWithRequestContext(createRequestContext({
|
|
247
|
+
headersContext: headersContextFromRequest(request),
|
|
248
|
+
executionContext,
|
|
249
|
+
unstableCacheRevalidation: "background"
|
|
250
|
+
}), () => runWithPrerenderWorkUnit(async () => {
|
|
251
|
+
ensureFetchPatch();
|
|
252
|
+
const preMiddlewareRequestContext = requestContextFromRequest(request);
|
|
253
|
+
let response;
|
|
254
|
+
try {
|
|
255
|
+
response = await handleAppRscRequest(options, request, preMiddlewareRequestContext);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (process.env.NODE_ENV !== "production") flattenErrorCauses(error);
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
return finalizeAppRscResponse(response, request, {
|
|
261
|
+
basePath: options.basePath,
|
|
262
|
+
configHeaders: options.configHeaders,
|
|
263
|
+
requestContext: preMiddlewareRequestContext
|
|
264
|
+
});
|
|
265
|
+
}, { route: () => new URL(request.url).pathname }));
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
//#endregion
|
|
269
|
+
export { createAppRscHandler };
|
|
270
|
+
|
|
271
|
+
//# sourceMappingURL=app-rsc-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-rsc-handler.js","names":[],"sources":["../../src/server/app-rsc-handler.ts"],"sourcesContent":["import type {\n NextHeader,\n NextI18nConfig,\n NextRedirect,\n NextRewrite,\n} from \"../config/next-config.js\";\nimport {\n isExternalUrl,\n matchRedirect,\n matchRewrite,\n proxyExternalRequest,\n requestContextFromRequest,\n sanitizeDestination,\n} from \"../config/config-matchers.js\";\nimport { headersContextFromRequest } from \"vinext/shims/headers\";\nimport { ensureFetchPatch, setCurrentFetchSoftTags } from \"vinext/shims/fetch-cache\";\nimport {\n getRequestExecutionContext,\n type ExecutionContextLike,\n} from \"vinext/shims/request-context\";\nimport { pickRootParams, setRootParams } from \"vinext/shims/root-params\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport { flattenErrorCauses } from \"../utils/error-cause.js\";\nimport { hasBasePath } from \"../utils/base-path.js\";\nimport { applyAppMiddleware, type AppMiddlewareContext } from \"./app-middleware.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./app-page-response.js\";\nimport { handleAppPrerenderEndpoint } from \"./app-prerender-endpoints.js\";\nimport {\n createRscRedirectLocation,\n resolveInvalidRscCacheBustingRequest,\n stripRscCacheBustingSearchParam,\n stripRscSuffix,\n} from \"./app-rsc-cache-busting.js\";\nimport { finalizeAppRscResponse } from \"./app-rsc-response-finalizer.js\";\nimport { normalizeRscRequest } from \"./app-rsc-request-normalization.js\";\nimport { notFoundResponse } from \"./http-error-responses.js\";\nimport { getScriptNonceFromHeaderSources } from \"./csp.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { handleMetadataRouteRequest } from \"./metadata-route-response.js\";\nimport type { MiddlewareModule } from \"./middleware-runtime.js\";\nimport { runWithPrerenderWorkUnit } from \"./prerender-work-unit-setup.js\";\nimport { buildPostMwRequestContext } from \"./app-post-middleware-context.js\";\nimport {\n cloneRequestWithHeaders,\n filterInternalHeaders,\n normalizeTrailingSlash,\n resolvePublicFileRoute,\n validateImageUrl,\n} from \"./request-pipeline.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\ntype RequestContext = ReturnType<typeof requestContextFromRequest>;\ntype MetadataRoutes = Parameters<typeof handleMetadataRouteRequest>[0][\"metadataRoutes\"];\ntype MakeThenableParams = Parameters<typeof handleMetadataRouteRequest>[0][\"makeThenableParams\"];\ntype StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1][\"staticParamsMap\"];\ntype RootParamNamesMap = Parameters<\n typeof handleAppPrerenderEndpoint\n>[1][\"rootParamNamesByPattern\"];\n\ntype AppRscMiddlewareContext = AppMiddlewareContext;\n\ntype AppRscHandlerRoute = {\n page?: unknown;\n pattern: string;\n rootParamNames?: readonly string[];\n routeHandler?: unknown;\n routeSegments: readonly string[];\n};\n\ntype AppRscRouteMatch<TRoute> = {\n params: AppPageParams;\n route: TRoute;\n};\n\ntype DispatchMatchedPageOptions<TRoute> = {\n cleanPathname: string;\n handlerStart: number;\n interceptionContext: string | null;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n scriptNonce?: string;\n searchParams: URLSearchParams;\n};\n\ntype DispatchMatchedRouteHandlerOptions<TRoute> = {\n cleanPathname: string;\n middlewareContext: AppRscMiddlewareContext;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n searchParams: URLSearchParams;\n};\n\ntype HandleProgressiveActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n};\n\ntype HandleServerActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n interceptionContext: string | null;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n request: Request;\n searchParams: URLSearchParams;\n};\n\ntype RenderNotFoundOptions<TRoute> = {\n isRscRequest: boolean;\n matchedParams?: AppPageParams;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n route: TRoute | null;\n scriptNonce?: string;\n};\n\ntype RenderPagesFallbackOptions = {\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n url: URL;\n};\n\ntype NavigationContextValue = {\n params: AppPageParams;\n pathname: string;\n searchParams: URLSearchParams;\n};\n\ntype CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {\n basePath: string;\n clearRequestContext: () => void;\n configHeaders: NextHeader[];\n configRedirects: NextRedirect[];\n configRewrites: {\n afterFiles: NextRewrite[];\n beforeFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;\n dispatchMatchedRouteHandler: (\n options: DispatchMatchedRouteHandlerOptions<TRoute>,\n ) => Promise<Response>;\n ensureInstrumentation?: () => Promise<void>;\n handleProgressiveActionRequest: (\n options: HandleProgressiveActionRequestOptions,\n ) => Promise<Response | null>;\n handleServerActionRequest: (\n options: HandleServerActionRequestOptions,\n ) => Promise<Response | null>;\n i18nConfig: NextI18nConfig | null;\n isMiddlewareProxy: boolean;\n loadPrerenderPagesRoutes?: () => Promise<unknown>;\n makeThenableParams: MakeThenableParams;\n matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;\n metadataRoutes: MetadataRoutes;\n middlewareModule: MiddlewareModule | null;\n publicFiles: ReadonlySet<string>;\n renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;\n renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;\n rootParamNamesByPattern?: RootParamNamesMap;\n setNavigationContext: (context: NavigationContextValue) => void;\n staticParamsMap: StaticParamsMap;\n trailingSlash: boolean;\n validateDevRequestOrigin?: (request: Request) => Response | null;\n};\n\nfunction hasProperty<TKey extends PropertyKey>(\n value: object,\n key: TKey,\n): value is object & Record<TKey, unknown> {\n return key in value;\n}\n\nfunction isExecutionContextLike(value: unknown): value is ExecutionContextLike {\n if (!value || typeof value !== \"object\") return false;\n return hasProperty(value, \"waitUntil\") && typeof value.waitUntil === \"function\";\n}\n\nfunction redirectDestinationWithBasePath(destination: string, basePath: string): string {\n if (!basePath || isExternalUrl(destination) || hasBasePath(destination, basePath)) {\n return destination;\n }\n return basePath + destination;\n}\n\nasync function applyRewrite(\n options: {\n clearRequestContext: () => void;\n request: Request;\n requestContext: RequestContext;\n rewrites: NextRewrite[];\n },\n cleanPathname: string,\n): Promise<Response | string | null> {\n if (!options.rewrites.length) return null;\n\n const rewritten = matchRewrite(cleanPathname, options.rewrites, options.requestContext);\n if (!rewritten) return null;\n\n if (isExternalUrl(rewritten)) {\n options.clearRequestContext();\n return proxyExternalRequest(options.request, rewritten);\n }\n\n return rewritten;\n}\n\nasync function handleAppRscRequest<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n request: Request,\n preMiddlewareRequestContext: RequestContext,\n): Promise<Response> {\n const handlerStart = process.env.NODE_ENV !== \"production\" ? performance.now() : 0;\n\n if (process.env.NODE_ENV !== \"production\") {\n const originBlock = options.validateDevRequestOrigin?.(request);\n if (originBlock) return originBlock;\n }\n\n const normalized = normalizeRscRequest(request, options.basePath);\n if (normalized instanceof Response) return normalized;\n\n const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader } = normalized;\n let { pathname, cleanPathname } = normalized;\n\n const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {\n isPrerenderEnabled() {\n return process.env.VINEXT_PRERENDER === \"1\";\n },\n loadPagesRoutes: options.loadPrerenderPagesRoutes,\n pathname,\n rootParamNamesByPattern: options.rootParamNamesByPattern,\n staticParamsMap: options.staticParamsMap,\n });\n if (prerenderEndpointResponse) return prerenderEndpointResponse;\n\n const trailingSlashRedirect = normalizeTrailingSlash(\n pathname,\n options.basePath,\n options.trailingSlash,\n url.search,\n );\n if (trailingSlashRedirect) return trailingSlashRedirect;\n\n const redirectPathname = stripRscSuffix(pathname);\n const redirect = matchRedirect(\n redirectPathname,\n options.configRedirects,\n preMiddlewareRequestContext,\n );\n if (redirect) {\n const destination = sanitizeDestination(\n redirectDestinationWithBasePath(redirect.destination, options.basePath),\n );\n const location =\n isRscRequest && request.headers.get(\"RSC\") === \"1\"\n ? await createRscRedirectLocation(destination, request)\n : destination;\n return new Response(null, {\n status: redirect.permanent ? 308 : 307,\n headers: { Location: location },\n });\n }\n\n const rscCacheBustingRedirect = await resolveInvalidRscCacheBustingRequest({\n isRscRequest,\n request,\n });\n if (rscCacheBustingRedirect) return rscCacheBustingRedirect;\n\n const middlewareContext: AppRscMiddlewareContext = {\n headers: null,\n requestHeaders: null,\n status: null,\n };\n\n if (options.middlewareModule) {\n const middlewareResult = await applyAppMiddleware({\n basePath: options.basePath,\n cleanPathname,\n context: middlewareContext,\n i18nConfig: options.i18nConfig,\n isProxy: options.isMiddlewareProxy,\n module: options.middlewareModule,\n request,\n });\n if (middlewareResult.kind === \"response\") return middlewareResult.response;\n\n cleanPathname = middlewareResult.cleanPathname;\n if (middlewareResult.search !== null) {\n url.search = middlewareResult.search;\n }\n }\n\n const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareContext.headers);\n const postMiddlewareRequestContext = buildPostMwRequestContext(request);\n\n const beforeFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.beforeFiles,\n },\n cleanPathname,\n );\n if (beforeFilesRewrite instanceof Response) return beforeFilesRewrite;\n if (beforeFilesRewrite) cleanPathname = beforeFilesRewrite;\n\n if (cleanPathname === \"/_vinext/image\") {\n const imageUrlResult = validateImageUrl(url.searchParams.get(\"url\"), request.url);\n if (imageUrlResult instanceof Response) return imageUrlResult;\n return Response.redirect(new URL(imageUrlResult, url.origin).href, 302);\n }\n\n const metadataRouteResponse = await handleMetadataRouteRequest({\n metadataRoutes: options.metadataRoutes,\n cleanPathname,\n makeThenableParams: options.makeThenableParams,\n });\n if (metadataRouteResponse) return metadataRouteResponse;\n\n const publicFileResponse = resolvePublicFileRoute({\n cleanPathname,\n middlewareContext,\n pathname,\n publicFiles: options.publicFiles,\n request,\n });\n if (publicFileResponse) {\n options.clearRequestContext();\n return publicFileResponse;\n }\n\n if (isRscRequest) {\n stripRscCacheBustingSearchParam(url);\n }\n\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params: {},\n });\n\n const actionId = request.headers.get(\"x-rsc-action\") ?? request.headers.get(\"next-action\");\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n const progressiveActionResponse = await options.handleProgressiveActionRequest({\n actionId,\n cleanPathname,\n contentType,\n middlewareContext,\n request,\n });\n if (progressiveActionResponse) return progressiveActionResponse;\n\n const serverActionResponse = await options.handleServerActionRequest({\n actionId,\n cleanPathname,\n contentType,\n interceptionContext: interceptionContextHeader,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n request,\n searchParams: url.searchParams,\n });\n if (serverActionResponse) return serverActionResponse;\n\n const afterFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.afterFiles,\n },\n cleanPathname,\n );\n if (afterFilesRewrite instanceof Response) return afterFilesRewrite;\n if (afterFilesRewrite) cleanPathname = afterFilesRewrite;\n\n let match = options.matchRoute(cleanPathname);\n if (!match) {\n const fallbackRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.fallback,\n },\n cleanPathname,\n );\n if (fallbackRewrite instanceof Response) return fallbackRewrite;\n if (fallbackRewrite) {\n cleanPathname = fallbackRewrite;\n match = options.matchRoute(cleanPathname);\n }\n }\n\n if (!match) {\n const pagesFallbackResponse = await options.renderPagesFallback?.({\n isRscRequest,\n middlewareContext,\n request,\n url,\n });\n if (pagesFallbackResponse) {\n options.clearRequestContext();\n return pagesFallbackResponse;\n }\n\n const renderedNotFoundResponse = await options.renderNotFound({\n isRscRequest,\n middlewareContext,\n request,\n route: null,\n scriptNonce,\n });\n if (renderedNotFoundResponse) return renderedNotFoundResponse;\n\n options.clearRequestContext();\n const headers = new Headers();\n mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);\n return notFoundResponse({ headers });\n }\n\n const { route, params } = match;\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params,\n });\n setRootParams(pickRootParams(params, route.rootParamNames));\n\n if (route.routeHandler) {\n setCurrentFetchSoftTags(\n buildPageCacheTags(cleanPathname, [], [...route.routeSegments], \"route\"),\n );\n return options.dispatchMatchedRouteHandler({\n cleanPathname,\n middlewareContext,\n params,\n request,\n route,\n searchParams: url.searchParams,\n });\n }\n\n return options.dispatchMatchedPage({\n cleanPathname,\n handlerStart,\n interceptionContext: interceptionContextHeader,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n params,\n request,\n route,\n scriptNonce,\n searchParams: url.searchParams,\n });\n}\n\nexport function createAppRscHandler<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n): (request: Request, ctx: unknown) => Promise<Response> {\n return async function appRscHandler(rawRequest, ctx) {\n await options.ensureInstrumentation?.();\n\n // Strip forged internal headers at the App Router request boundary.\n // Must happen BEFORE headersContextFromRequest() and\n // requestContextFromRequest() so the captured context never contains\n // attacker-controlled internal headers. This is the correct boundary\n // for pure App Router requests; in hybrid app+pages mode the connect\n // handler already filtered headers upstream and x-vinext-mw-ctx\n // (not in INTERNAL_HEADERS) carries the forwarded middleware context.\n // srvx's NodeRequestHeaders reads from rawHeaders for iteration but falls\n // back to req.headers for .get() / .has(). In the dev server we add\n // x-vinext-mw-ctx to req.headers after the Request is built, so it is\n // visible to .get() but lost when filterInternalHeaders iterates. Read it\n // BEFORE iterating so applyForwardedMiddlewareContext can skip middleware.\n const mwCtx = rawRequest.headers.get(\"x-vinext-mw-ctx\");\n const filteredHeaders = filterInternalHeaders(rawRequest.headers);\n if (mwCtx !== null) {\n filteredHeaders.set(\"x-vinext-mw-ctx\", mwCtx);\n }\n const request = cloneRequestWithHeaders(rawRequest, filteredHeaders);\n\n const executionContext = isExecutionContextLike(ctx)\n ? ctx\n : (getRequestExecutionContext() ?? null);\n const headersContext = headersContextFromRequest(request);\n const requestContext = createRequestContext({\n headersContext,\n executionContext,\n unstableCacheRevalidation: \"background\",\n });\n\n return runWithRequestContext(requestContext, () =>\n runWithPrerenderWorkUnit(\n async () => {\n ensureFetchPatch();\n const preMiddlewareRequestContext = requestContextFromRequest(request);\n let response: Response;\n\n try {\n response = await handleAppRscRequest(options, request, preMiddlewareRequestContext);\n } catch (error) {\n if (process.env.NODE_ENV !== \"production\") {\n flattenErrorCauses(error);\n }\n throw error;\n }\n\n return finalizeAppRscResponse(response, request, {\n basePath: options.basePath,\n configHeaders: options.configHeaders,\n requestContext: preMiddlewareRequestContext,\n });\n },\n { route: () => new URL(request.url).pathname },\n ),\n );\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
2
|
+
|
|
3
|
+
//#region src/server/app-rsc-request-normalization.d.ts
|
|
4
|
+
type NormalizedRscRequest = {
|
|
5
|
+
/** Parsed URL. Callers may mutate `url.search` after middleware runs. */url: URL; /** Normalized pathname with basePath stripped. Used for all internal routing. */
|
|
6
|
+
pathname: string; /** Pathname with `.rsc` suffix removed. Used for route matching and navigation context. */
|
|
7
|
+
cleanPathname: string; /** True when the request targets a canonical `.rsc` payload URL. */
|
|
8
|
+
isRscRequest: boolean; /** Sanitized X-Vinext-Interception-Context header (null bytes stripped). null when absent. */
|
|
9
|
+
interceptionContextHeader: string | null; /** Normalized x-vinext-mounted-slots header (deduplicated, sorted). null when absent or blank. */
|
|
10
|
+
mountedSlotsHeader: string | null;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Normalize an App Router RSC request.
|
|
14
|
+
*
|
|
15
|
+
* Performs all security-sensitive and compatibility-sensitive preprocessing before
|
|
16
|
+
* route matching. The ordering of steps is security-critical — changing it introduces
|
|
17
|
+
* vulnerabilities:
|
|
18
|
+
*
|
|
19
|
+
* 1. Parse URL
|
|
20
|
+
* 2. Protocol-relative URL guard — on the raw pathname, BEFORE normalizePath collapses
|
|
21
|
+
* `//` to `/`. If the guard ran after normalization, `//evil.com` → `/evil.com`
|
|
22
|
+
* would bypass the check and reach the trailing-slash redirector, which echoes the
|
|
23
|
+
* path into a `Location` header that browsers interpret as protocol-relative.
|
|
24
|
+
* 3. Strict percent-decode each segment — throws on malformed sequences (→ 400). Must
|
|
25
|
+
* run before basePath check so %2F-encoded slashes cannot create fake basePath prefixes.
|
|
26
|
+
* 4. Collapse double-slashes, resolve `.` and `..` segments (normalizePath)
|
|
27
|
+
* 5. basePath check + strip — 404 when pathname lacks the basePath prefix.
|
|
28
|
+
* `/__vinext/` bypasses this for internal prerender endpoints.
|
|
29
|
+
* 6. RSC detection: `.rsc` suffix only. RSC headers do not select payload
|
|
30
|
+
* rendering at the canonical HTML URL, so caches that ignore Vary cannot
|
|
31
|
+
* store Flight responses under HTML URLs.
|
|
32
|
+
* 7. cleanPathname — pathname with `.rsc` suffix stripped
|
|
33
|
+
* 8. Sanitize X-Vinext-Interception-Context — strip null bytes (header injection)
|
|
34
|
+
* 9. Normalize x-vinext-mounted-slots — dedup and sort for canonical cache keys
|
|
35
|
+
*
|
|
36
|
+
* @returns A 400 or 404 Response for invalid or out-of-scope inputs,
|
|
37
|
+
* or a NormalizedRscRequest for valid requests.
|
|
38
|
+
*/
|
|
39
|
+
declare function normalizeRscRequest(request: Request, basePath: string): Response | NormalizedRscRequest;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { NormalizedRscRequest, normalizeMountedSlotsHeader, normalizeRscRequest };
|
|
42
|
+
//# sourceMappingURL=app-rsc-request-normalization.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
2
|
+
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
3
|
+
import { normalizePath } from "./normalize-path.js";
|
|
4
|
+
import { badRequestResponse, notFoundResponse } from "./http-error-responses.js";
|
|
5
|
+
import { guardProtocolRelativeUrl } from "./request-pipeline.js";
|
|
6
|
+
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
7
|
+
import { stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
8
|
+
//#region src/server/app-rsc-request-normalization.ts
|
|
9
|
+
/**
|
|
10
|
+
* Normalize an App Router RSC request.
|
|
11
|
+
*
|
|
12
|
+
* Performs all security-sensitive and compatibility-sensitive preprocessing before
|
|
13
|
+
* route matching. The ordering of steps is security-critical — changing it introduces
|
|
14
|
+
* vulnerabilities:
|
|
15
|
+
*
|
|
16
|
+
* 1. Parse URL
|
|
17
|
+
* 2. Protocol-relative URL guard — on the raw pathname, BEFORE normalizePath collapses
|
|
18
|
+
* `//` to `/`. If the guard ran after normalization, `//evil.com` → `/evil.com`
|
|
19
|
+
* would bypass the check and reach the trailing-slash redirector, which echoes the
|
|
20
|
+
* path into a `Location` header that browsers interpret as protocol-relative.
|
|
21
|
+
* 3. Strict percent-decode each segment — throws on malformed sequences (→ 400). Must
|
|
22
|
+
* run before basePath check so %2F-encoded slashes cannot create fake basePath prefixes.
|
|
23
|
+
* 4. Collapse double-slashes, resolve `.` and `..` segments (normalizePath)
|
|
24
|
+
* 5. basePath check + strip — 404 when pathname lacks the basePath prefix.
|
|
25
|
+
* `/__vinext/` bypasses this for internal prerender endpoints.
|
|
26
|
+
* 6. RSC detection: `.rsc` suffix only. RSC headers do not select payload
|
|
27
|
+
* rendering at the canonical HTML URL, so caches that ignore Vary cannot
|
|
28
|
+
* store Flight responses under HTML URLs.
|
|
29
|
+
* 7. cleanPathname — pathname with `.rsc` suffix stripped
|
|
30
|
+
* 8. Sanitize X-Vinext-Interception-Context — strip null bytes (header injection)
|
|
31
|
+
* 9. Normalize x-vinext-mounted-slots — dedup and sort for canonical cache keys
|
|
32
|
+
*
|
|
33
|
+
* @returns A 400 or 404 Response for invalid or out-of-scope inputs,
|
|
34
|
+
* or a NormalizedRscRequest for valid requests.
|
|
35
|
+
*/
|
|
36
|
+
function normalizeRscRequest(request, basePath) {
|
|
37
|
+
const url = new URL(request.url);
|
|
38
|
+
const protoGuard = guardProtocolRelativeUrl(url.pathname);
|
|
39
|
+
if (protoGuard) return protoGuard;
|
|
40
|
+
let decoded;
|
|
41
|
+
try {
|
|
42
|
+
decoded = normalizePathnameForRouteMatchStrict(url.pathname);
|
|
43
|
+
} catch {
|
|
44
|
+
return badRequestResponse();
|
|
45
|
+
}
|
|
46
|
+
let pathname = normalizePath(decoded);
|
|
47
|
+
if (basePath) {
|
|
48
|
+
if (!hasBasePath(pathname, basePath) && !pathname.startsWith("/__vinext/")) return notFoundResponse();
|
|
49
|
+
pathname = stripBasePath(pathname, basePath);
|
|
50
|
+
}
|
|
51
|
+
const isRscRequest = pathname.endsWith(".rsc");
|
|
52
|
+
const cleanPathname = stripRscSuffix(pathname);
|
|
53
|
+
const interceptionContextHeader = request.headers.get("X-Vinext-Interception-Context")?.replaceAll("\0", "") || null;
|
|
54
|
+
const mountedSlotsHeader = normalizeMountedSlotsHeader(request.headers.get("x-vinext-mounted-slots"));
|
|
55
|
+
return {
|
|
56
|
+
url,
|
|
57
|
+
pathname,
|
|
58
|
+
cleanPathname,
|
|
59
|
+
isRscRequest,
|
|
60
|
+
interceptionContextHeader,
|
|
61
|
+
mountedSlotsHeader
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { normalizeMountedSlotsHeader, normalizeRscRequest };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=app-rsc-request-normalization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-rsc-request-normalization.js","names":[],"sources":["../../src/server/app-rsc-request-normalization.ts"],"sourcesContent":["import { normalizePath } from \"./normalize-path.js\";\nimport { normalizePathnameForRouteMatchStrict } from \"../routing/utils.js\";\nimport { guardProtocolRelativeUrl } from \"./request-pipeline.js\";\nimport { hasBasePath, stripBasePath } from \"../utils/base-path.js\";\nimport { normalizeMountedSlotsHeader } from \"./app-mounted-slots-header.js\";\nimport { stripRscSuffix } from \"./app-rsc-cache-busting.js\";\nimport { badRequestResponse, notFoundResponse } from \"./http-error-responses.js\";\n\nexport { normalizeMountedSlotsHeader } from \"./app-mounted-slots-header.js\";\n\nexport type NormalizedRscRequest = {\n /** Parsed URL. Callers may mutate `url.search` after middleware runs. */\n url: URL;\n /** Normalized pathname with basePath stripped. Used for all internal routing. */\n pathname: string;\n /** Pathname with `.rsc` suffix removed. Used for route matching and navigation context. */\n cleanPathname: string;\n /** True when the request targets a canonical `.rsc` payload URL. */\n isRscRequest: boolean;\n /** Sanitized X-Vinext-Interception-Context header (null bytes stripped). null when absent. */\n interceptionContextHeader: string | null;\n /** Normalized x-vinext-mounted-slots header (deduplicated, sorted). null when absent or blank. */\n mountedSlotsHeader: string | null;\n};\n\n/**\n * Normalize an App Router RSC request.\n *\n * Performs all security-sensitive and compatibility-sensitive preprocessing before\n * route matching. The ordering of steps is security-critical — changing it introduces\n * vulnerabilities:\n *\n * 1. Parse URL\n * 2. Protocol-relative URL guard — on the raw pathname, BEFORE normalizePath collapses\n * `//` to `/`. If the guard ran after normalization, `//evil.com` → `/evil.com`\n * would bypass the check and reach the trailing-slash redirector, which echoes the\n * path into a `Location` header that browsers interpret as protocol-relative.\n * 3. Strict percent-decode each segment — throws on malformed sequences (→ 400). Must\n * run before basePath check so %2F-encoded slashes cannot create fake basePath prefixes.\n * 4. Collapse double-slashes, resolve `.` and `..` segments (normalizePath)\n * 5. basePath check + strip — 404 when pathname lacks the basePath prefix.\n * `/__vinext/` bypasses this for internal prerender endpoints.\n * 6. RSC detection: `.rsc` suffix only. RSC headers do not select payload\n * rendering at the canonical HTML URL, so caches that ignore Vary cannot\n * store Flight responses under HTML URLs.\n * 7. cleanPathname — pathname with `.rsc` suffix stripped\n * 8. Sanitize X-Vinext-Interception-Context — strip null bytes (header injection)\n * 9. Normalize x-vinext-mounted-slots — dedup and sort for canonical cache keys\n *\n * @returns A 400 or 404 Response for invalid or out-of-scope inputs,\n * or a NormalizedRscRequest for valid requests.\n */\nexport function normalizeRscRequest(\n request: Request,\n basePath: string,\n): Response | NormalizedRscRequest {\n const url = new URL(request.url);\n\n // Step 2: Guard against protocol-relative open redirects on the raw pathname.\n // normalizePath (step 4) would collapse //evil.com to /evil.com, causing the\n // guard to miss it. Raw pathname must be checked first.\n const protoGuard = guardProtocolRelativeUrl(url.pathname);\n if (protoGuard) return protoGuard;\n\n // Step 3: Strict segment-wise percent-decode. Preserves encoded path delimiters\n // (%2F stays %2F) to prevent encoded slashes from acting as path separators.\n // Throws on malformed sequences like %GG — caller must return 400.\n let decoded: string;\n try {\n decoded = normalizePathnameForRouteMatchStrict(url.pathname);\n } catch {\n return badRequestResponse();\n }\n\n // Step 4: Collapse double-slashes and resolve . / .. segments.\n let pathname = normalizePath(decoded);\n\n // Step 5: basePath check and strip.\n // Skipped when basePath is empty (no basePath configured).\n // /__vinext/ prefix bypasses the check for internal prerender endpoints\n // that must be reachable regardless of basePath configuration.\n if (basePath) {\n if (!hasBasePath(pathname, basePath) && !pathname.startsWith(\"/__vinext/\")) {\n return notFoundResponse();\n }\n pathname = stripBasePath(pathname, basePath);\n }\n\n // Steps 6-7: RSC detection and cleanPathname.\n const isRscRequest = pathname.endsWith(\".rsc\");\n const cleanPathname = stripRscSuffix(pathname);\n\n // Step 8: Sanitize X-Vinext-Interception-Context.\n // Null bytes in header values can be used for injection in some HTTP stacks.\n const interceptionContextHeader =\n request.headers.get(\"X-Vinext-Interception-Context\")?.replaceAll(\"\\0\", \"\") || null;\n\n // Step 9: Normalize mounted-slots header for canonical cache keying.\n const mountedSlotsHeader = normalizeMountedSlotsHeader(\n request.headers.get(\"x-vinext-mounted-slots\"),\n );\n\n return {\n url,\n pathname,\n cleanPathname,\n isRscRequest,\n interceptionContextHeader,\n mountedSlotsHeader,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgB,oBACd,SACA,UACiC;CACjC,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAKhC,MAAM,aAAa,yBAAyB,IAAI,SAAS;AACzD,KAAI,WAAY,QAAO;CAKvB,IAAI;AACJ,KAAI;AACF,YAAU,qCAAqC,IAAI,SAAS;SACtD;AACN,SAAO,oBAAoB;;CAI7B,IAAI,WAAW,cAAc,QAAQ;AAMrC,KAAI,UAAU;AACZ,MAAI,CAAC,YAAY,UAAU,SAAS,IAAI,CAAC,SAAS,WAAW,aAAa,CACxE,QAAO,kBAAkB;AAE3B,aAAW,cAAc,UAAU,SAAS;;CAI9C,MAAM,eAAe,SAAS,SAAS,OAAO;CAC9C,MAAM,gBAAgB,eAAe,SAAS;CAI9C,MAAM,4BACJ,QAAQ,QAAQ,IAAI,gCAAgC,EAAE,WAAW,MAAM,GAAG,IAAI;CAGhF,MAAM,qBAAqB,4BACzB,QAAQ,QAAQ,IAAI,yBAAyB,CAC9C;AAED,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NextHeader } from "../config/next-config.js";
|
|
2
|
+
import { RequestContext } from "../config/config-matchers.js";
|
|
3
|
+
|
|
4
|
+
//#region src/server/app-rsc-response-finalizer.d.ts
|
|
5
|
+
type FinalizeAppRscResponseOptions = {
|
|
6
|
+
basePath: string;
|
|
7
|
+
configHeaders: NextHeader[];
|
|
8
|
+
/**
|
|
9
|
+
* Original pre-middleware request context.
|
|
10
|
+
* Next.js evaluates config header has/missing conditions against the
|
|
11
|
+
* unmodified incoming request, so callers must pass the snapshot taken
|
|
12
|
+
* before middleware runs.
|
|
13
|
+
*/
|
|
14
|
+
requestContext: RequestContext;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Apply next.config.js response headers to an App Router response.
|
|
18
|
+
*
|
|
19
|
+
* Called once per request in the outer handler() wrapper, after all route
|
|
20
|
+
* handling, so that every response path (page, route handler, server action,
|
|
21
|
+
* metadata, not-found) gets headers applied consistently.
|
|
22
|
+
*
|
|
23
|
+
* Skips 3xx redirect responses. Response.redirect() creates immutable
|
|
24
|
+
* headers that throw on mutation, and Next.js does not apply config headers
|
|
25
|
+
* to redirects regardless.
|
|
26
|
+
*/
|
|
27
|
+
declare function finalizeAppRscResponse(response: Response, request: Request, options: FinalizeAppRscResponseOptions): Response;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { finalizeAppRscResponse };
|
|
30
|
+
//# sourceMappingURL=app-rsc-response-finalizer.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
2
|
+
import { stripBasePath } from "../utils/base-path.js";
|
|
3
|
+
import { normalizePath } from "./normalize-path.js";
|
|
4
|
+
import { applyConfigHeadersToResponse } from "./request-pipeline.js";
|
|
5
|
+
//#region src/server/app-rsc-response-finalizer.ts
|
|
6
|
+
/**
|
|
7
|
+
* Apply next.config.js response headers to an App Router response.
|
|
8
|
+
*
|
|
9
|
+
* Called once per request in the outer handler() wrapper, after all route
|
|
10
|
+
* handling, so that every response path (page, route handler, server action,
|
|
11
|
+
* metadata, not-found) gets headers applied consistently.
|
|
12
|
+
*
|
|
13
|
+
* Skips 3xx redirect responses. Response.redirect() creates immutable
|
|
14
|
+
* headers that throw on mutation, and Next.js does not apply config headers
|
|
15
|
+
* to redirects regardless.
|
|
16
|
+
*/
|
|
17
|
+
function finalizeAppRscResponse(response, request, options) {
|
|
18
|
+
if (response.status >= 300 && response.status < 400) return response;
|
|
19
|
+
if (!options.configHeaders.length) return response;
|
|
20
|
+
const url = new URL(request.url);
|
|
21
|
+
let pathname;
|
|
22
|
+
try {
|
|
23
|
+
pathname = normalizePath(normalizePathnameForRouteMatch(url.pathname));
|
|
24
|
+
} catch {
|
|
25
|
+
pathname = url.pathname;
|
|
26
|
+
}
|
|
27
|
+
pathname = stripBasePath(pathname, options.basePath);
|
|
28
|
+
applyConfigHeadersToResponse(response.headers, {
|
|
29
|
+
configHeaders: options.configHeaders,
|
|
30
|
+
pathname,
|
|
31
|
+
requestContext: options.requestContext
|
|
32
|
+
});
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { finalizeAppRscResponse };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=app-rsc-response-finalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-rsc-response-finalizer.js","names":[],"sources":["../../src/server/app-rsc-response-finalizer.ts"],"sourcesContent":["import type { NextHeader } from \"../config/next-config.js\";\nimport type { RequestContext } from \"../config/config-matchers.js\";\nimport { applyConfigHeadersToResponse } from \"./request-pipeline.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport { normalizePath } from \"./normalize-path.js\";\nimport { normalizePathnameForRouteMatch } from \"../routing/utils.js\";\n\ntype FinalizeAppRscResponseOptions = {\n basePath: string;\n configHeaders: NextHeader[];\n /**\n * Original pre-middleware request context.\n * Next.js evaluates config header has/missing conditions against the\n * unmodified incoming request, so callers must pass the snapshot taken\n * before middleware runs.\n */\n requestContext: RequestContext;\n};\n\n/**\n * Apply next.config.js response headers to an App Router response.\n *\n * Called once per request in the outer handler() wrapper, after all route\n * handling, so that every response path (page, route handler, server action,\n * metadata, not-found) gets headers applied consistently.\n *\n * Skips 3xx redirect responses. Response.redirect() creates immutable\n * headers that throw on mutation, and Next.js does not apply config headers\n * to redirects regardless.\n */\nexport function finalizeAppRscResponse(\n response: Response,\n request: Request,\n options: FinalizeAppRscResponseOptions,\n): Response {\n // 3xx responses: Response.redirect() headers are immutable (throws on write),\n // and Next.js deliberately excludes config headers from redirect responses.\n if (response.status >= 300 && response.status < 400) {\n return response;\n }\n\n if (!options.configHeaders.length) {\n return response;\n }\n\n const url = new URL(request.url);\n let pathname: string;\n try {\n pathname = normalizePath(normalizePathnameForRouteMatch(url.pathname));\n } catch {\n // Malformed percent-encoding. The request reached this point only because\n // normalizePathnameForRouteMatchStrict ran earlier and returned 400 for\n // truly-malformed paths. This catch exists as a safety net for edge cases;\n // keep the historical raw-path fallback rather than crashing the response.\n pathname = url.pathname;\n }\n\n // Config header sources are defined without basePath prefix. Strip basePath\n // at a segment boundary (not a string prefix) so /app2/page with basePath\n // /app is not incorrectly treated as /app with suffix /2/page.\n pathname = stripBasePath(pathname, options.basePath);\n\n applyConfigHeadersToResponse(response.headers, {\n configHeaders: options.configHeaders,\n pathname,\n requestContext: options.requestContext,\n });\n\n return response;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8BA,SAAgB,uBACd,UACA,SACA,SACU;AAGV,KAAI,SAAS,UAAU,OAAO,SAAS,SAAS,IAC9C,QAAO;AAGT,KAAI,CAAC,QAAQ,cAAc,OACzB,QAAO;CAGT,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,IAAI;AACJ,KAAI;AACF,aAAW,cAAc,+BAA+B,IAAI,SAAS,CAAC;SAChE;AAKN,aAAW,IAAI;;AAMjB,YAAW,cAAc,UAAU,QAAQ,SAAS;AAEpD,8BAA6B,SAAS,SAAS;EAC7C,eAAe,QAAQ;EACvB;EACA,gBAAgB,QAAQ;EACzB,CAAC;AAEF,QAAO"}
|