@qzsy/vinext 0.1.7
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/LICENSE +21 -0
- package/README.md +773 -0
- package/dist/build/assets-ignore.d.ts +32 -0
- package/dist/build/assets-ignore.js +48 -0
- package/dist/build/clean-output.d.ts +13 -0
- package/dist/build/clean-output.js +34 -0
- package/dist/build/client-build-config.d.ts +171 -0
- package/dist/build/client-build-config.js +270 -0
- package/dist/build/css-url-assets.d.ts +29 -0
- package/dist/build/css-url-assets.js +213 -0
- package/dist/build/google-fonts/build-url.d.ts +9 -0
- package/dist/build/google-fonts/build-url.js +28 -0
- package/dist/build/google-fonts/fallback-metrics-data.js +14029 -0
- package/dist/build/google-fonts/fallback-metrics.d.ts +12 -0
- package/dist/build/google-fonts/fallback-metrics.js +44 -0
- package/dist/build/google-fonts/find-font-files-in-css.d.ts +16 -0
- package/dist/build/google-fonts/find-font-files-in-css.js +28 -0
- package/dist/build/google-fonts/font-data.js +24983 -0
- package/dist/build/google-fonts/font-metadata.d.ts +16 -0
- package/dist/build/google-fonts/font-metadata.js +5 -0
- package/dist/build/google-fonts/get-axes.d.ts +6 -0
- package/dist/build/google-fonts/get-axes.js +37 -0
- package/dist/build/google-fonts/sort-variants.d.ts +4 -0
- package/dist/build/google-fonts/sort-variants.js +12 -0
- package/dist/build/google-fonts/validate.d.ts +27 -0
- package/dist/build/google-fonts/validate.js +54 -0
- package/dist/build/inline-css.d.ts +6 -0
- package/dist/build/inline-css.js +48 -0
- package/dist/build/layout-classification-types.d.ts +61 -0
- package/dist/build/layout-classification-types.js +1 -0
- package/dist/build/layout-classification.d.ts +59 -0
- package/dist/build/layout-classification.js +98 -0
- package/dist/build/next-client-runtime-manifests.d.ts +14 -0
- package/dist/build/next-client-runtime-manifests.js +39 -0
- package/dist/build/nitro-route-rules.d.ts +49 -0
- package/dist/build/nitro-route-rules.js +79 -0
- package/dist/build/precompress.d.ts +27 -0
- package/dist/build/precompress.js +110 -0
- package/dist/build/prerender.d.ts +209 -0
- package/dist/build/prerender.js +932 -0
- package/dist/build/report.d.ts +132 -0
- package/dist/build/report.js +504 -0
- package/dist/build/route-classification-injector.d.ts +34 -0
- package/dist/build/route-classification-injector.js +59 -0
- package/dist/build/route-classification-manifest.d.ts +52 -0
- package/dist/build/route-classification-manifest.js +143 -0
- package/dist/build/run-prerender.d.ts +61 -0
- package/dist/build/run-prerender.js +224 -0
- package/dist/build/server-manifest.d.ts +18 -0
- package/dist/build/server-manifest.js +22 -0
- package/dist/build/ssr-manifest.d.ts +18 -0
- package/dist/build/ssr-manifest.js +69 -0
- package/dist/build/standalone.d.ts +31 -0
- package/dist/build/standalone.js +203 -0
- package/dist/build/static-export.d.ts +55 -0
- package/dist/build/static-export.js +60 -0
- package/dist/cache/cache-adapters-virtual.d.ts +50 -0
- package/dist/cache/cache-adapters-virtual.js +45 -0
- package/dist/cache.d.ts +2 -0
- package/dist/cache.js +2 -0
- package/dist/check.d.ts +87 -0
- package/dist/check.js +1037 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.js +124 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +744 -0
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/empty-module.d.ts +1 -0
- package/dist/client/empty-module.js +1 -0
- package/dist/client/instrumentation-client-inject.d.ts +33 -0
- package/dist/client/instrumentation-client-inject.js +55 -0
- package/dist/client/instrumentation-client-state.d.ts +9 -0
- package/dist/client/instrumentation-client-state.js +17 -0
- package/dist/client/instrumentation-client.d.ts +7 -0
- package/dist/client/instrumentation-client.js +6 -0
- package/dist/client/navigation-runtime.d.ts +70 -0
- package/dist/client/navigation-runtime.js +169 -0
- package/dist/client/pages-router-link-navigation.d.ts +61 -0
- package/dist/client/pages-router-link-navigation.js +42 -0
- package/dist/client/validate-module-path.d.ts +17 -0
- package/dist/client/validate-module-path.js +24 -0
- package/dist/client/vinext-next-data.d.ts +44 -0
- package/dist/client/vinext-next-data.js +50 -0
- package/dist/client/window-next.d.ts +168 -0
- package/dist/client/window-next.js +57 -0
- package/dist/cloudflare/index.d.ts +3 -0
- package/dist/cloudflare/index.js +3 -0
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +102 -0
- package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +126 -0
- package/dist/cloudflare/src/cache/kv-data-adapter.runtime.js +435 -0
- package/dist/cloudflare/src/utils/cache-control-metadata.js +20 -0
- package/dist/cloudflare/tpr.d.ts +82 -0
- package/dist/cloudflare/tpr.js +558 -0
- package/dist/config/config-matchers.d.ts +257 -0
- package/dist/config/config-matchers.js +1046 -0
- package/dist/config/dotenv.d.ts +56 -0
- package/dist/config/dotenv.js +88 -0
- package/dist/config/next-config.d.ts +540 -0
- package/dist/config/next-config.js +1050 -0
- package/dist/config/tsconfig-paths.d.ts +21 -0
- package/dist/config/tsconfig-paths.js +157 -0
- package/dist/deploy.d.ts +190 -0
- package/dist/deploy.js +1033 -0
- package/dist/entries/app-browser-entry.d.ts +29 -0
- package/dist/entries/app-browser-entry.js +83 -0
- package/dist/entries/app-rsc-entry.d.ts +81 -0
- package/dist/entries/app-rsc-entry.js +943 -0
- package/dist/entries/app-rsc-manifest.d.ts +53 -0
- package/dist/entries/app-rsc-manifest.js +294 -0
- package/dist/entries/app-ssr-entry.d.ts +15 -0
- package/dist/entries/app-ssr-entry.js +24 -0
- package/dist/entries/pages-client-entry.d.ts +11 -0
- package/dist/entries/pages-client-entry.js +204 -0
- package/dist/entries/pages-entry-helpers.d.ts +2 -0
- package/dist/entries/pages-entry-helpers.js +2 -0
- package/dist/entries/pages-server-entry.d.ts +11 -0
- package/dist/entries/pages-server-entry.js +398 -0
- package/dist/entries/runtime-entry-module.d.ts +25 -0
- package/dist/entries/runtime-entry-module.js +46 -0
- package/dist/index.d.ts +115 -0
- package/dist/index.js +2661 -0
- package/dist/init.d.ts +69 -0
- package/dist/init.js +253 -0
- package/dist/plugins/ast-utils.d.ts +20 -0
- package/dist/plugins/ast-utils.js +78 -0
- package/dist/plugins/async-hooks-stub.d.ts +18 -0
- package/dist/plugins/async-hooks-stub.js +40 -0
- package/dist/plugins/client-reference-dedup.d.ts +35 -0
- package/dist/plugins/client-reference-dedup.js +189 -0
- package/dist/plugins/css-data-url.d.ts +6 -0
- package/dist/plugins/css-data-url.js +83 -0
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +413 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +155 -0
- package/dist/plugins/fonts.d.ts +95 -0
- package/dist/plugins/fonts.js +711 -0
- package/dist/plugins/import-meta-url.d.ts +16 -0
- package/dist/plugins/import-meta-url.js +353 -0
- package/dist/plugins/instrumentation-client.d.ts +6 -0
- package/dist/plugins/instrumentation-client.js +27 -0
- package/dist/plugins/middleware-export-validation.d.ts +5 -0
- package/dist/plugins/middleware-export-validation.js +36 -0
- package/dist/plugins/middleware-server-only.d.ts +53 -0
- package/dist/plugins/middleware-server-only.js +90 -0
- package/dist/plugins/og-asset-ownership.d.ts +27 -0
- package/dist/plugins/og-asset-ownership.js +285 -0
- package/dist/plugins/og-assets.d.ts +50 -0
- package/dist/plugins/og-assets.js +229 -0
- package/dist/plugins/optimize-imports.d.ts +42 -0
- package/dist/plugins/optimize-imports.js +587 -0
- package/dist/plugins/postcss.d.ts +26 -0
- package/dist/plugins/postcss.js +96 -0
- package/dist/plugins/remove-console.d.ts +21 -0
- package/dist/plugins/remove-console.js +177 -0
- package/dist/plugins/require-context.d.ts +6 -0
- package/dist/plugins/require-context.js +185 -0
- package/dist/plugins/rsc-client-reference-loaders.d.ts +6 -0
- package/dist/plugins/rsc-client-reference-loaders.js +46 -0
- package/dist/plugins/rsc-client-shim-excludes.d.ts +6 -0
- package/dist/plugins/rsc-client-shim-excludes.js +35 -0
- package/dist/plugins/sass.d.ts +62 -0
- package/dist/plugins/sass.js +268 -0
- package/dist/plugins/server-externals-manifest.d.ts +26 -0
- package/dist/plugins/server-externals-manifest.js +81 -0
- package/dist/plugins/strip-server-exports.d.ts +21 -0
- package/dist/plugins/strip-server-exports.js +519 -0
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +336 -0
- package/dist/routing/app-route-graph.js +1518 -0
- package/dist/routing/app-router.d.ts +30 -0
- package/dist/routing/app-router.js +59 -0
- package/dist/routing/file-matcher.d.ts +60 -0
- package/dist/routing/file-matcher.js +147 -0
- package/dist/routing/pages-router.d.ts +48 -0
- package/dist/routing/pages-router.js +163 -0
- package/dist/routing/route-matching.d.ts +27 -0
- package/dist/routing/route-matching.js +42 -0
- package/dist/routing/route-pattern.d.ts +64 -0
- package/dist/routing/route-pattern.js +165 -0
- package/dist/routing/route-trie.d.ts +67 -0
- package/dist/routing/route-trie.js +143 -0
- package/dist/routing/route-validation.d.ts +10 -0
- package/dist/routing/route-validation.js +101 -0
- package/dist/routing/utils.d.ts +117 -0
- package/dist/routing/utils.js +242 -0
- package/dist/server/accept-encoding.d.ts +29 -0
- package/dist/server/accept-encoding.js +95 -0
- package/dist/server/api-handler.d.ts +17 -0
- package/dist/server/api-handler.js +276 -0
- package/dist/server/app-action-request.d.ts +4 -0
- package/dist/server/app-action-request.js +9 -0
- package/dist/server/app-bfcache-id.d.ts +5 -0
- package/dist/server/app-bfcache-id.js +5 -0
- package/dist/server/app-bfcache-identity.d.ts +36 -0
- package/dist/server/app-bfcache-identity.js +156 -0
- package/dist/server/app-browser-action-result.d.ts +64 -0
- package/dist/server/app-browser-action-result.js +111 -0
- package/dist/server/app-browser-client-reuse-manifest.d.ts +12 -0
- package/dist/server/app-browser-client-reuse-manifest.js +101 -0
- package/dist/server/app-browser-entry.d.ts +1 -0
- package/dist/server/app-browser-entry.js +1087 -0
- package/dist/server/app-browser-error.d.ts +13 -0
- package/dist/server/app-browser-error.js +52 -0
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +32 -0
- package/dist/server/app-browser-hydration.js +29 -0
- package/dist/server/app-browser-interception-context.d.ts +24 -0
- package/dist/server/app-browser-interception-context.js +43 -0
- package/dist/server/app-browser-mpa-navigation.d.ts +16 -0
- package/dist/server/app-browser-mpa-navigation.js +42 -0
- package/dist/server/app-browser-navigation-controller.d.ts +109 -0
- package/dist/server/app-browser-navigation-controller.js +465 -0
- package/dist/server/app-browser-popstate.d.ts +26 -0
- package/dist/server/app-browser-popstate.js +44 -0
- package/dist/server/app-browser-rsc-redirect.d.ts +38 -0
- package/dist/server/app-browser-rsc-redirect.js +64 -0
- package/dist/server/app-browser-server-action-client.d.ts +32 -0
- package/dist/server/app-browser-server-action-client.js +128 -0
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.d.ts +140 -0
- package/dist/server/app-browser-state.js +315 -0
- package/dist/server/app-browser-stream.d.ts +28 -0
- package/dist/server/app-browser-stream.js +122 -0
- package/dist/server/app-browser-visible-commit.d.ts +78 -0
- package/dist/server/app-browser-visible-commit.js +241 -0
- package/dist/server/app-client-reference-preloader.d.ts +14 -0
- package/dist/server/app-client-reference-preloader.js +44 -0
- package/dist/server/app-elements-wire.d.ts +192 -0
- package/dist/server/app-elements-wire.js +443 -0
- package/dist/server/app-elements.d.ts +9 -0
- package/dist/server/app-elements.js +18 -0
- package/dist/server/app-fallback-renderer.d.ts +89 -0
- package/dist/server/app-fallback-renderer.js +136 -0
- package/dist/server/app-history-state.d.ts +85 -0
- package/dist/server/app-history-state.js +223 -0
- package/dist/server/app-hook-warning-suppression.d.ts +6 -0
- package/dist/server/app-hook-warning-suppression.js +10 -0
- package/dist/server/app-inline-css-client.d.ts +6 -0
- package/dist/server/app-inline-css-client.js +35 -0
- package/dist/server/app-interception-context-header.d.ts +32 -0
- package/dist/server/app-interception-context-header.js +42 -0
- package/dist/server/app-layout-param-observation.d.ts +43 -0
- package/dist/server/app-layout-param-observation.js +168 -0
- package/dist/server/app-middleware.d.ts +46 -0
- package/dist/server/app-middleware.js +168 -0
- package/dist/server/app-mounted-slots-header.d.ts +35 -0
- package/dist/server/app-mounted-slots-header.js +58 -0
- package/dist/server/app-optimistic-routing.d.ts +53 -0
- package/dist/server/app-optimistic-routing.js +227 -0
- package/dist/server/app-page-boundary-render.d.ts +85 -0
- package/dist/server/app-page-boundary-render.js +305 -0
- package/dist/server/app-page-boundary.d.ts +102 -0
- package/dist/server/app-page-boundary.js +120 -0
- package/dist/server/app-page-cache-finalizer.d.ts +62 -0
- package/dist/server/app-page-cache-finalizer.js +122 -0
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +83 -0
- package/dist/server/app-page-cache.js +272 -0
- package/dist/server/app-page-dispatch.d.ts +223 -0
- package/dist/server/app-page-dispatch.js +610 -0
- package/dist/server/app-page-element-builder.d.ts +96 -0
- package/dist/server/app-page-element-builder.js +205 -0
- package/dist/server/app-page-execution.d.ts +138 -0
- package/dist/server/app-page-execution.js +328 -0
- package/dist/server/app-page-head.d.ts +65 -0
- package/dist/server/app-page-head.js +228 -0
- package/dist/server/app-page-method.d.ts +15 -0
- package/dist/server/app-page-method.js +25 -0
- package/dist/server/app-page-params.d.ts +8 -0
- package/dist/server/app-page-params.js +39 -0
- package/dist/server/app-page-ppr-runtime.d.ts +7 -0
- package/dist/server/app-page-ppr-runtime.js +70 -0
- package/dist/server/app-page-probe.d.ts +134 -0
- package/dist/server/app-page-probe.js +276 -0
- package/dist/server/app-page-render-identity.d.ts +21 -0
- package/dist/server/app-page-render-identity.js +40 -0
- package/dist/server/app-page-render-observation.d.ts +36 -0
- package/dist/server/app-page-render-observation.js +82 -0
- package/dist/server/app-page-render.d.ts +111 -0
- package/dist/server/app-page-render.js +602 -0
- package/dist/server/app-page-request.d.ts +137 -0
- package/dist/server/app-page-request.js +216 -0
- package/dist/server/app-page-response.d.ts +68 -0
- package/dist/server/app-page-response.js +120 -0
- package/dist/server/app-page-route-wiring.d.ts +151 -0
- package/dist/server/app-page-route-wiring.js +452 -0
- package/dist/server/app-page-search-params-observation.d.ts +10 -0
- package/dist/server/app-page-search-params-observation.js +20 -0
- package/dist/server/app-page-segment-state.d.ts +9 -0
- package/dist/server/app-page-segment-state.js +80 -0
- package/dist/server/app-page-stream.d.ts +151 -0
- package/dist/server/app-page-stream.js +143 -0
- package/dist/server/app-pages-bridge.d.ts +63 -0
- package/dist/server/app-pages-bridge.js +63 -0
- package/dist/server/app-post-middleware-context.d.ts +15 -0
- package/dist/server/app-post-middleware-context.js +26 -0
- package/dist/server/app-ppr-fallback-shell-render.d.ts +18 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +33 -0
- package/dist/server/app-ppr-fallback-shell.js +89 -0
- package/dist/server/app-prerender-endpoints.d.ts +18 -0
- package/dist/server/app-prerender-endpoints.js +94 -0
- package/dist/server/app-prerender-static-params.d.ts +30 -0
- package/dist/server/app-prerender-static-params.js +81 -0
- package/dist/server/app-render-dependency.d.ts +14 -0
- package/dist/server/app-render-dependency.js +41 -0
- package/dist/server/app-request-context.d.ts +20 -0
- package/dist/server/app-request-context.js +29 -0
- package/dist/server/app-route-handler-cache.d.ts +46 -0
- package/dist/server/app-route-handler-cache.js +78 -0
- package/dist/server/app-route-handler-dispatch.d.ts +49 -0
- package/dist/server/app-route-handler-dispatch.js +163 -0
- package/dist/server/app-route-handler-execution.d.ts +86 -0
- package/dist/server/app-route-handler-execution.js +128 -0
- package/dist/server/app-route-handler-policy.d.ts +55 -0
- package/dist/server/app-route-handler-policy.js +58 -0
- package/dist/server/app-route-handler-response.d.ts +28 -0
- package/dist/server/app-route-handler-response.js +145 -0
- package/dist/server/app-route-handler-runtime.d.ts +39 -0
- package/dist/server/app-route-handler-runtime.js +250 -0
- package/dist/server/app-route-module-loader.d.ts +91 -0
- package/dist/server/app-route-module-loader.js +83 -0
- package/dist/server/app-router-entry.d.ts +13 -0
- package/dist/server/app-router-entry.js +49 -0
- package/dist/server/app-rsc-cache-busting.d.ts +64 -0
- package/dist/server/app-rsc-cache-busting.js +206 -0
- package/dist/server/app-rsc-embedded-chunks.d.ts +8 -0
- package/dist/server/app-rsc-embedded-chunks.js +32 -0
- package/dist/server/app-rsc-error-handler.d.ts +20 -0
- package/dist/server/app-rsc-error-handler.js +28 -0
- package/dist/server/app-rsc-errors.d.ts +40 -0
- package/dist/server/app-rsc-errors.js +60 -0
- package/dist/server/app-rsc-handler.d.ts +201 -0
- package/dist/server/app-rsc-handler.js +538 -0
- package/dist/server/app-rsc-render-mode.d.ts +11 -0
- package/dist/server/app-rsc-render-mode.js +25 -0
- package/dist/server/app-rsc-request-normalization.d.ts +48 -0
- package/dist/server/app-rsc-request-normalization.js +75 -0
- package/dist/server/app-rsc-response-finalizer.d.ts +37 -0
- package/dist/server/app-rsc-response-finalizer.js +54 -0
- package/dist/server/app-rsc-route-matching.d.ts +93 -0
- package/dist/server/app-rsc-route-matching.js +134 -0
- package/dist/server/app-segment-config.d.ts +46 -0
- package/dist/server/app-segment-config.js +113 -0
- package/dist/server/app-server-action-execution.d.ts +219 -0
- package/dist/server/app-server-action-execution.js +767 -0
- package/dist/server/app-ssr-entry.d.ts +52 -0
- package/dist/server/app-ssr-entry.js +295 -0
- package/dist/server/app-ssr-error-meta.d.ts +13 -0
- package/dist/server/app-ssr-error-meta.js +48 -0
- package/dist/server/app-ssr-router-instance.d.ts +6 -0
- package/dist/server/app-ssr-router-instance.js +24 -0
- package/dist/server/app-ssr-stream.d.ts +60 -0
- package/dist/server/app-ssr-stream.js +408 -0
- package/dist/server/app-static-generation.d.ts +15 -0
- package/dist/server/app-static-generation.js +19 -0
- package/dist/server/app-visited-response-cache.d.ts +23 -0
- package/dist/server/app-visited-response-cache.js +19 -0
- package/dist/server/artifact-compatibility.d.ts +54 -0
- package/dist/server/artifact-compatibility.js +91 -0
- package/dist/server/before-interactive-head.d.ts +17 -0
- package/dist/server/before-interactive-head.js +35 -0
- package/dist/server/cache-control.d.ts +37 -0
- package/dist/server/cache-control.js +56 -0
- package/dist/server/cache-headers.d.ts +6 -0
- package/dist/server/cache-headers.js +17 -0
- package/dist/server/cache-proof.d.ts +364 -0
- package/dist/server/cache-proof.js +794 -0
- package/dist/server/client-reuse-manifest.d.ts +104 -0
- package/dist/server/client-reuse-manifest.js +209 -0
- package/dist/server/client-trace-metadata.d.ts +30 -0
- package/dist/server/client-trace-metadata.js +81 -0
- package/dist/server/cookie-utils.d.ts +12 -0
- package/dist/server/cookie-utils.js +18 -0
- package/dist/server/csp.d.ts +10 -0
- package/dist/server/csp.js +41 -0
- package/dist/server/default-global-error-module.d.ts +19 -0
- package/dist/server/default-global-error-module.js +18 -0
- package/dist/server/default-not-found-module.d.ts +19 -0
- package/dist/server/default-not-found-module.js +18 -0
- package/dist/server/defer-until-stream-consumed.d.ts +7 -0
- package/dist/server/defer-until-stream-consumed.js +34 -0
- package/dist/server/dev-error-overlay-store.d.ts +39 -0
- package/dist/server/dev-error-overlay-store.js +86 -0
- package/dist/server/dev-error-overlay.d.ts +51 -0
- package/dist/server/dev-error-overlay.js +1341 -0
- package/dist/server/dev-initial-server-error.d.ts +9 -0
- package/dist/server/dev-initial-server-error.js +26 -0
- package/dist/server/dev-lockfile.d.ts +109 -0
- package/dist/server/dev-lockfile.js +179 -0
- package/dist/server/dev-module-runner.d.ts +30 -0
- package/dist/server/dev-module-runner.js +91 -0
- package/dist/server/dev-origin-check.d.ts +62 -0
- package/dist/server/dev-origin-check.js +156 -0
- package/dist/server/dev-route-files.d.ts +6 -0
- package/dist/server/dev-route-files.js +71 -0
- package/dist/server/dev-server.d.ts +58 -0
- package/dist/server/dev-server.js +1114 -0
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/server/dev-stack-sourcemap-endpoint.js +4 -0
- package/dist/server/dev-stack-sourcemap.d.ts +43 -0
- package/dist/server/dev-stack-sourcemap.js +443 -0
- package/dist/server/document-initial-head.d.ts +6 -0
- package/dist/server/document-initial-head.js +33 -0
- package/dist/server/edge-api-runtime.d.ts +4 -0
- package/dist/server/edge-api-runtime.js +6 -0
- package/dist/server/file-based-metadata.d.ts +29 -0
- package/dist/server/file-based-metadata.js +401 -0
- package/dist/server/headers.d.ts +114 -0
- package/dist/server/headers.js +136 -0
- package/dist/server/html.d.ts +28 -0
- package/dist/server/html.js +41 -0
- package/dist/server/http-error-responses.d.ts +91 -0
- package/dist/server/http-error-responses.js +105 -0
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +130 -0
- package/dist/server/image-optimization.js +247 -0
- package/dist/server/implicit-tags.d.ts +6 -0
- package/dist/server/implicit-tags.js +44 -0
- package/dist/server/instrumentation-runtime.d.ts +49 -0
- package/dist/server/instrumentation-runtime.js +35 -0
- package/dist/server/instrumentation.d.ts +85 -0
- package/dist/server/instrumentation.js +130 -0
- package/dist/server/isr-cache.d.ts +127 -0
- package/dist/server/isr-cache.js +282 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-build-data.d.ts +24 -0
- package/dist/server/metadata-route-build-data.js +148 -0
- package/dist/server/metadata-route-response.d.ts +16 -0
- package/dist/server/metadata-route-response.js +205 -0
- package/dist/server/metadata-routes.d.ts +139 -0
- package/dist/server/metadata-routes.js +433 -0
- package/dist/server/middleware-matcher.d.ts +14 -0
- package/dist/server/middleware-matcher.js +111 -0
- package/dist/server/middleware-request-headers.d.ts +11 -0
- package/dist/server/middleware-request-headers.js +65 -0
- package/dist/server/middleware-response-headers.d.ts +12 -0
- package/dist/server/middleware-response-headers.js +42 -0
- package/dist/server/middleware-runtime.d.ts +67 -0
- package/dist/server/middleware-runtime.js +240 -0
- package/dist/server/middleware.d.ts +62 -0
- package/dist/server/middleware.js +114 -0
- package/dist/server/navigation-planner.d.ts +308 -0
- package/dist/server/navigation-planner.js +831 -0
- package/dist/server/navigation-trace.d.ts +68 -0
- package/dist/server/navigation-trace.js +71 -0
- package/dist/server/next-error-digest.d.ts +44 -0
- package/dist/server/next-error-digest.js +40 -0
- package/dist/server/normalize-path.d.ts +38 -0
- package/dist/server/normalize-path.js +70 -0
- package/dist/server/open-redirect.d.ts +12 -0
- package/dist/server/open-redirect.js +21 -0
- package/dist/server/operation-token.d.ts +40 -0
- package/dist/server/operation-token.js +85 -0
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +83 -0
- package/dist/server/pages-api-route.js +75 -0
- package/dist/server/pages-asset-tags.d.ts +78 -0
- package/dist/server/pages-asset-tags.js +126 -0
- package/dist/server/pages-body-parser-config.d.ts +59 -0
- package/dist/server/pages-body-parser-config.js +77 -0
- package/dist/server/pages-data-route.d.ts +121 -0
- package/dist/server/pages-data-route.js +157 -0
- package/dist/server/pages-default-404.d.ts +30 -0
- package/dist/server/pages-default-404.js +38 -0
- package/dist/server/pages-dev-module-url.d.ts +4 -0
- package/dist/server/pages-dev-module-url.js +15 -0
- package/dist/server/pages-document-initial-props.d.ts +77 -0
- package/dist/server/pages-document-initial-props.js +109 -0
- package/dist/server/pages-get-initial-props.d.ts +67 -0
- package/dist/server/pages-get-initial-props.js +92 -0
- package/dist/server/pages-i18n.d.ts +106 -0
- package/dist/server/pages-i18n.js +183 -0
- package/dist/server/pages-media-type.d.ts +15 -0
- package/dist/server/pages-media-type.js +24 -0
- package/dist/server/pages-node-compat.d.ts +55 -0
- package/dist/server/pages-node-compat.js +235 -0
- package/dist/server/pages-page-data.d.ts +223 -0
- package/dist/server/pages-page-data.js +484 -0
- package/dist/server/pages-page-handler.d.ts +100 -0
- package/dist/server/pages-page-handler.js +403 -0
- package/dist/server/pages-page-method.d.ts +47 -0
- package/dist/server/pages-page-method.js +17 -0
- package/dist/server/pages-page-response.d.ts +138 -0
- package/dist/server/pages-page-response.js +285 -0
- package/dist/server/pages-readiness.d.ts +36 -0
- package/dist/server/pages-readiness.js +21 -0
- package/dist/server/pages-request-pipeline.d.ts +116 -0
- package/dist/server/pages-request-pipeline.js +311 -0
- package/dist/server/pages-revalidate.d.ts +15 -0
- package/dist/server/pages-revalidate.js +19 -0
- package/dist/server/pages-serializable-props.d.ts +24 -0
- package/dist/server/pages-serializable-props.js +67 -0
- package/dist/server/pregenerated-concrete-paths.d.ts +16 -0
- package/dist/server/pregenerated-concrete-paths.js +61 -0
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +23 -0
- package/dist/server/prerender-route-params.js +113 -0
- package/dist/server/prerender-work-unit-setup.d.ts +6 -0
- package/dist/server/prerender-work-unit-setup.js +28 -0
- package/dist/server/prod-server.d.ts +148 -0
- package/dist/server/prod-server.js +1136 -0
- package/dist/server/proxy-trust.d.ts +40 -0
- package/dist/server/proxy-trust.js +68 -0
- package/dist/server/request-log.d.ts +39 -0
- package/dist/server/request-log.js +56 -0
- package/dist/server/request-pipeline.d.ts +187 -0
- package/dist/server/request-pipeline.js +447 -0
- package/dist/server/rsc-stream-hints.d.ts +10 -0
- package/dist/server/rsc-stream-hints.js +41 -0
- package/dist/server/seed-cache.d.ts +29 -0
- package/dist/server/seed-cache.js +125 -0
- package/dist/server/server-action-not-found.d.ts +21 -0
- package/dist/server/server-action-not-found.js +62 -0
- package/dist/server/server-globals.d.ts +4 -0
- package/dist/server/server-globals.js +35 -0
- package/dist/server/skip-cache-proof.d.ts +61 -0
- package/dist/server/skip-cache-proof.js +168 -0
- package/dist/server/socket-error-backstop.d.ts +34 -0
- package/dist/server/socket-error-backstop.js +200 -0
- package/dist/server/static-file-cache.d.ts +56 -0
- package/dist/server/static-file-cache.js +231 -0
- package/dist/server/static-layout-client-reuse-proof.d.ts +15 -0
- package/dist/server/static-layout-client-reuse-proof.js +33 -0
- package/dist/server/streaming-metadata.d.ts +4 -0
- package/dist/server/streaming-metadata.js +8 -0
- package/dist/server/worker-utils.d.ts +7 -0
- package/dist/server/worker-utils.js +99 -0
- package/dist/shims/amp.d.ts +19 -0
- package/dist/shims/amp.js +23 -0
- package/dist/shims/app-router-scroll-state.d.ts +15 -0
- package/dist/shims/app-router-scroll-state.js +61 -0
- package/dist/shims/app-router-scroll.d.ts +29 -0
- package/dist/shims/app-router-scroll.js +141 -0
- package/dist/shims/app.d.ts +42 -0
- package/dist/shims/app.js +48 -0
- package/dist/shims/before-interactive-context.d.ts +40 -0
- package/dist/shims/before-interactive-context.js +8 -0
- package/dist/shims/cache-for-request.d.ts +57 -0
- package/dist/shims/cache-for-request.js +72 -0
- package/dist/shims/cache-handler.d.ts +106 -0
- package/dist/shims/cache-handler.js +176 -0
- package/dist/shims/cache-request-state.d.ts +47 -0
- package/dist/shims/cache-request-state.js +126 -0
- package/dist/shims/cache-runtime.d.ts +83 -0
- package/dist/shims/cache-runtime.js +452 -0
- package/dist/shims/cache.d.ts +145 -0
- package/dist/shims/cache.js +401 -0
- package/dist/shims/cdn-cache.d.ts +125 -0
- package/dist/shims/cdn-cache.js +100 -0
- package/dist/shims/client-hook-error.d.ts +13 -0
- package/dist/shims/client-hook-error.js +17 -0
- package/dist/shims/client-locale.d.ts +14 -0
- package/dist/shims/client-locale.js +11 -0
- package/dist/shims/client-only.d.ts +1 -0
- package/dist/shims/client-only.js +1 -0
- package/dist/shims/compat-router.d.ts +16 -0
- package/dist/shims/compat-router.js +25 -0
- package/dist/shims/config.d.ts +28 -0
- package/dist/shims/config.js +21 -0
- package/dist/shims/constants.d.ts +130 -0
- package/dist/shims/constants.js +167 -0
- package/dist/shims/default-global-error.d.ts +31 -0
- package/dist/shims/default-global-error.js +179 -0
- package/dist/shims/default-not-found.d.ts +11 -0
- package/dist/shims/default-not-found.js +59 -0
- package/dist/shims/document.d.ts +92 -0
- package/dist/shims/document.js +76 -0
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +35 -0
- package/dist/shims/dynamic.js +204 -0
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +44 -0
- package/dist/shims/error-boundary.d.ts +155 -0
- package/dist/shims/error-boundary.js +342 -0
- package/dist/shims/error.d.ts +31 -0
- package/dist/shims/error.js +123 -0
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +136 -0
- package/dist/shims/fetch-cache.js +766 -0
- package/dist/shims/font-google-base.d.ts +83 -0
- package/dist/shims/font-google-base.js +290 -0
- package/dist/shims/font-google.d.ts +2 -0
- package/dist/shims/font-google.js +2 -0
- package/dist/shims/font-local.d.ts +50 -0
- package/dist/shims/font-local.js +195 -0
- package/dist/shims/font-utils.d.ts +56 -0
- package/dist/shims/font-utils.js +107 -0
- package/dist/shims/form.d.ts +19 -0
- package/dist/shims/form.js +236 -0
- package/dist/shims/hash-scroll.d.ts +10 -0
- package/dist/shims/hash-scroll.js +47 -0
- package/dist/shims/head-state.d.ts +16 -0
- package/dist/shims/head-state.js +43 -0
- package/dist/shims/head.d.ts +73 -0
- package/dist/shims/head.js +340 -0
- package/dist/shims/headers.d.ts +253 -0
- package/dist/shims/headers.js +754 -0
- package/dist/shims/i18n-context.d.ts +22 -0
- package/dist/shims/i18n-context.js +42 -0
- package/dist/shims/i18n-state.d.ts +14 -0
- package/dist/shims/i18n-state.js +38 -0
- package/dist/shims/image-config.d.ts +45 -0
- package/dist/shims/image-config.js +85 -0
- package/dist/shims/image.d.ts +55 -0
- package/dist/shims/image.js +582 -0
- package/dist/shims/internal/als-registry.d.ts +14 -0
- package/dist/shims/internal/als-registry.js +80 -0
- package/dist/shims/internal/api-utils.d.ts +14 -0
- package/dist/shims/internal/api-utils.js +1 -0
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
- package/dist/shims/internal/app-page-props-cache-key.js +16 -0
- package/dist/shims/internal/app-route-detection.d.ts +39 -0
- package/dist/shims/internal/app-route-detection.js +62 -0
- package/dist/shims/internal/app-router-context.d.ts +31 -0
- package/dist/shims/internal/app-router-context.js +28 -0
- package/dist/shims/internal/cookie-serialize.d.ts +45 -0
- package/dist/shims/internal/cookie-serialize.js +49 -0
- package/dist/shims/internal/cookies.d.ts +2 -0
- package/dist/shims/internal/cookies.js +2 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/interpolate-as.d.ts +25 -0
- package/dist/shims/internal/interpolate-as.js +196 -0
- package/dist/shims/internal/link-status-registry.d.ts +43 -0
- package/dist/shims/internal/link-status-registry.js +42 -0
- package/dist/shims/internal/make-hanging-promise.d.ts +15 -0
- package/dist/shims/internal/make-hanging-promise.js +44 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +56 -0
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +54 -0
- package/dist/shims/internal/pages-data-fetch-dedup.js +121 -0
- package/dist/shims/internal/pages-data-target.d.ts +62 -0
- package/dist/shims/internal/pages-data-target.js +98 -0
- package/dist/shims/internal/pages-data-url.d.ts +41 -0
- package/dist/shims/internal/pages-data-url.js +71 -0
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
- package/dist/shims/internal/route-pattern-for-warning.js +40 -0
- package/dist/shims/internal/router-context.d.ts +7 -0
- package/dist/shims/internal/router-context.js +13 -0
- package/dist/shims/internal/utils.d.ts +52 -0
- package/dist/shims/internal/utils.js +27 -0
- package/dist/shims/internal/work-unit-async-storage.d.ts +30 -0
- package/dist/shims/internal/work-unit-async-storage.js +17 -0
- package/dist/shims/layout-segment-context.d.ts +24 -0
- package/dist/shims/layout-segment-context.js +39 -0
- package/dist/shims/legacy-image.d.ts +41 -0
- package/dist/shims/legacy-image.js +49 -0
- package/dist/shims/link-prefetch.d.ts +41 -0
- package/dist/shims/link-prefetch.js +43 -0
- package/dist/shims/link.d.ts +102 -0
- package/dist/shims/link.js +687 -0
- package/dist/shims/metadata.d.ts +285 -0
- package/dist/shims/metadata.js +820 -0
- package/dist/shims/navigation-context-state.d.ts +40 -0
- package/dist/shims/navigation-context-state.js +116 -0
- package/dist/shims/navigation-errors.d.ts +55 -0
- package/dist/shims/navigation-errors.js +110 -0
- package/dist/shims/navigation-server.d.ts +3 -0
- package/dist/shims/navigation-server.js +3 -0
- package/dist/shims/navigation-state.d.ts +25 -0
- package/dist/shims/navigation-state.js +66 -0
- package/dist/shims/navigation.d.ts +286 -0
- package/dist/shims/navigation.js +1206 -0
- package/dist/shims/navigation.react-server.d.ts +14 -0
- package/dist/shims/navigation.react-server.js +32 -0
- package/dist/shims/offline.d.ts +4 -0
- package/dist/shims/offline.js +15 -0
- package/dist/shims/og.d.ts +17 -0
- package/dist/shims/og.js +48 -0
- package/dist/shims/pages-router-runtime.d.ts +12 -0
- package/dist/shims/pages-router-runtime.js +24 -0
- package/dist/shims/ppr-fallback-shell.d.ts +33 -0
- package/dist/shims/ppr-fallback-shell.js +170 -0
- package/dist/shims/readonly-url-search-params.d.ts +13 -0
- package/dist/shims/readonly-url-search-params.js +26 -0
- package/dist/shims/request-context.d.ts +58 -0
- package/dist/shims/request-context.js +45 -0
- package/dist/shims/request-state-types.d.ts +12 -0
- package/dist/shims/request-state-types.js +1 -0
- package/dist/shims/root-params.d.ts +12 -0
- package/dist/shims/root-params.js +30 -0
- package/dist/shims/router-state.d.ts +32 -0
- package/dist/shims/router-state.js +39 -0
- package/dist/shims/router.d.ts +192 -0
- package/dist/shims/router.js +1786 -0
- package/dist/shims/script-nonce-context.d.ts +11 -0
- package/dist/shims/script-nonce-context.js +23 -0
- package/dist/shims/script.d.ts +43 -0
- package/dist/shims/script.js +370 -0
- package/dist/shims/server-only.d.ts +1 -0
- package/dist/shims/server-only.js +1 -0
- package/dist/shims/server.d.ts +323 -0
- package/dist/shims/server.js +729 -0
- package/dist/shims/slot.d.ts +45 -0
- package/dist/shims/slot.js +230 -0
- package/dist/shims/thenable-params.d.ts +11 -0
- package/dist/shims/thenable-params.js +176 -0
- package/dist/shims/unified-request-context.d.ts +68 -0
- package/dist/shims/unified-request-context.js +86 -0
- package/dist/shims/unrecognized-action-error.d.ts +34 -0
- package/dist/shims/unrecognized-action-error.js +39 -0
- package/dist/shims/url-safety.d.ts +34 -0
- package/dist/shims/url-safety.js +70 -0
- package/dist/shims/url-utils.d.ts +51 -0
- package/dist/shims/url-utils.js +156 -0
- package/dist/shims/use-merged-ref.d.ts +6 -0
- package/dist/shims/use-merged-ref.js +38 -0
- package/dist/shims/web-vitals.d.ts +8 -0
- package/dist/shims/web-vitals.js +22 -0
- package/dist/typegen.d.ts +9 -0
- package/dist/typegen.js +228 -0
- package/dist/utils/asset-prefix.d.ts +96 -0
- package/dist/utils/asset-prefix.js +122 -0
- package/dist/utils/base-path.d.ts +31 -0
- package/dist/utils/base-path.js +45 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/cache-control-metadata.d.ts +4 -0
- package/dist/utils/cache-control-metadata.js +12 -0
- package/dist/utils/client-build-manifest.d.ts +21 -0
- package/dist/utils/client-build-manifest.js +87 -0
- package/dist/utils/client-entry-manifest.d.ts +11 -0
- package/dist/utils/client-entry-manifest.js +29 -0
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/compare.d.ts +4 -0
- package/dist/utils/compare.js +8 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/dev-error-recovery-event.d.ts +4 -0
- package/dist/utils/dev-error-recovery-event.js +4 -0
- package/dist/utils/domain-locale.d.ts +26 -0
- package/dist/utils/domain-locale.js +50 -0
- package/dist/utils/encode-cache-tag.d.ts +30 -0
- package/dist/utils/encode-cache-tag.js +36 -0
- package/dist/utils/error-cause.d.ts +4 -0
- package/dist/utils/error-cause.js +95 -0
- package/dist/utils/has-trailing-comma.d.ts +24 -0
- package/dist/utils/has-trailing-comma.js +62 -0
- package/dist/utils/hash.d.ts +24 -0
- package/dist/utils/hash.js +55 -0
- package/dist/utils/html-limited-bots.d.ts +21 -0
- package/dist/utils/html-limited-bots.js +35 -0
- package/dist/utils/lazy-chunks.d.ts +59 -0
- package/dist/utils/lazy-chunks.js +112 -0
- package/dist/utils/manifest-paths.d.ts +30 -0
- package/dist/utils/manifest-paths.js +66 -0
- package/dist/utils/mdx-scan.d.ts +9 -0
- package/dist/utils/mdx-scan.js +34 -0
- package/dist/utils/navigation-signal.d.ts +4 -0
- package/dist/utils/navigation-signal.js +12 -0
- package/dist/utils/number.d.ts +4 -0
- package/dist/utils/number.js +6 -0
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +22 -0
- package/dist/utils/path.js +30 -0
- package/dist/utils/prerender-output-paths.d.ts +14 -0
- package/dist/utils/prerender-output-paths.js +22 -0
- package/dist/utils/project.d.ts +76 -0
- package/dist/utils/project.js +213 -0
- package/dist/utils/promise.d.ts +4 -0
- package/dist/utils/promise.js +6 -0
- package/dist/utils/public-routes.d.ts +4 -0
- package/dist/utils/public-routes.js +48 -0
- package/dist/utils/query.d.ts +49 -0
- package/dist/utils/query.js +122 -0
- package/dist/utils/record.d.ts +4 -0
- package/dist/utils/record.js +6 -0
- package/dist/utils/regex.d.ts +4 -0
- package/dist/utils/regex.js +6 -0
- package/dist/utils/safe-json-file.d.ts +17 -0
- package/dist/utils/safe-json-file.js +23 -0
- package/dist/utils/sorted-array.d.ts +8 -0
- package/dist/utils/sorted-array.js +20 -0
- package/dist/utils/text-stream.d.ts +28 -0
- package/dist/utils/text-stream.js +64 -0
- package/dist/utils/vinext-root.d.ts +23 -0
- package/dist/utils/vinext-root.js +29 -0
- package/dist/utils/virtual-module.d.ts +5 -0
- package/dist/utils/virtual-module.js +0 -0
- package/dist/utils/vite-version.d.ts +21 -0
- package/dist/utils/vite-version.js +42 -0
- package/package.json +145 -0
|
@@ -0,0 +1,1046 @@
|
|
|
1
|
+
import { VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../server/headers.js";
|
|
2
|
+
import { buildRequestHeadersFromMiddlewareResponse } from "../server/middleware-request-headers.js";
|
|
3
|
+
import { parseCookieHeader } from "../utils/parse-cookie.js";
|
|
4
|
+
//#region src/config/config-matchers.ts
|
|
5
|
+
/**
|
|
6
|
+
* Cache for compiled regex patterns in matchConfigPattern.
|
|
7
|
+
*
|
|
8
|
+
* Redirect/rewrite patterns are static — they come from next.config.js and
|
|
9
|
+
* never change at runtime. Without caching, every request that hits the regex
|
|
10
|
+
* branch re-runs the full tokeniser walk + isSafeRegex + new RegExp() for
|
|
11
|
+
* every rule in the array. On apps with many locale-prefixed rules (which all
|
|
12
|
+
* contain `(` and therefore enter the regex branch) this dominated profiling
|
|
13
|
+
* at ~2.4 seconds of CPU self-time.
|
|
14
|
+
*
|
|
15
|
+
* Value is `null` when safeRegExp rejected the pattern (ReDoS risk), so we
|
|
16
|
+
* skip it on subsequent requests too without re-running the scanner.
|
|
17
|
+
*/
|
|
18
|
+
const _compiledPatternCache = /* @__PURE__ */ new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Cache for compiled header source regexes in matchHeaders.
|
|
21
|
+
*
|
|
22
|
+
* Each NextHeader rule has a `source` that is run through escapeHeaderSource()
|
|
23
|
+
* then safeRegExp() to produce a RegExp. Both are pure functions of the source
|
|
24
|
+
* string and the result never changes. Without caching, every request
|
|
25
|
+
* re-runs the full escapeHeaderSource tokeniser + isSafeRegex scan + new RegExp()
|
|
26
|
+
* for every header rule.
|
|
27
|
+
*
|
|
28
|
+
* Value is `null` when safeRegExp rejected the pattern (ReDoS risk).
|
|
29
|
+
*/
|
|
30
|
+
const _compiledHeaderSourceCache = /* @__PURE__ */ new Map();
|
|
31
|
+
/**
|
|
32
|
+
* Cache for compiled has/missing condition value regexes in checkSingleCondition.
|
|
33
|
+
*
|
|
34
|
+
* Each has/missing condition may carry a `value` string that is passed directly
|
|
35
|
+
* to safeRegExp() for matching against header/cookie/query/host values. The
|
|
36
|
+
* condition objects are static (from next.config.js) so the compiled RegExp
|
|
37
|
+
* never changes. Without caching, safeRegExp() is called on every request for
|
|
38
|
+
* every condition on every rule.
|
|
39
|
+
*
|
|
40
|
+
* Value is `null` when safeRegExp rejected the pattern, or `false` when the
|
|
41
|
+
* value string was undefined (no regex needed — use exact string comparison).
|
|
42
|
+
*/
|
|
43
|
+
const _compiledConditionCache = /* @__PURE__ */ new Map();
|
|
44
|
+
/**
|
|
45
|
+
* Cache for destination substitution regexes in substituteDestinationParams.
|
|
46
|
+
*
|
|
47
|
+
* The regex depends only on the set of param keys captured from the matched
|
|
48
|
+
* source pattern. Caching by sorted key list avoids recompiling a new RegExp
|
|
49
|
+
* for repeated redirect/rewrite calls that use the same param shape.
|
|
50
|
+
*/
|
|
51
|
+
const _compiledDestinationParamCache = /* @__PURE__ */ new Map();
|
|
52
|
+
/**
|
|
53
|
+
* Generic helper for the regex compilation caches above.
|
|
54
|
+
*
|
|
55
|
+
* Each cache stores the compiled artifact (or `null` when safeRegExp rejected
|
|
56
|
+
* the pattern) the first time a key is seen, and reuses it forever. The
|
|
57
|
+
* `undefined` sentinel distinguishes "not yet seen" from "seen and rejected"
|
|
58
|
+
* so we never re-run isSafeRegex on the same input.
|
|
59
|
+
*
|
|
60
|
+
* Keep the security path intact: `compile()` is responsible for calling
|
|
61
|
+
* safeRegExp(); this helper only handles caching.
|
|
62
|
+
*/
|
|
63
|
+
function getCachedRegex(cache, key, compile) {
|
|
64
|
+
let value = cache.get(key);
|
|
65
|
+
if (value === void 0) {
|
|
66
|
+
value = compile();
|
|
67
|
+
cache.set(key, value);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Redirect index for O(1) locale-static rule lookup.
|
|
73
|
+
*
|
|
74
|
+
* Many Next.js apps generate 50-100 redirect rules of the form:
|
|
75
|
+
* /:locale(en|es|fr|...)?/some-static-path → /some-destination
|
|
76
|
+
*
|
|
77
|
+
* The compiled regex for each is like:
|
|
78
|
+
* ^/(en|es|fr|...)?/some-static-path$
|
|
79
|
+
*
|
|
80
|
+
* When no redirect matches (the common case for ordinary page loads),
|
|
81
|
+
* matchRedirect previously ran exec() on every one of those regexes —
|
|
82
|
+
* ~2ms per call, ~2992ms total self-time in profiles.
|
|
83
|
+
*
|
|
84
|
+
* The index splits rules into two buckets:
|
|
85
|
+
*
|
|
86
|
+
* localeStatic — rules whose source is exactly /:paramName(alt1|alt2|...)?/suffix
|
|
87
|
+
* where `suffix` is a static path with no further params or regex groups.
|
|
88
|
+
* These are indexed in a Map<suffix, entry[]> for O(1) lookup after a
|
|
89
|
+
* single fast strip of the optional locale prefix.
|
|
90
|
+
*
|
|
91
|
+
* linear — all other rules. Matched with the original O(n) loop.
|
|
92
|
+
*
|
|
93
|
+
* The index is stored in a WeakMap keyed by the redirects array so it is
|
|
94
|
+
* computed once per config load and GC'd when the array is no longer live.
|
|
95
|
+
*
|
|
96
|
+
* ## Ordering invariant
|
|
97
|
+
*
|
|
98
|
+
* Redirect rules must be evaluated in their original order (first match wins).
|
|
99
|
+
* Each locale-static entry stores its `originalIndex` so that, when a
|
|
100
|
+
* locale-static fast-path match is found, any linear rules that appear earlier
|
|
101
|
+
* in the array are still checked first.
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
104
|
+
* Matches `/:param(alternation)?/static/suffix` — the locale-static pattern.
|
|
105
|
+
*
|
|
106
|
+
* The `?` after the capture group is itself optional so that both forms are
|
|
107
|
+
* detected:
|
|
108
|
+
* - `/:locale(en|fr)?/foo` (locale segment optional — user-written rules)
|
|
109
|
+
* - `/:nextInternalLocale(en|fr)/foo` (locale segment mandatory — emitted
|
|
110
|
+
* by `applyLocaleToRoutes` for the locale-capture variant)
|
|
111
|
+
* Both forms benefit from O(1) suffix lookup; the optionality is recorded
|
|
112
|
+
* on the entry so we know whether to try the no-locale-prefix bucket.
|
|
113
|
+
*/
|
|
114
|
+
const _LOCALE_STATIC_RE = /^\/:[\w-]+\(([^)]+)\)(\??)\/([a-zA-Z0-9_~.%@!$&'*+,;=:/-]+)$/;
|
|
115
|
+
const _redirectIndexCache = /* @__PURE__ */ new WeakMap();
|
|
116
|
+
/**
|
|
117
|
+
* Build (or retrieve from cache) the redirect index for a given redirects array.
|
|
118
|
+
*
|
|
119
|
+
* Called once per config load from matchRedirect. The WeakMap ensures the index
|
|
120
|
+
* is recomputed if the config is reloaded (new array reference) and GC'd when
|
|
121
|
+
* the array is collected.
|
|
122
|
+
*/
|
|
123
|
+
function _getRedirectIndex(redirects) {
|
|
124
|
+
let index = _redirectIndexCache.get(redirects);
|
|
125
|
+
if (index !== void 0) return index;
|
|
126
|
+
const localeStatic = /* @__PURE__ */ new Map();
|
|
127
|
+
const linear = [];
|
|
128
|
+
for (let i = 0; i < redirects.length; i++) {
|
|
129
|
+
const redirect = redirects[i];
|
|
130
|
+
const m = _LOCALE_STATIC_RE.exec(redirect.source);
|
|
131
|
+
if (m) {
|
|
132
|
+
const paramName = redirect.source.slice(2, redirect.source.indexOf("("));
|
|
133
|
+
const alternation = m[1];
|
|
134
|
+
const optional = m[2] === "?";
|
|
135
|
+
const suffix = "/" + m[3];
|
|
136
|
+
const altRe = safeRegExp("^(?:" + alternation + ")$");
|
|
137
|
+
if (!altRe) {
|
|
138
|
+
linear.push([i, redirect]);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const entry = {
|
|
142
|
+
paramName,
|
|
143
|
+
altRe,
|
|
144
|
+
optional,
|
|
145
|
+
redirect,
|
|
146
|
+
originalIndex: i
|
|
147
|
+
};
|
|
148
|
+
const bucket = localeStatic.get(suffix);
|
|
149
|
+
if (bucket) bucket.push(entry);
|
|
150
|
+
else localeStatic.set(suffix, [entry]);
|
|
151
|
+
} else linear.push([i, redirect]);
|
|
152
|
+
}
|
|
153
|
+
index = {
|
|
154
|
+
localeStatic,
|
|
155
|
+
linear
|
|
156
|
+
};
|
|
157
|
+
_redirectIndexCache.set(redirects, index);
|
|
158
|
+
return index;
|
|
159
|
+
}
|
|
160
|
+
/** Hop-by-hop headers that should not be forwarded through a proxy. */
|
|
161
|
+
const HOP_BY_HOP_HEADERS = new Set([
|
|
162
|
+
"connection",
|
|
163
|
+
"keep-alive",
|
|
164
|
+
"proxy-authenticate",
|
|
165
|
+
"proxy-authorization",
|
|
166
|
+
"te",
|
|
167
|
+
"trailers",
|
|
168
|
+
"transfer-encoding",
|
|
169
|
+
"upgrade"
|
|
170
|
+
]);
|
|
171
|
+
/**
|
|
172
|
+
* Request hop-by-hop headers to strip before proxying with fetch().
|
|
173
|
+
* Intentionally narrower than HOP_BY_HOP_HEADERS: external rewrite proxying
|
|
174
|
+
* still forwards proxy auth credentials, while response sanitization strips
|
|
175
|
+
* them before returning data to the client.
|
|
176
|
+
*/
|
|
177
|
+
const REQUEST_HOP_BY_HOP_HEADERS = new Set([
|
|
178
|
+
"connection",
|
|
179
|
+
"keep-alive",
|
|
180
|
+
"te",
|
|
181
|
+
"trailers",
|
|
182
|
+
"transfer-encoding",
|
|
183
|
+
"upgrade"
|
|
184
|
+
]);
|
|
185
|
+
function stripHopByHopRequestHeaders(headers) {
|
|
186
|
+
const connectionTokens = (headers.get("connection") || "").split(",").map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
187
|
+
for (const header of REQUEST_HOP_BY_HOP_HEADERS) headers.delete(header);
|
|
188
|
+
for (const token of connectionTokens) headers.delete(token);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Detect regex patterns vulnerable to catastrophic backtracking (ReDoS).
|
|
192
|
+
*
|
|
193
|
+
* Uses a lightweight heuristic: scans the pattern string for nested quantifiers
|
|
194
|
+
* (a quantifier applied to a group that itself contains a quantifier). This
|
|
195
|
+
* catches the most common pathological patterns like `(a+)+`, `(.*)*`,
|
|
196
|
+
* `([^/]+)+`, `(a|a+)+` without needing a full regex parser.
|
|
197
|
+
*
|
|
198
|
+
* Returns true if the pattern appears safe, false if it's potentially dangerous.
|
|
199
|
+
*/
|
|
200
|
+
function isSafeRegex(pattern) {
|
|
201
|
+
const quantifierAtDepth = [];
|
|
202
|
+
let depth = 0;
|
|
203
|
+
let i = 0;
|
|
204
|
+
while (i < pattern.length) {
|
|
205
|
+
const ch = pattern[i];
|
|
206
|
+
if (ch === "\\") {
|
|
207
|
+
i += 2;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (ch === "[") {
|
|
211
|
+
i++;
|
|
212
|
+
while (i < pattern.length && pattern[i] !== "]") {
|
|
213
|
+
if (pattern[i] === "\\") i++;
|
|
214
|
+
i++;
|
|
215
|
+
}
|
|
216
|
+
i++;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (ch === "(") {
|
|
220
|
+
depth++;
|
|
221
|
+
if (quantifierAtDepth.length <= depth) quantifierAtDepth.push(false);
|
|
222
|
+
else quantifierAtDepth[depth] = false;
|
|
223
|
+
i++;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (ch === ")") {
|
|
227
|
+
const hadQuantifier = depth > 0 && quantifierAtDepth[depth];
|
|
228
|
+
if (depth > 0) depth--;
|
|
229
|
+
const next = pattern[i + 1];
|
|
230
|
+
if (next === "+" || next === "*" || next === "{") {
|
|
231
|
+
if (hadQuantifier) return false;
|
|
232
|
+
if (depth >= 0 && depth < quantifierAtDepth.length) quantifierAtDepth[depth] = true;
|
|
233
|
+
}
|
|
234
|
+
i++;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (ch === "+" || ch === "*") {
|
|
238
|
+
if (depth > 0) quantifierAtDepth[depth] = true;
|
|
239
|
+
i++;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (ch === "?") {
|
|
243
|
+
const prev = i > 0 ? pattern[i - 1] : "";
|
|
244
|
+
if (prev !== "+" && prev !== "*" && prev !== "?" && prev !== "}") {
|
|
245
|
+
if (depth > 0) quantifierAtDepth[depth] = true;
|
|
246
|
+
}
|
|
247
|
+
i++;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (ch === "{") {
|
|
251
|
+
let j = i + 1;
|
|
252
|
+
while (j < pattern.length && /[\d,]/.test(pattern[j])) j++;
|
|
253
|
+
if (j < pattern.length && pattern[j] === "}" && j > i + 1) {
|
|
254
|
+
if (depth > 0) quantifierAtDepth[depth] = true;
|
|
255
|
+
i = j + 1;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
i++;
|
|
260
|
+
}
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Compile a regex pattern safely. Returns the compiled RegExp or null if the
|
|
265
|
+
* pattern is invalid or vulnerable to ReDoS.
|
|
266
|
+
*
|
|
267
|
+
* Logs a warning when a pattern is rejected so developers can fix their config.
|
|
268
|
+
*/
|
|
269
|
+
function safeRegExp(pattern, flags) {
|
|
270
|
+
if (!isSafeRegex(pattern)) {
|
|
271
|
+
console.warn(`[vinext] Rejecting potentially unsafe regex pattern (ReDoS risk): ${pattern}\n Patterns with nested quantifiers (e.g. (a+)+) can cause catastrophic backtracking.\n Simplify the pattern to avoid nested repetition.`);
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
return new RegExp(pattern, flags);
|
|
276
|
+
} catch {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Convert a Next.js header/rewrite/redirect source pattern into a regex string.
|
|
282
|
+
*
|
|
283
|
+
* Regex groups in the source (e.g. `(\d+)`) are extracted first, the remaining
|
|
284
|
+
* text is escaped/converted in a **single pass** (avoiding chained `.replace()`
|
|
285
|
+
* which CodeQL flags as incomplete sanitization), then groups are restored.
|
|
286
|
+
*/
|
|
287
|
+
function escapeHeaderSource(source) {
|
|
288
|
+
const S = "";
|
|
289
|
+
const groups = [];
|
|
290
|
+
const withPlaceholders = source.replace(/\(([^)]+)\)/g, (_m, inner) => {
|
|
291
|
+
groups.push(inner);
|
|
292
|
+
return `${S}G${groups.length - 1}${S}`;
|
|
293
|
+
});
|
|
294
|
+
let result = "";
|
|
295
|
+
const re = new RegExp(`${S}G(\\d+)${S}|:[\\w-]+|[.+?*]|[^.+?*:\\uE000]+`, "g");
|
|
296
|
+
let m;
|
|
297
|
+
while ((m = re.exec(withPlaceholders)) !== null) if (m[1] !== void 0) result += `(${groups[Number(m[1])]})`;
|
|
298
|
+
else if (m[0].startsWith(":")) {
|
|
299
|
+
const constraintMatch = withPlaceholders.slice(re.lastIndex).match(new RegExp(`^${S}G(\\d+)${S}`));
|
|
300
|
+
if (constraintMatch) {
|
|
301
|
+
re.lastIndex += constraintMatch[0].length;
|
|
302
|
+
result += `(${groups[Number(constraintMatch[1])]})`;
|
|
303
|
+
} else result += "[^/]+";
|
|
304
|
+
} else switch (m[0]) {
|
|
305
|
+
case ".":
|
|
306
|
+
result += "\\.";
|
|
307
|
+
break;
|
|
308
|
+
case "+":
|
|
309
|
+
result += "\\+";
|
|
310
|
+
break;
|
|
311
|
+
case "?":
|
|
312
|
+
result += "\\?";
|
|
313
|
+
break;
|
|
314
|
+
case "*":
|
|
315
|
+
result += ".*";
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
result += m[0];
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
const _BASEPATH_DEFAULT = {
|
|
324
|
+
basePath: "",
|
|
325
|
+
hadBasePath: true
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Decide whether a rule should be evaluated at all given the current
|
|
329
|
+
* basePath-gating state.
|
|
330
|
+
*
|
|
331
|
+
* Encodes the Next.js rules:
|
|
332
|
+
* - basePath: false rule → only when the request was NOT under basePath
|
|
333
|
+
* (i.e. it's the explicit opt-out path). When `basePath` itself is
|
|
334
|
+
* empty, basePath: false rules are still allowed to match — there's
|
|
335
|
+
* just no basePath to gate them.
|
|
336
|
+
* - default rule (basePath !== false) → only when the request WAS under
|
|
337
|
+
* basePath (or no basePath is configured).
|
|
338
|
+
*/
|
|
339
|
+
function shouldEvaluateRule(ruleBasePath, state) {
|
|
340
|
+
if (!state.basePath) return true;
|
|
341
|
+
return ruleBasePath === false ? !state.hadBasePath : state.hadBasePath;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Parse a Cookie header string into a key-value record.
|
|
345
|
+
*/
|
|
346
|
+
function parseCookies(cookieHeader) {
|
|
347
|
+
return parseCookieHeader(cookieHeader);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Build a RequestContext from a Web Request object.
|
|
351
|
+
*
|
|
352
|
+
* `cookies` and `query` are lazy memoized getters: they are consumed only by
|
|
353
|
+
* `has`/`missing` condition evaluation (`checkHasConditions` /
|
|
354
|
+
* `matchesRuleConditions`), and most apps configure no such conditions. The
|
|
355
|
+
* cookie split and `searchParams` access are therefore deferred until first
|
|
356
|
+
* read and computed at most once. Mirrors `headersContextFromRequest` in
|
|
357
|
+
* `shims/headers.ts`.
|
|
358
|
+
*/
|
|
359
|
+
function requestContextFromRequest(request) {
|
|
360
|
+
const url = new URL(request.url);
|
|
361
|
+
let cookies;
|
|
362
|
+
let query;
|
|
363
|
+
return {
|
|
364
|
+
headers: request.headers,
|
|
365
|
+
get cookies() {
|
|
366
|
+
return cookies ??= parseCookies(request.headers.get("cookie"));
|
|
367
|
+
},
|
|
368
|
+
get query() {
|
|
369
|
+
return query ??= url.searchParams;
|
|
370
|
+
},
|
|
371
|
+
host: normalizeHost(request.headers.get("host"), url.hostname)
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function normalizeHost(hostHeader, fallbackHostname) {
|
|
375
|
+
return (hostHeader ?? fallbackHostname).split(":", 1)[0].toLowerCase();
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Unpack `x-middleware-request-*` headers from the collected middleware
|
|
379
|
+
* response headers into the actual request, and strip all `x-middleware-*`
|
|
380
|
+
* internal signals so they never reach clients.
|
|
381
|
+
*
|
|
382
|
+
* `middlewareHeaders` is mutated in-place (matching keys are deleted).
|
|
383
|
+
* Returns a (possibly cloned) `Request` with the unpacked headers applied,
|
|
384
|
+
* and a fresh `RequestContext` built from it — ready for post-middleware
|
|
385
|
+
* config rule matching (beforeFiles, afterFiles, fallback).
|
|
386
|
+
*
|
|
387
|
+
* Works for both Node.js requests (mutable headers) and Workers requests
|
|
388
|
+
* (immutable — cloned only when there are headers to apply).
|
|
389
|
+
*
|
|
390
|
+
* `x-middleware-request-*` values are always plain strings (they carry
|
|
391
|
+
* individual header values), so the wider `string | string[]` type of
|
|
392
|
+
* `middlewareHeaders` is safe to cast here.
|
|
393
|
+
*/
|
|
394
|
+
function applyMiddlewareRequestHeaders(middlewareHeaders, request, options = {}) {
|
|
395
|
+
const nextHeaders = buildRequestHeadersFromMiddlewareResponse(request.headers, middlewareHeaders, options);
|
|
396
|
+
for (const key of Object.keys(middlewareHeaders)) if (key.startsWith("x-middleware-")) delete middlewareHeaders[key];
|
|
397
|
+
if (nextHeaders) request = new Request(request.url, {
|
|
398
|
+
method: request.method,
|
|
399
|
+
headers: nextHeaders,
|
|
400
|
+
body: request.body,
|
|
401
|
+
duplex: request.body ? "half" : void 0
|
|
402
|
+
});
|
|
403
|
+
return {
|
|
404
|
+
request,
|
|
405
|
+
postMwReqCtx: requestContextFromRequest(request)
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function _emptyParams() {
|
|
409
|
+
return Object.create(null);
|
|
410
|
+
}
|
|
411
|
+
function _matchConditionValue(actualValue, expectedValue) {
|
|
412
|
+
if (expectedValue === void 0) return _emptyParams();
|
|
413
|
+
const re = _cachedConditionRegex(expectedValue);
|
|
414
|
+
if (re) {
|
|
415
|
+
const match = re.exec(actualValue);
|
|
416
|
+
if (!match) return null;
|
|
417
|
+
const params = _emptyParams();
|
|
418
|
+
if (match.groups) {
|
|
419
|
+
for (const [key, value] of Object.entries(match.groups)) if (value !== void 0) params[key] = value;
|
|
420
|
+
}
|
|
421
|
+
return params;
|
|
422
|
+
}
|
|
423
|
+
return actualValue === expectedValue ? _emptyParams() : null;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Check a single has/missing condition against request context.
|
|
427
|
+
* Returns captured params when the condition is satisfied, or null otherwise.
|
|
428
|
+
*/
|
|
429
|
+
function matchSingleCondition(condition, ctx) {
|
|
430
|
+
switch (condition.type) {
|
|
431
|
+
case "header": {
|
|
432
|
+
const headerValue = ctx.headers.get(condition.key);
|
|
433
|
+
if (headerValue === null) return null;
|
|
434
|
+
return _matchConditionValue(headerValue, condition.value);
|
|
435
|
+
}
|
|
436
|
+
case "cookie": {
|
|
437
|
+
if (!Object.hasOwn(ctx.cookies, condition.key)) return null;
|
|
438
|
+
const cookieValue = ctx.cookies[condition.key];
|
|
439
|
+
return _matchConditionValue(cookieValue, condition.value);
|
|
440
|
+
}
|
|
441
|
+
case "query": {
|
|
442
|
+
const queryValue = ctx.query.get(condition.key);
|
|
443
|
+
if (queryValue === null) return null;
|
|
444
|
+
return _matchConditionValue(queryValue, condition.value);
|
|
445
|
+
}
|
|
446
|
+
case "host":
|
|
447
|
+
if (condition.value !== void 0) return _matchConditionValue(ctx.host, condition.value);
|
|
448
|
+
return ctx.host === condition.key ? _emptyParams() : null;
|
|
449
|
+
default: return null;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Return a cached RegExp for a has/missing condition value string, compiling
|
|
454
|
+
* on first use. Returns null if safeRegExp rejected the pattern or if the
|
|
455
|
+
* value is not a valid regex (fall back to exact string comparison).
|
|
456
|
+
*/
|
|
457
|
+
function _cachedConditionRegex(value) {
|
|
458
|
+
return getCachedRegex(_compiledConditionCache, value, () => safeRegExp(`^${value}$`));
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Check all has/missing conditions for a config rule.
|
|
462
|
+
* Returns true if the rule should be applied (all has conditions pass, all missing conditions pass).
|
|
463
|
+
*
|
|
464
|
+
* - has: every condition must match (the request must have it)
|
|
465
|
+
* - missing: every condition must NOT match (the request must not have it)
|
|
466
|
+
*/
|
|
467
|
+
function collectConditionParams(has, missing, ctx) {
|
|
468
|
+
const params = _emptyParams();
|
|
469
|
+
if (has) for (const condition of has) {
|
|
470
|
+
const conditionParams = matchSingleCondition(condition, ctx);
|
|
471
|
+
if (!conditionParams) return null;
|
|
472
|
+
Object.assign(params, conditionParams);
|
|
473
|
+
}
|
|
474
|
+
if (missing) {
|
|
475
|
+
for (const condition of missing) if (matchSingleCondition(condition, ctx)) return null;
|
|
476
|
+
}
|
|
477
|
+
return params;
|
|
478
|
+
}
|
|
479
|
+
function checkHasConditions(has, missing, ctx) {
|
|
480
|
+
return collectConditionParams(has, missing, ctx) !== null;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* If the current position in `str` starts with a parenthesized group, consume
|
|
484
|
+
* it and advance `re.lastIndex` past the closing `)`. Returns the group
|
|
485
|
+
* contents or null if no group is present.
|
|
486
|
+
*/
|
|
487
|
+
function extractConstraint(str, re) {
|
|
488
|
+
if (str[re.lastIndex] !== "(") return null;
|
|
489
|
+
const start = re.lastIndex + 1;
|
|
490
|
+
let depth = 1;
|
|
491
|
+
let i = start;
|
|
492
|
+
while (i < str.length && depth > 0) {
|
|
493
|
+
if (str[i] === "(") depth++;
|
|
494
|
+
else if (str[i] === ")") depth--;
|
|
495
|
+
i++;
|
|
496
|
+
}
|
|
497
|
+
if (depth !== 0) return null;
|
|
498
|
+
re.lastIndex = i;
|
|
499
|
+
return str.slice(start, i - 1);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Match a Next.js config pattern (from redirects/rewrites sources) against a pathname.
|
|
503
|
+
* Returns matched params or null.
|
|
504
|
+
*
|
|
505
|
+
* Supports:
|
|
506
|
+
* :param - matches a single path segment
|
|
507
|
+
* :param* - matches zero or more segments (catch-all)
|
|
508
|
+
* :param+ - matches one or more segments
|
|
509
|
+
* (regex) - inline regex patterns in the source
|
|
510
|
+
* :param(constraint) - named param with inline regex constraint
|
|
511
|
+
*/
|
|
512
|
+
/**
|
|
513
|
+
* Strip a single trailing slash from a pathname for config-source matching.
|
|
514
|
+
*
|
|
515
|
+
* Next.js conditionally appends `(/)?` to rewrite/redirect/header source
|
|
516
|
+
* regexes when `trailingSlash: true` (see Next.js
|
|
517
|
+
* `resolve-rewrites.ts` and `server-utils.ts:checkRewrite`). Rather than
|
|
518
|
+
* threading the trailingSlash flag through every matcher, we unconditionally
|
|
519
|
+
* strip a trailing slash from the incoming pathname. When `trailingSlash: false`
|
|
520
|
+
* the request pipeline emits a normalizing redirect (step 3) before config
|
|
521
|
+
* rewrites/redirects (step 6) ever run, so the pathname is already slash-free;
|
|
522
|
+
* the unconditional strip is defense-in-depth for that ordering. When
|
|
523
|
+
* `trailingSlash: true` it bridges the gap between the canonicalized request
|
|
524
|
+
* path (`/rewrite-1/`) and source patterns written without a trailing slash
|
|
525
|
+
* (`/rewrite-1`).
|
|
526
|
+
*
|
|
527
|
+
* The root path `"/"` is preserved as-is.
|
|
528
|
+
*/
|
|
529
|
+
function stripTrailingSlashForConfigMatch(pathname) {
|
|
530
|
+
return pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
|
|
531
|
+
}
|
|
532
|
+
function matchConfigPattern(pathname, pattern) {
|
|
533
|
+
pathname = stripTrailingSlashForConfigMatch(pathname);
|
|
534
|
+
const catchAllAnchor = /:[\w-]+[*+]/.test(pattern);
|
|
535
|
+
const namedParamCount = (pattern.match(/:[\w-]+/g) || []).length;
|
|
536
|
+
if (pattern.includes("(") || pattern.includes("\\") || /:[\w-]+[*+][^/]/.test(pattern) || /:[\w-]+\./.test(pattern) || /[^/]:[\w-]+/.test(pattern) || catchAllAnchor && namedParamCount > 1) try {
|
|
537
|
+
const compiled = getCachedRegex(_compiledPatternCache, pattern, () => {
|
|
538
|
+
const paramNames = [];
|
|
539
|
+
let regexStr = "";
|
|
540
|
+
const tokenRe = /:([\w-]+)|[.]|[^:.]+/g;
|
|
541
|
+
let tok;
|
|
542
|
+
while ((tok = tokenRe.exec(pattern)) !== null) if (tok[1] !== void 0) {
|
|
543
|
+
const name = tok[1];
|
|
544
|
+
const rest = pattern.slice(tokenRe.lastIndex);
|
|
545
|
+
if (rest.startsWith("*") || rest.startsWith("+")) {
|
|
546
|
+
const quantifier = rest[0];
|
|
547
|
+
tokenRe.lastIndex += 1;
|
|
548
|
+
const constraint = extractConstraint(pattern, tokenRe);
|
|
549
|
+
paramNames.push(name);
|
|
550
|
+
if (constraint !== null) regexStr += `(${constraint})`;
|
|
551
|
+
else regexStr += quantifier === "*" ? "(.*)" : "(.+)";
|
|
552
|
+
} else {
|
|
553
|
+
const constraint = extractConstraint(pattern, tokenRe);
|
|
554
|
+
paramNames.push(name);
|
|
555
|
+
regexStr += constraint !== null ? `(${constraint})` : "([^/]+)";
|
|
556
|
+
}
|
|
557
|
+
} else if (tok[0] === ".") regexStr += "\\.";
|
|
558
|
+
else regexStr += tok[0];
|
|
559
|
+
const re = safeRegExp("^" + regexStr + "$");
|
|
560
|
+
return re ? {
|
|
561
|
+
re,
|
|
562
|
+
paramNames
|
|
563
|
+
} : null;
|
|
564
|
+
});
|
|
565
|
+
if (!compiled) return null;
|
|
566
|
+
const match = compiled.re.exec(pathname);
|
|
567
|
+
if (!match) return null;
|
|
568
|
+
const params = Object.create(null);
|
|
569
|
+
for (let i = 0; i < compiled.paramNames.length; i++) params[compiled.paramNames[i]] = match[i + 1] ?? "";
|
|
570
|
+
return params;
|
|
571
|
+
} catch {}
|
|
572
|
+
const catchAllMatch = pattern.match(/:([\w-]+)(\*|\+)$/);
|
|
573
|
+
if (catchAllMatch) {
|
|
574
|
+
const prefix = pattern.slice(0, pattern.lastIndexOf(":"));
|
|
575
|
+
const paramName = catchAllMatch[1];
|
|
576
|
+
const isPlus = catchAllMatch[2] === "+";
|
|
577
|
+
const prefixNoSlash = prefix.replace(/\/$/, "");
|
|
578
|
+
if (!pathname.startsWith(prefixNoSlash)) return null;
|
|
579
|
+
const charAfter = pathname[prefixNoSlash.length];
|
|
580
|
+
if (charAfter !== void 0 && charAfter !== "/") return null;
|
|
581
|
+
const rest = pathname.slice(prefixNoSlash.length);
|
|
582
|
+
if (isPlus && (!rest || rest === "/")) return null;
|
|
583
|
+
let restValue = rest.startsWith("/") ? rest.slice(1) : rest;
|
|
584
|
+
return { [paramName]: restValue };
|
|
585
|
+
}
|
|
586
|
+
const parts = pattern.split("/");
|
|
587
|
+
const pathParts = pathname.split("/");
|
|
588
|
+
if (parts.length !== pathParts.length) return null;
|
|
589
|
+
const params = Object.create(null);
|
|
590
|
+
for (let i = 0; i < parts.length; i++) if (parts[i].startsWith(":")) params[parts[i].slice(1)] = pathParts[i];
|
|
591
|
+
else if (parts[i] !== pathParts[i]) return null;
|
|
592
|
+
return params;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Apply redirect rules from next.config.js.
|
|
596
|
+
* Returns the redirect info if a redirect was matched, or null.
|
|
597
|
+
*
|
|
598
|
+
* `ctx` provides the request context (cookies, headers, query, host) used
|
|
599
|
+
* to evaluate has/missing conditions. Next.js always has request context
|
|
600
|
+
* when evaluating redirects, so this parameter is required.
|
|
601
|
+
*
|
|
602
|
+
* ## Performance
|
|
603
|
+
*
|
|
604
|
+
* Rules with a locale-capture-group prefix (the dominant pattern in large
|
|
605
|
+
* Next.js apps — e.g. `/:locale(en|es|fr|...)?/some-path`) are handled via
|
|
606
|
+
* a pre-built index. Instead of running exec() on each locale regex
|
|
607
|
+
* individually, we:
|
|
608
|
+
*
|
|
609
|
+
* 1. Strip the optional locale prefix from the pathname with one cheap
|
|
610
|
+
* string-slice check (no regex exec on the hot path).
|
|
611
|
+
* 2. Look up the stripped suffix in a Map<suffix, entry[]>.
|
|
612
|
+
* 3. For each matching entry, validate the captured locale string against
|
|
613
|
+
* a small, anchored alternation regex.
|
|
614
|
+
*
|
|
615
|
+
* This reduces the per-request cost from O(n × regex) to O(1) map lookup +
|
|
616
|
+
* O(matches × tiny-regex), eliminating the ~2992ms self-time reported in
|
|
617
|
+
* profiles for apps with 63+ locale-prefixed rules.
|
|
618
|
+
*
|
|
619
|
+
* Rules that don't fit the locale-static pattern fall back to the original
|
|
620
|
+
* linear matchConfigPattern scan.
|
|
621
|
+
*
|
|
622
|
+
* ## Ordering invariant
|
|
623
|
+
*
|
|
624
|
+
* First match wins, preserving the original redirect array order. When a
|
|
625
|
+
* locale-static fast-path match is found at position N, all linear rules with
|
|
626
|
+
* an original index < N are checked via matchConfigPattern first — they are
|
|
627
|
+
* few in practice (typically zero) so this is not a hot-path concern.
|
|
628
|
+
*/
|
|
629
|
+
function matchRedirect(pathname, redirects, ctx, basePathState = _BASEPATH_DEFAULT) {
|
|
630
|
+
if (redirects.length === 0) return null;
|
|
631
|
+
pathname = stripTrailingSlashForConfigMatch(pathname);
|
|
632
|
+
const index = _getRedirectIndex(redirects);
|
|
633
|
+
let localeMatch = null;
|
|
634
|
+
let localeMatchIndex = Infinity;
|
|
635
|
+
if (index.localeStatic.size > 0) {
|
|
636
|
+
const noLocaleBucket = index.localeStatic.get(pathname);
|
|
637
|
+
if (noLocaleBucket) for (const entry of noLocaleBucket) {
|
|
638
|
+
if (!entry.optional) continue;
|
|
639
|
+
if (entry.originalIndex >= localeMatchIndex) continue;
|
|
640
|
+
const redirect = entry.redirect;
|
|
641
|
+
if (!shouldEvaluateRule(redirect.basePath, basePathState)) continue;
|
|
642
|
+
const conditionParams = redirect.has || redirect.missing ? collectConditionParams(redirect.has, redirect.missing, ctx) : _emptyParams();
|
|
643
|
+
if (!conditionParams) continue;
|
|
644
|
+
localeMatch = {
|
|
645
|
+
destination: substituteAndSanitizeDestination(redirect.destination, {
|
|
646
|
+
[entry.paramName]: "",
|
|
647
|
+
...conditionParams
|
|
648
|
+
}),
|
|
649
|
+
permanent: redirect.permanent
|
|
650
|
+
};
|
|
651
|
+
localeMatchIndex = entry.originalIndex;
|
|
652
|
+
break;
|
|
653
|
+
}
|
|
654
|
+
const slashTwo = pathname.indexOf("/", 1);
|
|
655
|
+
if (slashTwo !== -1) {
|
|
656
|
+
const suffix = pathname.slice(slashTwo);
|
|
657
|
+
const localePart = pathname.slice(1, slashTwo);
|
|
658
|
+
const localeBucket = index.localeStatic.get(suffix);
|
|
659
|
+
if (localeBucket) for (const entry of localeBucket) {
|
|
660
|
+
if (entry.originalIndex >= localeMatchIndex) continue;
|
|
661
|
+
if (!entry.altRe.test(localePart)) continue;
|
|
662
|
+
const redirect = entry.redirect;
|
|
663
|
+
if (!shouldEvaluateRule(redirect.basePath, basePathState)) continue;
|
|
664
|
+
const conditionParams = redirect.has || redirect.missing ? collectConditionParams(redirect.has, redirect.missing, ctx) : _emptyParams();
|
|
665
|
+
if (!conditionParams) continue;
|
|
666
|
+
localeMatch = {
|
|
667
|
+
destination: substituteAndSanitizeDestination(redirect.destination, {
|
|
668
|
+
[entry.paramName]: localePart,
|
|
669
|
+
...conditionParams
|
|
670
|
+
}),
|
|
671
|
+
permanent: redirect.permanent
|
|
672
|
+
};
|
|
673
|
+
localeMatchIndex = entry.originalIndex;
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
for (const [origIdx, redirect] of index.linear) {
|
|
679
|
+
if (origIdx >= localeMatchIndex) break;
|
|
680
|
+
if (!shouldEvaluateRule(redirect.basePath, basePathState)) continue;
|
|
681
|
+
const params = matchConfigPattern(pathname, redirect.source);
|
|
682
|
+
if (params) {
|
|
683
|
+
const conditionParams = redirect.has || redirect.missing ? collectConditionParams(redirect.has, redirect.missing, ctx) : _emptyParams();
|
|
684
|
+
if (!conditionParams) continue;
|
|
685
|
+
return {
|
|
686
|
+
destination: substituteAndSanitizeDestination(redirect.destination, {
|
|
687
|
+
...params,
|
|
688
|
+
...conditionParams
|
|
689
|
+
}),
|
|
690
|
+
permanent: redirect.permanent
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return localeMatch;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Apply rewrite rules from next.config.js.
|
|
698
|
+
* Returns the rewritten URL or null if no rewrite matched.
|
|
699
|
+
*
|
|
700
|
+
* `ctx` provides the request context (cookies, headers, query, host) used
|
|
701
|
+
* to evaluate has/missing conditions. Next.js always has request context
|
|
702
|
+
* when evaluating rewrites, so this parameter is required.
|
|
703
|
+
*/
|
|
704
|
+
function matchRewrite(pathname, rewrites, ctx, basePathState = _BASEPATH_DEFAULT) {
|
|
705
|
+
for (const rewrite of rewrites) {
|
|
706
|
+
if (!shouldEvaluateRule(rewrite.basePath, basePathState)) continue;
|
|
707
|
+
const params = matchConfigPattern(pathname, rewrite.source);
|
|
708
|
+
if (params) {
|
|
709
|
+
const conditionParams = rewrite.has || rewrite.missing ? collectConditionParams(rewrite.has, rewrite.missing, ctx) : _emptyParams();
|
|
710
|
+
if (!conditionParams) continue;
|
|
711
|
+
const rewriteParams = {
|
|
712
|
+
...params,
|
|
713
|
+
...conditionParams
|
|
714
|
+
};
|
|
715
|
+
return substituteAndSanitizeRewriteDestination(rewrite.destination, rewriteParams);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return null;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Check whether a rewrite source can match a pathname without evaluating its
|
|
722
|
+
* request-dependent `has` / `missing` conditions.
|
|
723
|
+
*
|
|
724
|
+
* Dev uses this only as a conservative preflight before middleware runs. The
|
|
725
|
+
* conditions may become true after middleware overrides request headers, so
|
|
726
|
+
* evaluating them against the original request would incorrectly skip the
|
|
727
|
+
* Pages request pipeline for file-looking paths.
|
|
728
|
+
*/
|
|
729
|
+
function matchesRewriteSource(pathname, rewrite, basePathState = _BASEPATH_DEFAULT) {
|
|
730
|
+
return shouldEvaluateRule(rewrite.basePath, basePathState) && matchConfigPattern(pathname, rewrite.source) !== null;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Substitute all matched route params into a redirect/rewrite destination.
|
|
734
|
+
*
|
|
735
|
+
* Handles repeated params (e.g. `/api/:id/:id`) and catch-all suffix forms
|
|
736
|
+
* (`:path*`, `:path+`) in a single pass. Unknown params are left intact.
|
|
737
|
+
*/
|
|
738
|
+
function substituteDestinationParams(destination, params) {
|
|
739
|
+
const keys = Object.keys(params);
|
|
740
|
+
if (keys.length === 0) return destination;
|
|
741
|
+
const sortedKeys = [...keys].sort((a, b) => b.length - a.length);
|
|
742
|
+
const cacheKey = sortedKeys.join("\0");
|
|
743
|
+
let paramRe = _compiledDestinationParamCache.get(cacheKey);
|
|
744
|
+
if (!paramRe) {
|
|
745
|
+
const paramAlternation = sortedKeys.map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
746
|
+
paramRe = new RegExp(`:(${paramAlternation})([+*])?(?![A-Za-z0-9_])`, "g");
|
|
747
|
+
_compiledDestinationParamCache.set(cacheKey, paramRe);
|
|
748
|
+
}
|
|
749
|
+
return destination.replace(paramRe, (_token, key) => params[key]);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Substitute params into a redirect/rewrite destination and sanitize the
|
|
753
|
+
* result. Used by every redirect/rewrite branch — the substitution can
|
|
754
|
+
* introduce protocol-relative URLs (e.g. `//evil.com` from a decoded `%2F`
|
|
755
|
+
* in a catch-all param), which sanitizeDestination collapses.
|
|
756
|
+
*/
|
|
757
|
+
function substituteAndSanitizeDestination(destination, params) {
|
|
758
|
+
return sanitizeDestination(substituteDestinationParams(destination, params));
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Match Next.js's rewrite-specific prepareDestination behavior: source params
|
|
762
|
+
* that are not consumed by the destination path/host are exposed to the target
|
|
763
|
+
* page through query.
|
|
764
|
+
*
|
|
765
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
|
|
766
|
+
*/
|
|
767
|
+
function substituteAndSanitizeRewriteDestination(destination, params) {
|
|
768
|
+
const rewritten = substituteAndSanitizeDestination(destination, params);
|
|
769
|
+
if (!shouldAppendRewriteParamsToQuery(destination, params)) return rewritten;
|
|
770
|
+
const existingQueryKeys = getDestinationQueryKeys(destination);
|
|
771
|
+
const paramsToAppend = [];
|
|
772
|
+
for (const [key, value] of Object.entries(params)) {
|
|
773
|
+
if (key === "nextInternalLocale" || existingQueryKeys.has(key)) continue;
|
|
774
|
+
paramsToAppend.push([key, value]);
|
|
775
|
+
}
|
|
776
|
+
if (paramsToAppend.length === 0) return rewritten;
|
|
777
|
+
return appendQueryParams(rewritten, paramsToAppend);
|
|
778
|
+
}
|
|
779
|
+
function shouldAppendRewriteParamsToQuery(destination, params) {
|
|
780
|
+
const keys = Object.keys(params).filter((key) => key !== "nextInternalLocale");
|
|
781
|
+
if (keys.length === 0) return false;
|
|
782
|
+
return !destinationPathOrHostUsesParam(destination, keys);
|
|
783
|
+
}
|
|
784
|
+
function destinationPathOrHostUsesParam(destination, keys) {
|
|
785
|
+
const pathAndHost = getDestinationPathAndHost(destination);
|
|
786
|
+
if (!pathAndHost) return false;
|
|
787
|
+
for (const key of keys) {
|
|
788
|
+
const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
789
|
+
if (new RegExp(`:${escapedKey}([+*])?(?![A-Za-z0-9_])`).test(pathAndHost)) return true;
|
|
790
|
+
}
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
function getDestinationPathAndHost(destination) {
|
|
794
|
+
const hashIndex = destination.indexOf("#");
|
|
795
|
+
const beforeHash = hashIndex === -1 ? destination : destination.slice(0, hashIndex);
|
|
796
|
+
const hash = hashIndex === -1 ? "" : destination.slice(hashIndex);
|
|
797
|
+
const queryIndex = beforeHash.indexOf("?");
|
|
798
|
+
const beforeQuery = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);
|
|
799
|
+
const schemeMatch = /^[a-z][a-z0-9+.-]*:\/\//i.exec(beforeQuery);
|
|
800
|
+
if (!schemeMatch) return `${beforeQuery}${hash}`;
|
|
801
|
+
const withoutScheme = beforeQuery.slice(schemeMatch[0].length);
|
|
802
|
+
const slashIndex = withoutScheme.indexOf("/");
|
|
803
|
+
if (slashIndex === -1) return `${withoutScheme}${hash}`;
|
|
804
|
+
return `${withoutScheme.slice(0, slashIndex)}${withoutScheme.slice(slashIndex)}${hash}`;
|
|
805
|
+
}
|
|
806
|
+
function getDestinationQueryKeys(destination) {
|
|
807
|
+
const hashIndex = destination.indexOf("#");
|
|
808
|
+
const beforeHash = hashIndex === -1 ? destination : destination.slice(0, hashIndex);
|
|
809
|
+
const queryIndex = beforeHash.indexOf("?");
|
|
810
|
+
if (queryIndex === -1) return /* @__PURE__ */ new Set();
|
|
811
|
+
const query = beforeHash.slice(queryIndex + 1);
|
|
812
|
+
return new Set(new URLSearchParams(query).keys());
|
|
813
|
+
}
|
|
814
|
+
function appendQueryParams(url, params) {
|
|
815
|
+
const hashIndex = url.indexOf("#");
|
|
816
|
+
const beforeHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
817
|
+
const hash = hashIndex === -1 ? "" : url.slice(hashIndex);
|
|
818
|
+
const queryIndex = beforeHash.indexOf("?");
|
|
819
|
+
const base = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);
|
|
820
|
+
const query = queryIndex === -1 ? "" : beforeHash.slice(queryIndex + 1);
|
|
821
|
+
const merged = new URLSearchParams(query);
|
|
822
|
+
for (const [key, value] of params) merged.append(key, value);
|
|
823
|
+
const search = merged.toString();
|
|
824
|
+
return `${base}${search ? `?${search}` : ""}${hash}`;
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Sanitize a redirect/rewrite destination to collapse protocol-relative URLs.
|
|
828
|
+
*
|
|
829
|
+
* After parameter substitution, a destination like `/:path*` can become
|
|
830
|
+
* `//evil.com` if the catch-all captured a decoded `%2F` (`/evil.com`).
|
|
831
|
+
* Browsers interpret `//evil.com` as a protocol-relative URL, redirecting
|
|
832
|
+
* users off-site.
|
|
833
|
+
*
|
|
834
|
+
* This function collapses any leading double (or more) slashes to a single
|
|
835
|
+
* slash for non-external (relative) destinations.
|
|
836
|
+
*/
|
|
837
|
+
function sanitizeDestination(dest) {
|
|
838
|
+
if (dest.startsWith("http://") || dest.startsWith("https://")) return dest;
|
|
839
|
+
dest = dest.replace(/^[\\/]+/, "/");
|
|
840
|
+
return dest;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Check if a URL is external (absolute URL or protocol-relative).
|
|
844
|
+
* Detects any URL scheme (http:, https:, data:, javascript:, blob:, etc.)
|
|
845
|
+
* per RFC 3986, plus protocol-relative URLs (//).
|
|
846
|
+
*/
|
|
847
|
+
function isExternalUrl(url) {
|
|
848
|
+
return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith("//");
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Merge the original request's query params into a config-redirect
|
|
852
|
+
* destination, preserving them on the resulting `Location`.
|
|
853
|
+
*
|
|
854
|
+
* Next.js carries the original request query across config redirects
|
|
855
|
+
* (`prepareDestination({ query: parsedUrl.query })` →
|
|
856
|
+
* `stringifyQuery(...)` in resolve-routes.ts). This matters for App Router
|
|
857
|
+
* RSC client navigations: the cache-busting `_rsc` query must survive the
|
|
858
|
+
* redirect so the browser's auto-followed request to the destination is
|
|
859
|
+
* still treated as an RSC fetch. Dropping it breaks RSC fetch semantics
|
|
860
|
+
* (issue #1529).
|
|
861
|
+
*
|
|
862
|
+
* Destination query params win — a request param is only carried over when
|
|
863
|
+
* the destination does not already specify that key. Mirrors the merge
|
|
864
|
+
* semantics in `proxyExternalRequest`. External destinations are returned
|
|
865
|
+
* untouched (a config redirect to another origin should not leak the
|
|
866
|
+
* original request's query).
|
|
867
|
+
*/
|
|
868
|
+
function preserveRedirectDestinationQuery(destination, requestSearch) {
|
|
869
|
+
if (requestSearch === "" || requestSearch === "?" || isExternalUrl(destination)) return destination;
|
|
870
|
+
const requestParams = new URLSearchParams(requestSearch);
|
|
871
|
+
if ([...requestParams.keys()].length === 0) return destination;
|
|
872
|
+
const hashIndex = destination.indexOf("#");
|
|
873
|
+
const hash = hashIndex === -1 ? "" : destination.slice(hashIndex);
|
|
874
|
+
const beforeHash = hashIndex === -1 ? destination : destination.slice(0, hashIndex);
|
|
875
|
+
const queryIndex = beforeHash.indexOf("?");
|
|
876
|
+
const pathPart = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);
|
|
877
|
+
const destQuery = queryIndex === -1 ? "" : beforeHash.slice(queryIndex + 1);
|
|
878
|
+
const merged = new URLSearchParams(destQuery);
|
|
879
|
+
const destKeys = new Set(merged.keys());
|
|
880
|
+
for (const [key, value] of requestParams) if (!destKeys.has(key)) merged.append(key, value);
|
|
881
|
+
const mergedQuery = merged.toString();
|
|
882
|
+
return mergedQuery === "" ? `${pathPart}${hash}` : `${pathPart}?${mergedQuery}${hash}`;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Proxy an incoming request to an external URL and return the upstream response.
|
|
886
|
+
*
|
|
887
|
+
* Used for external rewrites (e.g. `/ph/:path*` → `https://us.i.posthog.com/:path*`).
|
|
888
|
+
* Next.js handles these as server-side reverse proxies, forwarding the request
|
|
889
|
+
* method, headers, and body to the external destination.
|
|
890
|
+
*
|
|
891
|
+
* Works in all runtimes (Node.js, Cloudflare Workers) via the standard fetch() API.
|
|
892
|
+
*/
|
|
893
|
+
async function proxyExternalRequest(request, externalUrl) {
|
|
894
|
+
const originalUrl = new URL(request.url);
|
|
895
|
+
const targetUrl = new URL(externalUrl);
|
|
896
|
+
const destinationKeys = new Set(targetUrl.searchParams.keys());
|
|
897
|
+
for (const [key, value] of originalUrl.searchParams) if (!destinationKeys.has(key)) targetUrl.searchParams.append(key, value);
|
|
898
|
+
const headers = new Headers(request.headers);
|
|
899
|
+
headers.set("host", targetUrl.host);
|
|
900
|
+
stripHopByHopRequestHeaders(headers);
|
|
901
|
+
const keysToDelete = [];
|
|
902
|
+
for (const key of headers.keys()) if (key.startsWith("x-middleware-")) keysToDelete.push(key);
|
|
903
|
+
for (const key of keysToDelete) headers.delete(key);
|
|
904
|
+
headers.delete(VINEXT_PRERENDER_SECRET_HEADER);
|
|
905
|
+
headers.delete(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER);
|
|
906
|
+
headers.delete(VINEXT_MW_CTX_HEADER);
|
|
907
|
+
const method = request.method;
|
|
908
|
+
const hasBody = method !== "GET" && method !== "HEAD";
|
|
909
|
+
const init = {
|
|
910
|
+
method,
|
|
911
|
+
headers,
|
|
912
|
+
redirect: "manual"
|
|
913
|
+
};
|
|
914
|
+
if (hasBody && request.body) {
|
|
915
|
+
init.body = request.body;
|
|
916
|
+
init.duplex = "half";
|
|
917
|
+
}
|
|
918
|
+
const controller = new AbortController();
|
|
919
|
+
const timeout = setTimeout(() => controller.abort(), 3e4);
|
|
920
|
+
let upstreamResponse;
|
|
921
|
+
try {
|
|
922
|
+
upstreamResponse = await fetch(targetUrl.href, {
|
|
923
|
+
...init,
|
|
924
|
+
signal: controller.signal
|
|
925
|
+
});
|
|
926
|
+
} catch (e) {
|
|
927
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
928
|
+
console.error("[vinext] External rewrite proxy timeout:", targetUrl.href);
|
|
929
|
+
return new Response("Gateway Timeout", { status: 504 });
|
|
930
|
+
}
|
|
931
|
+
console.error("[vinext] External rewrite proxy error:", e);
|
|
932
|
+
return new Response("Bad Gateway", { status: 502 });
|
|
933
|
+
} finally {
|
|
934
|
+
clearTimeout(timeout);
|
|
935
|
+
}
|
|
936
|
+
const isNodeRuntime = typeof process !== "undefined" && !!process.versions?.node;
|
|
937
|
+
const responseHeaders = new Headers();
|
|
938
|
+
upstreamResponse.headers.forEach((value, key) => {
|
|
939
|
+
const lower = key.toLowerCase();
|
|
940
|
+
if (HOP_BY_HOP_HEADERS.has(lower)) return;
|
|
941
|
+
if (isNodeRuntime && (lower === "content-encoding" || lower === "content-length")) return;
|
|
942
|
+
responseHeaders.append(key, value);
|
|
943
|
+
});
|
|
944
|
+
return new Response(upstreamResponse.body, {
|
|
945
|
+
status: upstreamResponse.status,
|
|
946
|
+
statusText: upstreamResponse.statusText,
|
|
947
|
+
headers: responseHeaders
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* Apply custom header rules from next.config.js.
|
|
952
|
+
* Returns an array of { key, value } pairs to set on the response.
|
|
953
|
+
*
|
|
954
|
+
* `ctx` provides the request context (cookies, headers, query, host) used
|
|
955
|
+
* to evaluate has/missing conditions. Next.js always has request context
|
|
956
|
+
* when evaluating headers, so this parameter is required.
|
|
957
|
+
*/
|
|
958
|
+
function matchHeaders(pathname, headers, ctx, basePathState = _BASEPATH_DEFAULT) {
|
|
959
|
+
pathname = stripTrailingSlashForConfigMatch(pathname);
|
|
960
|
+
const result = [];
|
|
961
|
+
for (const rule of headers) {
|
|
962
|
+
if (!shouldEvaluateRule(rule.basePath, basePathState)) continue;
|
|
963
|
+
const sourceRegex = getCachedRegex(_compiledHeaderSourceCache, rule.source, () => safeRegExp("^" + escapeHeaderSource(rule.source) + "$"));
|
|
964
|
+
if (sourceRegex && sourceRegex.test(pathname)) {
|
|
965
|
+
if (rule.has || rule.missing) {
|
|
966
|
+
if (!checkHasConditions(rule.has, rule.missing, ctx)) continue;
|
|
967
|
+
}
|
|
968
|
+
result.push(...rule.headers);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return result;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Escape a string for inclusion in a regex character class / alternation.
|
|
975
|
+
* Mirrors `escape-string-regexp` semantics used by Next.js's processRoutes.
|
|
976
|
+
*/
|
|
977
|
+
function _escapeRegexString(value) {
|
|
978
|
+
return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Apply Next.js i18n locale-prefix transformation to a set of redirect or
|
|
982
|
+
* rewrite rules. Mirrors the relevant slice of Next.js's `processRoutes`
|
|
983
|
+
* (load-custom-routes.ts) with one deliberate divergence noted below.
|
|
984
|
+
*
|
|
985
|
+
* For each rule:
|
|
986
|
+
* - If `locale === false` or no i18n is configured, the rule is emitted
|
|
987
|
+
* untouched. This is the core of issue #1336 item 1: with `locale: false`
|
|
988
|
+
* the user-supplied source is matched against the raw locale-prefixed
|
|
989
|
+
* URL so a `:locale` segment in the source captures the prefix itself.
|
|
990
|
+
* - Otherwise an internal locale-capture variant is produced whose source
|
|
991
|
+
* starts with `/:nextInternalLocale(en|sv|nl)` so that locale-prefixed
|
|
992
|
+
* URLs match. For redirects only, a second variant prefixed with
|
|
993
|
+
* `/${defaultLocale}` is also emitted, matching Next.js exactly.
|
|
994
|
+
* - **Vinext divergence**: we ALSO retain the original (unprefixed) source
|
|
995
|
+
* so that requests for the default locale that arrive without a prefix
|
|
996
|
+
* still match. Next.js solves this upstream by path-normalising every
|
|
997
|
+
* incoming default-locale request to include the prefix
|
|
998
|
+
* (`resolve-routes.ts` lines ~251-263); vinext currently does that
|
|
999
|
+
* normalisation only inside the pages-server-entry route matcher, so
|
|
1000
|
+
* the rewrite/redirect matcher would otherwise miss unprefixed paths.
|
|
1001
|
+
* Keeping the unprefixed variant gives functionally identical behaviour
|
|
1002
|
+
* without requiring a server-wide path normalisation pass. The original
|
|
1003
|
+
* source is appended LAST so the locale-aware variants win when both
|
|
1004
|
+
* forms could match.
|
|
1005
|
+
*
|
|
1006
|
+
* Destinations that are local (start with `/`) are similarly rewritten with
|
|
1007
|
+
* `/:nextInternalLocale` for the locale-capture variant so the locale
|
|
1008
|
+
* survives the rewrite/redirect target.
|
|
1009
|
+
*
|
|
1010
|
+
* Mirrors the Next.js reference in
|
|
1011
|
+
* packages/next/src/lib/load-custom-routes.ts — see `processRoutes`.
|
|
1012
|
+
*/
|
|
1013
|
+
function applyLocaleToRoutes(routes, i18n, type, options = {}) {
|
|
1014
|
+
if (!i18n || routes.length === 0) return routes;
|
|
1015
|
+
const trailingSlash = options.trailingSlash ?? false;
|
|
1016
|
+
const internalLocale = `/:nextInternalLocale(${i18n.locales.map(_escapeRegexString).join("|")})`;
|
|
1017
|
+
const suffixFor = (source) => source === "/" && !trailingSlash ? "" : source;
|
|
1018
|
+
const defaultLocales = type === "redirect" ? [i18n.defaultLocale] : [];
|
|
1019
|
+
const out = [];
|
|
1020
|
+
for (const r of routes) {
|
|
1021
|
+
if (r.locale === false) {
|
|
1022
|
+
out.push(r);
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
const isExternal = !!r.destination && !r.destination.startsWith("/");
|
|
1026
|
+
if (!isExternal) for (const locale of defaultLocales) {
|
|
1027
|
+
const localizedSource = `/${locale}${suffixFor(r.source)}`;
|
|
1028
|
+
out.push({
|
|
1029
|
+
...r,
|
|
1030
|
+
source: localizedSource
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
const internalSource = `${internalLocale}${suffixFor(r.source)}`;
|
|
1034
|
+
let internalDestination = r.destination;
|
|
1035
|
+
if (internalDestination && internalDestination.startsWith("/") && !isExternal) internalDestination = `/:nextInternalLocale${internalDestination === "/" && !trailingSlash ? "" : internalDestination}`;
|
|
1036
|
+
out.push({
|
|
1037
|
+
...r,
|
|
1038
|
+
source: internalSource,
|
|
1039
|
+
destination: internalDestination
|
|
1040
|
+
});
|
|
1041
|
+
out.push(r);
|
|
1042
|
+
}
|
|
1043
|
+
return out;
|
|
1044
|
+
}
|
|
1045
|
+
//#endregion
|
|
1046
|
+
export { applyLocaleToRoutes, applyMiddlewareRequestHeaders, checkHasConditions, escapeHeaderSource, isExternalUrl, isSafeRegex, matchConfigPattern, matchHeaders, matchRedirect, matchRewrite, matchesRewriteSource, normalizeHost, parseCookies, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, safeRegExp, sanitizeDestination };
|