vinext 0.0.40 → 0.0.42

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.
Files changed (201) hide show
  1. package/README.md +1 -2
  2. package/dist/build/client-build-config.d.ts +119 -0
  3. package/dist/build/client-build-config.js +149 -0
  4. package/dist/build/client-build-config.js.map +1 -0
  5. package/dist/build/layout-classification-types.d.ts +62 -0
  6. package/dist/build/layout-classification-types.js +1 -0
  7. package/dist/build/layout-classification.d.ts +60 -0
  8. package/dist/build/layout-classification.js +98 -0
  9. package/dist/build/layout-classification.js.map +1 -0
  10. package/dist/build/report.d.ts +15 -1
  11. package/dist/build/report.js +50 -1
  12. package/dist/build/report.js.map +1 -1
  13. package/dist/build/route-classification-manifest.d.ts +53 -0
  14. package/dist/build/route-classification-manifest.js +145 -0
  15. package/dist/build/route-classification-manifest.js.map +1 -0
  16. package/dist/build/run-prerender.js +1 -1
  17. package/dist/build/ssr-manifest.d.ts +19 -0
  18. package/dist/build/ssr-manifest.js +71 -0
  19. package/dist/build/ssr-manifest.js.map +1 -0
  20. package/dist/check.js +4 -4
  21. package/dist/check.js.map +1 -1
  22. package/dist/cli.js +1 -1
  23. package/dist/cli.js.map +1 -1
  24. package/dist/client/entry.js +1 -1
  25. package/dist/config/config-matchers.js +1 -0
  26. package/dist/config/config-matchers.js.map +1 -1
  27. package/dist/entries/app-rsc-entry.js +341 -114
  28. package/dist/entries/app-rsc-entry.js.map +1 -1
  29. package/dist/entries/pages-server-entry.js +205 -199
  30. package/dist/entries/pages-server-entry.js.map +1 -1
  31. package/dist/index.d.ts +1 -169
  32. package/dist/index.js +113 -432
  33. package/dist/index.js.map +1 -1
  34. package/dist/init.d.ts +1 -1
  35. package/dist/init.js +2 -2
  36. package/dist/init.js.map +1 -1
  37. package/dist/plugins/fonts.d.ts +49 -1
  38. package/dist/plugins/fonts.js +97 -3
  39. package/dist/plugins/fonts.js.map +1 -1
  40. package/dist/plugins/postcss.d.ts +27 -0
  41. package/dist/plugins/postcss.js +94 -0
  42. package/dist/plugins/postcss.js.map +1 -0
  43. package/dist/plugins/strip-server-exports.d.ts +14 -0
  44. package/dist/plugins/strip-server-exports.js +73 -0
  45. package/dist/plugins/strip-server-exports.js.map +1 -0
  46. package/dist/routing/app-router.d.ts +6 -4
  47. package/dist/routing/app-router.js +21 -22
  48. package/dist/routing/app-router.js.map +1 -1
  49. package/dist/server/app-browser-entry.js +235 -97
  50. package/dist/server/app-browser-entry.js.map +1 -1
  51. package/dist/server/app-browser-error.d.ts +8 -0
  52. package/dist/server/app-browser-error.js +9 -0
  53. package/dist/server/app-browser-error.js.map +1 -0
  54. package/dist/server/app-browser-state.d.ts +93 -0
  55. package/dist/server/app-browser-state.js +132 -0
  56. package/dist/server/app-browser-state.js.map +1 -0
  57. package/dist/server/app-elements.d.ts +92 -0
  58. package/dist/server/app-elements.js +122 -0
  59. package/dist/server/app-elements.js.map +1 -0
  60. package/dist/server/app-page-boundary-render.d.ts +3 -1
  61. package/dist/server/app-page-boundary-render.js +41 -1
  62. package/dist/server/app-page-boundary-render.js.map +1 -1
  63. package/dist/server/app-page-cache.d.ts +6 -3
  64. package/dist/server/app-page-cache.js +14 -8
  65. package/dist/server/app-page-cache.js.map +1 -1
  66. package/dist/server/app-page-execution.d.ts +36 -3
  67. package/dist/server/app-page-execution.js +50 -10
  68. package/dist/server/app-page-execution.js.map +1 -1
  69. package/dist/server/app-page-probe.d.ts +10 -4
  70. package/dist/server/app-page-probe.js +24 -15
  71. package/dist/server/app-page-probe.js.map +1 -1
  72. package/dist/server/app-page-render.d.ts +8 -4
  73. package/dist/server/app-page-render.js +15 -4
  74. package/dist/server/app-page-render.js.map +1 -1
  75. package/dist/server/app-page-request.d.ts +52 -4
  76. package/dist/server/app-page-request.js +86 -16
  77. package/dist/server/app-page-request.js.map +1 -1
  78. package/dist/server/app-page-response.d.ts +4 -11
  79. package/dist/server/app-page-response.js +7 -19
  80. package/dist/server/app-page-response.js.map +1 -1
  81. package/dist/server/app-page-route-wiring.d.ts +22 -8
  82. package/dist/server/app-page-route-wiring.js +219 -81
  83. package/dist/server/app-page-route-wiring.js.map +1 -1
  84. package/dist/server/app-page-stream.d.ts +4 -1
  85. package/dist/server/app-page-stream.js +2 -1
  86. package/dist/server/app-page-stream.js.map +1 -1
  87. package/dist/server/app-render-dependency.d.ts +13 -0
  88. package/dist/server/app-render-dependency.js +35 -0
  89. package/dist/server/app-render-dependency.js.map +1 -0
  90. package/dist/server/app-route-handler-execution.d.ts +1 -0
  91. package/dist/server/app-route-handler-execution.js +1 -0
  92. package/dist/server/app-route-handler-execution.js.map +1 -1
  93. package/dist/server/app-route-handler-response.js +2 -1
  94. package/dist/server/app-route-handler-response.js.map +1 -1
  95. package/dist/server/app-route-handler-runtime.d.ts +1 -0
  96. package/dist/server/app-route-handler-runtime.js +26 -1
  97. package/dist/server/app-route-handler-runtime.js.map +1 -1
  98. package/dist/server/app-ssr-entry.d.ts +3 -1
  99. package/dist/server/app-ssr-entry.js +23 -19
  100. package/dist/server/app-ssr-entry.js.map +1 -1
  101. package/dist/server/app-ssr-stream.d.ts +1 -1
  102. package/dist/server/app-ssr-stream.js +4 -4
  103. package/dist/server/app-ssr-stream.js.map +1 -1
  104. package/dist/server/csp.d.ts +12 -0
  105. package/dist/server/csp.js +46 -0
  106. package/dist/server/csp.js.map +1 -0
  107. package/dist/server/dev-server.js +22 -18
  108. package/dist/server/dev-server.js.map +1 -1
  109. package/dist/server/html.d.ts +4 -1
  110. package/dist/server/html.js +11 -1
  111. package/dist/server/html.js.map +1 -1
  112. package/dist/server/middleware-response-headers.d.ts +12 -0
  113. package/dist/server/middleware-response-headers.js +23 -0
  114. package/dist/server/middleware-response-headers.js.map +1 -0
  115. package/dist/server/middleware.js +1 -5
  116. package/dist/server/middleware.js.map +1 -1
  117. package/dist/server/pages-page-data.d.ts +1 -0
  118. package/dist/server/pages-page-data.js +2 -2
  119. package/dist/server/pages-page-data.js.map +1 -1
  120. package/dist/server/pages-page-response.d.ts +2 -1
  121. package/dist/server/pages-page-response.js +16 -14
  122. package/dist/server/pages-page-response.js.map +1 -1
  123. package/dist/server/prod-server.d.ts +3 -3
  124. package/dist/server/prod-server.js +5 -4
  125. package/dist/server/prod-server.js.map +1 -1
  126. package/dist/server/request-pipeline.d.ts +15 -1
  127. package/dist/server/request-pipeline.js +88 -5
  128. package/dist/server/request-pipeline.js.map +1 -1
  129. package/dist/shims/cache-runtime.d.ts +1 -0
  130. package/dist/shims/cache-runtime.js +0 -5
  131. package/dist/shims/cache-runtime.js.map +1 -1
  132. package/dist/shims/cache.d.ts +1 -0
  133. package/dist/shims/cache.js +1 -8
  134. package/dist/shims/cache.js.map +1 -1
  135. package/dist/shims/client-hook-error.d.ts +14 -0
  136. package/dist/shims/client-hook-error.js +19 -0
  137. package/dist/shims/client-hook-error.js.map +1 -0
  138. package/dist/shims/constants.d.ts +3 -3
  139. package/dist/shims/constants.js +3 -3
  140. package/dist/shims/constants.js.map +1 -1
  141. package/dist/shims/document.d.ts +6 -6
  142. package/dist/shims/error-boundary.d.ts +4 -4
  143. package/dist/shims/error-boundary.js +1 -1
  144. package/dist/shims/error-boundary.js.map +1 -1
  145. package/dist/shims/form.d.ts +3 -3
  146. package/dist/shims/head-state.d.ts +1 -0
  147. package/dist/shims/head-state.js +0 -5
  148. package/dist/shims/head-state.js.map +1 -1
  149. package/dist/shims/headers.d.ts +11 -0
  150. package/dist/shims/headers.js +13 -10
  151. package/dist/shims/headers.js.map +1 -1
  152. package/dist/shims/i18n-state.d.ts +1 -0
  153. package/dist/shims/i18n-state.js +0 -4
  154. package/dist/shims/i18n-state.js.map +1 -1
  155. package/dist/shims/internal/app-router-context.d.ts +6 -6
  156. package/dist/shims/internal/router-context.d.ts +2 -2
  157. package/dist/shims/layout-segment-context.d.ts +2 -2
  158. package/dist/shims/link.js +19 -11
  159. package/dist/shims/link.js.map +1 -1
  160. package/dist/shims/metadata.d.ts +3 -3
  161. package/dist/shims/navigation-state.d.ts +2 -0
  162. package/dist/shims/navigation-state.js +0 -13
  163. package/dist/shims/navigation-state.js.map +1 -1
  164. package/dist/shims/navigation.d.ts +55 -8
  165. package/dist/shims/navigation.js +97 -23
  166. package/dist/shims/navigation.js.map +1 -1
  167. package/dist/shims/navigation.react-server.d.ts +14 -0
  168. package/dist/shims/navigation.react-server.js +29 -0
  169. package/dist/shims/navigation.react-server.js.map +1 -0
  170. package/dist/shims/request-context.d.ts +1 -0
  171. package/dist/shims/request-context.js +0 -9
  172. package/dist/shims/request-context.js.map +1 -1
  173. package/dist/shims/request-state-types.d.ts +1 -1
  174. package/dist/shims/router-state.d.ts +1 -0
  175. package/dist/shims/router-state.js +0 -5
  176. package/dist/shims/router-state.js.map +1 -1
  177. package/dist/shims/script-nonce-context.d.ts +12 -0
  178. package/dist/shims/script-nonce-context.js +17 -0
  179. package/dist/shims/script-nonce-context.js.map +1 -0
  180. package/dist/shims/script.js +41 -10
  181. package/dist/shims/script.js.map +1 -1
  182. package/dist/shims/server.js +6 -1
  183. package/dist/shims/server.js.map +1 -1
  184. package/dist/shims/slot.d.ts +11 -7
  185. package/dist/shims/slot.js +28 -19
  186. package/dist/shims/slot.js.map +1 -1
  187. package/dist/shims/unified-request-context.d.ts +2 -0
  188. package/dist/shims/unified-request-context.js +0 -14
  189. package/dist/shims/unified-request-context.js.map +1 -1
  190. package/dist/shims/url-safety.js +25 -4
  191. package/dist/shims/url-safety.js.map +1 -1
  192. package/dist/utils/mdx-scan.d.ts +10 -0
  193. package/dist/utils/mdx-scan.js +36 -0
  194. package/dist/utils/mdx-scan.js.map +1 -0
  195. package/dist/utils/public-routes.d.ts +5 -0
  196. package/dist/utils/public-routes.js +50 -0
  197. package/dist/utils/public-routes.js.map +1 -0
  198. package/package.json +9 -9
  199. package/dist/plugins/fix-use-server-closure-collision.d.ts +0 -29
  200. package/dist/plugins/fix-use-server-closure-collision.js +0 -204
  201. package/dist/plugins/fix-use-server-closure-collision.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pages-page-data.js","names":[],"sources":["../../src/server/pages-page-data.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { Route } from \"../routing/pages-router.js\";\nimport type { CachedPagesValue } from \"../shims/cache.js\";\nimport { buildPagesCacheValue, type ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n buildPagesNextDataScript,\n type PagesGsspResponse,\n type PagesI18nRenderContext,\n} from \"./pages-page-response.js\";\n\ntype PagesRedirectResult = {\n destination: string;\n permanent?: boolean;\n statusCode?: number;\n};\n\ntype PagesStaticPathsEntry = {\n params: Record<string, unknown>;\n};\n\ntype PagesStaticPathsResult = {\n fallback?: boolean | \"blocking\";\n paths?: PagesStaticPathsEntry[];\n};\n\ntype PagesPagePropsResult = {\n props?: Record<string, unknown>;\n redirect?: PagesRedirectResult;\n notFound?: boolean;\n revalidate?: number;\n};\n\nexport type PagesMutableGsspResponse = {\n headersSent: boolean;\n} & PagesGsspResponse;\n\nexport type PagesGsspContextResponse = {\n req: unknown;\n res: PagesMutableGsspResponse;\n responsePromise: Promise<Response>;\n};\n\nexport type PagesPageModule = {\n default?: unknown;\n getStaticPaths?: (context: {\n locales: string[];\n defaultLocale: string;\n }) => Promise<PagesStaticPathsResult> | PagesStaticPathsResult;\n getServerSideProps?: (context: {\n params: Record<string, unknown>;\n req: unknown;\n res: PagesMutableGsspResponse;\n query: Record<string, unknown>;\n resolvedUrl: string;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n }) => Promise<PagesPagePropsResult> | PagesPagePropsResult;\n getStaticProps?: (context: {\n params: Record<string, unknown>;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n }) => Promise<PagesPagePropsResult> | PagesPagePropsResult;\n};\n\nexport type RenderPagesIsrHtmlOptions = {\n buildId: string | null;\n cachedHtml: string;\n createPageElement: (pageProps: Record<string, unknown>) => ReactNode;\n i18n: PagesI18nRenderContext;\n pageProps: Record<string, unknown>;\n params: Record<string, unknown>;\n renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>;\n routePattern: string;\n safeJsonStringify: (value: unknown) => string;\n};\n\nexport type ResolvePagesPageDataOptions = {\n applyRequestContexts: () => void;\n buildId: string | null;\n createGsspReqRes: () => PagesGsspContextResponse;\n createPageElement: (pageProps: Record<string, unknown>) => ReactNode;\n fontLinkHeader: string;\n i18n: PagesI18nRenderContext;\n isrCacheKey: (router: string, pathname: string) => string;\n isrGet: (key: string) => Promise<ISRCacheEntry | null>;\n isrSet: (\n key: string,\n data: CachedPagesValue,\n revalidateSeconds: number,\n tags?: string[],\n ) => Promise<void>;\n pageModule: PagesPageModule;\n params: Record<string, unknown>;\n query: Record<string, unknown>;\n route: Pick<Route, \"isDynamic\">;\n routePattern: string;\n routeUrl: string;\n runInFreshUnifiedContext: <T>(callback: () => Promise<T>) => Promise<T>;\n safeJsonStringify: (value: unknown) => string;\n sanitizeDestination: (destination: string) => string;\n triggerBackgroundRegeneration: (key: string, renderFn: () => Promise<void>) => void;\n renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>;\n};\n\nexport type ResolvePagesPageDataRenderResult = {\n kind: \"render\";\n gsspRes: PagesGsspResponse | null;\n isrRevalidateSeconds: number | null;\n pageProps: Record<string, unknown>;\n};\n\nexport type ResolvePagesPageDataResponseResult = {\n kind: \"response\";\n response: Response;\n};\n\nexport type ResolvePagesPageDataResult =\n | ResolvePagesPageDataRenderResult\n | ResolvePagesPageDataResponseResult;\n\nfunction buildPagesNotFoundResponse(): Response {\n return new Response(\"<!DOCTYPE html><html><body><h1>404 - Page not found</h1></body></html>\", {\n status: 404,\n headers: { \"Content-Type\": \"text/html\" },\n });\n}\n\nfunction buildPagesDataNotFoundResponse(): Response {\n return new Response(\"404\", { status: 404 });\n}\n\nfunction resolvePagesRedirectStatus(redirect: PagesRedirectResult): number {\n return redirect.statusCode != null ? redirect.statusCode : redirect.permanent ? 308 : 307;\n}\n\nfunction matchesPagesStaticPath(\n pathEntry: PagesStaticPathsEntry,\n params: Record<string, unknown>,\n): boolean {\n return Object.entries(pathEntry.params).every(([key, value]) => {\n const actual = params[key];\n if (Array.isArray(value)) {\n return Array.isArray(actual) && value.join(\"/\") === actual.join(\"/\");\n }\n return String(value) === String(actual);\n });\n}\n\nfunction buildPagesCacheResponse(\n html: string,\n cacheState: \"HIT\" | \"STALE\",\n fontLinkHeader: string,\n revalidateSeconds?: number,\n): Response {\n const headers: Record<string, string> = {\n \"Content-Type\": \"text/html\",\n \"X-Vinext-Cache\": cacheState,\n \"Cache-Control\":\n cacheState === \"HIT\"\n ? `s-maxage=${revalidateSeconds ?? 60}, stale-while-revalidate`\n : \"s-maxage=0, stale-while-revalidate\",\n };\n\n if (fontLinkHeader) {\n headers.Link = fontLinkHeader;\n }\n\n return new Response(html, {\n status: 200,\n headers,\n });\n}\n\nfunction rewritePagesCachedHtml(\n cachedHtml: string,\n freshBody: string,\n nextDataScript: string,\n): string {\n const bodyMarker = '<div id=\"__next\">';\n const bodyStart = cachedHtml.indexOf(bodyMarker);\n const contentStart = bodyStart >= 0 ? bodyStart + bodyMarker.length : -1;\n const nextDataMarker = \"<script>window.__NEXT_DATA__\";\n const nextDataStart = cachedHtml.indexOf(nextDataMarker);\n\n if (contentStart >= 0 && nextDataStart >= 0) {\n const region = cachedHtml.slice(contentStart, nextDataStart);\n const lastCloseDiv = region.lastIndexOf(\"</div>\");\n const gap = lastCloseDiv >= 0 ? region.slice(lastCloseDiv + 6) : \"\";\n const nextDataEnd = cachedHtml.indexOf(\"</script>\", nextDataStart) + 9;\n const tail = cachedHtml.slice(nextDataEnd);\n\n return cachedHtml.slice(0, contentStart) + freshBody + \"</div>\" + gap + nextDataScript + tail;\n }\n\n return (\n '<!DOCTYPE html>\\n<html>\\n<head>\\n</head>\\n<body>\\n <div id=\"__next\">' +\n freshBody +\n \"</div>\\n \" +\n nextDataScript +\n \"\\n</body>\\n</html>\"\n );\n}\n\nexport async function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string> {\n const freshBody = await options.renderIsrPassToStringAsync(\n options.createPageElement(options.pageProps),\n );\n const nextDataScript = buildPagesNextDataScript({\n buildId: options.buildId,\n i18n: options.i18n,\n pageProps: options.pageProps,\n params: options.params,\n routePattern: options.routePattern,\n safeJsonStringify: options.safeJsonStringify,\n });\n\n return rewritePagesCachedHtml(options.cachedHtml, freshBody, nextDataScript);\n}\n\nexport async function resolvePagesPageData(\n options: ResolvePagesPageDataOptions,\n): Promise<ResolvePagesPageDataResult> {\n if (typeof options.pageModule.getStaticPaths === \"function\" && options.route.isDynamic) {\n const pathsResult = await options.pageModule.getStaticPaths({\n locales: options.i18n.locales ?? [],\n defaultLocale: options.i18n.defaultLocale ?? \"\",\n });\n const fallback = pathsResult?.fallback ?? false;\n\n if (fallback === false) {\n const paths = pathsResult?.paths ?? [];\n const isValidPath = paths.some((pathEntry) =>\n matchesPagesStaticPath(pathEntry, options.params),\n );\n\n if (!isValidPath) {\n return {\n kind: \"response\",\n response: buildPagesNotFoundResponse(),\n };\n }\n }\n }\n\n let pageProps: Record<string, unknown> = {};\n let gsspRes: PagesMutableGsspResponse | null = null;\n\n if (typeof options.pageModule.getServerSideProps === \"function\") {\n const { req, res, responsePromise } = options.createGsspReqRes();\n const result = await options.pageModule.getServerSideProps({\n params: options.params,\n req,\n res,\n query: options.query,\n resolvedUrl: options.routeUrl,\n locale: options.i18n.locale,\n locales: options.i18n.locales,\n defaultLocale: options.i18n.defaultLocale,\n });\n\n if (res.headersSent) {\n return {\n kind: \"response\",\n response: await responsePromise,\n };\n }\n\n if (result?.props) {\n pageProps = result.props;\n }\n\n if (result?.redirect) {\n return {\n kind: \"response\",\n response: new Response(null, {\n status: resolvePagesRedirectStatus(result.redirect),\n headers: { Location: options.sanitizeDestination(result.redirect.destination) },\n }),\n };\n }\n\n if (result?.notFound) {\n return {\n kind: \"response\",\n response: buildPagesDataNotFoundResponse(),\n };\n }\n\n gsspRes = res;\n }\n\n let isrRevalidateSeconds: number | null = null;\n\n if (typeof options.pageModule.getStaticProps === \"function\") {\n const pathname = options.routeUrl.split(\"?\")[0];\n const cacheKey = options.isrCacheKey(\"pages\", pathname);\n const cached = await options.isrGet(cacheKey);\n const cachedValue = cached?.value.value;\n\n if (cachedValue?.kind === \"PAGES\" && cached && !cached.isStale) {\n return {\n kind: \"response\",\n response: buildPagesCacheResponse(\n cachedValue.html,\n \"HIT\",\n options.fontLinkHeader,\n (cachedValue as CachedPagesValue & { revalidate?: number }).revalidate,\n ),\n };\n }\n\n if (cachedValue?.kind === \"PAGES\" && cached && cached.isStale) {\n options.triggerBackgroundRegeneration(cacheKey, async function () {\n return options.runInFreshUnifiedContext(async () => {\n const freshResult = await options.pageModule.getStaticProps?.({\n params: options.params,\n locale: options.i18n.locale,\n locales: options.i18n.locales,\n defaultLocale: options.i18n.defaultLocale,\n });\n\n if (\n freshResult?.props &&\n typeof freshResult.revalidate === \"number\" &&\n freshResult.revalidate > 0\n ) {\n options.applyRequestContexts();\n const freshHtml = await renderPagesIsrHtml({\n buildId: options.buildId,\n cachedHtml: cachedValue.html,\n createPageElement: options.createPageElement,\n i18n: options.i18n,\n pageProps: freshResult.props,\n params: options.params,\n renderIsrPassToStringAsync: options.renderIsrPassToStringAsync,\n routePattern: options.routePattern,\n safeJsonStringify: options.safeJsonStringify,\n });\n\n await options.isrSet(\n cacheKey,\n buildPagesCacheValue(freshHtml, freshResult.props),\n freshResult.revalidate,\n );\n }\n });\n });\n\n return {\n kind: \"response\",\n response: buildPagesCacheResponse(cachedValue.html, \"STALE\", options.fontLinkHeader),\n };\n }\n\n const result = await options.pageModule.getStaticProps({\n params: options.params,\n locale: options.i18n.locale,\n locales: options.i18n.locales,\n defaultLocale: options.i18n.defaultLocale,\n });\n\n if (result?.props) {\n pageProps = result.props;\n }\n\n if (result?.redirect) {\n return {\n kind: \"response\",\n response: new Response(null, {\n status: resolvePagesRedirectStatus(result.redirect),\n headers: { Location: options.sanitizeDestination(result.redirect.destination) },\n }),\n };\n }\n\n if (result?.notFound) {\n return {\n kind: \"response\",\n response: buildPagesDataNotFoundResponse(),\n };\n }\n\n if (typeof result?.revalidate === \"number\" && result.revalidate > 0) {\n isrRevalidateSeconds = result.revalidate;\n }\n }\n\n return {\n kind: \"render\",\n gsspRes,\n isrRevalidateSeconds,\n pageProps,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pages-page-data.js","names":[],"sources":["../../src/server/pages-page-data.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { Route } from \"../routing/pages-router.js\";\nimport type { CachedPagesValue } from \"../shims/cache.js\";\nimport { buildPagesCacheValue, type ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n buildPagesNextDataScript,\n type PagesGsspResponse,\n type PagesI18nRenderContext,\n} from \"./pages-page-response.js\";\n\ntype PagesRedirectResult = {\n destination: string;\n permanent?: boolean;\n statusCode?: number;\n};\n\ntype PagesStaticPathsEntry = {\n params: Record<string, unknown>;\n};\n\ntype PagesStaticPathsResult = {\n fallback?: boolean | \"blocking\";\n paths?: PagesStaticPathsEntry[];\n};\n\ntype PagesPagePropsResult = {\n props?: Record<string, unknown>;\n redirect?: PagesRedirectResult;\n notFound?: boolean;\n revalidate?: number;\n};\n\nexport type PagesMutableGsspResponse = {\n headersSent: boolean;\n} & PagesGsspResponse;\n\nexport type PagesGsspContextResponse = {\n req: unknown;\n res: PagesMutableGsspResponse;\n responsePromise: Promise<Response>;\n};\n\nexport type PagesPageModule = {\n default?: unknown;\n getStaticPaths?: (context: {\n locales: string[];\n defaultLocale: string;\n }) => Promise<PagesStaticPathsResult> | PagesStaticPathsResult;\n getServerSideProps?: (context: {\n params: Record<string, unknown>;\n req: unknown;\n res: PagesMutableGsspResponse;\n query: Record<string, unknown>;\n resolvedUrl: string;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n }) => Promise<PagesPagePropsResult> | PagesPagePropsResult;\n getStaticProps?: (context: {\n params: Record<string, unknown>;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n }) => Promise<PagesPagePropsResult> | PagesPagePropsResult;\n};\n\nexport type RenderPagesIsrHtmlOptions = {\n buildId: string | null;\n cachedHtml: string;\n createPageElement: (pageProps: Record<string, unknown>) => ReactNode;\n i18n: PagesI18nRenderContext;\n pageProps: Record<string, unknown>;\n params: Record<string, unknown>;\n renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>;\n routePattern: string;\n safeJsonStringify: (value: unknown) => string;\n};\n\nexport type ResolvePagesPageDataOptions = {\n applyRequestContexts: () => void;\n buildId: string | null;\n createGsspReqRes: () => PagesGsspContextResponse;\n createPageElement: (pageProps: Record<string, unknown>) => ReactNode;\n fontLinkHeader: string;\n i18n: PagesI18nRenderContext;\n isrCacheKey: (router: string, pathname: string) => string;\n isrGet: (key: string) => Promise<ISRCacheEntry | null>;\n isrSet: (\n key: string,\n data: CachedPagesValue,\n revalidateSeconds: number,\n tags?: string[],\n ) => Promise<void>;\n pageModule: PagesPageModule;\n params: Record<string, unknown>;\n query: Record<string, unknown>;\n route: Pick<Route, \"isDynamic\">;\n routePattern: string;\n routeUrl: string;\n runInFreshUnifiedContext: <T>(callback: () => Promise<T>) => Promise<T>;\n safeJsonStringify: (value: unknown) => string;\n sanitizeDestination: (destination: string) => string;\n scriptNonce?: string;\n triggerBackgroundRegeneration: (key: string, renderFn: () => Promise<void>) => void;\n renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>;\n};\n\nexport type ResolvePagesPageDataRenderResult = {\n kind: \"render\";\n gsspRes: PagesGsspResponse | null;\n isrRevalidateSeconds: number | null;\n pageProps: Record<string, unknown>;\n};\n\nexport type ResolvePagesPageDataResponseResult = {\n kind: \"response\";\n response: Response;\n};\n\nexport type ResolvePagesPageDataResult =\n | ResolvePagesPageDataRenderResult\n | ResolvePagesPageDataResponseResult;\n\nfunction buildPagesNotFoundResponse(): Response {\n return new Response(\"<!DOCTYPE html><html><body><h1>404 - Page not found</h1></body></html>\", {\n status: 404,\n headers: { \"Content-Type\": \"text/html\" },\n });\n}\n\nfunction buildPagesDataNotFoundResponse(): Response {\n return new Response(\"404\", { status: 404 });\n}\n\nfunction resolvePagesRedirectStatus(redirect: PagesRedirectResult): number {\n return redirect.statusCode != null ? redirect.statusCode : redirect.permanent ? 308 : 307;\n}\n\nfunction matchesPagesStaticPath(\n pathEntry: PagesStaticPathsEntry,\n params: Record<string, unknown>,\n): boolean {\n return Object.entries(pathEntry.params).every(([key, value]) => {\n const actual = params[key];\n if (Array.isArray(value)) {\n return Array.isArray(actual) && value.join(\"/\") === actual.join(\"/\");\n }\n return String(value) === String(actual);\n });\n}\n\nfunction buildPagesCacheResponse(\n html: string,\n cacheState: \"HIT\" | \"STALE\",\n fontLinkHeader: string,\n revalidateSeconds?: number,\n): Response {\n const headers: Record<string, string> = {\n \"Content-Type\": \"text/html\",\n \"X-Vinext-Cache\": cacheState,\n \"Cache-Control\":\n cacheState === \"HIT\"\n ? `s-maxage=${revalidateSeconds ?? 60}, stale-while-revalidate`\n : \"s-maxage=0, stale-while-revalidate\",\n };\n\n if (fontLinkHeader) {\n headers.Link = fontLinkHeader;\n }\n\n return new Response(html, {\n status: 200,\n headers,\n });\n}\n\nfunction rewritePagesCachedHtml(\n cachedHtml: string,\n freshBody: string,\n nextDataScript: string,\n): string {\n const bodyMarker = '<div id=\"__next\">';\n const bodyStart = cachedHtml.indexOf(bodyMarker);\n const contentStart = bodyStart >= 0 ? bodyStart + bodyMarker.length : -1;\n // This intentionally looks for the bare inline __NEXT_DATA__ marker.\n // Pages responses with scriptNonce are excluded from ISR writes, so cached\n // HTML should never contain nonce-prefixed __NEXT_DATA__ scripts here.\n const nextDataMarker = \"<script>window.__NEXT_DATA__\";\n const nextDataStart = cachedHtml.indexOf(nextDataMarker);\n\n if (contentStart >= 0 && nextDataStart >= 0) {\n const region = cachedHtml.slice(contentStart, nextDataStart);\n const lastCloseDiv = region.lastIndexOf(\"</div>\");\n const gap = lastCloseDiv >= 0 ? region.slice(lastCloseDiv + 6) : \"\";\n const nextDataEnd = cachedHtml.indexOf(\"</script>\", nextDataStart) + 9;\n const tail = cachedHtml.slice(nextDataEnd);\n\n return cachedHtml.slice(0, contentStart) + freshBody + \"</div>\" + gap + nextDataScript + tail;\n }\n\n return (\n '<!DOCTYPE html>\\n<html>\\n<head>\\n</head>\\n<body>\\n <div id=\"__next\">' +\n freshBody +\n \"</div>\\n \" +\n nextDataScript +\n \"\\n</body>\\n</html>\"\n );\n}\n\nexport async function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string> {\n const freshBody = await options.renderIsrPassToStringAsync(\n options.createPageElement(options.pageProps),\n );\n const nextDataScript = buildPagesNextDataScript({\n buildId: options.buildId,\n i18n: options.i18n,\n pageProps: options.pageProps,\n params: options.params,\n routePattern: options.routePattern,\n safeJsonStringify: options.safeJsonStringify,\n });\n\n return rewritePagesCachedHtml(options.cachedHtml, freshBody, nextDataScript);\n}\n\nexport async function resolvePagesPageData(\n options: ResolvePagesPageDataOptions,\n): Promise<ResolvePagesPageDataResult> {\n if (typeof options.pageModule.getStaticPaths === \"function\" && options.route.isDynamic) {\n const pathsResult = await options.pageModule.getStaticPaths({\n locales: options.i18n.locales ?? [],\n defaultLocale: options.i18n.defaultLocale ?? \"\",\n });\n const fallback = pathsResult?.fallback ?? false;\n\n if (fallback === false) {\n const paths = pathsResult?.paths ?? [];\n const isValidPath = paths.some((pathEntry) =>\n matchesPagesStaticPath(pathEntry, options.params),\n );\n\n if (!isValidPath) {\n return {\n kind: \"response\",\n response: buildPagesNotFoundResponse(),\n };\n }\n }\n }\n\n let pageProps: Record<string, unknown> = {};\n let gsspRes: PagesMutableGsspResponse | null = null;\n\n if (typeof options.pageModule.getServerSideProps === \"function\") {\n const { req, res, responsePromise } = options.createGsspReqRes();\n const result = await options.pageModule.getServerSideProps({\n params: options.params,\n req,\n res,\n query: options.query,\n resolvedUrl: options.routeUrl,\n locale: options.i18n.locale,\n locales: options.i18n.locales,\n defaultLocale: options.i18n.defaultLocale,\n });\n\n if (res.headersSent) {\n return {\n kind: \"response\",\n response: await responsePromise,\n };\n }\n\n if (result?.props) {\n pageProps = result.props;\n }\n\n if (result?.redirect) {\n return {\n kind: \"response\",\n response: new Response(null, {\n status: resolvePagesRedirectStatus(result.redirect),\n headers: { Location: options.sanitizeDestination(result.redirect.destination) },\n }),\n };\n }\n\n if (result?.notFound) {\n return {\n kind: \"response\",\n response: buildPagesDataNotFoundResponse(),\n };\n }\n\n gsspRes = res;\n }\n\n let isrRevalidateSeconds: number | null = null;\n\n if (typeof options.pageModule.getStaticProps === \"function\") {\n const pathname = options.routeUrl.split(\"?\")[0];\n const cacheKey = options.isrCacheKey(\"pages\", pathname);\n const cached = await options.isrGet(cacheKey);\n const cachedValue = cached?.value.value;\n\n if (cachedValue?.kind === \"PAGES\" && cached && !cached.isStale && !options.scriptNonce) {\n return {\n kind: \"response\",\n response: buildPagesCacheResponse(\n cachedValue.html,\n \"HIT\",\n options.fontLinkHeader,\n (cachedValue as CachedPagesValue & { revalidate?: number }).revalidate,\n ),\n };\n }\n\n if (cachedValue?.kind === \"PAGES\" && cached && cached.isStale && !options.scriptNonce) {\n options.triggerBackgroundRegeneration(cacheKey, async function () {\n return options.runInFreshUnifiedContext(async () => {\n const freshResult = await options.pageModule.getStaticProps?.({\n params: options.params,\n locale: options.i18n.locale,\n locales: options.i18n.locales,\n defaultLocale: options.i18n.defaultLocale,\n });\n\n if (\n freshResult?.props &&\n typeof freshResult.revalidate === \"number\" &&\n freshResult.revalidate > 0\n ) {\n options.applyRequestContexts();\n const freshHtml = await renderPagesIsrHtml({\n buildId: options.buildId,\n cachedHtml: cachedValue.html,\n createPageElement: options.createPageElement,\n i18n: options.i18n,\n pageProps: freshResult.props,\n params: options.params,\n renderIsrPassToStringAsync: options.renderIsrPassToStringAsync,\n routePattern: options.routePattern,\n safeJsonStringify: options.safeJsonStringify,\n });\n\n await options.isrSet(\n cacheKey,\n buildPagesCacheValue(freshHtml, freshResult.props),\n freshResult.revalidate,\n );\n }\n });\n });\n\n return {\n kind: \"response\",\n response: buildPagesCacheResponse(cachedValue.html, \"STALE\", options.fontLinkHeader),\n };\n }\n\n const result = await options.pageModule.getStaticProps({\n params: options.params,\n locale: options.i18n.locale,\n locales: options.i18n.locales,\n defaultLocale: options.i18n.defaultLocale,\n });\n\n if (result?.props) {\n pageProps = result.props;\n }\n\n if (result?.redirect) {\n return {\n kind: \"response\",\n response: new Response(null, {\n status: resolvePagesRedirectStatus(result.redirect),\n headers: { Location: options.sanitizeDestination(result.redirect.destination) },\n }),\n };\n }\n\n if (result?.notFound) {\n return {\n kind: \"response\",\n response: buildPagesDataNotFoundResponse(),\n };\n }\n\n if (typeof result?.revalidate === \"number\" && result.revalidate > 0) {\n isrRevalidateSeconds = result.revalidate;\n }\n }\n\n return {\n kind: \"render\",\n gsspRes,\n isrRevalidateSeconds,\n pageProps,\n };\n}\n"],"mappings":"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"}
