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
package/README.md
CHANGED
|
@@ -558,7 +558,7 @@ These are intentional exclusions. For things that are missing today but on the r
|
|
|
558
558
|
|
|
559
559
|
These are gaps we'd like to close — distinct from the [intentional exclusions](#whats-not-supported-and-wont-be) above.
|
|
560
560
|
|
|
561
|
-
- **Image optimization doesn't happen at build time.** Remote images work via `@unpic/react` (auto-detects 28 CDN providers). Local images are routed through a `/
|
|
561
|
+
- **Image optimization doesn't happen at build time.** Remote images work via `@unpic/react` (auto-detects 28 CDN providers). Local images are routed through a `/_next/image` endpoint that can resize and transcode on Cloudflare Workers (via the Images binding) in production, but no build-time optimization or static resizing occurs.
|
|
562
562
|
- **Google Fonts are loaded from the CDN, not self-hosted.** No `size-adjust` fallback font metrics. Local fonts work but `@font-face` CSS is injected at runtime, not extracted at build time.
|
|
563
563
|
- **Route segment config** — `runtime` and `preferredRegion` are ignored (everything runs in the same environment).
|
|
564
564
|
- **Node.js production server (`vinext start`)** works for testing but is less complete than Workers deployment. Cloudflare Workers is the primary target.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/build/clean-output.d.ts
|
|
2
|
+
type CleanBuildOutputOptions = {
|
|
3
|
+
root: string;
|
|
4
|
+
outDir?: string;
|
|
5
|
+
emptyOutDir?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type CleanBuildOutputResult = {
|
|
8
|
+
cleaned: boolean;
|
|
9
|
+
outDir: string;
|
|
10
|
+
};
|
|
11
|
+
declare function cleanBuildOutput(options: CleanBuildOutputOptions): CleanBuildOutputResult;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { cleanBuildOutput };
|
|
14
|
+
//# sourceMappingURL=clean-output.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region src/build/clean-output.ts
|
|
4
|
+
function resolveOutDir(root, outDir) {
|
|
5
|
+
const resolvedRoot = path.resolve(root);
|
|
6
|
+
if (!outDir) return path.join(resolvedRoot, "dist");
|
|
7
|
+
return path.isAbsolute(outDir) ? outDir : path.resolve(resolvedRoot, outDir);
|
|
8
|
+
}
|
|
9
|
+
function isPathInsideOrEqual(parent, child) {
|
|
10
|
+
const relative = path.relative(parent, child);
|
|
11
|
+
return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
12
|
+
}
|
|
13
|
+
function shouldCleanBuildOutput(options) {
|
|
14
|
+
if (options.emptyOutDir === false) return false;
|
|
15
|
+
if (options.emptyOutDir === true) return true;
|
|
16
|
+
return isPathInsideOrEqual(path.resolve(options.root), resolveOutDir(options.root, options.outDir));
|
|
17
|
+
}
|
|
18
|
+
function cleanBuildOutput(options) {
|
|
19
|
+
const outDir = resolveOutDir(options.root, options.outDir);
|
|
20
|
+
if (!shouldCleanBuildOutput(options)) return {
|
|
21
|
+
cleaned: false,
|
|
22
|
+
outDir
|
|
23
|
+
};
|
|
24
|
+
fs.rmSync(outDir, {
|
|
25
|
+
recursive: true,
|
|
26
|
+
force: true
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
cleaned: true,
|
|
30
|
+
outDir
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { cleanBuildOutput };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=clean-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean-output.js","names":[],"sources":["../../src/build/clean-output.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\ntype CleanBuildOutputOptions = {\n root: string;\n outDir?: string;\n emptyOutDir?: boolean;\n};\n\ntype CleanBuildOutputResult = {\n cleaned: boolean;\n outDir: string;\n};\n\nfunction resolveOutDir(root: string, outDir: string | undefined): string {\n const resolvedRoot = path.resolve(root);\n if (!outDir) return path.join(resolvedRoot, \"dist\");\n return path.isAbsolute(outDir) ? outDir : path.resolve(resolvedRoot, outDir);\n}\n\nfunction isPathInsideOrEqual(parent: string, child: string): boolean {\n const relative = path.relative(parent, child);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction shouldCleanBuildOutput(options: CleanBuildOutputOptions): boolean {\n if (options.emptyOutDir === false) return false;\n if (options.emptyOutDir === true) return true;\n\n return isPathInsideOrEqual(\n path.resolve(options.root),\n resolveOutDir(options.root, options.outDir),\n );\n}\n\nexport function cleanBuildOutput(options: CleanBuildOutputOptions): CleanBuildOutputResult {\n const outDir = resolveOutDir(options.root, options.outDir);\n if (!shouldCleanBuildOutput(options)) return { cleaned: false, outDir };\n\n fs.rmSync(outDir, { recursive: true, force: true });\n return { cleaned: true, outDir };\n}\n"],"mappings":";;;AAcA,SAAS,cAAc,MAAc,QAAoC;CACvE,MAAM,eAAe,KAAK,QAAQ,KAAK;CACvC,IAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,cAAc,OAAO;CACnD,OAAO,KAAK,WAAW,OAAO,GAAG,SAAS,KAAK,QAAQ,cAAc,OAAO;;AAG9E,SAAS,oBAAoB,QAAgB,OAAwB;CACnE,MAAM,WAAW,KAAK,SAAS,QAAQ,MAAM;CAC7C,OAAO,aAAa,MAAO,CAAC,SAAS,WAAW,KAAK,IAAI,CAAC,KAAK,WAAW,SAAS;;AAGrF,SAAS,uBAAuB,SAA2C;CACzE,IAAI,QAAQ,gBAAgB,OAAO,OAAO;CAC1C,IAAI,QAAQ,gBAAgB,MAAM,OAAO;CAEzC,OAAO,oBACL,KAAK,QAAQ,QAAQ,KAAK,EAC1B,cAAc,QAAQ,MAAM,QAAQ,OAAO,CAC5C;;AAGH,SAAgB,iBAAiB,SAA0D;CACzF,MAAM,SAAS,cAAc,QAAQ,MAAM,QAAQ,OAAO;CAC1D,IAAI,CAAC,uBAAuB,QAAQ,EAAE,OAAO;EAAE,SAAS;EAAO;EAAQ;CAEvE,GAAG,OAAO,QAAQ;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;CACnD,OAAO;EAAE,SAAS;EAAM;EAAQ"}
|
|
@@ -11,16 +11,16 @@ type PrecompressResult = {
|
|
|
11
11
|
* Safe to re-run — overwrites existing compressed variants with identical
|
|
12
12
|
* output, and never compresses `.br`, `.gz`, or `.zst` files themselves.
|
|
13
13
|
*
|
|
14
|
-
* `assetsDir` defaults to `"
|
|
15
|
-
* `assetPrefix` is configured
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* `assetsDir` defaults to `"_next/static"` (Next.js's canonical convention,
|
|
15
|
+
* matching `resolveAssetsDir("")`). When `assetPrefix` is configured as a
|
|
16
|
+
* path prefix the build writes assets to a different directory (e.g.
|
|
17
|
+
* `"cdn/_next/static"`); callers should resolve that with
|
|
18
18
|
* `resolveAssetsDir(assetPrefix)` and thread it through. Without this,
|
|
19
|
-
* `assetPrefix` builds would walk an empty `
|
|
20
|
-
* zero compressed variants.
|
|
19
|
+
* `assetPrefix` builds would walk an empty `_next/static/` directory and
|
|
20
|
+
* emit zero compressed variants.
|
|
21
21
|
*/
|
|
22
22
|
declare function precompressAssets(clientDir: string, options?: {
|
|
23
|
-
/** Subdirectory under `clientDir` containing hashed assets. Defaults to `"
|
|
23
|
+
/** Subdirectory under `clientDir` containing hashed assets. Defaults to `"_next/static"`. */assetsDir?: string;
|
|
24
24
|
onProgress?: (completed: number, total: number, file: string) => void;
|
|
25
25
|
}): Promise<PrecompressResult>;
|
|
26
26
|
//#endregion
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ASSET_PREFIX_URL_DIR } from "../utils/asset-prefix.js";
|
|
1
2
|
import path from "node:path";
|
|
2
|
-
import
|
|
3
|
+
import fs from "node:fs/promises";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import zlib from "node:zlib";
|
|
5
6
|
import { promisify } from "node:util";
|
|
@@ -8,12 +9,12 @@ import { promisify } from "node:util";
|
|
|
8
9
|
* Build-time precompression for hashed static assets.
|
|
9
10
|
*
|
|
10
11
|
* Generates .br (brotli q5), .gz (gzip l8), and .zst (zstd l8) files
|
|
11
|
-
* alongside compressible assets in dist/client/
|
|
12
|
-
* the production server — no per-request compression needed
|
|
13
|
-
* build output.
|
|
12
|
+
* alongside compressible assets in dist/client/_next/static/. Served
|
|
13
|
+
* directly by the production server — no per-request compression needed
|
|
14
|
+
* for immutable build output.
|
|
14
15
|
*
|
|
15
|
-
* Only targets
|
|
16
|
-
* on-the-fly compression since they may change between deploys.
|
|
16
|
+
* Only targets the hashed-asset directory (immutable) — public directory
|
|
17
|
+
* files use on-the-fly compression since they may change between deploys.
|
|
17
18
|
*/
|
|
18
19
|
const brotliCompress = promisify(zlib.brotliCompress);
|
|
19
20
|
const gzip = promisify(zlib.gzip);
|
|
@@ -45,7 +46,7 @@ const CONCURRENCY = Math.min(os.availableParallelism(), 8);
|
|
|
45
46
|
async function* walkFiles(dir, base = dir) {
|
|
46
47
|
let entries;
|
|
47
48
|
try {
|
|
48
|
-
entries = await
|
|
49
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
49
50
|
} catch {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
@@ -62,16 +63,16 @@ async function* walkFiles(dir, base = dir) {
|
|
|
62
63
|
* Safe to re-run — overwrites existing compressed variants with identical
|
|
63
64
|
* output, and never compresses `.br`, `.gz`, or `.zst` files themselves.
|
|
64
65
|
*
|
|
65
|
-
* `assetsDir` defaults to `"
|
|
66
|
-
* `assetPrefix` is configured
|
|
67
|
-
*
|
|
68
|
-
*
|
|
66
|
+
* `assetsDir` defaults to `"_next/static"` (Next.js's canonical convention,
|
|
67
|
+
* matching `resolveAssetsDir("")`). When `assetPrefix` is configured as a
|
|
68
|
+
* path prefix the build writes assets to a different directory (e.g.
|
|
69
|
+
* `"cdn/_next/static"`); callers should resolve that with
|
|
69
70
|
* `resolveAssetsDir(assetPrefix)` and thread it through. Without this,
|
|
70
|
-
* `assetPrefix` builds would walk an empty `
|
|
71
|
-
* zero compressed variants.
|
|
71
|
+
* `assetPrefix` builds would walk an empty `_next/static/` directory and
|
|
72
|
+
* emit zero compressed variants.
|
|
72
73
|
*/
|
|
73
74
|
async function precompressAssets(clientDir, options = {}) {
|
|
74
|
-
const { assetsDir: assetsSubdir =
|
|
75
|
+
const { assetsDir: assetsSubdir = ASSET_PREFIX_URL_DIR, onProgress } = options;
|
|
75
76
|
const assetsDir = path.join(clientDir, assetsSubdir);
|
|
76
77
|
const result = {
|
|
77
78
|
filesCompressed: 0,
|
|
@@ -88,13 +89,13 @@ async function precompressAssets(clientDir, options = {}) {
|
|
|
88
89
|
for (let i = 0; i < filePaths.length; i += CONCURRENCY) {
|
|
89
90
|
const chunk = filePaths.slice(i, i + CONCURRENCY);
|
|
90
91
|
await Promise.all(chunk.map(async (fullPath) => {
|
|
91
|
-
const content = await
|
|
92
|
+
const content = await fs.readFile(fullPath);
|
|
92
93
|
if (content.length < MIN_SIZE) return;
|
|
93
94
|
const compressions = [brotliCompress(content, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 5 } }), gzip(content, { level: 8 })];
|
|
94
95
|
if (zstdCompress) compressions.push(zstdCompress(content, { params: { [zlib.constants.ZSTD_c_compressionLevel]: 8 } }));
|
|
95
96
|
const [brContent, gzContent, zstdContent] = await Promise.all(compressions);
|
|
96
|
-
const writes = [
|
|
97
|
-
if (zstdContent) writes.push(
|
|
97
|
+
const writes = [fs.writeFile(fullPath + ".br", brContent), fs.writeFile(fullPath + ".gz", gzContent)];
|
|
98
|
+
if (zstdContent) writes.push(fs.writeFile(fullPath + ".zst", zstdContent));
|
|
98
99
|
await Promise.all(writes);
|
|
99
100
|
result.filesCompressed++;
|
|
100
101
|
result.totalOriginalBytes += content.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"precompress.js","names":[],"sources":["../../src/build/precompress.ts"],"sourcesContent":["/**\n * Build-time precompression for hashed static assets.\n *\n * Generates .br (brotli q5), .gz (gzip l8), and .zst (zstd l8) files\n * alongside compressible assets in dist/client/
|
|
1
|
+
{"version":3,"file":"precompress.js","names":["fsp"],"sources":["../../src/build/precompress.ts"],"sourcesContent":["/**\n * Build-time precompression for hashed static assets.\n *\n * Generates .br (brotli q5), .gz (gzip l8), and .zst (zstd l8) files\n * alongside compressible assets in dist/client/_next/static/. Served\n * directly by the production server — no per-request compression needed\n * for immutable build output.\n *\n * Only targets the hashed-asset directory (immutable) — public directory\n * files use on-the-fly compression since they may change between deploys.\n */\nimport fsp from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport zlib from \"node:zlib\";\nimport { promisify } from \"node:util\";\nimport { ASSET_PREFIX_URL_DIR } from \"../utils/asset-prefix.js\";\n\nconst brotliCompress = promisify(zlib.brotliCompress);\nconst gzip = promisify(zlib.gzip);\nconst zstdCompress = typeof zlib.zstdCompress === \"function\" ? promisify(zlib.zstdCompress) : null;\n\n/** File extensions worth compressing (text-based, not already compressed). */\nconst COMPRESSIBLE_EXTENSIONS = new Set([\n \".js\",\n \".mjs\",\n \".css\",\n \".html\",\n \".json\",\n \".xml\",\n \".svg\",\n \".txt\",\n \".map\",\n \".wasm\",\n]);\n\n/** Below this size, compression overhead exceeds savings. */\nconst MIN_SIZE = 1024;\n\n/**\n * Past ~8 parallel files, mixed-size asset sets spend more time queueing zlib\n * work than making forward progress. Keep the batch size bounded even on\n * higher-core machines.\n */\nconst CONCURRENCY = Math.min(os.availableParallelism(), 8);\n\ntype PrecompressResult = {\n filesCompressed: number;\n totalOriginalBytes: number;\n /** Sum of brotli-compressed sizes (used for compression ratio reporting). */\n totalBrotliBytes: number;\n};\n\n/**\n * Walk a directory recursively, yielding relative paths for regular files.\n */\nasync function* walkFiles(dir: string, base: string = dir): AsyncGenerator<string> {\n let entries;\n try {\n entries = await fsp.readdir(dir, { withFileTypes: true });\n } catch {\n return; // directory doesn't exist\n }\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkFiles(fullPath, base);\n } else if (entry.isFile()) {\n yield path.relative(base, fullPath);\n }\n }\n}\n\n/**\n * Precompress all compressible hashed assets under `clientDir/<assetsDir>/`.\n *\n * Writes `.br`, `.gz`, and `.zst` files alongside each original.\n * Safe to re-run — overwrites existing compressed variants with identical\n * output, and never compresses `.br`, `.gz`, or `.zst` files themselves.\n *\n * `assetsDir` defaults to `\"_next/static\"` (Next.js's canonical convention,\n * matching `resolveAssetsDir(\"\")`). When `assetPrefix` is configured as a\n * path prefix the build writes assets to a different directory (e.g.\n * `\"cdn/_next/static\"`); callers should resolve that with\n * `resolveAssetsDir(assetPrefix)` and thread it through. Without this,\n * `assetPrefix` builds would walk an empty `_next/static/` directory and\n * emit zero compressed variants.\n */\nexport async function precompressAssets(\n clientDir: string,\n options: {\n /** Subdirectory under `clientDir` containing hashed assets. Defaults to `\"_next/static\"`. */\n assetsDir?: string;\n onProgress?: (completed: number, total: number, file: string) => void;\n } = {},\n): Promise<PrecompressResult> {\n const { assetsDir: assetsSubdir = ASSET_PREFIX_URL_DIR, onProgress } = options;\n const assetsDir = path.join(clientDir, assetsSubdir);\n const result: PrecompressResult = {\n filesCompressed: 0,\n totalOriginalBytes: 0,\n totalBrotliBytes: 0,\n };\n\n // Collect compressible file paths, then read + compress in bounded chunks\n // to keep peak memory at O(CONCURRENCY * max_file_size) instead of\n // O(total_assets).\n const filePaths: string[] = [];\n\n for await (const relativePath of walkFiles(assetsDir)) {\n const ext = path.extname(relativePath).toLowerCase();\n\n if (!COMPRESSIBLE_EXTENSIONS.has(ext)) continue;\n // .br/.gz/.zst are intentionally absent from COMPRESSIBLE_EXTENSIONS, so\n // precompressed variants generated by a previous run are never re-compressed.\n\n filePaths.push(path.join(assetsDir, relativePath));\n }\n\n let processed = 0;\n for (let i = 0; i < filePaths.length; i += CONCURRENCY) {\n const chunk = filePaths.slice(i, i + CONCURRENCY);\n await Promise.all(\n chunk.map(async (fullPath) => {\n const content = await fsp.readFile(fullPath);\n // readFile already done before this check — stat()-first would save\n // the read for tiny files but costs an extra syscall per file;\n // sub-1KB hashed assets are rare enough that read-first is cheaper.\n if (content.length < MIN_SIZE) return;\n\n // Compress all variants concurrently within each file\n const compressions: Promise<Buffer>[] = [\n brotliCompress(content, {\n params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 5 },\n }),\n gzip(content, { level: 8 }),\n ];\n if (zstdCompress) {\n compressions.push(\n zstdCompress(content, {\n params: { [zlib.constants.ZSTD_c_compressionLevel]: 8 },\n }),\n );\n }\n\n const results = await Promise.all(compressions);\n const [brContent, gzContent, zstdContent] = results;\n\n const writes = [\n fsp.writeFile(fullPath + \".br\", brContent),\n fsp.writeFile(fullPath + \".gz\", gzContent),\n ];\n if (zstdContent) {\n writes.push(fsp.writeFile(fullPath + \".zst\", zstdContent));\n }\n await Promise.all(writes);\n\n // Increment counters only after all writes succeed, so partial\n // failures (e.g. ENOSPC mid-write) don't inflate the reported totals.\n result.filesCompressed++;\n result.totalOriginalBytes += content.length;\n result.totalBrotliBytes += brContent.length;\n }),\n );\n // Report progress once per chunk to avoid non-deterministic ordering\n // within Promise.all (smaller files complete before larger ones).\n // Progress tracks all files (including skipped ones below MIN_SIZE),\n // which differs from filesCompressed (only files actually compressed).\n processed += chunk.length;\n onProgress?.(processed, filePaths.length, path.basename(chunk[chunk.length - 1]));\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAM,iBAAiB,UAAU,KAAK,eAAe;AACrD,MAAM,OAAO,UAAU,KAAK,KAAK;AACjC,MAAM,eAAe,OAAO,KAAK,iBAAiB,aAAa,UAAU,KAAK,aAAa,GAAG;;AAG9F,MAAM,0BAA0B,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;AAGF,MAAM,WAAW;;;;;;AAOjB,MAAM,cAAc,KAAK,IAAI,GAAG,sBAAsB,EAAE,EAAE;;;;AAY1D,gBAAgB,UAAU,KAAa,OAAe,KAA6B;CACjF,IAAI;CACJ,IAAI;EACF,UAAU,MAAMA,GAAI,QAAQ,KAAK,EAAE,eAAe,MAAM,CAAC;SACnD;EACN;;CAEF,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,KAAK,KAAK,KAAK,MAAM,KAAK;EAC3C,IAAI,MAAM,aAAa,EACrB,OAAO,UAAU,UAAU,KAAK;OAC3B,IAAI,MAAM,QAAQ,EACvB,MAAM,KAAK,SAAS,MAAM,SAAS;;;;;;;;;;;;;;;;;;AAoBzC,eAAsB,kBACpB,WACA,UAII,EAAE,EACsB;CAC5B,MAAM,EAAE,WAAW,eAAe,sBAAsB,eAAe;CACvE,MAAM,YAAY,KAAK,KAAK,WAAW,aAAa;CACpD,MAAM,SAA4B;EAChC,iBAAiB;EACjB,oBAAoB;EACpB,kBAAkB;EACnB;CAKD,MAAM,YAAsB,EAAE;CAE9B,WAAW,MAAM,gBAAgB,UAAU,UAAU,EAAE;EACrD,MAAM,MAAM,KAAK,QAAQ,aAAa,CAAC,aAAa;EAEpD,IAAI,CAAC,wBAAwB,IAAI,IAAI,EAAE;EAIvC,UAAU,KAAK,KAAK,KAAK,WAAW,aAAa,CAAC;;CAGpD,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,aAAa;EACtD,MAAM,QAAQ,UAAU,MAAM,GAAG,IAAI,YAAY;EACjD,MAAM,QAAQ,IACZ,MAAM,IAAI,OAAO,aAAa;GAC5B,MAAM,UAAU,MAAMA,GAAI,SAAS,SAAS;GAI5C,IAAI,QAAQ,SAAS,UAAU;GAG/B,MAAM,eAAkC,CACtC,eAAe,SAAS,EACtB,QAAQ,GAAG,KAAK,UAAU,uBAAuB,GAAG,EACrD,CAAC,EACF,KAAK,SAAS,EAAE,OAAO,GAAG,CAAC,CAC5B;GACD,IAAI,cACF,aAAa,KACX,aAAa,SAAS,EACpB,QAAQ,GAAG,KAAK,UAAU,0BAA0B,GAAG,EACxD,CAAC,CACH;GAIH,MAAM,CAAC,WAAW,WAAW,eAAe,MADtB,QAAQ,IAAI,aAAa;GAG/C,MAAM,SAAS,CACbA,GAAI,UAAU,WAAW,OAAO,UAAU,EAC1CA,GAAI,UAAU,WAAW,OAAO,UAAU,CAC3C;GACD,IAAI,aACF,OAAO,KAAKA,GAAI,UAAU,WAAW,QAAQ,YAAY,CAAC;GAE5D,MAAM,QAAQ,IAAI,OAAO;GAIzB,OAAO;GACP,OAAO,sBAAsB,QAAQ;GACrC,OAAO,oBAAoB,UAAU;IACrC,CACH;EAKD,aAAa,MAAM;EACnB,aAAa,WAAW,UAAU,QAAQ,KAAK,SAAS,MAAM,MAAM,SAAS,GAAG,CAAC;;CAGnF,OAAO"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Route } from "../routing/pages-router.js";
|
|
2
2
|
import { AppRoute } from "../routing/app-route-graph.js";
|
|
3
3
|
import { ResolvedNextConfig } from "../config/next-config.js";
|
|
4
|
+
import { MetadataFileRoute } from "../server/metadata-routes.js";
|
|
4
5
|
import { readPrerenderSecret } from "./server-manifest.js";
|
|
5
6
|
import { Server } from "node:http";
|
|
6
7
|
|
|
7
8
|
//#region src/build/prerender.d.ts
|
|
8
9
|
type PrerenderResult = {
|
|
9
|
-
/** One entry per route (including skipped/error routes). */routes: PrerenderRouteResult[];
|
|
10
|
+
/** One entry per route (including skipped/error routes). */routes: PrerenderRouteResult[]; /** Additional generated files that are not represented as route entries. */
|
|
11
|
+
outputFiles?: string[];
|
|
10
12
|
};
|
|
11
13
|
type PrerenderRouteResult = {
|
|
12
14
|
/** The route's file-system pattern, e.g. `/blog/:slug`. */route: string;
|
|
@@ -83,7 +85,8 @@ type PrerenderPagesOptions = {
|
|
|
83
85
|
pagesBundlePath?: string;
|
|
84
86
|
} & PrerenderOptions;
|
|
85
87
|
type PrerenderAppOptions = {
|
|
86
|
-
/** Discovered app routes. */routes: AppRoute[];
|
|
88
|
+
/** Discovered app routes. */routes: AppRoute[]; /** Discovered file-based metadata routes. Used by static export. */
|
|
89
|
+
metadataRoutes?: readonly MetadataFileRoute[];
|
|
87
90
|
/**
|
|
88
91
|
* Absolute path to the pre-built RSC handler bundle (e.g. `dist/server/index.js`).
|
|
89
92
|
*/
|
|
@@ -123,15 +126,10 @@ type PrerenderAppOptionsInternal = PrerenderAppOptions & {
|
|
|
123
126
|
* all '<' and '>' in the embedded JSON, preventing false </script> matches.
|
|
124
127
|
*/
|
|
125
128
|
declare function extractRscPayloadFromPrerenderedHtml(html: string): Uint8Array | null;
|
|
126
|
-
/**
|
|
127
|
-
* Determine the HTML output file path for a URL.
|
|
128
|
-
* Respects trailingSlash config.
|
|
129
|
-
*/
|
|
130
|
-
declare function getOutputPath(urlPath: string, trailingSlash: boolean): string;
|
|
131
129
|
/** Map of route patterns to generateStaticParams functions (or null/undefined). */
|
|
132
130
|
type StaticParamsMap = Record<string, ((opts: {
|
|
133
131
|
params: Record<string, string | string[]>;
|
|
134
|
-
}) => Promise<
|
|
132
|
+
}) => Promise<unknown>) | null | undefined>;
|
|
135
133
|
/**
|
|
136
134
|
* Resolve parent dynamic segment params for a route.
|
|
137
135
|
* Handles top-down generateStaticParams resolution for nested dynamic routes.
|
|
@@ -139,7 +137,7 @@ type StaticParamsMap = Record<string, ((opts: {
|
|
|
139
137
|
* Uses the `staticParamsMap` (pattern → generateStaticParams) exported from
|
|
140
138
|
* the production bundle.
|
|
141
139
|
*/
|
|
142
|
-
declare function resolveParentParams(childRoute: AppRoute,
|
|
140
|
+
declare function resolveParentParams(childRoute: AppRoute, staticParamsMap: StaticParamsMap): Promise<Record<string, string | string[]>[]>;
|
|
143
141
|
/**
|
|
144
142
|
* Run the prerender phase for Pages Router.
|
|
145
143
|
*
|
|
@@ -181,18 +179,13 @@ declare function prerenderPages({
|
|
|
181
179
|
*/
|
|
182
180
|
declare function prerenderApp({
|
|
183
181
|
routes,
|
|
182
|
+
metadataRoutes,
|
|
184
183
|
outDir,
|
|
185
184
|
config,
|
|
186
185
|
mode,
|
|
187
186
|
rscBundlePath,
|
|
188
187
|
...options
|
|
189
188
|
}: PrerenderAppOptionsInternal): Promise<PrerenderResult>;
|
|
190
|
-
/**
|
|
191
|
-
* Determine the RSC output file path for a URL.
|
|
192
|
-
* "/blog/hello-world" → "blog/hello-world.rsc"
|
|
193
|
-
* "/" → "index.rsc"
|
|
194
|
-
*/
|
|
195
|
-
declare function getRscOutputPath(urlPath: string): string;
|
|
196
189
|
/**
|
|
197
190
|
* Write `vinext-prerender.json` to `outDir`.
|
|
198
191
|
*
|
|
@@ -205,5 +198,5 @@ declare function writePrerenderIndex(routes: PrerenderRouteResult[], outDir: str
|
|
|
205
198
|
trailingSlash?: boolean;
|
|
206
199
|
}): void;
|
|
207
200
|
//#endregion
|
|
208
|
-
export { PrerenderResult, PrerenderRouteResult, StaticParamsMap, extractRscPayloadFromPrerenderedHtml,
|
|
201
|
+
export { PrerenderResult, PrerenderRouteResult, StaticParamsMap, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
|
|
209
202
|
//# sourceMappingURL=prerender.d.ts.map
|
package/dist/build/prerender.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { createValidFileMatcher, findFileWithExtensions } from "../routing/file-matcher.js";
|
|
2
|
-
import { VINEXT_PRERENDER_SECRET_HEADER } from "../server/headers.js";
|
|
2
|
+
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../server/headers.js";
|
|
3
3
|
import { normalizeStaticPathsEntry } from "../routing/route-pattern.js";
|
|
4
4
|
import { headersContextFromRequest, runWithHeadersContext } from "../shims/headers.js";
|
|
5
5
|
import { NoOpCacheHandler, _consumeRequestScopedCacheLife, getCacheHandler, setCacheHandler } from "../shims/cache.js";
|
|
6
6
|
import { classifyAppRoute, classifyPagesRoute, getAppRouteRenderEntryPath } from "./report.js";
|
|
7
7
|
import { concatUint8Arrays, decodeRscEmbeddedChunk } from "../server/app-rsc-embedded-chunks.js";
|
|
8
|
+
import { navigationRuntimeRscBootstrapExpression } from "../server/app-ssr-stream.js";
|
|
9
|
+
import { encodePrerenderRouteParams, serializePrerenderRouteParamsHeader } from "../server/prerender-route-params.js";
|
|
8
10
|
import { readPrerenderSecret } from "./server-manifest.js";
|
|
11
|
+
import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths.js";
|
|
9
12
|
import { startProdServer } from "../server/prod-server.js";
|
|
10
13
|
import fs from "node:fs";
|
|
11
14
|
import path from "node:path";
|
|
@@ -34,9 +37,12 @@ function getErrorMessageWithStack(err) {
|
|
|
34
37
|
/** Sentinel path used to trigger 404 rendering without a real route match. */
|
|
35
38
|
const NOT_FOUND_SENTINEL_PATH = "/__vinext_nonexistent_for_404__";
|
|
36
39
|
const DEFAULT_CONCURRENCY = Math.min(os.availableParallelism(), 8);
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
+
const RSC_LEGACY_CHUNK_SCRIPT_PREFIX = "self.__VINEXT_RSC_CHUNKS__=self.__VINEXT_RSC_CHUNKS__||[];";
|
|
41
|
+
const RSC_LEGACY_DONE_SCRIPT = "self.__VINEXT_RSC_DONE__=true";
|
|
42
|
+
const RSC_LEGACY_CHUNK_FULL_PREFIX = `${RSC_LEGACY_CHUNK_SCRIPT_PREFIX}self.__VINEXT_RSC_CHUNKS__.push(`;
|
|
43
|
+
const RSC_RUNTIME_BOOTSTRAP_EXPRESSION = navigationRuntimeRscBootstrapExpression();
|
|
44
|
+
const RSC_RUNTIME_CHUNK_FULL_PREFIX = `${RSC_RUNTIME_BOOTSTRAP_EXPRESSION}.rsc.push(`;
|
|
45
|
+
const RSC_RUNTIME_DONE_SCRIPT = `${RSC_RUNTIME_BOOTSTRAP_EXPRESSION}.done=true`;
|
|
40
46
|
/**
|
|
41
47
|
* Reconstruct the RSC payload from a prerender HTML response by parsing the
|
|
42
48
|
* inline bootstrap chunk scripts emitted by createRscEmbedTransform.
|
|
@@ -59,15 +65,19 @@ function extractRscPayloadFromPrerenderedHtml(html) {
|
|
|
59
65
|
let match;
|
|
60
66
|
while ((match = scriptPattern.exec(html)) !== null) {
|
|
61
67
|
const script = (match[1] ?? "").trim().replace(/;$/, "");
|
|
62
|
-
if (script ===
|
|
68
|
+
if (script === RSC_RUNTIME_DONE_SCRIPT || script === RSC_LEGACY_DONE_SCRIPT) {
|
|
63
69
|
sawDone = true;
|
|
64
70
|
continue;
|
|
65
71
|
}
|
|
66
|
-
if (script.startsWith(
|
|
72
|
+
if (script.startsWith(RSC_RUNTIME_CHUNK_FULL_PREFIX)) {
|
|
73
|
+
chunks.push(decodeRscEmbeddedChunk(parseRscChunkPushArgument(script, RSC_RUNTIME_CHUNK_FULL_PREFIX)));
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (script.startsWith(RSC_LEGACY_CHUNK_SCRIPT_PREFIX)) chunks.push(decodeRscEmbeddedChunk(parseRscChunkPushArgument(script, RSC_LEGACY_CHUNK_FULL_PREFIX)));
|
|
67
77
|
}
|
|
68
78
|
if (chunks.length === 0 && !sawDone) return null;
|
|
69
79
|
if (chunks.length === 0) throw new Error("[vinext] Malformed prerender RSC embed: done marker present without chunk scripts");
|
|
70
|
-
if (!sawDone) throw new Error("[vinext] Malformed prerender RSC embed: missing
|
|
80
|
+
if (!sawDone) throw new Error("[vinext] Malformed prerender RSC embed: missing RSC done marker");
|
|
71
81
|
return concatUint8Arrays(chunks);
|
|
72
82
|
}
|
|
73
83
|
/**
|
|
@@ -77,9 +87,9 @@ function extractRscPayloadFromPrerenderedHtml(html) {
|
|
|
77
87
|
* prefix and ends with `)`. JSON.parse on the slice catches any tampering or
|
|
78
88
|
* trailing code.
|
|
79
89
|
*/
|
|
80
|
-
function parseRscChunkPushArgument(script) {
|
|
81
|
-
if (!script.startsWith(
|
|
82
|
-
const jsonSource = script.slice(
|
|
90
|
+
function parseRscChunkPushArgument(script, chunkPrefix) {
|
|
91
|
+
if (!script.startsWith(chunkPrefix) || !script.endsWith(")")) throw new Error("[vinext] Malformed prerender RSC embed: unexpected chunk script shape");
|
|
92
|
+
const jsonSource = script.slice(chunkPrefix.length, -1);
|
|
83
93
|
let parsed;
|
|
84
94
|
try {
|
|
85
95
|
parsed = JSON.parse(jsonSource);
|
|
@@ -134,15 +144,25 @@ function buildUrlFromParams(pattern, params) {
|
|
|
134
144
|
} else result.push(part);
|
|
135
145
|
return "/" + result.join("/");
|
|
136
146
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
function metadataOutputPath(servedUrl) {
|
|
148
|
+
const pathname = servedUrl.split("?", 1)[0];
|
|
149
|
+
if (!pathname || !pathname.startsWith("/")) return null;
|
|
150
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
151
|
+
if (segments.length === 0 || segments.some((segment) => segment === "." || segment === "..")) return null;
|
|
152
|
+
return segments.join("/");
|
|
153
|
+
}
|
|
154
|
+
function emitStaticMetadataFiles(metadataRoutes, outDir) {
|
|
155
|
+
const outputFiles = [];
|
|
156
|
+
for (const route of metadataRoutes) {
|
|
157
|
+
if (route.isDynamic) continue;
|
|
158
|
+
const outputPath = metadataOutputPath(route.servedUrl);
|
|
159
|
+
if (!outputPath) continue;
|
|
160
|
+
const fullPath = path.join(outDir, ...outputPath.split("/"));
|
|
161
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
162
|
+
fs.copyFileSync(route.filePath, fullPath);
|
|
163
|
+
outputFiles.push(outputPath);
|
|
164
|
+
}
|
|
165
|
+
return outputFiles;
|
|
146
166
|
}
|
|
147
167
|
/**
|
|
148
168
|
* Resolve parent dynamic segment params for a route.
|
|
@@ -151,7 +171,7 @@ function getOutputPath(urlPath, trailingSlash) {
|
|
|
151
171
|
* Uses the `staticParamsMap` (pattern → generateStaticParams) exported from
|
|
152
172
|
* the production bundle.
|
|
153
173
|
*/
|
|
154
|
-
async function resolveParentParams(childRoute,
|
|
174
|
+
async function resolveParentParams(childRoute, staticParamsMap) {
|
|
155
175
|
const { patternParts } = childRoute;
|
|
156
176
|
let lastDynamicIdx = -1;
|
|
157
177
|
for (let i = patternParts.length - 1; i >= 0; i--) if (patternParts[i].startsWith(":")) {
|
|
@@ -164,25 +184,29 @@ async function resolveParentParams(childRoute, routeIndex, staticParamsMap) {
|
|
|
164
184
|
const part = patternParts[i];
|
|
165
185
|
prefixPattern += "/" + part;
|
|
166
186
|
if (!part.startsWith(":")) continue;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (typeof fn === "function") parentSegments.push(fn);
|
|
170
|
-
}
|
|
187
|
+
const fn = staticParamsMap[prefixPattern];
|
|
188
|
+
if (typeof fn === "function") parentSegments.push(fn);
|
|
171
189
|
}
|
|
172
190
|
if (parentSegments.length === 0) return [];
|
|
173
191
|
let currentParams = [{}];
|
|
192
|
+
let resolvedAnyParent = false;
|
|
174
193
|
for (const generateStaticParams of parentSegments) {
|
|
175
194
|
const nextParams = [];
|
|
195
|
+
let resolvedThisParent = false;
|
|
176
196
|
for (const parentParams of currentParams) {
|
|
177
197
|
const results = await generateStaticParams({ params: parentParams });
|
|
178
|
-
if (
|
|
198
|
+
if (results === null) continue;
|
|
199
|
+
if (!Array.isArray(results)) return [];
|
|
200
|
+
resolvedThisParent = true;
|
|
201
|
+
resolvedAnyParent = true;
|
|
202
|
+
for (const result of results) nextParams.push({
|
|
179
203
|
...parentParams,
|
|
180
204
|
...result
|
|
181
205
|
});
|
|
182
206
|
}
|
|
183
|
-
currentParams = nextParams;
|
|
207
|
+
if (resolvedThisParent) currentParams = nextParams;
|
|
184
208
|
}
|
|
185
|
-
return currentParams;
|
|
209
|
+
return resolvedAnyParent ? currentParams : [];
|
|
186
210
|
}
|
|
187
211
|
/**
|
|
188
212
|
* Run the prerender phase for Pages Router.
|
|
@@ -265,6 +289,7 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
265
289
|
const pagesToRender = [];
|
|
266
290
|
for (const route of bundlePageRoutes) {
|
|
267
291
|
if (path.basename(route.filePath, path.extname(route.filePath)).startsWith("_")) continue;
|
|
292
|
+
if (route.pattern === "/404") continue;
|
|
268
293
|
if (!routes.find((r) => r.filePath === route.filePath || r.pattern === route.pattern)) continue;
|
|
269
294
|
const { type, revalidate: classifiedRevalidate } = classifyPagesRoute(route.filePath);
|
|
270
295
|
if (type === "ssr") {
|
|
@@ -391,9 +416,12 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
391
416
|
return result;
|
|
392
417
|
});
|
|
393
418
|
results.push(...pageResults);
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
419
|
+
const hasCustom404 = findFileWithExtensions(path.join(pagesDir, "404"), fileMatcher);
|
|
420
|
+
const hasErrorPage = findFileWithExtensions(path.join(pagesDir, "_error"), fileMatcher);
|
|
421
|
+
if (hasCustom404 || hasErrorPage) try {
|
|
422
|
+
const notFoundRes = await renderPage(hasCustom404 ? "/404" : NOT_FOUND_SENTINEL_PATH);
|
|
423
|
+
const contentType = notFoundRes.headers.get("content-type") ?? "";
|
|
424
|
+
if (notFoundRes.status === 404 && contentType.includes("text/html")) {
|
|
397
425
|
const html404 = await notFoundRes.text();
|
|
398
426
|
const fullPath = path.join(outDir, "404.html");
|
|
399
427
|
fs.writeFileSync(fullPath, html404, "utf-8");
|
|
@@ -435,7 +463,7 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
435
463
|
* If they succeed, they are marked as rendered. If they throw a DynamicUsageError
|
|
436
464
|
* or fail, they are marked as skipped with reason 'dynamic'.
|
|
437
465
|
*/
|
|
438
|
-
async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...options }) {
|
|
466
|
+
async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode, rscBundlePath, ...options }) {
|
|
439
467
|
const manifestDir = options.manifestDir ?? outDir;
|
|
440
468
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
441
469
|
const onProgress = options.onProgress;
|
|
@@ -474,7 +502,8 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
474
502
|
...secretHeaders,
|
|
475
503
|
...Object.fromEntries(req.headers.entries())
|
|
476
504
|
},
|
|
477
|
-
body: req.method !== "GET" && req.method !== "HEAD" ? req.body : void 0
|
|
505
|
+
body: req.method !== "GET" && req.method !== "HEAD" ? req.body : void 0,
|
|
506
|
+
redirect: "manual"
|
|
478
507
|
});
|
|
479
508
|
};
|
|
480
509
|
const staticParamsCache = /* @__PURE__ */ new Map();
|
|
@@ -505,7 +534,6 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
505
534
|
return false;
|
|
506
535
|
}
|
|
507
536
|
});
|
|
508
|
-
const routeIndex = new Map(routes.map((r) => [r.pattern, r]));
|
|
509
537
|
const urlsToRender = [];
|
|
510
538
|
for (const route of routes) {
|
|
511
539
|
const renderEntryPath = getAppRouteRenderEntryPath(route);
|
|
@@ -556,7 +584,7 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
556
584
|
});
|
|
557
585
|
continue;
|
|
558
586
|
}
|
|
559
|
-
const parentParamSets = await resolveParentParams(route,
|
|
587
|
+
const parentParamSets = await resolveParentParams(route, staticParamsMap);
|
|
560
588
|
let paramSets;
|
|
561
589
|
if (parentParamSets.length > 0) {
|
|
562
590
|
paramSets = [];
|
|
@@ -570,8 +598,15 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
570
598
|
...parentParams,
|
|
571
599
|
...childParams
|
|
572
600
|
});
|
|
601
|
+
else {
|
|
602
|
+
paramSets = [];
|
|
603
|
+
break;
|
|
604
|
+
}
|
|
573
605
|
}
|
|
574
|
-
} else
|
|
606
|
+
} else {
|
|
607
|
+
const results = await generateStaticParamsFn({ params: {} });
|
|
608
|
+
paramSets = Array.isArray(results) || results === null ? results : [];
|
|
609
|
+
}
|
|
575
610
|
if (paramSets === null) {
|
|
576
611
|
if (mode === "export") results.push({
|
|
577
612
|
route: route.pattern,
|
|
@@ -599,6 +634,7 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
599
634
|
urlsToRender.push({
|
|
600
635
|
urlPath,
|
|
601
636
|
routePattern: route.pattern,
|
|
637
|
+
prerenderRouteParams: encodePrerenderRouteParams(route.pattern, params),
|
|
602
638
|
revalidate,
|
|
603
639
|
isSpeculative: false
|
|
604
640
|
});
|
|
@@ -615,12 +651,14 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
615
651
|
else if (type === "unknown") urlsToRender.push({
|
|
616
652
|
urlPath: route.pattern,
|
|
617
653
|
routePattern: route.pattern,
|
|
654
|
+
prerenderRouteParams: null,
|
|
618
655
|
revalidate: false,
|
|
619
656
|
isSpeculative: true
|
|
620
657
|
});
|
|
621
658
|
else urlsToRender.push({
|
|
622
659
|
urlPath: route.pattern,
|
|
623
660
|
routePattern: route.pattern,
|
|
661
|
+
prerenderRouteParams: null,
|
|
624
662
|
revalidate,
|
|
625
663
|
isSpeculative: false
|
|
626
664
|
});
|
|
@@ -631,9 +669,12 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
631
669
|
* exactly once per URL after this function returns, keeping the callback
|
|
632
670
|
* at a single, predictable call site.
|
|
633
671
|
*/
|
|
634
|
-
async function renderUrl({ urlPath, routePattern, revalidate, isSpeculative }) {
|
|
672
|
+
async function renderUrl({ urlPath, routePattern, prerenderRouteParams, revalidate, isSpeculative }) {
|
|
635
673
|
try {
|
|
636
|
-
const
|
|
674
|
+
const prerenderRouteParamsHeader = serializePrerenderRouteParamsHeader(prerenderRouteParams);
|
|
675
|
+
const htmlHeaders = new Headers();
|
|
676
|
+
if (prerenderRouteParamsHeader !== null) htmlHeaders.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
|
|
677
|
+
const htmlRequest = new Request(`http://localhost${urlPath}`, { headers: htmlHeaders });
|
|
637
678
|
const htmlRender = await runWithHeadersContext(headersContextFromRequest(htmlRequest), async () => {
|
|
638
679
|
const response = await rscHandler(htmlRequest);
|
|
639
680
|
const cacheControl = response.headers.get("cache-control") ?? "";
|
|
@@ -683,10 +724,12 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
683
724
|
const html = htmlRender.html;
|
|
684
725
|
let rscData = extractRscPayloadFromPrerenderedHtml(html);
|
|
685
726
|
if (rscData === null) {
|
|
686
|
-
const
|
|
727
|
+
const rscHeaders = new Headers({
|
|
687
728
|
Accept: "text/x-component",
|
|
688
729
|
RSC: "1"
|
|
689
|
-
}
|
|
730
|
+
});
|
|
731
|
+
if (prerenderRouteParamsHeader !== null) rscHeaders.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
|
|
732
|
+
const rscRequest = new Request(`http://localhost${urlPath}`, { headers: rscHeaders });
|
|
690
733
|
const rscRes = await runWithHeadersContext(headersContextFromRequest(rscRequest), () => rscHandler(rscRequest));
|
|
691
734
|
if (!rscRes.ok) {
|
|
692
735
|
await rscRes.body?.cancel();
|
|
@@ -743,6 +786,7 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
743
786
|
return result;
|
|
744
787
|
});
|
|
745
788
|
results.push(...appResults);
|
|
789
|
+
const outputFiles = mode === "export" && metadataRoutes.length > 0 ? emitStaticMetadataFiles(metadataRoutes, outDir) : [];
|
|
746
790
|
try {
|
|
747
791
|
const notFoundRequest = new Request(`http://localhost${NOT_FOUND_SENTINEL_PATH}`);
|
|
748
792
|
const notFoundRes = await runWithHeadersContext(headersContextFromRequest(notFoundRequest), () => rscHandler(notFoundRequest));
|
|
@@ -764,7 +808,10 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
764
808
|
buildId: config.buildId,
|
|
765
809
|
trailingSlash: config.trailingSlash
|
|
766
810
|
});
|
|
767
|
-
return {
|
|
811
|
+
return {
|
|
812
|
+
routes: results,
|
|
813
|
+
...outputFiles.length > 0 ? { outputFiles } : {}
|
|
814
|
+
};
|
|
768
815
|
} finally {
|
|
769
816
|
setCacheHandler(previousHandler);
|
|
770
817
|
if (previousPrerenderFlag === void 0) delete process.env.VINEXT_PRERENDER;
|
|
@@ -772,15 +819,6 @@ async function prerenderApp({ routes, outDir, config, mode, rscBundlePath, ...op
|
|
|
772
819
|
if (ownedProdServerHandle) await new Promise((resolve) => ownedProdServerHandle.server.close(() => resolve()));
|
|
773
820
|
}
|
|
774
821
|
}
|
|
775
|
-
/**
|
|
776
|
-
* Determine the RSC output file path for a URL.
|
|
777
|
-
* "/blog/hello-world" → "blog/hello-world.rsc"
|
|
778
|
-
* "/" → "index.rsc"
|
|
779
|
-
*/
|
|
780
|
-
function getRscOutputPath(urlPath) {
|
|
781
|
-
if (urlPath === "/") return "index.rsc";
|
|
782
|
-
return urlPath.replace(/^\//, "") + ".rsc";
|
|
783
|
-
}
|
|
784
822
|
function resolveRenderedCacheControl(requestCacheLife, cacheControl, fallbackExpireSeconds) {
|
|
785
823
|
const sMaxage = parseCacheControlSeconds(cacheControl, "s-maxage");
|
|
786
824
|
const staleWhileRevalidate = parseCacheControlSeconds(cacheControl, "stale-while-revalidate");
|
|
@@ -846,6 +884,6 @@ function writePrerenderIndex(routes, outDir, options) {
|
|
|
846
884
|
fs.writeFileSync(path.join(outDir, "vinext-prerender.json"), JSON.stringify(index, null, 2), "utf-8");
|
|
847
885
|
}
|
|
848
886
|
//#endregion
|
|
849
|
-
export { extractRscPayloadFromPrerenderedHtml,
|
|
887
|
+
export { extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
|
|
850
888
|
|
|
851
889
|
//# sourceMappingURL=prerender.js.map
|