vinext 0.0.52 → 0.0.54
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/inline-css.d.ts +7 -0
- package/dist/build/inline-css.js +50 -0
- package/dist/build/inline-css.js.map +1 -0
- package/dist/build/prerender.d.ts +6 -2
- package/dist/build/prerender.js +51 -12
- 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.js +19 -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 +16 -2
- package/dist/client/navigation-runtime.js +16 -1
- package/dist/client/navigation-runtime.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/client/vinext-next-data.js.map +1 -1
- package/dist/client/window-next.d.ts +17 -2
- package/dist/client/window-next.js.map +1 -1
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.js +2 -1
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +95 -4
- package/dist/config/next-config.js +173 -14
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +42 -7
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +11 -1
- package/dist/entries/app-browser-entry.js +16 -6
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +12 -3
- package/dist/entries/app-rsc-entry.js +41 -8
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +21 -1
- package/dist/entries/app-rsc-manifest.js +6 -4
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.d.ts +4 -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 +292 -34
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +1 -10
- package/dist/entries/runtime-entry-module.js +2 -12
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +91 -10
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.js +25 -2
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/remove-console.d.ts +16 -0
- package/dist/plugins/remove-console.js +176 -0
- package/dist/plugins/remove-console.js.map +1 -0
- package/dist/routing/app-route-graph.d.ts +24 -1
- package/dist/routing/app-route-graph.js +52 -4
- 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/file-matcher.d.ts +21 -1
- package/dist/routing/file-matcher.js +39 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.d.ts +1 -1
- package/dist/routing/pages-router.js +10 -3
- package/dist/routing/pages-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 +11 -1
- package/dist/routing/utils.js +15 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js +19 -10
- 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 +47 -28
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +4 -0
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +13 -4
- package/dist/server/app-elements-wire.js +10 -1
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +27 -8
- package/dist/server/app-fallback-renderer.js +19 -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-inline-css-client.d.ts +7 -0
- package/dist/server/app-inline-css-client.js +37 -0
- package/dist/server/app-inline-css-client.js.map +1 -0
- 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-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.js +26 -18
- package/dist/server/app-optimistic-routing.js.map +1 -1
- 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 +22 -1
- package/dist/server/app-page-boundary.js +30 -3
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +9 -3
- package/dist/server/app-page-cache.js +14 -8
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +13 -1
- package/dist/server/app-page-dispatch.js +136 -82
- 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 +17 -30
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +1 -0
- package/dist/server/app-page-execution.js +2 -0
- 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 +8 -0
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-render-identity.d.ts +22 -0
- package/dist/server/app-page-render-identity.js +42 -0
- package/dist/server/app-page-render-identity.js.map +1 -0
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-render.d.ts +9 -1
- package/dist/server/app-page-render.js +8 -2
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +6 -3
- package/dist/server/app-page-request.js +5 -2
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +11 -1
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +16 -0
- package/dist/server/app-page-route-wiring.js +25 -10
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +12 -0
- package/dist/server/app-page-stream.js +3 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +3 -0
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- 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 +38 -6
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +16 -3
- package/dist/server/app-rsc-handler.js +60 -11
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +2 -1
- package/dist/server/app-rsc-request-normalization.js +6 -4
- package/dist/server/app-rsc-request-normalization.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 +22 -3
- package/dist/server/app-server-action-execution.js +46 -7
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +57 -6
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-error-meta.js +3 -3
- package/dist/server/app-ssr-error-meta.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +25 -1
- package/dist/server/app-ssr-stream.js +237 -19
- 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/client-trace-metadata.d.ts +31 -0
- package/dist/server/client-trace-metadata.js +83 -0
- package/dist/server/client-trace-metadata.js.map +1 -0
- package/dist/server/cookie-utils.d.ts +13 -0
- package/dist/server/cookie-utils.js +20 -0
- package/dist/server/cookie-utils.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 +8 -1
- package/dist/server/dev-server.js +56 -11
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/headers.d.ts +5 -1
- package/dist/server/headers.js +5 -1
- package/dist/server/headers.js.map +1 -1
- package/dist/server/html.d.ts +2 -1
- package/dist/server/html.js +6 -1
- package/dist/server/html.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 +7 -5
- package/dist/server/isr-cache.js +17 -6
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/middleware-runtime.js +1 -2
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.js +1 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/pages-api-route.d.ts +18 -0
- package/dist/server/pages-api-route.js +3 -1
- 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.js +1 -0
- package/dist/server/pages-data-route.js.map +1 -1
- 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-document-initial-props.d.ts +7 -0
- package/dist/server/pages-document-initial-props.js +14 -0
- package/dist/server/pages-document-initial-props.js.map +1 -0
- 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 +40 -0
- package/dist/server/pages-page-data.js +19 -14
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-method.d.ts +48 -0
- package/dist/server/pages-page-method.js +19 -0
- package/dist/server/pages-page-method.js.map +1 -0
- package/dist/server/pages-page-response.d.ts +8 -0
- package/dist/server/pages-page-response.js +21 -11
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/pages-serializable-props.d.ts +25 -0
- package/dist/server/pages-serializable-props.js +69 -0
- package/dist/server/pages-serializable-props.js.map +1 -0
- 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 +3 -23
- package/dist/server/prod-server.js +43 -57
- 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 +3 -3
- package/dist/server/request-pipeline.js +5 -4
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/seed-cache.js +12 -6
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.js +3 -2
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/static-file-cache.js +2 -1
- 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 +14 -0
- package/dist/shims/app-router-scroll-state.js +51 -0
- package/dist/shims/app-router-scroll-state.js.map +1 -0
- package/dist/shims/app-router-scroll.d.ts +28 -0
- package/dist/shims/app-router-scroll.js +115 -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/cache.d.ts +6 -0
- package/dist/shims/cache.js +7 -0
- package/dist/shims/cache.js.map +1 -1
- 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/error.js +3 -0
- package/dist/shims/error.js.map +1 -1
- 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/head.js +4 -4
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +13 -2
- package/dist/shims/headers.js +73 -22
- 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/app-route-detection.d.ts +37 -0
- package/dist/shims/internal/app-route-detection.js +69 -0
- package/dist/shims/internal/app-route-detection.js.map +1 -0
- 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 +18 -2
- package/dist/shims/link.js +129 -15
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +9 -7
- package/dist/shims/metadata.js +70 -7
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +1 -2
- package/dist/shims/navigation.js +94 -20
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/router.d.ts +5 -0
- package/dist/shims/router.js +389 -80
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.d.ts +11 -1
- package/dist/shims/script.js +158 -15
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +1 -0
- package/dist/shims/server.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/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/path.d.ts +13 -0
- package/dist/utils/path.js +16 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/query.d.ts +6 -0
- package/dist/utils/query.js +10 -1
- package/dist/utils/query.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/server/client-trace-metadata.d.ts
|
|
2
|
+
type ClientTraceDataEntry = {
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Filter an entry list against the configured `clientTraceMetadata` allow-list.
|
|
8
|
+
* Returns `undefined` when the allow-list is unset so callers can skip
|
|
9
|
+
* rendering altogether.
|
|
10
|
+
*/
|
|
11
|
+
declare function filterClientTraceMetadata(entries: readonly ClientTraceDataEntry[], allowList: readonly string[] | undefined): ClientTraceDataEntry[] | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Render the filtered entries as a sequence of self-closing `<meta>` tags.
|
|
14
|
+
* Names and values are HTML-attribute escaped. Returns an empty string when
|
|
15
|
+
* `entries` is empty or undefined so callers can append unconditionally.
|
|
16
|
+
*/
|
|
17
|
+
declare function renderClientTraceMetadataTags(entries: readonly ClientTraceDataEntry[] | undefined): string;
|
|
18
|
+
/**
|
|
19
|
+
* Convenience helper: read OTel propagation data, filter against the
|
|
20
|
+
* configured allow-list, and render the resulting `<meta>` tags. Returns an
|
|
21
|
+
* empty string when the allow-list is unset, OTel is not installed, or no
|
|
22
|
+
* matching keys were emitted by the propagator.
|
|
23
|
+
*
|
|
24
|
+
* Safe to call unconditionally on every SSR render — when nothing is
|
|
25
|
+
* configured/active this is a few `try/catch`-bounded operations and returns
|
|
26
|
+
* `""`.
|
|
27
|
+
*/
|
|
28
|
+
declare function getClientTraceMetadataHTML(allowList: readonly string[] | undefined): string;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { ClientTraceDataEntry, filterClientTraceMetadata, getClientTraceMetadataHTML, renderClientTraceMetadataTags };
|
|
31
|
+
//# sourceMappingURL=client-trace-metadata.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { escapeHtmlAttr } from "./html.js";
|
|
2
|
+
//#region src/server/client-trace-metadata.ts
|
|
3
|
+
/**
|
|
4
|
+
* Client trace metadata renderer.
|
|
5
|
+
*
|
|
6
|
+
* When `experimental.clientTraceMetadata` is configured in `next.config`,
|
|
7
|
+
* vinext emits `<meta name="..." content="...">` tags in the SSR HTML head
|
|
8
|
+
* for each configured key. The values are sourced from the active
|
|
9
|
+
* OpenTelemetry context via the registered propagator.
|
|
10
|
+
*
|
|
11
|
+
* This mirrors Next.js' implementation:
|
|
12
|
+
* - packages/next/src/server/lib/trace/utils.ts (getTracedMetadata)
|
|
13
|
+
* - packages/next/src/server/app-render/make-get-server-inserted-html.tsx (traceMetaTags)
|
|
14
|
+
*
|
|
15
|
+
* OpenTelemetry is an optional peer — we resolve `@opentelemetry/api` at
|
|
16
|
+
* runtime and silently no-op when it is not installed. This matches user
|
|
17
|
+
* expectations: apps that don't configure OTel get no meta tags, and apps
|
|
18
|
+
* that do get the filtered subset they asked for in `clientTraceMetadata`.
|
|
19
|
+
*/
|
|
20
|
+
const carrierSetter = { set(carrier, key, value) {
|
|
21
|
+
if (typeof key !== "string" || typeof value !== "string") return;
|
|
22
|
+
carrier.push({
|
|
23
|
+
key,
|
|
24
|
+
value
|
|
25
|
+
});
|
|
26
|
+
} };
|
|
27
|
+
function getOpenTelemetryTraceData() {
|
|
28
|
+
let api;
|
|
29
|
+
try {
|
|
30
|
+
const req = globalThis.require;
|
|
31
|
+
if (typeof req === "function") api = req("@opentelemetry/api");
|
|
32
|
+
} catch {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
if (!api) return [];
|
|
36
|
+
try {
|
|
37
|
+
const activeContext = api.context.active();
|
|
38
|
+
const entries = [];
|
|
39
|
+
api.propagation.inject(activeContext, entries, carrierSetter);
|
|
40
|
+
return entries;
|
|
41
|
+
} catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Filter an entry list against the configured `clientTraceMetadata` allow-list.
|
|
47
|
+
* Returns `undefined` when the allow-list is unset so callers can skip
|
|
48
|
+
* rendering altogether.
|
|
49
|
+
*/
|
|
50
|
+
function filterClientTraceMetadata(entries, allowList) {
|
|
51
|
+
if (!allowList || allowList.length === 0) return void 0;
|
|
52
|
+
const allowSet = new Set(allowList);
|
|
53
|
+
return entries.filter(({ key }) => allowSet.has(key));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Render the filtered entries as a sequence of self-closing `<meta>` tags.
|
|
57
|
+
* Names and values are HTML-attribute escaped. Returns an empty string when
|
|
58
|
+
* `entries` is empty or undefined so callers can append unconditionally.
|
|
59
|
+
*/
|
|
60
|
+
function renderClientTraceMetadataTags(entries) {
|
|
61
|
+
if (!entries || entries.length === 0) return "";
|
|
62
|
+
let html = "";
|
|
63
|
+
for (const { key, value } of entries) html += `<meta name="${escapeHtmlAttr(key)}" content="${escapeHtmlAttr(value)}"/>`;
|
|
64
|
+
return html;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Convenience helper: read OTel propagation data, filter against the
|
|
68
|
+
* configured allow-list, and render the resulting `<meta>` tags. Returns an
|
|
69
|
+
* empty string when the allow-list is unset, OTel is not installed, or no
|
|
70
|
+
* matching keys were emitted by the propagator.
|
|
71
|
+
*
|
|
72
|
+
* Safe to call unconditionally on every SSR render — when nothing is
|
|
73
|
+
* configured/active this is a few `try/catch`-bounded operations and returns
|
|
74
|
+
* `""`.
|
|
75
|
+
*/
|
|
76
|
+
function getClientTraceMetadataHTML(allowList) {
|
|
77
|
+
if (!allowList || allowList.length === 0) return "";
|
|
78
|
+
return renderClientTraceMetadataTags(filterClientTraceMetadata(getOpenTelemetryTraceData(), allowList));
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { filterClientTraceMetadata, getClientTraceMetadataHTML, renderClientTraceMetadataTags };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=client-trace-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-trace-metadata.js","names":[],"sources":["../../src/server/client-trace-metadata.ts"],"sourcesContent":["/**\n * Client trace metadata renderer.\n *\n * When `experimental.clientTraceMetadata` is configured in `next.config`,\n * vinext emits `<meta name=\"...\" content=\"...\">` tags in the SSR HTML head\n * for each configured key. The values are sourced from the active\n * OpenTelemetry context via the registered propagator.\n *\n * This mirrors Next.js' implementation:\n * - packages/next/src/server/lib/trace/utils.ts (getTracedMetadata)\n * - packages/next/src/server/app-render/make-get-server-inserted-html.tsx (traceMetaTags)\n *\n * OpenTelemetry is an optional peer — we resolve `@opentelemetry/api` at\n * runtime and silently no-op when it is not installed. This matches user\n * expectations: apps that don't configure OTel get no meta tags, and apps\n * that do get the filtered subset they asked for in `clientTraceMetadata`.\n */\nimport { escapeHtmlAttr } from \"./html.js\";\n\nexport type ClientTraceDataEntry = {\n key: string;\n value: string;\n};\n\ntype TextMapSetter = {\n set(carrier: ClientTraceDataEntry[], key: string, value: string): void;\n};\n\nconst carrierSetter: TextMapSetter = {\n set(carrier, key, value) {\n if (typeof key !== \"string\" || typeof value !== \"string\") return;\n carrier.push({ key, value });\n },\n};\n\n/**\n * Pull entries off the active OpenTelemetry context via the registered\n * propagator. Returns an empty array when `@opentelemetry/api` is not\n * installed or when no propagator has been registered.\n *\n * The implementation mirrors Next.js's `NextTracerImpl.getTracePropagationData`:\n * we call `propagation.inject(activeContext, entries, setter)` and let the\n * setter push entries into our carrier array.\n */\ntype OpenTelemetryApi = {\n context: { active(): unknown };\n propagation: {\n inject(context: unknown, carrier: ClientTraceDataEntry[], setter: TextMapSetter): void;\n };\n};\n\nfunction getOpenTelemetryTraceData(): ClientTraceDataEntry[] {\n let api: OpenTelemetryApi | undefined;\n try {\n // Use require() at runtime so `@opentelemetry/api` is an optional peer.\n // Bundlers (Vite/esbuild) leave the `require` reference alone, so apps\n // that don't install the package never hit this branch.\n const req = (globalThis as { require?: (id: string) => unknown }).require;\n if (typeof req === \"function\") {\n api = req(\"@opentelemetry/api\") as OpenTelemetryApi;\n }\n } catch {\n return [];\n }\n\n if (!api) return [];\n\n try {\n const activeContext = api.context.active();\n const entries: ClientTraceDataEntry[] = [];\n api.propagation.inject(activeContext, entries, carrierSetter);\n return entries;\n } catch {\n return [];\n }\n}\n\n/**\n * Filter an entry list against the configured `clientTraceMetadata` allow-list.\n * Returns `undefined` when the allow-list is unset so callers can skip\n * rendering altogether.\n */\nexport function filterClientTraceMetadata(\n entries: readonly ClientTraceDataEntry[],\n allowList: readonly string[] | undefined,\n): ClientTraceDataEntry[] | undefined {\n if (!allowList || allowList.length === 0) return undefined;\n const allowSet = new Set(allowList);\n return entries.filter(({ key }) => allowSet.has(key));\n}\n\n/**\n * Render the filtered entries as a sequence of self-closing `<meta>` tags.\n * Names and values are HTML-attribute escaped. Returns an empty string when\n * `entries` is empty or undefined so callers can append unconditionally.\n */\nexport function renderClientTraceMetadataTags(\n entries: readonly ClientTraceDataEntry[] | undefined,\n): string {\n if (!entries || entries.length === 0) return \"\";\n let html = \"\";\n for (const { key, value } of entries) {\n html += `<meta name=\"${escapeHtmlAttr(key)}\" content=\"${escapeHtmlAttr(value)}\"/>`;\n }\n return html;\n}\n\n/**\n * Convenience helper: read OTel propagation data, filter against the\n * configured allow-list, and render the resulting `<meta>` tags. Returns an\n * empty string when the allow-list is unset, OTel is not installed, or no\n * matching keys were emitted by the propagator.\n *\n * Safe to call unconditionally on every SSR render — when nothing is\n * configured/active this is a few `try/catch`-bounded operations and returns\n * `\"\"`.\n */\nexport function getClientTraceMetadataHTML(allowList: readonly string[] | undefined): string {\n if (!allowList || allowList.length === 0) return \"\";\n const entries = getOpenTelemetryTraceData();\n const filtered = filterClientTraceMetadata(entries, allowList);\n return renderClientTraceMetadataTags(filtered);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA4BA,MAAM,gBAA+B,EACnC,IAAI,SAAS,KAAK,OAAO;CACvB,IAAI,OAAO,QAAQ,YAAY,OAAO,UAAU,UAAU;CAC1D,QAAQ,KAAK;EAAE;EAAK;EAAO,CAAC;GAE/B;AAkBD,SAAS,4BAAoD;CAC3D,IAAI;CACJ,IAAI;EAIF,MAAM,MAAO,WAAqD;EAClE,IAAI,OAAO,QAAQ,YACjB,MAAM,IAAI,qBAAqB;SAE3B;EACN,OAAO,EAAE;;CAGX,IAAI,CAAC,KAAK,OAAO,EAAE;CAEnB,IAAI;EACF,MAAM,gBAAgB,IAAI,QAAQ,QAAQ;EAC1C,MAAM,UAAkC,EAAE;EAC1C,IAAI,YAAY,OAAO,eAAe,SAAS,cAAc;EAC7D,OAAO;SACD;EACN,OAAO,EAAE;;;;;;;;AASb,SAAgB,0BACd,SACA,WACoC;CACpC,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO,KAAA;CACjD,MAAM,WAAW,IAAI,IAAI,UAAU;CACnC,OAAO,QAAQ,QAAQ,EAAE,UAAU,SAAS,IAAI,IAAI,CAAC;;;;;;;AAQvD,SAAgB,8BACd,SACQ;CACR,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,OAAO;CAC7C,IAAI,OAAO;CACX,KAAK,MAAM,EAAE,KAAK,WAAW,SAC3B,QAAQ,eAAe,eAAe,IAAI,CAAC,aAAa,eAAe,MAAM,CAAC;CAEhF,OAAO;;;;;;;;;;;;AAaT,SAAgB,2BAA2B,WAAkD;CAC3F,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO;CAGjD,OAAO,8BADU,0BADD,2BACkC,EAAE,UACP,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/server/cookie-utils.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Parse the cookie name out of a serialised Set-Cookie line.
|
|
4
|
+
*
|
|
5
|
+
* Bounded by the first `;` so the attribute portion (e.g. `Path=/`) is never
|
|
6
|
+
* mistaken for part of the name when the value happens to contain another
|
|
7
|
+
* `=`. Returns null when the line is not parseable (defensive — callers keep
|
|
8
|
+
* unparseable entries verbatim so they don't drop user-supplied cookies).
|
|
9
|
+
*/
|
|
10
|
+
declare function getSetCookieName(cookie: string): string | null;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { getSetCookieName };
|
|
13
|
+
//# sourceMappingURL=cookie-utils.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/server/cookie-utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Parse the cookie name out of a serialised Set-Cookie line.
|
|
4
|
+
*
|
|
5
|
+
* Bounded by the first `;` so the attribute portion (e.g. `Path=/`) is never
|
|
6
|
+
* mistaken for part of the name when the value happens to contain another
|
|
7
|
+
* `=`. Returns null when the line is not parseable (defensive — callers keep
|
|
8
|
+
* unparseable entries verbatim so they don't drop user-supplied cookies).
|
|
9
|
+
*/
|
|
10
|
+
function getSetCookieName(cookie) {
|
|
11
|
+
const equalsIndex = cookie.indexOf("=");
|
|
12
|
+
if (equalsIndex <= 0) return null;
|
|
13
|
+
const semicolonIndex = cookie.indexOf(";");
|
|
14
|
+
const end = semicolonIndex === -1 ? equalsIndex : Math.min(equalsIndex, semicolonIndex);
|
|
15
|
+
return cookie.slice(0, end);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { getSetCookieName };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=cookie-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie-utils.js","names":[],"sources":["../../src/server/cookie-utils.ts"],"sourcesContent":["/**\n * Parse the cookie name out of a serialised Set-Cookie line.\n *\n * Bounded by the first `;` so the attribute portion (e.g. `Path=/`) is never\n * mistaken for part of the name when the value happens to contain another\n * `=`. Returns null when the line is not parseable (defensive — callers keep\n * unparseable entries verbatim so they don't drop user-supplied cookies).\n */\nexport function getSetCookieName(cookie: string): string | null {\n const equalsIndex = cookie.indexOf(\"=\");\n if (equalsIndex <= 0) {\n return null;\n }\n const semicolonIndex = cookie.indexOf(\";\");\n const end = semicolonIndex === -1 ? equalsIndex : Math.min(equalsIndex, semicolonIndex);\n return cookie.slice(0, end);\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,iBAAiB,QAA+B;CAC9D,MAAM,cAAc,OAAO,QAAQ,IAAI;CACvC,IAAI,eAAe,GACjB,OAAO;CAET,MAAM,iBAAiB,OAAO,QAAQ,IAAI;CAC1C,MAAM,MAAM,mBAAmB,KAAK,cAAc,KAAK,IAAI,aAAa,eAAe;CACvF,OAAO,OAAO,MAAM,GAAG,IAAI"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/server/default-not-found-module.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Module-shaped wrapper around vinext's built-in default not-found component.
|
|
4
|
+
* Used as the fallback when an app does not define its own `app/not-found.tsx`
|
|
5
|
+
* (and has not opted into `app/global-not-found.tsx`). The runtime treats any
|
|
6
|
+
* `{ default: Component }` record as a "not-found module", so wrapping the
|
|
7
|
+
* component this way lets us thread the default through the existing
|
|
8
|
+
* `rootNotFoundModule` plumbing without introducing a parallel code path.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors Next.js's `defaultNotFoundPath`
|
|
11
|
+
* (`next/dist/client/components/builtin/not-found.js`), which is selected
|
|
12
|
+
* automatically when the user has not supplied a custom not-found file:
|
|
13
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts
|
|
14
|
+
*/
|
|
15
|
+
declare const DEFAULT_NOT_FOUND_MODULE: {
|
|
16
|
+
readonly default: any;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { DEFAULT_NOT_FOUND_MODULE };
|
|
20
|
+
//# sourceMappingURL=default-not-found-module.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import DefaultNotFound from "../shims/default-not-found.js";
|
|
2
|
+
//#region src/server/default-not-found-module.ts
|
|
3
|
+
/**
|
|
4
|
+
* Module-shaped wrapper around vinext's built-in default not-found component.
|
|
5
|
+
* Used as the fallback when an app does not define its own `app/not-found.tsx`
|
|
6
|
+
* (and has not opted into `app/global-not-found.tsx`). The runtime treats any
|
|
7
|
+
* `{ default: Component }` record as a "not-found module", so wrapping the
|
|
8
|
+
* component this way lets us thread the default through the existing
|
|
9
|
+
* `rootNotFoundModule` plumbing without introducing a parallel code path.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors Next.js's `defaultNotFoundPath`
|
|
12
|
+
* (`next/dist/client/components/builtin/not-found.js`), which is selected
|
|
13
|
+
* automatically when the user has not supplied a custom not-found file:
|
|
14
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_NOT_FOUND_MODULE = { default: DefaultNotFound };
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DEFAULT_NOT_FOUND_MODULE };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=default-not-found-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-not-found-module.js","names":[],"sources":["../../src/server/default-not-found-module.ts"],"sourcesContent":["import DefaultNotFound from \"vinext/shims/default-not-found\";\n\n/**\n * Module-shaped wrapper around vinext's built-in default not-found component.\n * Used as the fallback when an app does not define its own `app/not-found.tsx`\n * (and has not opted into `app/global-not-found.tsx`). The runtime treats any\n * `{ default: Component }` record as a \"not-found module\", so wrapping the\n * component this way lets us thread the default through the existing\n * `rootNotFoundModule` plumbing without introducing a parallel code path.\n *\n * Mirrors Next.js's `defaultNotFoundPath`\n * (`next/dist/client/components/builtin/not-found.js`), which is selected\n * automatically when the user has not supplied a custom not-found file:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-app-loader/index.ts\n */\nexport const DEFAULT_NOT_FOUND_MODULE = {\n default: DefaultNotFound,\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,2BAA2B,EACtC,SAAS,iBACV"}
|
|
@@ -36,7 +36,14 @@ declare function parseCookieLocale(req: IncomingMessage, i18nConfig: NextI18nCon
|
|
|
36
36
|
* 4. Render the component to HTML
|
|
37
37
|
* 5. Wrap in _document shell and send response
|
|
38
38
|
*/
|
|
39
|
-
declare function createSSRHandler(server: ViteDevServer, runner: ModuleImporter, routes: Route[], pagesDir: string, i18nConfig?: NextI18nConfig | null, fileMatcher?: ValidFileMatcher, basePath?: string, trailingSlash?: boolean
|
|
39
|
+
declare function createSSRHandler(server: ViteDevServer, runner: ModuleImporter, routes: Route[], pagesDir: string, i18nConfig?: NextI18nConfig | null, fileMatcher?: ValidFileMatcher, basePath?: string, trailingSlash?: boolean, hasMiddleware?: boolean,
|
|
40
|
+
/**
|
|
41
|
+
* Allow-list of OpenTelemetry propagation keys to emit as `<meta>` tags
|
|
42
|
+
* in the SSR head. Sourced from `experimental.clientTraceMetadata` in
|
|
43
|
+
* `next.config`. When undefined or empty, no meta tags are emitted.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
clientTraceMetadata?: readonly string[]): (req: IncomingMessage, res: ServerResponse, url: string, /** Status code override — propagated from middleware rewrite status. */
|
|
40
47
|
|
|
41
48
|
statusCode?: number,
|
|
42
49
|
/**
|
|
@@ -2,7 +2,6 @@ import { createRequestContext, runWithRequestContext } from "../shims/unified-re
|
|
|
2
2
|
import { createValidFileMatcher, findFileWithExtensions } from "../routing/file-matcher.js";
|
|
3
3
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
4
4
|
import { matchRoute } from "../routing/pages-router.js";
|
|
5
|
-
import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
|
|
6
5
|
import { normalizeStaticPathname } from "../routing/route-pattern.js";
|
|
7
6
|
import { importModule, reportRequestError } from "./instrumentation.js";
|
|
8
7
|
import { buildCacheStateHeaders } from "./cache-headers.js";
|
|
@@ -10,14 +9,20 @@ import { _runWithCacheState } from "../shims/cache.js";
|
|
|
10
9
|
import { buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, setRevalidateDuration, triggerBackgroundRegeneration } from "./isr-cache.js";
|
|
11
10
|
import { runWithPrivateCache } from "../shims/cache-runtime.js";
|
|
12
11
|
import { ensureFetchPatch, runWithFetchCache } from "../shims/fetch-cache.js";
|
|
12
|
+
import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
|
|
13
13
|
import "../shims/router-state.js";
|
|
14
14
|
import { runWithHeadState } from "../shims/head-state.js";
|
|
15
15
|
import { runWithServerInsertedHTMLState } from "../shims/navigation-state.js";
|
|
16
16
|
import { withScriptNonce } from "../shims/script-nonce-context.js";
|
|
17
17
|
import { createInlineScriptTag, createNonceAttribute, safeJsonStringify } from "./html.js";
|
|
18
|
+
import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
|
|
18
19
|
import { getScriptNonceFromNodeHeaderSources } from "./csp.js";
|
|
19
20
|
import { logRequest, now } from "./request-log.js";
|
|
20
21
|
import { detectLocaleFromAcceptLanguage, extractLocaleFromUrl as extractLocaleFromUrl$1, parseCookieLocaleFromHeader, resolvePagesI18nRequest } from "./pages-i18n.js";
|
|
22
|
+
import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
|
|
23
|
+
import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
|
|
24
|
+
import { isSerializableProps } from "./pages-serializable-props.js";
|
|
25
|
+
import { loadUserDocumentInitialProps } from "./pages-document-initial-props.js";
|
|
21
26
|
import path from "node:path";
|
|
22
27
|
import React from "react";
|
|
23
28
|
import { renderToReadableStream } from "react-dom/server.edge";
|
|
@@ -58,7 +63,8 @@ async function streamPageToResponse(res, element, options) {
|
|
|
58
63
|
const headHTML = getHeadHTML();
|
|
59
64
|
let shellTemplate;
|
|
60
65
|
if (DocumentComponent) {
|
|
61
|
-
|
|
66
|
+
const docProps = await loadUserDocumentInitialProps(DocumentComponent);
|
|
67
|
+
let docHtml = await renderToStringAsync(docProps ? React.createElement(DocumentComponent, docProps) : React.createElement(DocumentComponent));
|
|
62
68
|
docHtml = docHtml.replace("__NEXT_MAIN__", STREAM_BODY_MARKER);
|
|
63
69
|
if (headHTML || fontHeadHTML) docHtml = docHtml.replace("</head>", ` ${fontHeadHTML}${headHTML}\n</head>`);
|
|
64
70
|
docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", scripts);
|
|
@@ -132,7 +138,7 @@ function parseCookieLocale(req, i18nConfig) {
|
|
|
132
138
|
* 4. Render the component to HTML
|
|
133
139
|
* 5. Wrap in _document shell and send response
|
|
134
140
|
*/
|
|
135
|
-
function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false) {
|
|
141
|
+
function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false, hasMiddleware = false, clientTraceMetadata) {
|
|
136
142
|
const matcher = fileMatcher ?? createValidFileMatcher();
|
|
137
143
|
const _alsRegistration = Promise.all([runner.import("vinext/head-state"), runner.import("vinext/router-state")]);
|
|
138
144
|
_alsRegistration.catch(() => {});
|
|
@@ -215,6 +221,23 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
215
221
|
res.end("Page has no default export");
|
|
216
222
|
return;
|
|
217
223
|
}
|
|
224
|
+
{
|
|
225
|
+
const routePattern = patternToNextFormat(route.pattern);
|
|
226
|
+
if (!isDataReq && routePattern !== "/_error" && routePattern !== "/404" && routePattern !== "/500" && statusCode === void 0) {
|
|
227
|
+
const methodResponse = resolvePagesPageMethodResponse({
|
|
228
|
+
hasGetServerSideProps: typeof pageModule.getServerSideProps === "function",
|
|
229
|
+
method: req.method ?? "GET"
|
|
230
|
+
});
|
|
231
|
+
if (methodResponse) {
|
|
232
|
+
res.statusCode = methodResponse.status;
|
|
233
|
+
const allow = methodResponse.headers.get("allow");
|
|
234
|
+
if (allow) res.setHeader("Allow", allow);
|
|
235
|
+
res.setHeader("Content-Type", "text/plain;charset=UTF-8");
|
|
236
|
+
res.end(await methodResponse.text());
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
218
241
|
let pageProps = {};
|
|
219
242
|
let isrRevalidateSeconds = null;
|
|
220
243
|
let isFallbackRender = false;
|
|
@@ -274,7 +297,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
274
297
|
};
|
|
275
298
|
const result = await pageModule.getServerSideProps(context);
|
|
276
299
|
if (res.writableEnded) return;
|
|
277
|
-
if (result && "props" in result) pageProps = result.props;
|
|
300
|
+
if (result && "props" in result) pageProps = await Promise.resolve(result.props);
|
|
278
301
|
if (result && "redirect" in result) {
|
|
279
302
|
const { redirect } = result;
|
|
280
303
|
const status = redirect.statusCode ?? (redirect.permanent ? 308 : 307);
|
|
@@ -293,6 +316,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
293
316
|
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
294
317
|
return;
|
|
295
318
|
}
|
|
319
|
+
if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getServerSideProps", pageProps);
|
|
296
320
|
if (!statusCode && res.statusCode !== 200) statusCode = res.statusCode;
|
|
297
321
|
const headersAfterGSSP = res.getHeaders();
|
|
298
322
|
for (const [key, val] of Object.entries(headersAfterGSSP)) {
|
|
@@ -301,6 +325,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
301
325
|
if (Array.isArray(val)) gsspExtraHeaders[key] = val.map(String);
|
|
302
326
|
else gsspExtraHeaders[key] = String(val);
|
|
303
327
|
}
|
|
328
|
+
if (!Object.keys(gsspExtraHeaders).some((k) => k.toLowerCase() === "cache-control")) gsspExtraHeaders["Cache-Control"] = "private, no-cache, no-store, max-age=0, must-revalidate";
|
|
304
329
|
}
|
|
305
330
|
const responseHeaders = typeof res.getHeaders === "function" ? res.getHeaders() : void 0;
|
|
306
331
|
const scriptNonce = getScriptNonceFromNodeHeaderSources(req.headers, responseHeaders);
|
|
@@ -340,7 +365,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
340
365
|
params: userFacingParams,
|
|
341
366
|
locale: locale ?? currentDefaultLocale,
|
|
342
367
|
locales: i18nConfig?.locales,
|
|
343
|
-
defaultLocale: currentDefaultLocale
|
|
368
|
+
defaultLocale: currentDefaultLocale,
|
|
369
|
+
revalidateReason: "stale"
|
|
344
370
|
});
|
|
345
371
|
if (freshResult && "props" in freshResult) {
|
|
346
372
|
const revalidate = typeof freshResult.revalidate === "number" ? freshResult.revalidate : 0;
|
|
@@ -392,7 +418,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
392
418
|
domainLocales,
|
|
393
419
|
__vinext: {
|
|
394
420
|
pageModuleUrl: regenPageUrl,
|
|
395
|
-
appModuleUrl: regenAppUrl
|
|
421
|
+
appModuleUrl: regenAppUrl,
|
|
422
|
+
hasMiddleware
|
|
396
423
|
}
|
|
397
424
|
})}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}<\/script>`}\n ${cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/)?.[0] ?? ""}</body></html>`, freshProps), revalidate);
|
|
398
425
|
setRevalidateDuration(cacheKey, revalidate);
|
|
@@ -419,7 +446,8 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
419
446
|
params: userFacingParams,
|
|
420
447
|
locale: locale ?? currentDefaultLocale,
|
|
421
448
|
locales: i18nConfig?.locales,
|
|
422
|
-
defaultLocale: currentDefaultLocale
|
|
449
|
+
defaultLocale: currentDefaultLocale,
|
|
450
|
+
revalidateReason: "stale"
|
|
423
451
|
};
|
|
424
452
|
const result = await pageModule.getStaticProps(context);
|
|
425
453
|
if (result && "props" in result) pageProps = result.props;
|
|
@@ -441,6 +469,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
|
|
|
441
469
|
await renderErrorPage(server, runner, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
442
470
|
return;
|
|
443
471
|
}
|
|
472
|
+
if (result && "props" in result) isSerializableProps(patternToNextFormat(route.pattern), "getStaticProps", pageProps);
|
|
444
473
|
if (typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
|
|
445
474
|
}
|
|
446
475
|
if (isDataReq) {
|
|
@@ -546,7 +575,8 @@ hydrate();
|
|
|
546
575
|
domainLocales,
|
|
547
576
|
__vinext: {
|
|
548
577
|
pageModuleUrl,
|
|
549
|
-
appModuleUrl
|
|
578
|
+
appModuleUrl,
|
|
579
|
+
hasMiddleware
|
|
550
580
|
}
|
|
551
581
|
})}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}`, scriptNonce);
|
|
552
582
|
const docPath = path.join(pagesDir, "_document");
|
|
@@ -570,7 +600,11 @@ hydrate();
|
|
|
570
600
|
DocumentComponent,
|
|
571
601
|
statusCode,
|
|
572
602
|
extraHeaders,
|
|
573
|
-
getHeadHTML: () =>
|
|
603
|
+
getHeadHTML: () => {
|
|
604
|
+
const headHTML = typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : "";
|
|
605
|
+
const traceHTML = getClientTraceMetadataHTML(clientTraceMetadata);
|
|
606
|
+
return traceHTML ? `${headHTML}\n ${traceHTML}` : headHTML;
|
|
607
|
+
}
|
|
574
608
|
});
|
|
575
609
|
_renderEnd = now();
|
|
576
610
|
if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext(null);
|
|
@@ -648,7 +682,8 @@ async function renderErrorPage(server, runner, _req, res, url, pagesDir, statusC
|
|
|
648
682
|
DocumentComponent = (await importModule(runner, docPathErr)).default ?? null;
|
|
649
683
|
} catch {}
|
|
650
684
|
if (DocumentComponent) {
|
|
651
|
-
|
|
685
|
+
const docProps = await loadUserDocumentInitialProps(DocumentComponent);
|
|
686
|
+
let docHtml = await renderToStringAsync(docProps ? createElement(DocumentComponent, docProps) : createElement(DocumentComponent));
|
|
652
687
|
docHtml = docHtml.replace("__NEXT_MAIN__", bodyHtml);
|
|
653
688
|
docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", "");
|
|
654
689
|
html = docHtml;
|
|
@@ -669,8 +704,18 @@ async function renderErrorPage(server, runner, _req, res, url, pagesDir, statusC
|
|
|
669
704
|
} catch {
|
|
670
705
|
continue;
|
|
671
706
|
}
|
|
707
|
+
if (statusCode === 404) {
|
|
708
|
+
const defaultResponse = buildDefaultPagesNotFoundResponse();
|
|
709
|
+
const headers = {};
|
|
710
|
+
defaultResponse.headers.forEach((value, key) => {
|
|
711
|
+
headers[key] = value;
|
|
712
|
+
});
|
|
713
|
+
res.writeHead(defaultResponse.status, headers);
|
|
714
|
+
res.end(await defaultResponse.text());
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
672
717
|
res.writeHead(statusCode, { "Content-Type": "text/plain" });
|
|
673
|
-
res.end(`${statusCode} -
|
|
718
|
+
res.end(`${statusCode} - Internal Server Error`);
|
|
674
719
|
}
|
|
675
720
|
//#endregion
|
|
676
721
|
export { createSSRHandler, detectLocaleFromHeaders, extractLocaleFromUrl, parseCookieLocale };
|