@@ -47,8 +47,9 @@ type RenderPagesPageResponseOptions = {
47
47
  routePattern: string;
48
48
  routeUrl: string;
49
49
  safeJsonStringify: (value: unknown) => string;
50
+ scriptNonce?: string;
50
51
  };
51
- declare function buildPagesNextDataScript(options: Pick<RenderPagesPageResponseOptions, "buildId" | "i18n" | "pageProps" | "params" | "routePattern" | "safeJsonStringify">): string;
52
+ declare function buildPagesNextDataScript(options: Pick<RenderPagesPageResponseOptions, "buildId" | "i18n" | "pageProps" | "params" | "routePattern" | "safeJsonStringify" | "scriptNonce">): string;
52
53
  declare function renderPagesPageResponse(options: RenderPagesPageResponseOptions): Promise<Response>;
53
54
  //#endregion
54
55
  export { PagesFontPreload, PagesGsspResponse, PagesI18nRenderContext, RenderPagesPageResponseOptions, buildPagesNextDataScript, renderPagesPageResponse };
@@ -1,13 +1,13 @@
1
+ import { withScriptNonce } from "../shims/script-nonce-context.js";
2
+ import { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr } from "./html.js";
1
3
  import React from "react";
2
4
  //#region src/server/pages-page-response.ts
