vinext 0.0.51 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/build/clean-output.d.ts +14 -0
- package/dist/build/clean-output.js +36 -0
- package/dist/build/clean-output.js.map +1 -0
- package/dist/build/precompress.d.ts +7 -7
- package/dist/build/precompress.js +18 -17
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +9 -16
- package/dist/build/prerender.js +88 -50
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/run-prerender.js +10 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/static-export.d.ts +5 -0
- package/dist/build/static-export.js +8 -3
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.js +4 -0
- package/dist/check.js.map +1 -1
- package/dist/cli-args.d.ts +1 -0
- package/dist/cli-args.js +5 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +58 -4
- package/dist/cli.js.map +1 -1
- package/dist/client/instrumentation-client-inject.d.ts +34 -0
- package/dist/client/instrumentation-client-inject.js +57 -0
- package/dist/client/instrumentation-client-inject.js.map +1 -0
- package/dist/client/navigation-runtime.d.ts +60 -0
- package/dist/client/navigation-runtime.js +171 -0
- package/dist/client/navigation-runtime.js.map +1 -0
- package/dist/client/pages-router-link-navigation.d.ts +26 -0
- package/dist/client/pages-router-link-navigation.js +14 -0
- package/dist/client/pages-router-link-navigation.js.map +1 -0
- package/dist/client/vinext-next-data.d.ts +14 -3
- package/dist/client/vinext-next-data.js +50 -1
- package/dist/client/vinext-next-data.js.map +1 -0
- package/dist/client/window-next.d.ts +10 -2
- package/dist/client/window-next.js.map +1 -1
- package/dist/cloudflare/kv-cache-handler.js +2 -1
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +63 -16
- package/dist/config/config-matchers.js +145 -9
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +32 -5
- package/dist/config/next-config.js +55 -15
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +130 -46
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.js +9 -3
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +4 -2
- package/dist/entries/app-rsc-entry.js +76 -16
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +1 -0
- package/dist/entries/app-rsc-manifest.js +53 -6
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/app-ssr-entry.d.ts +3 -3
- package/dist/entries/app-ssr-entry.js +4 -4
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js +40 -3
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +261 -31
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +2 -1
- package/dist/entries/runtime-entry-module.js +9 -3
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +161 -46
- package/dist/index.js.map +1 -1
- package/dist/plugins/css-data-url.d.ts +7 -0
- package/dist/plugins/css-data-url.js +81 -0
- package/dist/plugins/css-data-url.js.map +1 -0
- package/dist/plugins/fonts.js +30 -5
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/middleware-server-only.d.ts +54 -0
- package/dist/plugins/middleware-server-only.js +91 -0
- package/dist/plugins/middleware-server-only.js.map +1 -0
- package/dist/plugins/optimize-imports.js +4 -4
- package/dist/plugins/optimize-imports.js.map +1 -1
- package/dist/plugins/strip-server-exports.js +5 -8
- package/dist/plugins/strip-server-exports.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +20 -1
- package/dist/routing/app-route-graph.js +58 -6
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.d.ts +2 -2
- package/dist/routing/app-router.js +2 -2
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/route-trie.js +13 -18
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/utils.d.ts +12 -1
- package/dist/routing/utils.js +18 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js +153 -42
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +16 -1
- package/dist/server/app-browser-action-result.js +15 -1
- package/dist/server/app-browser-action-result.js.map +1 -1
- package/dist/server/app-browser-entry.js +309 -155
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-interception-context.d.ts +24 -0
- package/dist/server/app-browser-interception-context.js +32 -0
- package/dist/server/app-browser-interception-context.js.map +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +3 -1
- package/dist/server/app-browser-navigation-controller.js +5 -1
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-rsc-redirect.d.ts +2 -1
- package/dist/server/app-browser-rsc-redirect.js +2 -2
- package/dist/server/app-browser-rsc-redirect.js.map +1 -1
- package/dist/server/app-browser-state.d.ts +18 -1
- package/dist/server/app-browser-state.js +19 -1
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +5 -14
- package/dist/server/app-browser-stream.js +13 -7
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +2 -1
- package/dist/server/app-browser-visible-commit.js +1 -0
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +10 -5
- package/dist/server/app-elements-wire.js +84 -2
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +3 -2
- package/dist/server/app-elements.js +3 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +12 -3
- package/dist/server/app-fallback-renderer.js +15 -8
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-history-state.js +6 -2
- package/dist/server/app-history-state.js.map +1 -1
- package/dist/server/app-interception-context-header.d.ts +33 -0
- package/dist/server/app-interception-context-header.js +44 -0
- package/dist/server/app-interception-context-header.js.map +1 -0
- package/dist/server/app-middleware.d.ts +13 -0
- package/dist/server/app-middleware.js +3 -1
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-mounted-slots-header.d.ts +19 -0
- package/dist/server/app-mounted-slots-header.js +40 -1
- package/dist/server/app-mounted-slots-header.js.map +1 -1
- package/dist/server/app-optimistic-routing.d.ts +54 -0
- package/dist/server/app-optimistic-routing.js +208 -0
- package/dist/server/app-optimistic-routing.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +2 -0
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +1 -0
- package/dist/server/app-page-boundary.js +2 -0
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +15 -1
- package/dist/server/app-page-cache.js +68 -7
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +5 -0
- package/dist/server/app-page-dispatch.js +39 -5
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +7 -3
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +29 -1
- package/dist/server/app-page-execution.js +91 -4
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +1 -0
- package/dist/server/app-page-head.js +29 -2
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-probe.js +1 -1
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-render.d.ts +3 -0
- package/dist/server/app-page-render.js +7 -3
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-response.d.ts +11 -1
- package/dist/server/app-page-response.js +18 -5
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +1 -0
- package/dist/server/app-page-route-wiring.js +35 -15
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +4 -0
- package/dist/server/app-page-stream.js +3 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-prerender-static-params.d.ts +2 -1
- package/dist/server/app-prerender-static-params.js +44 -8
- package/dist/server/app-prerender-static-params.js.map +1 -1
- package/dist/server/app-route-handler-cache.d.ts +2 -2
- package/dist/server/app-route-handler-cache.js +3 -2
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +7 -1
- package/dist/server/app-route-handler-dispatch.js +4 -1
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +18 -2
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-response.js +6 -5
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-router-entry.js +6 -2
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +11 -1
- package/dist/server/app-rsc-handler.js +48 -21
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-render-mode.d.ts +4 -3
- package/dist/server/app-rsc-render-mode.js +7 -1
- package/dist/server/app-rsc-render-mode.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +4 -1
- package/dist/server/app-rsc-request-normalization.js +6 -2
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
- package/dist/server/app-rsc-response-finalizer.js +10 -3
- package/dist/server/app-rsc-response-finalizer.js.map +1 -1
- package/dist/server/app-rsc-route-matching.js +2 -2
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-segment-config.d.ts +4 -1
- package/dist/server/app-segment-config.js +6 -1
- package/dist/server/app-segment-config.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +5 -1
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +92 -55
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +30 -2
- package/dist/server/app-ssr-stream.js +95 -8
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +2 -1
- package/dist/server/app-static-generation.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +1 -1
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-headers.d.ts +7 -0
- package/dist/server/cache-headers.js +19 -0
- package/dist/server/cache-headers.js.map +1 -0
- package/dist/server/cache-proof.d.ts +49 -3
- package/dist/server/cache-proof.js +78 -22
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/client-reuse-manifest.d.ts +99 -0
- package/dist/server/client-reuse-manifest.js +212 -0
- package/dist/server/client-reuse-manifest.js.map +1 -0
- package/dist/server/default-global-error-module.d.ts +20 -0
- package/dist/server/default-global-error-module.js +20 -0
- package/dist/server/default-global-error-module.js.map +1 -0
- package/dist/server/default-not-found-module.d.ts +20 -0
- package/dist/server/default-not-found-module.js +20 -0
- package/dist/server/default-not-found-module.js.map +1 -0
- package/dist/server/dev-server.d.ts +10 -2
- package/dist/server/dev-server.js +99 -36
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/edge-api-runtime.d.ts +5 -0
- package/dist/server/edge-api-runtime.js +8 -0
- package/dist/server/edge-api-runtime.js.map +1 -0
- package/dist/server/headers.d.ts +22 -1
- package/dist/server/headers.js +22 -1
- package/dist/server/headers.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +16 -1
- package/dist/server/http-error-responses.js +21 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/image-optimization.d.ts +13 -4
- package/dist/server/image-optimization.js +15 -4
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/isr-cache.d.ts +6 -2
- package/dist/server/isr-cache.js +20 -4
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +15 -0
- package/dist/server/middleware-runtime.js +59 -7
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +5 -3
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +9 -3
- package/dist/server/navigation-planner.js +98 -25
- package/dist/server/navigation-planner.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +2 -1
- package/dist/server/navigation-trace.js +1 -0
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/pages-api-route.d.ts +45 -1
- package/dist/server/pages-api-route.js +27 -4
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-body-parser-config.d.ts +60 -0
- package/dist/server/pages-body-parser-config.js +79 -0
- package/dist/server/pages-body-parser-config.js.map +1 -0
- package/dist/server/pages-data-route.d.ts +77 -0
- package/dist/server/pages-data-route.js +98 -0
- package/dist/server/pages-data-route.js.map +1 -0
- package/dist/server/pages-default-404.d.ts +31 -0
- package/dist/server/pages-default-404.js +40 -0
- package/dist/server/pages-default-404.js.map +1 -0
- package/dist/server/pages-i18n.d.ts +51 -1
- package/dist/server/pages-i18n.js +61 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-node-compat.d.ts +10 -0
- package/dist/server/pages-node-compat.js +12 -1
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +69 -2
- package/dist/server/pages-page-data.js +47 -31
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +13 -1
- package/dist/server/pages-page-response.js +16 -11
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prerender-route-params.d.ts +14 -0
- package/dist/server/prerender-route-params.js +94 -0
- package/dist/server/prerender-route-params.js.map +1 -0
- package/dist/server/prod-server.d.ts +15 -37
- package/dist/server/prod-server.js +143 -107
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/proxy-trust.d.ts +41 -0
- package/dist/server/proxy-trust.js +70 -0
- package/dist/server/proxy-trust.js.map +1 -0
- package/dist/server/request-pipeline.d.ts +13 -4
- package/dist/server/request-pipeline.js +32 -14
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/seed-cache.d.ts +12 -31
- package/dist/server/seed-cache.js +30 -37
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.js +8 -3
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/skip-cache-proof.d.ts +41 -0
- package/dist/server/skip-cache-proof.js +101 -0
- package/dist/server/skip-cache-proof.js.map +1 -0
- package/dist/server/static-file-cache.d.ts +1 -1
- package/dist/server/static-file-cache.js +8 -7
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/server/streaming-metadata.d.ts +5 -0
- package/dist/server/streaming-metadata.js +10 -0
- package/dist/server/streaming-metadata.js.map +1 -0
- package/dist/shims/app-router-scroll-state.d.ts +12 -0
- package/dist/shims/app-router-scroll-state.js +38 -0
- package/dist/shims/app-router-scroll-state.js.map +1 -0
- package/dist/shims/app-router-scroll.d.ts +14 -0
- package/dist/shims/app-router-scroll.js +100 -0
- package/dist/shims/app-router-scroll.js.map +1 -0
- package/dist/shims/before-interactive-context.d.ts +30 -0
- package/dist/shims/before-interactive-context.js +10 -0
- package/dist/shims/before-interactive-context.js.map +1 -0
- package/dist/shims/cache-runtime.d.ts +1 -1
- package/dist/shims/cache-runtime.js +14 -1
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/client-locale.d.ts +15 -0
- package/dist/shims/client-locale.js +13 -0
- package/dist/shims/client-locale.js.map +1 -0
- package/dist/shims/default-global-error.d.ts +32 -0
- package/dist/shims/default-global-error.js +181 -0
- package/dist/shims/default-global-error.js.map +1 -0
- package/dist/shims/default-not-found.d.ts +12 -0
- package/dist/shims/default-not-found.js +61 -0
- package/dist/shims/default-not-found.js.map +1 -0
- package/dist/shims/document.d.ts +59 -3
- package/dist/shims/document.js +36 -5
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +2 -2
- package/dist/shims/font-local.d.ts +5 -0
- package/dist/shims/font-local.js +6 -2
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/form.js +13 -6
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/head.js +4 -4
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +6 -2
- package/dist/shims/headers.js +64 -21
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.d.ts +1 -1
- package/dist/shims/image.js +4 -4
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/pages-data-target.d.ts +58 -0
- package/dist/shims/internal/pages-data-target.js +91 -0
- package/dist/shims/internal/pages-data-target.js.map +1 -0
- package/dist/shims/internal/pages-data-url.d.ts +42 -0
- package/dist/shims/internal/pages-data-url.js +73 -0
- package/dist/shims/internal/pages-data-url.js.map +1 -0
- package/dist/shims/link.d.ts +21 -3
- package/dist/shims/link.js +189 -30
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +2 -1
- package/dist/shims/metadata.js +65 -6
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +67 -23
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/og.d.ts +18 -2
- package/dist/shims/og.js +49 -1
- package/dist/shims/og.js.map +1 -0
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/root-params.d.ts +3 -1
- package/dist/shims/root-params.js +11 -3
- package/dist/shims/root-params.js.map +1 -1
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +12 -5
- package/dist/shims/router.js +535 -86
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.js +86 -12
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.d.ts +21 -4
- package/dist/shims/server.js +30 -9
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.js +5 -1
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/url-safety.d.ts +23 -1
- package/dist/shims/url-safety.js +29 -2
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/shims/url-utils.d.ts +2 -1
- package/dist/shims/url-utils.js +15 -4
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/typegen.d.ts +10 -0
- package/dist/typegen.js +242 -0
- package/dist/typegen.js.map +1 -0
- package/dist/utils/asset-prefix.d.ts +33 -5
- package/dist/utils/asset-prefix.js +39 -6
- package/dist/utils/asset-prefix.js.map +1 -1
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +1 -3
- package/dist/utils/cache-control-metadata.js.map +1 -1
- package/dist/utils/domain-locale.d.ts +2 -1
- package/dist/utils/domain-locale.js +9 -1
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/html-limited-bots.d.ts +5 -0
- package/dist/utils/html-limited-bots.js +15 -0
- package/dist/utils/html-limited-bots.js.map +1 -0
- package/dist/utils/lazy-chunks.d.ts +1 -1
- package/dist/utils/lazy-chunks.js +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/dist/utils/prerender-output-paths.d.ts +15 -0
- package/dist/utils/prerender-output-paths.js +24 -0
- package/dist/utils/prerender-output-paths.js.map +1 -0
- package/dist/utils/query.d.ts +23 -1
- package/dist/utils/query.js +46 -2
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/record.d.ts +5 -0
- package/dist/utils/record.js +8 -0
- package/dist/utils/record.js.map +1 -0
- package/package.json +11 -3
|
@@ -1,9 +1,45 @@
|
|
|
1
1
|
import { Route } from "../routing/pages-router.js";
|
|
2
|
+
import { ExecutionContextLike } from "../shims/request-context.js";
|
|
2
3
|
import { PagesReqResRequest, PagesReqResResponse, PagesRequestQuery } from "./pages-node-compat.js";
|
|
3
4
|
|
|
4
5
|
//#region src/server/pages-api-route.d.ts
|
|
6
|
+
type PagesApiRouteConfig = {
|
|
7
|
+
runtime?: string;
|
|
8
|
+
/**
|
|
9
|
+
* `export const config = { api: { bodyParser: false | { sizeLimit: '4mb' } } }`
|
|
10
|
+
* — controls whether vinext parses the request body for the route handler.
|
|
11
|
+
*
|
|
12
|
+
* `bodyParser: false` is critical for webhook handlers (Stripe, GitHub,
|
|
13
|
+
* Slack, etc.) that need to read the raw bytes to verify an HMAC
|
|
14
|
+
* signature. With it set, `req.body` is left undefined and the raw stream
|
|
15
|
+
* is exposed on `req.body` as a Web `ReadableStream<Uint8Array>` so user
|
|
16
|
+
* code can consume it.
|
|
17
|
+
*
|
|
18
|
+
* @see https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config
|
|
19
|
+
*/
|
|
20
|
+
api?: {
|
|
21
|
+
bodyParser?: boolean | {
|
|
22
|
+
sizeLimit?: string | number;
|
|
23
|
+
};
|
|
24
|
+
responseLimit?: boolean | string | number;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
type PagesNodeApiRouteHandler = (req: PagesReqResRequest, res: PagesReqResResponse) => void | Promise<void>;
|
|
28
|
+
type PagesEdgeApiRouteHandler = (request: Request) => Response | Promise<Response>;
|
|
5
29
|
type PagesApiRouteModule = {
|
|
6
|
-
|
|
30
|
+
/**
|
|
31
|
+
* `export const config = { runtime: 'edge' }` — historical Pages Router form.
|
|
32
|
+
*/
|
|
33
|
+
config?: PagesApiRouteConfig;
|
|
34
|
+
/**
|
|
35
|
+
* `export const runtime = 'edge'` — bare export form. Next.js resolves the
|
|
36
|
+
* effective runtime as `config.runtime ?? config.config?.runtime`, so a
|
|
37
|
+
* top-level `runtime` export takes precedence over the nested config form.
|
|
38
|
+
*
|
|
39
|
+
* @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/analysis/get-page-static-info.ts
|
|
40
|
+
*/
|
|
41
|
+
runtime?: string;
|
|
42
|
+
default?: PagesNodeApiRouteHandler | PagesEdgeApiRouteHandler;
|
|
7
43
|
};
|
|
8
44
|
type PagesApiRouteMatch = {
|
|
9
45
|
params: PagesRequestQuery;
|
|
@@ -12,6 +48,14 @@ type PagesApiRouteMatch = {
|
|
|
12
48
|
};
|
|
13
49
|
};
|
|
14
50
|
type HandlePagesApiRouteOptions = {
|
|
51
|
+
/**
|
|
52
|
+
* Per-request Cloudflare Workers `ExecutionContext`. When provided, the
|
|
53
|
+
* API route runs inside `runWithExecutionContext(ctx, ...)` so any
|
|
54
|
+
* `after()` (or other shim) call inside the handler can reach
|
|
55
|
+
* `ctx.waitUntil()` via the ALS and keep the isolate alive past the
|
|
56
|
+
* response. Omit on Node.js dev where no Workers lifecycle exists.
|
|
57
|
+
*/
|
|
58
|
+
ctx?: ExecutionContextLike;
|
|
15
59
|
match: PagesApiRouteMatch | null;
|
|
16
60
|
reportRequestError?: (error: Error, routePattern: string) => void | Promise<void>;
|
|
17
61
|
request: Request;
|
|
@@ -1,26 +1,49 @@
|
|
|
1
1
|
import "./server-globals.js";
|
|
2
|
+
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
3
|
+
import { NextRequest } from "../shims/server.js";
|
|
2
4
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
3
5
|
import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
|
|
4
6
|
import { PagesBodyParseError } from "./pages-media-type.js";
|
|
7
|
+
import { isEdgeApiRuntime } from "./edge-api-runtime.js";
|
|
8
|
+
import { resolveBodyParserConfig } from "./pages-body-parser-config.js";
|
|
5
9
|
import { createPagesReqRes, parsePagesApiBody } from "./pages-node-compat.js";
|
|
6
10
|
//#region src/server/pages-api-route.ts
|
|
11
|
+
function resolveModuleRuntime(module) {
|
|
12
|
+
return module.runtime ?? module.config?.runtime;
|
|
13
|
+
}
|
|
7
14
|
function buildPagesApiQuery(url, params) {
|
|
8
15
|
return mergeRouteParamsIntoQuery(parseQueryString(url), params);
|
|
9
16
|
}
|
|
17
|
+
function isEdgeApiRouteModule(module) {
|
|
18
|
+
return typeof module.default === "function" && isEdgeApiRuntime(resolveModuleRuntime(module));
|
|
19
|
+
}
|
|
20
|
+
function isNodeApiRouteModule(module) {
|
|
21
|
+
return typeof module.default === "function" && !isEdgeApiRuntime(resolveModuleRuntime(module));
|
|
22
|
+
}
|
|
10
23
|
async function handlePagesApiRoute(options) {
|
|
24
|
+
if (options.ctx) return runWithExecutionContext(options.ctx, () => _handlePagesApiRoute(options));
|
|
25
|
+
return _handlePagesApiRoute(options);
|
|
26
|
+
}
|
|
27
|
+
async function _handlePagesApiRoute(options) {
|
|
11
28
|
if (!options.match) return new Response("404 - API route not found", { status: 404 });
|
|
12
29
|
const { route, params } = options.match;
|
|
13
|
-
const handler = route.module.default;
|
|
14
|
-
if (typeof handler !== "function") return new Response("API route does not export a default function", { status: 500 });
|
|
15
30
|
try {
|
|
31
|
+
if (isEdgeApiRouteModule(route.module)) {
|
|
32
|
+
const nextRequest = new NextRequest(options.request);
|
|
33
|
+
const response = await route.module.default(nextRequest);
|
|
34
|
+
if (response instanceof Response) return response;
|
|
35
|
+
throw new Error("Edge API route did not return a Response");
|
|
36
|
+
}
|
|
37
|
+
if (!isNodeApiRouteModule(route.module)) return new Response("API route does not export a default function", { status: 500 });
|
|
16
38
|
const query = buildPagesApiQuery(options.url, params);
|
|
39
|
+
const bodyParserConfig = resolveBodyParserConfig(route.module.config);
|
|
17
40
|
const { req, res, responsePromise } = createPagesReqRes({
|
|
18
|
-
body: await parsePagesApiBody(options.request),
|
|
41
|
+
body: bodyParserConfig.enabled ? await parsePagesApiBody(options.request, bodyParserConfig.sizeLimit) : options.request.body ?? void 0,
|
|
19
42
|
query,
|
|
20
43
|
request: options.request,
|
|
21
44
|
url: options.url
|
|
22
45
|
});
|
|
23
|
-
await
|
|
46
|
+
await route.module.default(req, res);
|
|
24
47
|
res.end();
|
|
25
48
|
return await responsePromise;
|
|
26
49
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pages-api-route.js","names":["PagesApiBodyParseError"],"sources":["../../src/server/pages-api-route.ts"],"sourcesContent":["import \"./server-globals.js\";\nimport type { Route } from \"../routing/pages-router.js\";\nimport { mergeRouteParamsIntoQuery, parseQueryString } from \"../utils/query.js\";\nimport {\n createPagesReqRes,\n parsePagesApiBody,\n type PagesRequestQuery,\n type PagesReqResRequest,\n type PagesReqResResponse,\n PagesApiBodyParseError,\n} from \"./pages-node-compat.js\";\nimport { internalServerErrorResponse } from \"./http-error-responses.js\";\n\ntype
|
|
1
|
+
{"version":3,"file":"pages-api-route.js","names":["PagesApiBodyParseError"],"sources":["../../src/server/pages-api-route.ts"],"sourcesContent":["import \"./server-globals.js\";\nimport type { Route } from \"../routing/pages-router.js\";\nimport { mergeRouteParamsIntoQuery, parseQueryString } from \"../utils/query.js\";\nimport {\n createPagesReqRes,\n parsePagesApiBody,\n type PagesRequestQuery,\n type PagesReqResRequest,\n type PagesReqResResponse,\n PagesApiBodyParseError,\n} from \"./pages-node-compat.js\";\nimport { resolveBodyParserConfig } from \"./pages-body-parser-config.js\";\nimport { internalServerErrorResponse } from \"./http-error-responses.js\";\nimport { isEdgeApiRuntime } from \"./edge-api-runtime.js\";\nimport { runWithExecutionContext, type ExecutionContextLike } from \"vinext/shims/request-context\";\nimport { NextRequest } from \"vinext/shims/server\";\n\ntype PagesApiRouteConfig = {\n runtime?: string;\n /**\n * `export const config = { api: { bodyParser: false | { sizeLimit: '4mb' } } }`\n * — controls whether vinext parses the request body for the route handler.\n *\n * `bodyParser: false` is critical for webhook handlers (Stripe, GitHub,\n * Slack, etc.) that need to read the raw bytes to verify an HMAC\n * signature. With it set, `req.body` is left undefined and the raw stream\n * is exposed on `req.body` as a Web `ReadableStream<Uint8Array>` so user\n * code can consume it.\n *\n * @see https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config\n */\n api?: {\n bodyParser?: boolean | { sizeLimit?: string | number };\n responseLimit?: boolean | string | number;\n };\n};\n\ntype PagesNodeApiRouteHandler = (\n req: PagesReqResRequest,\n res: PagesReqResResponse,\n) => void | Promise<void>;\n\ntype PagesEdgeApiRouteHandler = (request: Request) => Response | Promise<Response>;\n\ntype PagesApiRouteModule = {\n /**\n * `export const config = { runtime: 'edge' }` — historical Pages Router form.\n */\n config?: PagesApiRouteConfig;\n /**\n * `export const runtime = 'edge'` — bare export form. Next.js resolves the\n * effective runtime as `config.runtime ?? config.config?.runtime`, so a\n * top-level `runtime` export takes precedence over the nested config form.\n *\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/analysis/get-page-static-info.ts\n */\n runtime?: string;\n default?: PagesNodeApiRouteHandler | PagesEdgeApiRouteHandler;\n};\n\nfunction resolveModuleRuntime(module: PagesApiRouteModule): string | undefined {\n return module.runtime ?? module.config?.runtime;\n}\n\nexport type PagesApiRouteMatch = {\n params: PagesRequestQuery;\n route: Pick<Route, \"pattern\"> & {\n module: PagesApiRouteModule;\n };\n};\n\ntype HandlePagesApiRouteOptions = {\n /**\n * Per-request Cloudflare Workers `ExecutionContext`. When provided, the\n * API route runs inside `runWithExecutionContext(ctx, ...)` so any\n * `after()` (or other shim) call inside the handler can reach\n * `ctx.waitUntil()` via the ALS and keep the isolate alive past the\n * response. Omit on Node.js dev where no Workers lifecycle exists.\n */\n ctx?: ExecutionContextLike;\n match: PagesApiRouteMatch | null;\n reportRequestError?: (error: Error, routePattern: string) => void | Promise<void>;\n request: Request;\n url: string;\n};\n\nfunction buildPagesApiQuery(url: string, params: PagesRequestQuery): PagesRequestQuery {\n return mergeRouteParamsIntoQuery(parseQueryString(url), params);\n}\n\nfunction isEdgeApiRouteModule(\n module: PagesApiRouteModule,\n): module is PagesApiRouteModule & { default: PagesEdgeApiRouteHandler } {\n return typeof module.default === \"function\" && isEdgeApiRuntime(resolveModuleRuntime(module));\n}\n\nfunction isNodeApiRouteModule(\n module: PagesApiRouteModule,\n): module is PagesApiRouteModule & { default: PagesNodeApiRouteHandler } {\n return typeof module.default === \"function\" && !isEdgeApiRuntime(resolveModuleRuntime(module));\n}\n\nexport async function handlePagesApiRoute(options: HandlePagesApiRouteOptions): Promise<Response> {\n if (options.ctx) {\n return runWithExecutionContext(options.ctx, () => _handlePagesApiRoute(options));\n }\n return _handlePagesApiRoute(options);\n}\n\nasync function _handlePagesApiRoute(options: HandlePagesApiRouteOptions): Promise<Response> {\n if (!options.match) {\n return new Response(\"404 - API route not found\", { status: 404 });\n }\n\n const { route, params } = options.match;\n\n try {\n if (isEdgeApiRouteModule(route.module)) {\n // Next.js wraps the incoming Request in a NextRequest before invoking\n // edge API handlers, so handlers can use `req.nextUrl.searchParams`,\n // `req.cookies`, etc. (Cf. NextRequestHint in next/src/server/web/adapter.ts.)\n const nextRequest = new NextRequest(options.request);\n const response = await route.module.default(nextRequest);\n if (response instanceof Response) {\n return response;\n }\n\n throw new Error(\"Edge API route did not return a Response\");\n }\n\n // This is redundant at runtime after the edge branch for function exports, but it\n // keeps the Node handler ABI narrowed without a production type assertion.\n if (!isNodeApiRouteModule(route.module)) {\n return new Response(\"API route does not export a default function\", { status: 500 });\n }\n\n const query = buildPagesApiQuery(options.url, params);\n\n // Honour `export const config = { api: { bodyParser: ... } }` on the\n // route module. When the handler opts out (`bodyParser: false`) we must\n // not consume the stream — leave `req.body` as the raw Web\n // `ReadableStream<Uint8Array>` so user code (e.g. a Stripe/GitHub\n // webhook) can read the raw bytes for HMAC verification.\n const bodyParserConfig = resolveBodyParserConfig(route.module.config);\n\n const body = bodyParserConfig.enabled\n ? await parsePagesApiBody(options.request, bodyParserConfig.sizeLimit)\n : (options.request.body ?? undefined);\n\n const { req, res, responsePromise } = createPagesReqRes({\n body,\n query,\n request: options.request,\n url: options.url,\n });\n\n await route.module.default(req, res);\n res.end();\n return await responsePromise;\n } catch (error) {\n if (error instanceof PagesApiBodyParseError) {\n return new Response(error.message, {\n status: error.statusCode,\n statusText: error.message,\n });\n }\n\n void options.reportRequestError?.(\n error instanceof Error ? error : new Error(String(error)),\n route.pattern,\n );\n return internalServerErrorResponse();\n }\n}\n"],"mappings":";;;;;;;;;;AA4DA,SAAS,qBAAqB,QAAiD;CAC7E,OAAO,OAAO,WAAW,OAAO,QAAQ;;AAyB1C,SAAS,mBAAmB,KAAa,QAA8C;CACrF,OAAO,0BAA0B,iBAAiB,IAAI,EAAE,OAAO;;AAGjE,SAAS,qBACP,QACuE;CACvE,OAAO,OAAO,OAAO,YAAY,cAAc,iBAAiB,qBAAqB,OAAO,CAAC;;AAG/F,SAAS,qBACP,QACuE;CACvE,OAAO,OAAO,OAAO,YAAY,cAAc,CAAC,iBAAiB,qBAAqB,OAAO,CAAC;;AAGhG,eAAsB,oBAAoB,SAAwD;CAChG,IAAI,QAAQ,KACV,OAAO,wBAAwB,QAAQ,WAAW,qBAAqB,QAAQ,CAAC;CAElF,OAAO,qBAAqB,QAAQ;;AAGtC,eAAe,qBAAqB,SAAwD;CAC1F,IAAI,CAAC,QAAQ,OACX,OAAO,IAAI,SAAS,6BAA6B,EAAE,QAAQ,KAAK,CAAC;CAGnE,MAAM,EAAE,OAAO,WAAW,QAAQ;CAElC,IAAI;EACF,IAAI,qBAAqB,MAAM,OAAO,EAAE;GAItC,MAAM,cAAc,IAAI,YAAY,QAAQ,QAAQ;GACpD,MAAM,WAAW,MAAM,MAAM,OAAO,QAAQ,YAAY;GACxD,IAAI,oBAAoB,UACtB,OAAO;GAGT,MAAM,IAAI,MAAM,2CAA2C;;EAK7D,IAAI,CAAC,qBAAqB,MAAM,OAAO,EACrC,OAAO,IAAI,SAAS,gDAAgD,EAAE,QAAQ,KAAK,CAAC;EAGtF,MAAM,QAAQ,mBAAmB,QAAQ,KAAK,OAAO;EAOrD,MAAM,mBAAmB,wBAAwB,MAAM,OAAO,OAAO;EAMrE,MAAM,EAAE,KAAK,KAAK,oBAAoB,kBAAkB;GACtD,MALW,iBAAiB,UAC1B,MAAM,kBAAkB,QAAQ,SAAS,iBAAiB,UAAU,GACnE,QAAQ,QAAQ,QAAQ,KAAA;GAI3B;GACA,SAAS,QAAQ;GACjB,KAAK,QAAQ;GACd,CAAC;EAEF,MAAM,MAAM,OAAO,QAAQ,KAAK,IAAI;EACpC,IAAI,KAAK;EACT,OAAO,MAAM;UACN,OAAO;EACd,IAAI,iBAAiBA,qBACnB,OAAO,IAAI,SAAS,MAAM,SAAS;GACjC,QAAQ,MAAM;GACd,YAAY,MAAM;GACnB,CAAC;EAGJ,QAAa,qBACX,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,EACzD,MAAM,QACP;EACD,OAAO,6BAA6B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//#region src/server/pages-body-parser-config.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the Pages Router `api.bodyParser` config from a route module export.
|
|
4
|
+
*
|
|
5
|
+
* Next.js API routes can opt out of automatic body parsing or raise the
|
|
6
|
+
* default 1 MB size limit:
|
|
7
|
+
*
|
|
8
|
+
* export const config = { api: { bodyParser: false } };
|
|
9
|
+
* export const config = { api: { bodyParser: { sizeLimit: '4mb' } } };
|
|
10
|
+
*
|
|
11
|
+
* `bodyParser: false` is critical for webhook handlers (Stripe, GitHub,
|
|
12
|
+
* Slack, etc.) that must read the raw request bytes to verify an HMAC
|
|
13
|
+
* signature. Silently parsing the body would consume the stream and break
|
|
14
|
+
* signature verification — usually failing closed, sometimes failing open.
|
|
15
|
+
*
|
|
16
|
+
* @see https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config
|
|
17
|
+
* @see Next.js: packages/next/src/server/api-utils/node/api-resolver.ts
|
|
18
|
+
*
|
|
19
|
+
* The format of `sizeLimit` mirrors what Next.js accepts via the `bytes`
|
|
20
|
+
* package: a number of bytes, or a string with a unit suffix
|
|
21
|
+
* (`"500b"`, `"100kb"`, `"4mb"`, `"1gb"`).
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Default Pages Router API body size limit, matching Next.js.
|
|
25
|
+
*/
|
|
26
|
+
declare const DEFAULT_PAGES_API_BODY_SIZE_LIMIT: number;
|
|
27
|
+
/**
|
|
28
|
+
* Resolved bodyParser configuration. When `enabled` is `false`, the body
|
|
29
|
+
* MUST be passed through to the handler as a raw stream (or left unparsed
|
|
30
|
+
* with `req.body === undefined`), so user code can read it itself.
|
|
31
|
+
*/
|
|
32
|
+
type ResolvedBodyParserConfig = {
|
|
33
|
+
enabled: false;
|
|
34
|
+
} | {
|
|
35
|
+
enabled: true;
|
|
36
|
+
sizeLimit: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Parse a Next.js-style `sizeLimit` string (e.g. `"4mb"`, `"100kb"`, `"1gb"`)
|
|
40
|
+
* or numeric byte value into a number of bytes. Returns `undefined` for
|
|
41
|
+
* inputs that can't be parsed — callers should fall back to the default.
|
|
42
|
+
*
|
|
43
|
+
* Matches the format accepted by Next.js (the `bytes` package); we
|
|
44
|
+
* implement it inline to avoid pulling a dependency for a tiny parser.
|
|
45
|
+
*/
|
|
46
|
+
declare function parseSizeLimit(value: string | number | undefined): number | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Read the resolved `bodyParser` config from a route module's `config`
|
|
49
|
+
* export. Defaults to enabled with the 1 MB Next.js default.
|
|
50
|
+
*/
|
|
51
|
+
declare function resolveBodyParserConfig(moduleConfig: {
|
|
52
|
+
api?: {
|
|
53
|
+
bodyParser?: boolean | {
|
|
54
|
+
sizeLimit?: string | number;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
} | undefined, defaultSizeLimit?: number): ResolvedBodyParserConfig;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, parseSizeLimit, resolveBodyParserConfig };
|
|
60
|
+
//# sourceMappingURL=pages-body-parser-config.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//#region src/server/pages-body-parser-config.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the Pages Router `api.bodyParser` config from a route module export.
|
|
4
|
+
*
|
|
5
|
+
* Next.js API routes can opt out of automatic body parsing or raise the
|
|
6
|
+
* default 1 MB size limit:
|
|
7
|
+
*
|
|
8
|
+
* export const config = { api: { bodyParser: false } };
|
|
9
|
+
* export const config = { api: { bodyParser: { sizeLimit: '4mb' } } };
|
|
10
|
+
*
|
|
11
|
+
* `bodyParser: false` is critical for webhook handlers (Stripe, GitHub,
|
|
12
|
+
* Slack, etc.) that must read the raw request bytes to verify an HMAC
|
|
13
|
+
* signature. Silently parsing the body would consume the stream and break
|
|
14
|
+
* signature verification — usually failing closed, sometimes failing open.
|
|
15
|
+
*
|
|
16
|
+
* @see https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config
|
|
17
|
+
* @see Next.js: packages/next/src/server/api-utils/node/api-resolver.ts
|
|
18
|
+
*
|
|
19
|
+
* The format of `sizeLimit` mirrors what Next.js accepts via the `bytes`
|
|
20
|
+
* package: a number of bytes, or a string with a unit suffix
|
|
21
|
+
* (`"500b"`, `"100kb"`, `"4mb"`, `"1gb"`).
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Default Pages Router API body size limit, matching Next.js.
|
|
25
|
+
*/
|
|
26
|
+
const DEFAULT_PAGES_API_BODY_SIZE_LIMIT = 1 * 1024 * 1024;
|
|
27
|
+
const SIZE_UNITS = {
|
|
28
|
+
b: 1,
|
|
29
|
+
kb: 1024,
|
|
30
|
+
mb: 1024 * 1024,
|
|
31
|
+
gb: 1024 * 1024 * 1024,
|
|
32
|
+
tb: 1024 * 1024 * 1024 * 1024
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Parse a Next.js-style `sizeLimit` string (e.g. `"4mb"`, `"100kb"`, `"1gb"`)
|
|
36
|
+
* or numeric byte value into a number of bytes. Returns `undefined` for
|
|
37
|
+
* inputs that can't be parsed — callers should fall back to the default.
|
|
38
|
+
*
|
|
39
|
+
* Matches the format accepted by Next.js (the `bytes` package); we
|
|
40
|
+
* implement it inline to avoid pulling a dependency for a tiny parser.
|
|
41
|
+
*/
|
|
42
|
+
function parseSizeLimit(value) {
|
|
43
|
+
if (value === void 0 || value === null) return void 0;
|
|
44
|
+
if (typeof value === "number") return Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
45
|
+
if (typeof value !== "string") return void 0;
|
|
46
|
+
const trimmed = value.trim().toLowerCase();
|
|
47
|
+
if (!trimmed) return void 0;
|
|
48
|
+
const match = /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb|tb)?$/.exec(trimmed);
|
|
49
|
+
if (!match) return void 0;
|
|
50
|
+
const amount = Number.parseFloat(match[1]);
|
|
51
|
+
if (!Number.isFinite(amount) || amount < 0) return void 0;
|
|
52
|
+
const multiplier = SIZE_UNITS[match[2] ?? "b"];
|
|
53
|
+
if (multiplier === void 0) return void 0;
|
|
54
|
+
return Math.floor(amount * multiplier);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read the resolved `bodyParser` config from a route module's `config`
|
|
58
|
+
* export. Defaults to enabled with the 1 MB Next.js default.
|
|
59
|
+
*/
|
|
60
|
+
function resolveBodyParserConfig(moduleConfig, defaultSizeLimit = DEFAULT_PAGES_API_BODY_SIZE_LIMIT) {
|
|
61
|
+
const bodyParser = moduleConfig?.api?.bodyParser;
|
|
62
|
+
if (bodyParser === false) return { enabled: false };
|
|
63
|
+
if (bodyParser === void 0 || bodyParser === true) return {
|
|
64
|
+
enabled: true,
|
|
65
|
+
sizeLimit: defaultSizeLimit
|
|
66
|
+
};
|
|
67
|
+
if (typeof bodyParser === "object" && bodyParser !== null) return {
|
|
68
|
+
enabled: true,
|
|
69
|
+
sizeLimit: parseSizeLimit(bodyParser.sizeLimit) ?? defaultSizeLimit
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
enabled: true,
|
|
73
|
+
sizeLimit: defaultSizeLimit
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, parseSizeLimit, resolveBodyParserConfig };
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=pages-body-parser-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages-body-parser-config.js","names":[],"sources":["../../src/server/pages-body-parser-config.ts"],"sourcesContent":["/**\n * Resolve the Pages Router `api.bodyParser` config from a route module export.\n *\n * Next.js API routes can opt out of automatic body parsing or raise the\n * default 1 MB size limit:\n *\n * export const config = { api: { bodyParser: false } };\n * export const config = { api: { bodyParser: { sizeLimit: '4mb' } } };\n *\n * `bodyParser: false` is critical for webhook handlers (Stripe, GitHub,\n * Slack, etc.) that must read the raw request bytes to verify an HMAC\n * signature. Silently parsing the body would consume the stream and break\n * signature verification — usually failing closed, sometimes failing open.\n *\n * @see https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config\n * @see Next.js: packages/next/src/server/api-utils/node/api-resolver.ts\n *\n * The format of `sizeLimit` mirrors what Next.js accepts via the `bytes`\n * package: a number of bytes, or a string with a unit suffix\n * (`\"500b\"`, `\"100kb\"`, `\"4mb\"`, `\"1gb\"`).\n */\n\n/**\n * Default Pages Router API body size limit, matching Next.js.\n */\nexport const DEFAULT_PAGES_API_BODY_SIZE_LIMIT = 1 * 1024 * 1024;\n\n/**\n * Resolved bodyParser configuration. When `enabled` is `false`, the body\n * MUST be passed through to the handler as a raw stream (or left unparsed\n * with `req.body === undefined`), so user code can read it itself.\n */\ntype ResolvedBodyParserConfig = { enabled: false } | { enabled: true; sizeLimit: number };\n\nconst SIZE_UNITS: Record<string, number> = {\n b: 1,\n kb: 1024,\n mb: 1024 * 1024,\n gb: 1024 * 1024 * 1024,\n tb: 1024 * 1024 * 1024 * 1024,\n};\n\n/**\n * Parse a Next.js-style `sizeLimit` string (e.g. `\"4mb\"`, `\"100kb\"`, `\"1gb\"`)\n * or numeric byte value into a number of bytes. Returns `undefined` for\n * inputs that can't be parsed — callers should fall back to the default.\n *\n * Matches the format accepted by Next.js (the `bytes` package); we\n * implement it inline to avoid pulling a dependency for a tiny parser.\n */\nexport function parseSizeLimit(value: string | number | undefined): number | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"number\") {\n return Number.isFinite(value) && value >= 0 ? value : undefined;\n }\n if (typeof value !== \"string\") return undefined;\n\n const trimmed = value.trim().toLowerCase();\n if (!trimmed) return undefined;\n\n // Match `<number><unit?>` where number can be int/decimal and unit is one\n // of b/kb/mb/gb/tb. The unit is optional — a bare number is bytes.\n const match = /^(\\d+(?:\\.\\d+)?)\\s*(b|kb|mb|gb|tb)?$/.exec(trimmed);\n if (!match) return undefined;\n\n const amount = Number.parseFloat(match[1]);\n if (!Number.isFinite(amount) || amount < 0) return undefined;\n\n const unit = match[2] ?? \"b\";\n const multiplier = SIZE_UNITS[unit];\n if (multiplier === undefined) return undefined;\n\n return Math.floor(amount * multiplier);\n}\n\n/**\n * Read the resolved `bodyParser` config from a route module's `config`\n * export. Defaults to enabled with the 1 MB Next.js default.\n */\nexport function resolveBodyParserConfig(\n moduleConfig: { api?: { bodyParser?: boolean | { sizeLimit?: string | number } } } | undefined,\n defaultSizeLimit: number = DEFAULT_PAGES_API_BODY_SIZE_LIMIT,\n): ResolvedBodyParserConfig {\n const bodyParser = moduleConfig?.api?.bodyParser;\n\n // Explicit opt-out: leave the body untouched so handlers can read raw bytes.\n if (bodyParser === false) {\n return { enabled: false };\n }\n\n // `true` or `undefined` → default behaviour.\n if (bodyParser === undefined || bodyParser === true) {\n return { enabled: true, sizeLimit: defaultSizeLimit };\n }\n\n // Object form: honour `sizeLimit` if present and parseable, else default.\n if (typeof bodyParser === \"object\" && bodyParser !== null) {\n const parsed = parseSizeLimit(bodyParser.sizeLimit);\n return { enabled: true, sizeLimit: parsed ?? defaultSizeLimit };\n }\n\n // Anything else (truthy non-object/non-true) — be conservative and use\n // the default, matching Next.js's `!== false` check.\n return { enabled: true, sizeLimit: defaultSizeLimit };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,oCAAoC,IAAI,OAAO;AAS5D,MAAM,aAAqC;CACzC,GAAG;CACH,IAAI;CACJ,IAAI,OAAO;CACX,IAAI,OAAO,OAAO;CAClB,IAAI,OAAO,OAAO,OAAO;CAC1B;;;;;;;;;AAUD,SAAgB,eAAe,OAAwD;CACrF,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO,KAAA;CAClD,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,SAAS,MAAM,IAAI,SAAS,IAAI,QAAQ,KAAA;CAExD,IAAI,OAAO,UAAU,UAAU,OAAO,KAAA;CAEtC,MAAM,UAAU,MAAM,MAAM,CAAC,aAAa;CAC1C,IAAI,CAAC,SAAS,OAAO,KAAA;CAIrB,MAAM,QAAQ,uCAAuC,KAAK,QAAQ;CAClE,IAAI,CAAC,OAAO,OAAO,KAAA;CAEnB,MAAM,SAAS,OAAO,WAAW,MAAM,GAAG;CAC1C,IAAI,CAAC,OAAO,SAAS,OAAO,IAAI,SAAS,GAAG,OAAO,KAAA;CAGnD,MAAM,aAAa,WADN,MAAM,MAAM;CAEzB,IAAI,eAAe,KAAA,GAAW,OAAO,KAAA;CAErC,OAAO,KAAK,MAAM,SAAS,WAAW;;;;;;AAOxC,SAAgB,wBACd,cACA,mBAA2B,mCACD;CAC1B,MAAM,aAAa,cAAc,KAAK;CAGtC,IAAI,eAAe,OACjB,OAAO,EAAE,SAAS,OAAO;CAI3B,IAAI,eAAe,KAAA,KAAa,eAAe,MAC7C,OAAO;EAAE,SAAS;EAAM,WAAW;EAAkB;CAIvD,IAAI,OAAO,eAAe,YAAY,eAAe,MAEnD,OAAO;EAAE,SAAS;EAAM,WADT,eAAe,WAAW,UACA,IAAI;EAAkB;CAKjE,OAAO;EAAE,SAAS;EAAM,WAAW;EAAkB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/server/pages-data-route.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Helpers for the Pages Router `/_next/data/{buildId}/{...page}.json` endpoint.
|
|
4
|
+
*
|
|
5
|
+
* Next.js uses this endpoint for client-side navigations in the Pages Router:
|
|
6
|
+
* `next/link` and `router.push()` fetch `pageProps` from this URL instead of
|
|
7
|
+
* doing a full HTML navigation. The server must:
|
|
8
|
+
* 1. Match the URL pattern and extract the page pathname (with the buildId
|
|
9
|
+
* and `.json` extension removed, locale prefix preserved).
|
|
10
|
+
* 2. Normalize the URL BEFORE middleware runs so middleware sees the page
|
|
11
|
+
* path (e.g. `/about`) rather than the raw `/_next/data/.../about.json`.
|
|
12
|
+
* 3. Invoke the same `getServerSideProps` / `getStaticProps` machinery as
|
|
13
|
+
* the HTML page and serialize the resulting props as a JSON envelope:
|
|
14
|
+
* `{ pageProps: ... }` with `Content-Type: application/json`.
|
|
15
|
+
*
|
|
16
|
+
* Ported from Next.js:
|
|
17
|
+
* - `packages/next/src/server/normalizers/request/next-data.ts` — prefix/suffix matcher.
|
|
18
|
+
* - `packages/next/src/server/base-server.ts` (`handleNextDataRequest`) — pipeline normalization.
|
|
19
|
+
* - `packages/next/src/server/render.tsx` — JSON envelope emission (`isNextDataRequest`).
|
|
20
|
+
*/
|
|
21
|
+
type NextDataMatch = {
|
|
22
|
+
/**
|
|
23
|
+
* The normalized page pathname (with leading slash, no trailing slash,
|
|
24
|
+
* `.json` stripped, buildId stripped). For locale-prefixed requests like
|
|
25
|
+
* `/_next/data/<buildId>/en/about.json` this is `/en/about` — locale
|
|
26
|
+
* handling is done downstream by the existing `resolvePagesI18nRequest`
|
|
27
|
+
* pipeline so this helper does not need to know about i18n config.
|
|
28
|
+
*/
|
|
29
|
+
pagePathname: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Returns true if the pathname looks like a `_next/data` request, regardless
|
|
33
|
+
* of buildId. Used by the request pipeline to short-circuit before middleware
|
|
34
|
+
* even when the buildId is wrong (so we can still return a 404 JSON response).
|
|
35
|
+
*/
|
|
36
|
+
declare function isNextDataPathname(pathname: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Parse `/_next/data/<buildId>/<...page>.json` and return the normalized page
|
|
39
|
+
* pathname. Returns `null` if the pathname does not match the pattern or if
|
|
40
|
+
* the buildId segment does not match the server's buildId.
|
|
41
|
+
*
|
|
42
|
+
* The returned `pagePathname` is the page route path Next.js would render for
|
|
43
|
+
* the equivalent HTML navigation — including any locale prefix, which is then
|
|
44
|
+
* stripped by `resolvePagesI18nRequest` downstream.
|
|
45
|
+
*
|
|
46
|
+
* `/_next/data/<buildId>/about.json` → `/about`
|
|
47
|
+
* `/_next/data/<buildId>/en/about.json` → `/en/about`
|
|
48
|
+
* `/_next/data/<buildId>/index.json` → `/`
|
|
49
|
+
* `/_next/data/<buildId>/en.json` → `/en`
|
|
50
|
+
* `/_next/data/<wrong-id>/about.json` → null
|
|
51
|
+
* `/_next/data/<buildId>/about` → null (missing .json suffix)
|
|
52
|
+
*/
|
|
53
|
+
declare function parseNextDataPathname(pathname: string, buildId: string): NextDataMatch | null;
|
|
54
|
+
/**
|
|
55
|
+
* Build the JSON envelope returned by `/_next/data/<buildId>/<page>.json`.
|
|
56
|
+
* Mirrors Next.js' `RenderResult(JSON.stringify(props))` path in
|
|
57
|
+
* `packages/next/src/server/render.tsx` (search for `isNextDataRequest`).
|
|
58
|
+
*
|
|
59
|
+
* The envelope is the outer `props` object the React tree would receive:
|
|
60
|
+
* { pageProps: {...}, /* optional locale data, redirect markers, etc. *\/ }
|
|
61
|
+
*/
|
|
62
|
+
declare function buildNextDataJsonResponse(pageProps: Record<string, unknown>, safeJsonStringify: (value: unknown) => string, init?: ResponseInit): Response;
|
|
63
|
+
/**
|
|
64
|
+
* Build the 404 response Next.js returns for an unknown `_next/data` page.
|
|
65
|
+
* Next.js renders this as a normal 404 page, but the body shape that clients
|
|
66
|
+
* see for a missing page-data endpoint is the literal string `"{ }"` for the
|
|
67
|
+
* body and a 404 status with `application/json` so client-side hard-navigation
|
|
68
|
+
* fallback fires (see `__N_SSP` handling in `router.ts`).
|
|
69
|
+
*
|
|
70
|
+
* We match Next.js' behavior: 404 status + JSON content type. The body is an
|
|
71
|
+
* empty JSON object so clients that blindly call `res.json()` do not throw
|
|
72
|
+
* before checking the status code.
|
|
73
|
+
*/
|
|
74
|
+
declare function buildNextDataNotFoundResponse(): Response;
|
|
75
|
+
//#endregion
|
|
76
|
+
export { buildNextDataJsonResponse, buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname };
|
|
77
|
+
//# sourceMappingURL=pages-data-route.d.ts.map
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
//#region src/server/pages-data-route.ts
|
|
2
|
+
/**
|
|
3
|
+
* Helpers for the Pages Router `/_next/data/{buildId}/{...page}.json` endpoint.
|
|
4
|
+
*
|
|
5
|
+
* Next.js uses this endpoint for client-side navigations in the Pages Router:
|
|
6
|
+
* `next/link` and `router.push()` fetch `pageProps` from this URL instead of
|
|
7
|
+
* doing a full HTML navigation. The server must:
|
|
8
|
+
* 1. Match the URL pattern and extract the page pathname (with the buildId
|
|
9
|
+
* and `.json` extension removed, locale prefix preserved).
|
|
10
|
+
* 2. Normalize the URL BEFORE middleware runs so middleware sees the page
|
|
11
|
+
* path (e.g. `/about`) rather than the raw `/_next/data/.../about.json`.
|
|
12
|
+
* 3. Invoke the same `getServerSideProps` / `getStaticProps` machinery as
|
|
13
|
+
* the HTML page and serialize the resulting props as a JSON envelope:
|
|
14
|
+
* `{ pageProps: ... }` with `Content-Type: application/json`.
|
|
15
|
+
*
|
|
16
|
+
* Ported from Next.js:
|
|
17
|
+
* - `packages/next/src/server/normalizers/request/next-data.ts` — prefix/suffix matcher.
|
|
18
|
+
* - `packages/next/src/server/base-server.ts` (`handleNextDataRequest`) — pipeline normalization.
|
|
19
|
+
* - `packages/next/src/server/render.tsx` — JSON envelope emission (`isNextDataRequest`).
|
|
20
|
+
*/
|
|
21
|
+
const NEXT_DATA_PREFIX = "/_next/data/";
|
|
22
|
+
const NEXT_DATA_SUFFIX = ".json";
|
|
23
|
+
/**
|
|
24
|
+
* Returns true if the pathname looks like a `_next/data` request, regardless
|
|
25
|
+
* of buildId. Used by the request pipeline to short-circuit before middleware
|
|
26
|
+
* even when the buildId is wrong (so we can still return a 404 JSON response).
|
|
27
|
+
*/
|
|
28
|
+
function isNextDataPathname(pathname) {
|
|
29
|
+
return pathname.startsWith(NEXT_DATA_PREFIX) && pathname.endsWith(NEXT_DATA_SUFFIX);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse `/_next/data/<buildId>/<...page>.json` and return the normalized page
|
|
33
|
+
* pathname. Returns `null` if the pathname does not match the pattern or if
|
|
34
|
+
* the buildId segment does not match the server's buildId.
|
|
35
|
+
*
|
|
36
|
+
* The returned `pagePathname` is the page route path Next.js would render for
|
|
37
|
+
* the equivalent HTML navigation — including any locale prefix, which is then
|
|
38
|
+
* stripped by `resolvePagesI18nRequest` downstream.
|
|
39
|
+
*
|
|
40
|
+
* `/_next/data/<buildId>/about.json` → `/about`
|
|
41
|
+
* `/_next/data/<buildId>/en/about.json` → `/en/about`
|
|
42
|
+
* `/_next/data/<buildId>/index.json` → `/`
|
|
43
|
+
* `/_next/data/<buildId>/en.json` → `/en`
|
|
44
|
+
* `/_next/data/<wrong-id>/about.json` → null
|
|
45
|
+
* `/_next/data/<buildId>/about` → null (missing .json suffix)
|
|
46
|
+
*/
|
|
47
|
+
function parseNextDataPathname(pathname, buildId) {
|
|
48
|
+
if (!buildId) return null;
|
|
49
|
+
if (!isNextDataPathname(pathname)) return null;
|
|
50
|
+
const expectedPrefix = `${NEXT_DATA_PREFIX}${buildId}/`;
|
|
51
|
+
if (!pathname.startsWith(expectedPrefix)) return null;
|
|
52
|
+
const rest = pathname.slice(expectedPrefix.length, -5);
|
|
53
|
+
if (rest.length === 0) return null;
|
|
54
|
+
if (rest === "index") return { pagePathname: "/" };
|
|
55
|
+
if (rest.endsWith("/index")) return { pagePathname: `/${rest.slice(0, -6)}` };
|
|
56
|
+
if (rest.startsWith("index/")) return { pagePathname: `/${rest.slice(6)}` };
|
|
57
|
+
return { pagePathname: `/${rest}` };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build the JSON envelope returned by `/_next/data/<buildId>/<page>.json`.
|
|
61
|
+
* Mirrors Next.js' `RenderResult(JSON.stringify(props))` path in
|
|
62
|
+
* `packages/next/src/server/render.tsx` (search for `isNextDataRequest`).
|
|
63
|
+
*
|
|
64
|
+
* The envelope is the outer `props` object the React tree would receive:
|
|
65
|
+
* { pageProps: {...}, /* optional locale data, redirect markers, etc. *\/ }
|
|
66
|
+
*/
|
|
67
|
+
function buildNextDataJsonResponse(pageProps, safeJsonStringify, init) {
|
|
68
|
+
const body = safeJsonStringify({ pageProps });
|
|
69
|
+
return new Response(body, {
|
|
70
|
+
status: init?.status ?? 200,
|
|
71
|
+
statusText: init?.statusText,
|
|
72
|
+
headers: {
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
...init?.headers
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Build the 404 response Next.js returns for an unknown `_next/data` page.
|
|
80
|
+
* Next.js renders this as a normal 404 page, but the body shape that clients
|
|
81
|
+
* see for a missing page-data endpoint is the literal string `"{ }"` for the
|
|
82
|
+
* body and a 404 status with `application/json` so client-side hard-navigation
|
|
83
|
+
* fallback fires (see `__N_SSP` handling in `router.ts`).
|
|
84
|
+
*
|
|
85
|
+
* We match Next.js' behavior: 404 status + JSON content type. The body is an
|
|
86
|
+
* empty JSON object so clients that blindly call `res.json()` do not throw
|
|
87
|
+
* before checking the status code.
|
|
88
|
+
*/
|
|
89
|
+
function buildNextDataNotFoundResponse() {
|
|
90
|
+
return new Response("{}", {
|
|
91
|
+
status: 404,
|
|
92
|
+
headers: { "Content-Type": "application/json" }
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
export { buildNextDataJsonResponse, buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=pages-data-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages-data-route.js","names":[],"sources":["../../src/server/pages-data-route.ts"],"sourcesContent":["/**\n * Helpers for the Pages Router `/_next/data/{buildId}/{...page}.json` endpoint.\n *\n * Next.js uses this endpoint for client-side navigations in the Pages Router:\n * `next/link` and `router.push()` fetch `pageProps` from this URL instead of\n * doing a full HTML navigation. The server must:\n * 1. Match the URL pattern and extract the page pathname (with the buildId\n * and `.json` extension removed, locale prefix preserved).\n * 2. Normalize the URL BEFORE middleware runs so middleware sees the page\n * path (e.g. `/about`) rather than the raw `/_next/data/.../about.json`.\n * 3. Invoke the same `getServerSideProps` / `getStaticProps` machinery as\n * the HTML page and serialize the resulting props as a JSON envelope:\n * `{ pageProps: ... }` with `Content-Type: application/json`.\n *\n * Ported from Next.js:\n * - `packages/next/src/server/normalizers/request/next-data.ts` — prefix/suffix matcher.\n * - `packages/next/src/server/base-server.ts` (`handleNextDataRequest`) — pipeline normalization.\n * - `packages/next/src/server/render.tsx` — JSON envelope emission (`isNextDataRequest`).\n */\n\nconst NEXT_DATA_PREFIX = \"/_next/data/\";\nconst NEXT_DATA_SUFFIX = \".json\";\n\ntype NextDataMatch = {\n /**\n * The normalized page pathname (with leading slash, no trailing slash,\n * `.json` stripped, buildId stripped). For locale-prefixed requests like\n * `/_next/data/<buildId>/en/about.json` this is `/en/about` — locale\n * handling is done downstream by the existing `resolvePagesI18nRequest`\n * pipeline so this helper does not need to know about i18n config.\n */\n pagePathname: string;\n};\n\n/**\n * Returns true if the pathname looks like a `_next/data` request, regardless\n * of buildId. Used by the request pipeline to short-circuit before middleware\n * even when the buildId is wrong (so we can still return a 404 JSON response).\n */\nexport function isNextDataPathname(pathname: string): boolean {\n return pathname.startsWith(NEXT_DATA_PREFIX) && pathname.endsWith(NEXT_DATA_SUFFIX);\n}\n\n/**\n * Parse `/_next/data/<buildId>/<...page>.json` and return the normalized page\n * pathname. Returns `null` if the pathname does not match the pattern or if\n * the buildId segment does not match the server's buildId.\n *\n * The returned `pagePathname` is the page route path Next.js would render for\n * the equivalent HTML navigation — including any locale prefix, which is then\n * stripped by `resolvePagesI18nRequest` downstream.\n *\n * `/_next/data/<buildId>/about.json` → `/about`\n * `/_next/data/<buildId>/en/about.json` → `/en/about`\n * `/_next/data/<buildId>/index.json` → `/`\n * `/_next/data/<buildId>/en.json` → `/en`\n * `/_next/data/<wrong-id>/about.json` → null\n * `/_next/data/<buildId>/about` → null (missing .json suffix)\n */\nexport function parseNextDataPathname(pathname: string, buildId: string): NextDataMatch | null {\n if (!buildId) return null;\n if (!isNextDataPathname(pathname)) return null;\n\n const expectedPrefix = `${NEXT_DATA_PREFIX}${buildId}/`;\n // `/_next/data/<buildId>.json` (no trailing slash) is not a valid data req.\n if (!pathname.startsWith(expectedPrefix)) return null;\n\n const rest = pathname.slice(expectedPrefix.length, -NEXT_DATA_SUFFIX.length);\n\n // Empty rest (`/_next/data/<buildId>/.json`) is not a valid page path.\n if (rest.length === 0) return null;\n\n // Next.js denormalizes `index` to `/` to mirror file-system page paths\n // (`pages/index.tsx` → `/`). See `denormalizePagePath` in Next.js.\n if (rest === \"index\") return { pagePathname: \"/\" };\n if (rest.endsWith(\"/index\")) return { pagePathname: `/${rest.slice(0, -\"/index\".length)}` };\n\n // The encoder (`getAssetPathFromRoute` in Next.js / `buildPagesDataPath` in\n // vinext) prefixes any path beginning with `index` with an extra `index/`\n // segment so an explicit `pages/index/foo.tsx` page (route `/index/foo`)\n // round-trips through the data URL without colliding with `/foo`. Strip\n // that prefix here.\n if (rest.startsWith(\"index/\")) return { pagePathname: `/${rest.slice(\"index/\".length)}` };\n\n return { pagePathname: `/${rest}` };\n}\n\n/**\n * Build the JSON envelope returned by `/_next/data/<buildId>/<page>.json`.\n * Mirrors Next.js' `RenderResult(JSON.stringify(props))` path in\n * `packages/next/src/server/render.tsx` (search for `isNextDataRequest`).\n *\n * The envelope is the outer `props` object the React tree would receive:\n * { pageProps: {...}, /* optional locale data, redirect markers, etc. *\\/ }\n */\nexport function buildNextDataJsonResponse(\n pageProps: Record<string, unknown>,\n safeJsonStringify: (value: unknown) => string,\n init?: ResponseInit,\n): Response {\n const body = safeJsonStringify({ pageProps });\n return new Response(body, {\n status: init?.status ?? 200,\n statusText: init?.statusText,\n headers: {\n \"Content-Type\": \"application/json\",\n ...(init?.headers as Record<string, string> | undefined),\n },\n });\n}\n\n/**\n * Build the 404 response Next.js returns for an unknown `_next/data` page.\n * Next.js renders this as a normal 404 page, but the body shape that clients\n * see for a missing page-data endpoint is the literal string `\"{ }\"` for the\n * body and a 404 status with `application/json` so client-side hard-navigation\n * fallback fires (see `__N_SSP` handling in `router.ts`).\n *\n * We match Next.js' behavior: 404 status + JSON content type. The body is an\n * empty JSON object so clients that blindly call `res.json()` do not throw\n * before checking the status code.\n */\nexport function buildNextDataNotFoundResponse(): Response {\n return new Response(\"{}\", {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;;;;;;AAkBzB,SAAgB,mBAAmB,UAA2B;CAC5D,OAAO,SAAS,WAAW,iBAAiB,IAAI,SAAS,SAAS,iBAAiB;;;;;;;;;;;;;;;;;;AAmBrF,SAAgB,sBAAsB,UAAkB,SAAuC;CAC7F,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI,CAAC,mBAAmB,SAAS,EAAE,OAAO;CAE1C,MAAM,iBAAiB,GAAG,mBAAmB,QAAQ;CAErD,IAAI,CAAC,SAAS,WAAW,eAAe,EAAE,OAAO;CAEjD,MAAM,OAAO,SAAS,MAAM,eAAe,QAAQ,GAAyB;CAG5E,IAAI,KAAK,WAAW,GAAG,OAAO;CAI9B,IAAI,SAAS,SAAS,OAAO,EAAE,cAAc,KAAK;CAClD,IAAI,KAAK,SAAS,SAAS,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK,MAAM,GAAG,GAAiB,IAAI;CAO3F,IAAI,KAAK,WAAW,SAAS,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK,MAAM,EAAgB,IAAI;CAEzF,OAAO,EAAE,cAAc,IAAI,QAAQ;;;;;;;;;;AAWrC,SAAgB,0BACd,WACA,mBACA,MACU;CACV,MAAM,OAAO,kBAAkB,EAAE,WAAW,CAAC;CAC7C,OAAO,IAAI,SAAS,MAAM;EACxB,QAAQ,MAAM,UAAU;EACxB,YAAY,MAAM;EAClB,SAAS;GACP,gBAAgB;GAChB,GAAI,MAAM;GACX;EACF,CAAC;;;;;;;;;;;;;AAcJ,SAAgB,gCAA0C;CACxD,OAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAChD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/server/pages-default-404.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Default 404 HTML body for the Pages Router.
|
|
4
|
+
*
|
|
5
|
+
* Used when a Pages Router request does not match any route (and the app has
|
|
6
|
+
* not supplied a custom `pages/404.tsx`). Mirrors the markup Next.js's
|
|
7
|
+
* `pages/_error.tsx` produces for a 404 response: a centered status / message
|
|
8
|
+
* pair plus minified theme CSS and dark-mode media query. The message string
|
|
9
|
+
* `"This page could not be found."` (note the trailing period) is the
|
|
10
|
+
* canonical body asserted by Next.js's deploy suite
|
|
11
|
+
* (`test/e2e/getserversideprops/test/index.test.ts`,
|
|
12
|
+
* `test/e2e/basepath/error-pages.test.ts`).
|
|
13
|
+
*
|
|
14
|
+
* Kept as a hand-rendered HTML literal rather than a React-rendered template
|
|
15
|
+
* because the Pages Router server entry is invoked from both Workers and the
|
|
16
|
+
* dev server before any React-renderer wiring is available for this path —
|
|
17
|
+
* matching the lightweight build-time strategy Next.js uses for its packaged
|
|
18
|
+
* `_error` static fallback. See:
|
|
19
|
+
* .nextjs-ref/packages/next/src/pages/_error.tsx
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Build the Next.js-compatible default 404 HTML response for the Pages Router.
|
|
23
|
+
* Content-type is `text/html; charset=utf-8`, matching Next.js's
|
|
24
|
+
* `pages-handler` 404 response.
|
|
25
|
+
*/
|
|
26
|
+
declare function buildDefaultPagesNotFoundResponse(): Response;
|
|
27
|
+
/** Exported for tests / callers that need the raw HTML body. */
|
|
28
|
+
declare const DEFAULT_PAGES_NOT_FOUND_HTML = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width\"/><title>404: This page could not be found.</title><meta name=\"next-head-count\" content=\"2\"/><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript></head><body><div id=\"__next\"><div style=\"font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div style=\"line-height:48px\"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class=\"next-error-h1\" style=\"display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top\">404</h1><div style=\"display:inline-block\"><h2 style=\"font-size:14px;font-weight:400;line-height:28px\">This page could not be found.</h2></div></div></div></div></body></html>";
|
|
29
|
+
//#endregion
|
|
30
|
+
export { DEFAULT_PAGES_NOT_FOUND_HTML, buildDefaultPagesNotFoundResponse };
|
|
31
|
+
//# sourceMappingURL=pages-default-404.d.ts.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/server/pages-default-404.ts
|
|
2
|
+
/**
|
|
3
|
+
* Default 404 HTML body for the Pages Router.
|
|
4
|
+
*
|
|
5
|
+
* Used when a Pages Router request does not match any route (and the app has
|
|
6
|
+
* not supplied a custom `pages/404.tsx`). Mirrors the markup Next.js's
|
|
7
|
+
* `pages/_error.tsx` produces for a 404 response: a centered status / message
|
|
8
|
+
* pair plus minified theme CSS and dark-mode media query. The message string
|
|
9
|
+
* `"This page could not be found."` (note the trailing period) is the
|
|
10
|
+
* canonical body asserted by Next.js's deploy suite
|
|
11
|
+
* (`test/e2e/getserversideprops/test/index.test.ts`,
|
|
12
|
+
* `test/e2e/basepath/error-pages.test.ts`).
|
|
13
|
+
*
|
|
14
|
+
* Kept as a hand-rendered HTML literal rather than a React-rendered template
|
|
15
|
+
* because the Pages Router server entry is invoked from both Workers and the
|
|
16
|
+
* dev server before any React-renderer wiring is available for this path —
|
|
17
|
+
* matching the lightweight build-time strategy Next.js uses for its packaged
|
|
18
|
+
* `_error` static fallback. See:
|
|
19
|
+
* .nextjs-ref/packages/next/src/pages/_error.tsx
|
|
20
|
+
*/
|
|
21
|
+
const STATUS = 404;
|
|
22
|
+
const MESSAGE = "This page could not be found.";
|
|
23
|
+
const HTML = `<!DOCTYPE html><html><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width"/><title>${STATUS}: ${MESSAGE}</title><meta name="next-head-count" content="2"/><style data-next-hide-fouc="true">body{display:none}</style><noscript data-next-hide-fouc="true"><style>body{display:block}</style></noscript></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">${STATUS}</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">${MESSAGE}</h2></div></div></div></div></body></html>`;
|
|
24
|
+
/**
|
|
25
|
+
* Build the Next.js-compatible default 404 HTML response for the Pages Router.
|
|
26
|
+
* Content-type is `text/html; charset=utf-8`, matching Next.js's
|
|
27
|
+
* `pages-handler` 404 response.
|
|
28
|
+
*/
|
|
29
|
+
function buildDefaultPagesNotFoundResponse() {
|
|
30
|
+
return new Response(HTML, {
|
|
31
|
+
status: STATUS,
|
|
32
|
+
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** Exported for tests / callers that need the raw HTML body. */
|
|
36
|
+
const DEFAULT_PAGES_NOT_FOUND_HTML = HTML;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { DEFAULT_PAGES_NOT_FOUND_HTML, buildDefaultPagesNotFoundResponse };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=pages-default-404.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages-default-404.js","names":[],"sources":["../../src/server/pages-default-404.ts"],"sourcesContent":["/**\n * Default 404 HTML body for the Pages Router.\n *\n * Used when a Pages Router request does not match any route (and the app has\n * not supplied a custom `pages/404.tsx`). Mirrors the markup Next.js's\n * `pages/_error.tsx` produces for a 404 response: a centered status / message\n * pair plus minified theme CSS and dark-mode media query. The message string\n * `\"This page could not be found.\"` (note the trailing period) is the\n * canonical body asserted by Next.js's deploy suite\n * (`test/e2e/getserversideprops/test/index.test.ts`,\n * `test/e2e/basepath/error-pages.test.ts`).\n *\n * Kept as a hand-rendered HTML literal rather than a React-rendered template\n * because the Pages Router server entry is invoked from both Workers and the\n * dev server before any React-renderer wiring is available for this path —\n * matching the lightweight build-time strategy Next.js uses for its packaged\n * `_error` static fallback. See:\n * .nextjs-ref/packages/next/src/pages/_error.tsx\n */\n\nconst STATUS = 404;\nconst MESSAGE = \"This page could not be found.\";\n\nconst CSS = `body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}`;\n\nconst HTML = `<!DOCTYPE html><html><head><meta charset=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width\"/><title>${STATUS}: ${MESSAGE}</title><meta name=\"next-head-count\" content=\"2\"/><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript></head><body><div id=\"__next\"><div style=\"font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div style=\"line-height:48px\"><style>${CSS}</style><h1 class=\"next-error-h1\" style=\"display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top\">${STATUS}</h1><div style=\"display:inline-block\"><h2 style=\"font-size:14px;font-weight:400;line-height:28px\">${MESSAGE}</h2></div></div></div></div></body></html>`;\n\n/**\n * Build the Next.js-compatible default 404 HTML response for the Pages Router.\n * Content-type is `text/html; charset=utf-8`, matching Next.js's\n * `pages-handler` 404 response.\n */\nexport function buildDefaultPagesNotFoundResponse(): Response {\n return new Response(HTML, {\n status: STATUS,\n headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n });\n}\n\n/** Exported for tests / callers that need the raw HTML body. */\nexport const DEFAULT_PAGES_NOT_FOUND_HTML = HTML;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,MAAM,SAAS;AACf,MAAM,UAAU;AAIhB,MAAM,OAAO,gHAAgH,OAAO,IAAI,QAAQ,u3BAAgqB,OAAO,qGAAqG,QAAQ;;;;;;AAOp6B,SAAgB,oCAA8C;CAC5D,OAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,SAAS,EAAE,gBAAgB,4BAA4B;EACxD,CAAC;;;AAIJ,MAAa,+BAA+B"}
|