3
- function escapeAttr(value) {
4
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
5
- }
6
- function buildPagesFontHeadHtml(fontLinks, fontPreloads, fontStyles) {
5
+ function buildPagesFontHeadHtml(fontLinks, fontPreloads, fontStyles, scriptNonce) {
7
6
  let html = "";
8
- for (const link of fontLinks) html += `<link rel="stylesheet" href="${escapeAttr(link)}" />\n `;
9
- for (const preload of fontPreloads) html += `<link rel="preload" href="${escapeAttr(preload.href)}" as="font" type="${escapeAttr(preload.type)}" crossorigin />\n `;
10
- if (fontStyles.length > 0) html += `<style data-vinext-fonts>${fontStyles.join("\n")}</style>\n `;
7
+ const nonceAttr = createNonceAttribute(scriptNonce);
8
+ for (const link of fontLinks) html += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(link)}" />\n `;
9
+ for (const preload of fontPreloads) html += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(preload.href)}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n `;
10
+ if (fontStyles.length > 0) html += `<style data-vinext-fonts${nonceAttr}>${fontStyles.join("\n")}</style>\n `;
11
11
  return html;
12
12
  }
13
13
  function buildPagesNextDataScript(options) {
@@ -25,7 +25,7 @@ function buildPagesNextDataScript(options) {
25
25
  nextDataPayload.domainLocales = options.i18n.domainLocales;
26
26
  }
27
27
  const localeGlobals = options.i18n.locales ? `;window.__VINEXT_LOCALE__=${options.safeJsonStringify(options.i18n.locale)};window.__VINEXT_LOCALES__=${options.safeJsonStringify(options.i18n.locales)};window.__VINEXT_DEFAULT_LOCALE__=${options.safeJsonStringify(options.i18n.defaultLocale)}` : "";
28
- return `<script>window.__NEXT_DATA__ = ${options.safeJsonStringify(nextDataPayload)}${localeGlobals}<\/script>`;
28
+ return createInlineScriptTag(`window.__NEXT_DATA__ = ${options.safeJsonStringify(nextDataPayload)}${localeGlobals}`, options.scriptNonce);
29
29
  }
30
30
  async function buildPagesShellHtml(bodyMarker, fontHeadHTML, nextDataScript, options) {
31
31
  if (options.DocumentComponent) {
@@ -83,17 +83,18 @@ function applyGsspHeaders(headers, gsspRes) {
83
83
  return gsspRes.statusCode;
84
84
  }
85
85
  async function renderPagesPageResponse(options) {
86
- const pageElement = options.createPageElement(options.pageProps);
86
+ const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(options.pageProps)), options.scriptNonce);
87
87
  options.resetSSRHead?.();
88
88
  await options.flushPreloads?.();
89
- const fontHeadHTML = buildPagesFontHeadHtml(options.getFontLinks(), options.fontPreloads, options.getFontStyles());
89
+ const fontHeadHTML = buildPagesFontHeadHtml(options.getFontLinks(), options.fontPreloads, options.getFontStyles(), options.scriptNonce);
90
90
  const nextDataScript = buildPagesNextDataScript({
91
91
  buildId: options.buildId,
92
92
  i18n: options.i18n,
93
93
  pageProps: options.pageProps,
94
94
  params: options.params,
95
95
  routePattern: options.routePattern,
96
- safeJsonStringify: options.safeJsonStringify
96
+ safeJsonStringify: options.safeJsonStringify,
97
+ scriptNonce: options.scriptNonce
97
98
  });
98
99
  const bodyMarker = "<!--VINEXT_STREAM_BODY-->";
99
100
  const shellHtml = await buildPagesShellHtml(bodyMarker, fontHeadHTML, nextDataScript, {
@@ -107,8 +108,8 @@ async function renderPagesPageResponse(options) {
107
108
  const shellPrefix = shellHtml.slice(0, markerIndex);
108
109
  const shellSuffix = shellHtml.slice(markerIndex + 25);
109
110
  const compositeStream = await buildPagesCompositeStream(await options.renderToReadableStream(pageElement), shellPrefix, shellSuffix);
110
- if (options.isrRevalidateSeconds !== null && options.isrRevalidateSeconds > 0) {
111
- const isrElement = options.createPageElement(options.pageProps);
111
+ if (!options.scriptNonce && options.isrRevalidateSeconds !== null && options.isrRevalidateSeconds > 0) {
112
+ const isrElement = React.createElement(React.Fragment, null, options.createPageElement(options.pageProps));
112
113
  const fullHtml = shellPrefix + await options.renderIsrPassToStringAsync(isrElement) + shellSuffix;
113
114
  const isrPathname = options.routeUrl.split("?")[0];
114
115
  const cacheKey = options.isrCacheKey("pages", isrPathname);
@@ -122,7 +123,8 @@ async function renderPagesPageResponse(options) {
122
123
  }
123
124
  const responseHeaders = new Headers({ "Content-Type": "text/html" });
124
125
  const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes);
125
- if (options.isrRevalidateSeconds) {
126
+ if (options.scriptNonce) responseHeaders.set("Cache-Control", "no-store, must-revalidate");
127
+ else if (options.isrRevalidateSeconds) {
126
128
  responseHeaders.set("Cache-Control", `s-maxage=${options.isrRevalidateSeconds}, stale-while-revalidate`);
127
129
  responseHeaders.set("X-Vinext-Cache", "MISS");
128
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pages-page-response.js","names":[],"sources":["../../src/server/pages-page-response.ts"],"sourcesContent":["import React, { type ComponentType, type ReactNode } from \"react\";\n\nexport type PagesFontPreload = {\n href: string;\n type: string;\n};\n\nexport type PagesI18nRenderContext = {\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n domainLocales?: unknown;\n};\n\nexport type PagesGsspResponse = {\n statusCode: number;\n getHeaders(): Record<string, string | number | boolean | string[]>;\n};\n\ntype PagesStreamedHtmlResponse = {\n __vinextStreamedHtmlResponse?: boolean;\n} & Response;\n\nexport type RenderPagesPageResponseOptions = {\n assetTags: string;\n buildId: string | null;\n clearSsrContext: () => void;\n createPageElement: (pageProps: Record<string, unknown>) => ReactNode;\n DocumentComponent: ComponentType | null;\n flushPreloads?: (() => Promise<void> | void) | undefined;\n fontLinkHeader: string;\n fontPreloads: PagesFontPreload[];\n getFontLinks: () => string[];\n getFontStyles: () => string[];\n getSSRHeadHTML?: (() => string) | undefined;\n gsspRes: PagesGsspResponse | null;\n isrCacheKey: (router: string, pathname: string) => string;\n isrRevalidateSeconds: number | null;\n isrSet: (\n key: string,\n data: {\n kind: \"PAGES\";\n html: string;\n pageData: Record<string, unknown>;\n headers: undefined;\n status: undefined;\n },\n revalidateSeconds: number,\n ) => Promise<void>;\n i18n: PagesI18nRenderContext;\n pageProps: Record<string, unknown>;\n params: Record<string, unknown>;\n renderDocumentToString: (element: ReactNode) => Promise<string>;\n renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>;\n renderToReadableStream: (element: ReactNode) => Promise<ReadableStream<Uint8Array>>;\n resetSSRHead?: (() => void) | undefined;\n routePattern: string;\n routeUrl: string;\n safeJsonStringify: (value: unknown) => string;\n};\n\nfunction escapeAttr(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nfunction buildPagesFontHeadHtml(\n fontLinks: string[],\n fontPreloads: PagesFontPreload[],\n fontStyles: string[],\n): string {\n let html = \"\";\n\n for (const link of fontLinks) {\n html += `<link rel=\"stylesheet\" href=\"${escapeAttr(link)}\" />\\n `;\n }\n\n for (const preload of fontPreloads) {\n html += `<link rel=\"preload\" href=\"${escapeAttr(preload.href)}\" as=\"font\" type=\"${escapeAttr(preload.type)}\" crossorigin />\\n `;\n }\n\n if (fontStyles.length > 0) {\n html += `<style data-vinext-fonts>${fontStyles.join(\"\\n\")}</style>\\n `;\n }\n\n return html;\n}\n\nexport function buildPagesNextDataScript(\n options: Pick<\n RenderPagesPageResponseOptions,\n \"buildId\" | \"i18n\" | \"pageProps\" | \"params\" | \"routePattern\" | \"safeJsonStringify\"\n >,\n): string {\n const nextDataPayload: Record<string, unknown> = {\n props: { pageProps: options.pageProps },\n page: options.routePattern,\n query: options.params,\n buildId: options.buildId,\n isFallback: false,\n };\n\n if (options.i18n.locales) {\n nextDataPayload.locale = options.i18n.locale;\n nextDataPayload.locales = options.i18n.locales;\n nextDataPayload.defaultLocale = options.i18n.defaultLocale;\n nextDataPayload.domainLocales = options.i18n.domainLocales;\n }\n\n const localeGlobals = options.i18n.locales\n ? `;window.__VINEXT_LOCALE__=${options.safeJsonStringify(options.i18n.locale)}` +\n `;window.__VINEXT_LOCALES__=${options.safeJsonStringify(options.i18n.locales)}` +\n `;window.__VINEXT_DEFAULT_LOCALE__=${options.safeJsonStringify(options.i18n.defaultLocale)}`\n : \"\";\n\n return `<script>window.__NEXT_DATA__ = ${options.safeJsonStringify(nextDataPayload)}${localeGlobals}</script>`;\n}\n\nasync function buildPagesShellHtml(\n bodyMarker: string,\n fontHeadHTML: string,\n nextDataScript: string,\n options: Pick<\n RenderPagesPageResponseOptions,\n \"assetTags\" | \"DocumentComponent\" | \"renderDocumentToString\"\n > & {\n ssrHeadHTML: string;\n },\n): Promise<string> {\n if (options.DocumentComponent) {\n let html = await options.renderDocumentToString(React.createElement(options.DocumentComponent));\n html = html.replace(\"__NEXT_MAIN__\", bodyMarker);\n if (options.ssrHeadHTML || options.assetTags || fontHeadHTML) {\n html = html.replace(\n \"</head>\",\n ` ${fontHeadHTML}${options.ssrHeadHTML}\\n ${options.assetTags}\\n</head>`,\n );\n }\n html = html.replace(\"<!-- __NEXT_SCRIPTS__ -->\", nextDataScript);\n if (!html.includes(\"__NEXT_DATA__\")) {\n html = html.replace(\"</body>\", ` ${nextDataScript}\\n</body>`);\n }\n return html;\n }\n\n return (\n \"<!DOCTYPE html>\\n<html>\\n<head>\\n\" +\n ' <meta charset=\"utf-8\" />\\n' +\n ' <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\\n' +\n ` ${fontHeadHTML}${options.ssrHeadHTML}\\n` +\n ` ${options.assetTags}\\n` +\n \"</head>\\n<body>\\n\" +\n ` <div id=\"__next\">${bodyMarker}</div>\\n` +\n ` ${nextDataScript}\\n` +\n \"</body>\\n</html>\"\n );\n}\n\nasync function buildPagesCompositeStream(\n bodyStream: ReadableStream<Uint8Array>,\n shellPrefix: string,\n shellSuffix: string,\n): Promise<ReadableStream<Uint8Array>> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n controller.enqueue(encoder.encode(shellPrefix));\n const reader = bodyStream.getReader();\n try {\n for (;;) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n controller.enqueue(chunk.value);\n }\n } finally {\n reader.releaseLock();\n }\n controller.enqueue(encoder.encode(shellSuffix));\n controller.close();\n },\n });\n}\n\nfunction applyGsspHeaders(headers: Headers, gsspRes: PagesGsspResponse | null): number {\n if (!gsspRes) {\n return 200;\n }\n\n const gsspHeaders = gsspRes.getHeaders();\n for (const key of Object.keys(gsspHeaders)) {\n const value = gsspHeaders[key];\n const lowerKey = key.toLowerCase();\n if (lowerKey === \"set-cookie\" && Array.isArray(value)) {\n for (const cookie of value) {\n headers.append(\"set-cookie\", String(cookie));\n }\n continue;\n }\n if (Array.isArray(value)) {\n headers.set(key, value.join(\", \"));\n continue;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n headers.set(key, String(value));\n }\n }\n headers.set(\"Content-Type\", \"text/html\");\n return gsspRes.statusCode;\n}\n\nexport async function renderPagesPageResponse(\n options: RenderPagesPageResponseOptions,\n): Promise<Response> {\n const pageElement = options.createPageElement(options.pageProps);\n\n options.resetSSRHead?.();\n await options.flushPreloads?.();\n\n const fontHeadHTML = buildPagesFontHeadHtml(\n options.getFontLinks(),\n options.fontPreloads,\n options.getFontStyles(),\n );\n const nextDataScript = buildPagesNextDataScript({\n buildId: options.buildId,\n i18n: options.i18n,\n pageProps: options.pageProps,\n params: options.params,\n routePattern: options.routePattern,\n safeJsonStringify: options.safeJsonStringify,\n });\n const bodyMarker = \"<!--VINEXT_STREAM_BODY-->\";\n const shellHtml = await buildPagesShellHtml(bodyMarker, fontHeadHTML, nextDataScript, {\n assetTags: options.assetTags,\n DocumentComponent: options.DocumentComponent,\n renderDocumentToString: options.renderDocumentToString,\n ssrHeadHTML: options.getSSRHeadHTML?.() ?? \"\",\n });\n\n options.clearSsrContext();\n\n const markerIndex = shellHtml.indexOf(bodyMarker);\n const shellPrefix = shellHtml.slice(0, markerIndex);\n const shellSuffix = shellHtml.slice(markerIndex + bodyMarker.length);\n const bodyStream = await options.renderToReadableStream(pageElement);\n const compositeStream = await buildPagesCompositeStream(bodyStream, shellPrefix, shellSuffix);\n\n if (options.isrRevalidateSeconds !== null && options.isrRevalidateSeconds > 0) {\n const isrElement = options.createPageElement(options.pageProps);\n const isrHtml = await options.renderIsrPassToStringAsync(isrElement);\n const fullHtml = shellPrefix + isrHtml + shellSuffix;\n const isrPathname = options.routeUrl.split(\"?\")[0];\n const cacheKey = options.isrCacheKey(\"pages\", isrPathname);\n await options.isrSet(\n cacheKey,\n {\n kind: \"PAGES\",\n html: fullHtml,\n pageData: options.pageProps,\n headers: undefined,\n status: undefined,\n },\n options.isrRevalidateSeconds,\n );\n }\n\n const responseHeaders = new Headers({ \"Content-Type\": \"text/html\" });\n const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes);\n\n if (options.isrRevalidateSeconds) {\n responseHeaders.set(\n \"Cache-Control\",\n `s-maxage=${options.isrRevalidateSeconds}, stale-while-revalidate`,\n );\n responseHeaders.set(\"X-Vinext-Cache\", \"MISS\");\n }\n if (options.fontLinkHeader) {\n responseHeaders.set(\"Link\", options.fontLinkHeader);\n }\n\n const response = new Response(compositeStream, {\n status: finalStatus,\n headers: responseHeaders,\n }) as PagesStreamedHtmlResponse;\n // Mark the normal streamed HTML render so the Node prod server can strip\n // stale Content-Length only for this path, not for custom gSSP responses.\n response.__vinextStreamedHtmlResponse = true;\n return response;\n}\n"],"mappings":";;AA6DA,SAAS,WAAW,OAAuB;AACzC,QAAO,MAAM,QAAQ,MAAM,QAAQ,CAAC,QAAQ,MAAM,SAAS;;AAG7D,SAAS,uBACP,WACA,cACA,YACQ;CACR,IAAI,OAAO;AAEX,MAAK,MAAM,QAAQ,UACjB,SAAQ,gCAAgC,WAAW,KAAK,CAAC;AAG3D,MAAK,MAAM,WAAW,aACpB,SAAQ,6BAA6B,WAAW,QAAQ,KAAK,CAAC,oBAAoB,WAAW,QAAQ,KAAK,CAAC;AAG7G,KAAI,WAAW,SAAS,EACtB,SAAQ,4BAA4B,WAAW,KAAK,KAAK,CAAC;AAG5D,QAAO;;AAGT,SAAgB,yBACd,SAIQ;CACR,MAAM,kBAA2C;EAC/C,OAAO,EAAE,WAAW,QAAQ,WAAW;EACvC,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf,SAAS,QAAQ;EACjB,YAAY;EACb;AAED,KAAI,QAAQ,KAAK,SAAS;AACxB,kBAAgB,SAAS,QAAQ,KAAK;AACtC,kBAAgB,UAAU,QAAQ,KAAK;AACvC,kBAAgB,gBAAgB,QAAQ,KAAK;AAC7C,kBAAgB,gBAAgB,QAAQ,KAAK;;CAG/C,MAAM,gBAAgB,QAAQ,KAAK,UAC/B,6BAA6B,QAAQ,kBAAkB,QAAQ,KAAK,OAAO,CAAA,6BAC7C,QAAQ,kBAAkB,QAAQ,KAAK,QAAQ,CAAA,oCACxC,QAAQ,kBAAkB,QAAQ,KAAK,cAAc,KAC1F;AAEJ,QAAO,kCAAkC,QAAQ,kBAAkB,gBAAgB,GAAG,cAAc;;AAGtG,eAAe,oBACb,YACA,cACA,gBACA,SAMiB;AACjB,KAAI,QAAQ,mBAAmB;EAC7B,IAAI,OAAO,MAAM,QAAQ,uBAAuB,MAAM,cAAc,QAAQ,kBAAkB,CAAC;AAC/F,SAAO,KAAK,QAAQ,iBAAiB,WAAW;AAChD,MAAI,QAAQ,eAAe,QAAQ,aAAa,aAC9C,QAAO,KAAK,QACV,WACA,KAAK,eAAe,QAAQ,YAAY,MAAM,QAAQ,UAAU,WACjE;AAEH,SAAO,KAAK,QAAQ,6BAA6B,eAAe;AAChE,MAAI,CAAC,KAAK,SAAS,gBAAgB,CACjC,QAAO,KAAK,QAAQ,WAAW,KAAK,eAAe,WAAW;AAEhE,SAAO;;AAGT,QACE;;;;;IAGK,eAAe,QAAQ,YAAY,MACnC,QAAQ,UAAU;;qBAED,WAAW,YAC5B,eAAe;;;AAKxB,eAAe,0BACb,YACA,aACA,aACqC;CACrC,MAAM,UAAU,IAAI,aAAa;AAEjC,QAAO,IAAI,eAAe,EACxB,MAAM,MAAM,YAAY;AACtB,aAAW,QAAQ,QAAQ,OAAO,YAAY,CAAC;EAC/C,MAAM,SAAS,WAAW,WAAW;AACrC,MAAI;AACF,YAAS;IACP,MAAM,QAAQ,MAAM,OAAO,MAAM;AACjC,QAAI,MAAM,KACR;AAEF,eAAW,QAAQ,MAAM,MAAM;;YAEzB;AACR,UAAO,aAAa;;AAEtB,aAAW,QAAQ,QAAQ,OAAO,YAAY,CAAC;AAC/C,aAAW,OAAO;IAErB,CAAC;;AAGJ,SAAS,iBAAiB,SAAkB,SAA2C;AACrF,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,cAAc,QAAQ,YAAY;AACxC,MAAK,MAAM,OAAO,OAAO,KAAK,YAAY,EAAE;EAC1C,MAAM,QAAQ,YAAY;AAE1B,MADiB,IAAI,aAAa,KACjB,gBAAgB,MAAM,QAAQ,MAAM,EAAE;AACrD,QAAK,MAAM,UAAU,MACnB,SAAQ,OAAO,cAAc,OAAO,OAAO,CAAC;AAE9C;;AAEF,MAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,WAAQ,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC;AAClC;;AAEF,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,UAC7E,SAAQ,IAAI,KAAK,OAAO,MAAM,CAAC;;AAGnC,SAAQ,IAAI,gBAAgB,YAAY;AACxC,QAAO,QAAQ;;AAGjB,eAAsB,wBACpB,SACmB;CACnB,MAAM,cAAc,QAAQ,kBAAkB,QAAQ,UAAU;AAEhE,SAAQ,gBAAgB;AACxB,OAAM,QAAQ,iBAAiB;CAE/B,MAAM,eAAe,uBACnB,QAAQ,cAAc,EACtB,QAAQ,cACR,QAAQ,eAAe,CACxB;CACD,MAAM,iBAAiB,yBAAyB;EAC9C,SAAS,QAAQ;EACjB,MAAM,QAAQ;EACd,WAAW,QAAQ;EACnB,QAAQ,QAAQ;EAChB,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC5B,CAAC;CACF,MAAM,aAAa;CACnB,MAAM,YAAY,MAAM,oBAAoB,YAAY,cAAc,gBAAgB;EACpF,WAAW,QAAQ;EACnB,mBAAmB,QAAQ;EAC3B,wBAAwB,QAAQ;EAChC,aAAa,QAAQ,kBAAkB,IAAI;EAC5C,CAAC;AAEF,SAAQ,iBAAiB;CAEzB,MAAM,cAAc,UAAU,QAAQ,WAAW;CACjD,MAAM,cAAc,UAAU,MAAM,GAAG,YAAY;CACnD,MAAM,cAAc,UAAU,MAAM,cAAc,GAAkB;CAEpE,MAAM,kBAAkB,MAAM,0BADX,MAAM,QAAQ,uBAAuB,YAAY,EACA,aAAa,YAAY;AAE7F,KAAI,QAAQ,yBAAyB,QAAQ,QAAQ,uBAAuB,GAAG;EAC7E,MAAM,aAAa,QAAQ,kBAAkB,QAAQ,UAAU;EAE/D,MAAM,WAAW,cADD,MAAM,QAAQ,2BAA2B,WAAW,GAC3B;EACzC,MAAM,cAAc,QAAQ,SAAS,MAAM,IAAI,CAAC;EAChD,MAAM,WAAW,QAAQ,YAAY,SAAS,YAAY;AAC1D,QAAM,QAAQ,OACZ,UACA;GACE,MAAM;GACN,MAAM;GACN,UAAU,QAAQ;GAClB,SAAS,KAAA;GACT,QAAQ,KAAA;GACT,EACD,QAAQ,qBACT;;CAGH,MAAM,kBAAkB,IAAI,QAAQ,EAAE,gBAAgB,aAAa,CAAC;CACpE,MAAM,cAAc,iBAAiB,iBAAiB,QAAQ,QAAQ;AAEtE,KAAI,QAAQ,sBAAsB;AAChC,kBAAgB,IACd,iBACA,YAAY,QAAQ,qBAAqB,0BAC1C;AACD,kBAAgB,IAAI,kBAAkB,OAAO;;AAE/C,KAAI,QAAQ,eACV,iBAAgB,IAAI,QAAQ,QAAQ,eAAe;CAGrD,MAAM,WAAW,IAAI,SAAS,iBAAiB;EAC7C,QAAQ;EACR,SAAS;EACV,CAAC;AAGF,UAAS,+BAA+B;AACxC,QAAO"}
1
+ {"version":3,"file":"pages-page-response.js","names":[],"sources":["../../src/server/pages-page-response.ts"],"sourcesContent":["import React, { type ComponentType, type ReactNode } from \"react\";\nimport { withScriptNonce } from \"../shims/script-nonce-context.js\";\nimport { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr } from \"./html.js\";\n\nexport type PagesFontPreload = {\n href: string;\n type: string;\n};\n\nexport type PagesI18nRenderContext = {\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n domainLocales?: unknown;\n};\n\nexport type PagesGsspResponse = {\n statusCode: number;\n getHeaders(): Record<string, string | number | boolean | string[]>;\n};\n\ntype PagesStreamedHtmlResponse = {\n __vinextStreamedHtmlResponse?: boolean;\n} & Response;\n\nexport type RenderPagesPageResponseOptions = {\n assetTags: string;\n buildId: string | null;\n clearSsrContext: () => void;\n createPageElement: (pageProps: Record<string, unknown>) => ReactNode;\n DocumentComponent: ComponentType | null;\n flushPreloads?: (() => Promise<void> | void) | undefined;\n fontLinkHeader: string;\n fontPreloads: PagesFontPreload[];\n getFontLinks: () => string[];\n getFontStyles: () => string[];\n getSSRHeadHTML?: (() => string) | undefined;\n gsspRes: PagesGsspResponse | null;\n isrCacheKey: (router: string, pathname: string) => string;\n isrRevalidateSeconds: number | null;\n isrSet: (\n key: string,\n data: {\n kind: \"PAGES\";\n html: string;\n pageData: Record<string, unknown>;\n headers: undefined;\n status: undefined;\n },\n revalidateSeconds: number,\n ) => Promise<void>;\n i18n: PagesI18nRenderContext;\n pageProps: Record<string, unknown>;\n params: Record<string, unknown>;\n renderDocumentToString: (element: ReactNode) => Promise<string>;\n renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>;\n renderToReadableStream: (element: ReactNode) => Promise<ReadableStream<Uint8Array>>;\n resetSSRHead?: (() => void) | undefined;\n routePattern: string;\n routeUrl: string;\n safeJsonStringify: (value: unknown) => string;\n scriptNonce?: string;\n};\n\nfunction buildPagesFontHeadHtml(\n fontLinks: string[],\n fontPreloads: PagesFontPreload[],\n fontStyles: string[],\n scriptNonce?: string,\n): string {\n let html = \"\";\n const nonceAttr = createNonceAttribute(scriptNonce);\n\n for (const link of fontLinks) {\n html += `<link rel=\"stylesheet\"${nonceAttr} href=\"${escapeHtmlAttr(link)}\" />\\n `;\n }\n\n for (const preload of fontPreloads) {\n html += `<link rel=\"preload\"${nonceAttr} href=\"${escapeHtmlAttr(preload.href)}\" as=\"font\" type=\"${escapeHtmlAttr(preload.type)}\" crossorigin />\\n `;\n }\n\n if (fontStyles.length > 0) {\n html += `<style data-vinext-fonts${nonceAttr}>${fontStyles.join(\"\\n\")}</style>\\n `;\n }\n\n return html;\n}\n\nexport function buildPagesNextDataScript(\n options: Pick<\n RenderPagesPageResponseOptions,\n | \"buildId\"\n | \"i18n\"\n | \"pageProps\"\n | \"params\"\n | \"routePattern\"\n | \"safeJsonStringify\"\n | \"scriptNonce\"\n >,\n): string {\n const nextDataPayload: Record<string, unknown> = {\n props: { pageProps: options.pageProps },\n page: options.routePattern,\n query: options.params,\n buildId: options.buildId,\n isFallback: false,\n };\n\n if (options.i18n.locales) {\n nextDataPayload.locale = options.i18n.locale;\n nextDataPayload.locales = options.i18n.locales;\n nextDataPayload.defaultLocale = options.i18n.defaultLocale;\n nextDataPayload.domainLocales = options.i18n.domainLocales;\n }\n\n const localeGlobals = options.i18n.locales\n ? `;window.__VINEXT_LOCALE__=${options.safeJsonStringify(options.i18n.locale)}` +\n `;window.__VINEXT_LOCALES__=${options.safeJsonStringify(options.i18n.locales)}` +\n `;window.__VINEXT_DEFAULT_LOCALE__=${options.safeJsonStringify(options.i18n.defaultLocale)}`\n : \"\";\n\n return createInlineScriptTag(\n `window.__NEXT_DATA__ = ${options.safeJsonStringify(nextDataPayload)}${localeGlobals}`,\n options.scriptNonce,\n );\n}\n\nasync function buildPagesShellHtml(\n bodyMarker: string,\n fontHeadHTML: string,\n nextDataScript: string,\n options: Pick<\n RenderPagesPageResponseOptions,\n \"assetTags\" | \"DocumentComponent\" | \"renderDocumentToString\"\n > & {\n ssrHeadHTML: string;\n },\n): Promise<string> {\n if (options.DocumentComponent) {\n let html = await options.renderDocumentToString(React.createElement(options.DocumentComponent));\n html = html.replace(\"__NEXT_MAIN__\", bodyMarker);\n if (options.ssrHeadHTML || options.assetTags || fontHeadHTML) {\n html = html.replace(\n \"</head>\",\n ` ${fontHeadHTML}${options.ssrHeadHTML}\\n ${options.assetTags}\\n</head>`,\n );\n }\n html = html.replace(\"<!-- __NEXT_SCRIPTS__ -->\", nextDataScript);\n if (!html.includes(\"__NEXT_DATA__\")) {\n html = html.replace(\"</body>\", ` ${nextDataScript}\\n</body>`);\n }\n return html;\n }\n\n return (\n \"<!DOCTYPE html>\\n<html>\\n<head>\\n\" +\n ' <meta charset=\"utf-8\" />\\n' +\n ' <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\\n' +\n ` ${fontHeadHTML}${options.ssrHeadHTML}\\n` +\n ` ${options.assetTags}\\n` +\n \"</head>\\n<body>\\n\" +\n ` <div id=\"__next\">${bodyMarker}</div>\\n` +\n ` ${nextDataScript}\\n` +\n \"</body>\\n</html>\"\n );\n}\n\nasync function buildPagesCompositeStream(\n bodyStream: ReadableStream<Uint8Array>,\n shellPrefix: string,\n shellSuffix: string,\n): Promise<ReadableStream<Uint8Array>> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n controller.enqueue(encoder.encode(shellPrefix));\n const reader = bodyStream.getReader();\n try {\n for (;;) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n controller.enqueue(chunk.value);\n }\n } finally {\n reader.releaseLock();\n }\n controller.enqueue(encoder.encode(shellSuffix));\n controller.close();\n },\n });\n}\n\nfunction applyGsspHeaders(headers: Headers, gsspRes: PagesGsspResponse | null): number {\n if (!gsspRes) {\n return 200;\n }\n\n const gsspHeaders = gsspRes.getHeaders();\n for (const key of Object.keys(gsspHeaders)) {\n const value = gsspHeaders[key];\n const lowerKey = key.toLowerCase();\n if (lowerKey === \"set-cookie\" && Array.isArray(value)) {\n for (const cookie of value) {\n headers.append(\"set-cookie\", String(cookie));\n }\n continue;\n }\n if (Array.isArray(value)) {\n headers.set(key, value.join(\", \"));\n continue;\n }\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n headers.set(key, String(value));\n }\n }\n headers.set(\"Content-Type\", \"text/html\");\n return gsspRes.statusCode;\n}\n\nexport async function renderPagesPageResponse(\n options: RenderPagesPageResponseOptions,\n): Promise<Response> {\n const pageElement = withScriptNonce(\n React.createElement(React.Fragment, null, options.createPageElement(options.pageProps)),\n options.scriptNonce,\n );\n\n options.resetSSRHead?.();\n await options.flushPreloads?.();\n\n const fontHeadHTML = buildPagesFontHeadHtml(\n options.getFontLinks(),\n options.fontPreloads,\n options.getFontStyles(),\n options.scriptNonce,\n );\n const nextDataScript = buildPagesNextDataScript({\n buildId: options.buildId,\n i18n: options.i18n,\n pageProps: options.pageProps,\n params: options.params,\n routePattern: options.routePattern,\n safeJsonStringify: options.safeJsonStringify,\n scriptNonce: options.scriptNonce,\n });\n const bodyMarker = \"<!--VINEXT_STREAM_BODY-->\";\n const shellHtml = await buildPagesShellHtml(bodyMarker, fontHeadHTML, nextDataScript, {\n assetTags: options.assetTags,\n DocumentComponent: options.DocumentComponent,\n renderDocumentToString: options.renderDocumentToString,\n ssrHeadHTML: options.getSSRHeadHTML?.() ?? \"\",\n });\n\n options.clearSsrContext();\n\n const markerIndex = shellHtml.indexOf(bodyMarker);\n const shellPrefix = shellHtml.slice(0, markerIndex);\n const shellSuffix = shellHtml.slice(markerIndex + bodyMarker.length);\n const bodyStream = await options.renderToReadableStream(pageElement);\n const compositeStream = await buildPagesCompositeStream(bodyStream, shellPrefix, shellSuffix);\n\n if (\n // Keep nonce-bearing pages out of ISR writes: rewritePagesCachedHtml()\n // later matches the cached __NEXT_DATA__ block via a bare <script> marker.\n !options.scriptNonce &&\n options.isrRevalidateSeconds !== null &&\n options.isrRevalidateSeconds > 0\n ) {\n const isrElement = React.createElement(\n React.Fragment,\n null,\n options.createPageElement(options.pageProps),\n );\n const isrHtml = await options.renderIsrPassToStringAsync(isrElement);\n const fullHtml = shellPrefix + isrHtml + shellSuffix;\n const isrPathname = options.routeUrl.split(\"?\")[0];\n const cacheKey = options.isrCacheKey(\"pages\", isrPathname);\n await options.isrSet(\n cacheKey,\n {\n kind: \"PAGES\",\n html: fullHtml,\n pageData: options.pageProps,\n headers: undefined,\n status: undefined,\n },\n options.isrRevalidateSeconds,\n );\n }\n\n const responseHeaders = new Headers({ \"Content-Type\": \"text/html\" });\n const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes);\n\n if (options.scriptNonce) {\n responseHeaders.set(\"Cache-Control\", \"no-store, must-revalidate\");\n } else if (options.isrRevalidateSeconds) {\n responseHeaders.set(\n \"Cache-Control\",\n `s-maxage=${options.isrRevalidateSeconds}, stale-while-revalidate`,\n );\n responseHeaders.set(\"X-Vinext-Cache\", \"MISS\");\n }\n if (options.fontLinkHeader) {\n responseHeaders.set(\"Link\", options.fontLinkHeader);\n }\n\n const response = new Response(compositeStream, {\n status: finalStatus,\n headers: responseHeaders,\n }) as PagesStreamedHtmlResponse;\n // Mark the normal streamed HTML render so the Node prod server can strip\n // stale Content-Length only for this path, not for custom gSSP responses.\n response.__vinextStreamedHtmlResponse = true;\n return response;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { StaticFileCache } from "./static-file-cache.js";
2
- import * as node_http0 from "node:http";
2
+ import * as _$node_http0 from "node:http";
3
3
  import { IncomingMessage, ServerResponse } from "node:http";
4
4
 
5
5
  //#region src/server/prod-server.d.ts
@@ -31,7 +31,7 @@ declare function mergeWebResponse(middlewareHeaders: Record<string, string | str
31
31
  * Send a compressed response if the content type is compressible and the
32
32
  * client supports compression. Otherwise send uncompressed.
33
33
  */
34
- declare function sendCompressed(req: IncomingMessage, res: ServerResponse, body: string | Buffer, contentType: string, statusCode: number, extraHeaders?: Record<string, string | string[]>, compress?: boolean, statusText?: string | undefined): void;
34
+ declare function sendCompressed(req: IncomingMessage, res: ServerResponse, body: string | Buffer, contentType: string, statusCode: number, extraHeaders?: Record<string, string | string[]>, compress?: boolean, statusText?: string): void;
35
35
  /**
36
36
  * Try to serve a static file from the client build directory.
37
37
  *
@@ -87,7 +87,7 @@ declare function sendWebResponse(webResponse: Response, req: IncomingMessage, re
87
87
  * Pages Router (dist/server/entry.js) and configures the appropriate handler.
88
88
  */
89
89
  declare function startProdServer(options?: ProdServerOptions): Promise<{
90
- server: node_http0.Server<typeof IncomingMessage, typeof ServerResponse>;
90
+ server: _$node_http0.Server<typeof IncomingMessage, typeof ServerResponse>;
91
91
  port: number;
92
92
  }>;
93
93
  //#endregion
@@ -204,7 +204,7 @@ function mergeWebResponse(middlewareHeaders, response, statusOverride) {
204
204
  * Send a compressed response if the content type is compressible and the
205
205
  * client supports compression. Otherwise send uncompressed.
206
206
  */
207
- function sendCompressed(req, res, body, contentType, statusCode, extraHeaders = {}, compress = true, statusText = void 0) {
207
+ function sendCompressed(req, res, body, contentType, statusCode, extraHeaders = {}, compress = true, statusText) {
208
208
  const buf = typeof body === "string" ? Buffer.from(body) : body;
209
209
  const baseType = contentType.split(";")[0].trim();
210
210
  const encoding = compress ? negotiateEncoding(req) : null;
@@ -697,7 +697,7 @@ async function startAppRouterServer(options) {
697
697
  * Start the Pages Router production server.
698
698
  *
699
699
  * Uses the server entry (dist/server/entry.js) which exports:
700
- * - renderPage(request, url, manifest) — SSR rendering (Web Request → Response)
700
+ * - renderPage(request, url, manifest, ctx?, middlewareHeaders?) — SSR rendering (Web Request → Response)
701
701
  * - handleApiRoute(request, url) — API route handling (Web Request → Response)
702
702
  * - runMiddleware(request, ctx?) — middleware execution (ctx optional; pass for ctx.waitUntil() on Workers)
703
703
  * - vinextConfig — embedded next.config.js settings
@@ -953,7 +953,8 @@ async function startPagesRouterServer(options) {
953
953
  }
954
954
  let response;
955
955
  if (typeof renderPage === "function") {
956
- response = await renderPage(webRequest, resolvedUrl, ssrManifest);
956
+ const middlewareResponseHeaders = toWebHeaders(middlewareHeaders);
957
+ response = await renderPage(webRequest, resolvedUrl, ssrManifest, void 0, middlewareResponseHeaders);
957
958
  if (response && response.status === 404 && configRewrites.fallback?.length) {
958
959
  const fallbackRewrite = matchRewrite(resolvedPathname, configRewrites.fallback, postMwReqCtx);
959
960
  if (fallbackRewrite) {
@@ -961,7 +962,7 @@ async function startPagesRouterServer(options) {
961
962
  await sendWebResponse(await proxyExternalRequest(webRequest, fallbackRewrite), req, res, compress);
962
963
  return;
963
964
  }
964
- response = await renderPage(webRequest, fallbackRewrite, ssrManifest);
965
+ response = await renderPage(webRequest, fallbackRewrite, ssrManifest, void 0, middlewareResponseHeaders);
965
966
  }
966
967
  }
967
968
  }