vinext 0.1.2 → 0.1.4

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 (243) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/prerender.d.ts +9 -1
  4. package/dist/build/prerender.js +42 -12
  5. package/dist/build/run-prerender.d.ts +10 -2
  6. package/dist/build/run-prerender.js +15 -1
  7. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  8. package/dist/client/app-nav-failure-handler.js +44 -0
  9. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  10. package/dist/client/pages-router-link-navigation.js +32 -2
  11. package/dist/client/vinext-next-data.d.ts +18 -1
  12. package/dist/client/vinext-next-data.js +2 -0
  13. package/dist/client/window-next.d.ts +2 -1
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -1
  17. package/dist/config/config-matchers.js +87 -16
  18. package/dist/config/next-config.d.ts +46 -4
  19. package/dist/config/next-config.js +147 -48
  20. package/dist/config/tsconfig-paths.js +14 -1
  21. package/dist/deploy.d.ts +30 -11
  22. package/dist/deploy.js +200 -112
  23. package/dist/entries/app-browser-entry.d.ts +9 -3
  24. package/dist/entries/app-browser-entry.js +21 -3
  25. package/dist/entries/app-rsc-entry.d.ts +2 -0
  26. package/dist/entries/app-rsc-entry.js +65 -5
  27. package/dist/entries/app-rsc-manifest.js +2 -0
  28. package/dist/entries/app-ssr-entry.js +1 -1
  29. package/dist/entries/pages-client-entry.js +66 -20
  30. package/dist/entries/pages-server-entry.js +47 -31
  31. package/dist/index.js +417 -102
  32. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  33. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  34. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  35. package/dist/plugins/fonts.js +5 -4
  36. package/dist/plugins/optimize-imports.d.ts +2 -1
  37. package/dist/plugins/optimize-imports.js +11 -9
  38. package/dist/plugins/postcss.js +7 -7
  39. package/dist/plugins/strip-server-exports.d.ts +9 -7
  40. package/dist/plugins/strip-server-exports.js +493 -46
  41. package/dist/plugins/typeof-window.d.ts +14 -0
  42. package/dist/plugins/typeof-window.js +150 -0
  43. package/dist/routing/app-route-graph.d.ts +2 -1
  44. package/dist/routing/app-route-graph.js +46 -16
  45. package/dist/routing/file-matcher.d.ts +10 -1
  46. package/dist/routing/file-matcher.js +22 -1
  47. package/dist/routing/pages-router.js +3 -3
  48. package/dist/routing/utils.d.ts +35 -6
  49. package/dist/routing/utils.js +59 -7
  50. package/dist/server/api-handler.d.ts +6 -1
  51. package/dist/server/api-handler.js +21 -15
  52. package/dist/server/app-browser-action-result.d.ts +19 -6
  53. package/dist/server/app-browser-action-result.js +20 -11
  54. package/dist/server/app-browser-entry.js +175 -91
  55. package/dist/server/app-browser-error.d.ts +10 -6
  56. package/dist/server/app-browser-error.js +43 -8
  57. package/dist/server/app-browser-hydration.d.ts +2 -0
  58. package/dist/server/app-browser-hydration.js +1 -0
  59. package/dist/server/app-browser-navigation-controller.d.ts +5 -3
  60. package/dist/server/app-browser-navigation-controller.js +23 -2
  61. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  62. package/dist/server/app-browser-server-action-navigation.js +9 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js +19 -11
  65. package/dist/server/app-browser-stream.js +86 -43
  66. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  67. package/dist/server/app-elements-wire.d.ts +6 -1
  68. package/dist/server/app-elements-wire.js +14 -4
  69. package/dist/server/app-elements.d.ts +2 -2
  70. package/dist/server/app-elements.js +2 -2
  71. package/dist/server/app-fallback-renderer.d.ts +1 -0
  72. package/dist/server/app-fallback-renderer.js +3 -1
  73. package/dist/server/app-optimistic-routing.js +2 -2
  74. package/dist/server/app-page-boundary-render.d.ts +1 -0
  75. package/dist/server/app-page-boundary-render.js +27 -14
  76. package/dist/server/app-page-cache-render.d.ts +53 -0
  77. package/dist/server/app-page-cache-render.js +91 -0
  78. package/dist/server/app-page-cache.d.ts +16 -2
  79. package/dist/server/app-page-cache.js +62 -1
  80. package/dist/server/app-page-dispatch.d.ts +26 -0
  81. package/dist/server/app-page-dispatch.js +149 -92
  82. package/dist/server/app-page-element-builder.d.ts +1 -0
  83. package/dist/server/app-page-element-builder.js +5 -2
  84. package/dist/server/app-page-execution.d.ts +6 -1
  85. package/dist/server/app-page-execution.js +21 -1
  86. package/dist/server/app-page-probe.d.ts +1 -0
  87. package/dist/server/app-page-probe.js +4 -0
  88. package/dist/server/app-page-render-observation.d.ts +3 -1
  89. package/dist/server/app-page-render-observation.js +17 -1
  90. package/dist/server/app-page-render.d.ts +12 -1
  91. package/dist/server/app-page-render.js +42 -4
  92. package/dist/server/app-page-request.d.ts +2 -0
  93. package/dist/server/app-page-request.js +2 -1
  94. package/dist/server/app-page-route-wiring.d.ts +3 -1
  95. package/dist/server/app-page-route-wiring.js +14 -5
  96. package/dist/server/app-page-stream.d.ts +15 -3
  97. package/dist/server/app-page-stream.js +11 -5
  98. package/dist/server/app-pages-bridge.d.ts +23 -1
  99. package/dist/server/app-pages-bridge.js +26 -17
  100. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  101. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  102. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  103. package/dist/server/app-ppr-fallback-shell.js +8 -1
  104. package/dist/server/app-route-handler-dispatch.js +9 -2
  105. package/dist/server/app-route-handler-policy.d.ts +1 -0
  106. package/dist/server/app-router-entry.js +5 -0
  107. package/dist/server/app-rsc-cache-busting.js +2 -0
  108. package/dist/server/app-rsc-handler.d.ts +28 -0
  109. package/dist/server/app-rsc-handler.js +195 -59
  110. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  111. package/dist/server/app-rsc-route-matching.js +8 -2
  112. package/dist/server/app-segment-config.d.ts +9 -1
  113. package/dist/server/app-segment-config.js +12 -3
  114. package/dist/server/app-server-action-execution.d.ts +1 -0
  115. package/dist/server/app-server-action-execution.js +47 -15
  116. package/dist/server/app-ssr-entry.d.ts +2 -0
  117. package/dist/server/app-ssr-entry.js +84 -39
  118. package/dist/server/before-interactive-head.d.ts +17 -0
  119. package/dist/server/before-interactive-head.js +35 -0
  120. package/dist/server/cache-control.js +4 -0
  121. package/dist/server/csp.js +1 -4
  122. package/dist/server/dev-server.d.ts +2 -2
  123. package/dist/server/dev-server.js +321 -83
  124. package/dist/server/hybrid-route-priority.d.ts +22 -0
  125. package/dist/server/hybrid-route-priority.js +33 -0
  126. package/dist/server/image-optimization.d.ts +18 -9
  127. package/dist/server/image-optimization.js +37 -23
  128. package/dist/server/implicit-tags.d.ts +2 -1
  129. package/dist/server/implicit-tags.js +4 -1
  130. package/dist/server/middleware-matcher.js +12 -3
  131. package/dist/server/middleware-runtime.d.ts +3 -4
  132. package/dist/server/middleware-runtime.js +2 -0
  133. package/dist/server/navigation-planner.d.ts +135 -41
  134. package/dist/server/navigation-planner.js +138 -0
  135. package/dist/server/navigation-trace.d.ts +9 -1
  136. package/dist/server/navigation-trace.js +9 -1
  137. package/dist/server/operation-token.d.ts +40 -0
  138. package/dist/server/operation-token.js +85 -0
  139. package/dist/server/pages-api-route.d.ts +6 -0
  140. package/dist/server/pages-api-route.js +13 -2
  141. package/dist/server/pages-asset-tags.d.ts +2 -1
  142. package/dist/server/pages-asset-tags.js +6 -2
  143. package/dist/server/pages-data-route.d.ts +9 -2
  144. package/dist/server/pages-data-route.js +18 -6
  145. package/dist/server/pages-dev-module-url.d.ts +4 -0
  146. package/dist/server/pages-dev-module-url.js +15 -0
  147. package/dist/server/pages-document-initial-props.d.ts +4 -15
  148. package/dist/server/pages-document-initial-props.js +27 -56
  149. package/dist/server/pages-get-initial-props.d.ts +54 -4
  150. package/dist/server/pages-get-initial-props.js +43 -1
  151. package/dist/server/pages-i18n.js +2 -2
  152. package/dist/server/pages-node-compat.js +2 -2
  153. package/dist/server/pages-page-data.d.ts +11 -2
  154. package/dist/server/pages-page-data.js +207 -34
  155. package/dist/server/pages-page-handler.d.ts +4 -2
  156. package/dist/server/pages-page-handler.js +62 -23
  157. package/dist/server/pages-page-response.d.ts +4 -1
  158. package/dist/server/pages-page-response.js +11 -8
  159. package/dist/server/pages-readiness.js +1 -1
  160. package/dist/server/pages-request-pipeline.d.ts +8 -7
  161. package/dist/server/pages-request-pipeline.js +126 -47
  162. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  163. package/dist/server/pregenerated-concrete-paths.js +2 -19
  164. package/dist/server/prerender-manifest.d.ts +33 -0
  165. package/dist/server/prerender-manifest.js +54 -0
  166. package/dist/server/prerender-route-params.d.ts +1 -2
  167. package/dist/server/prod-server.d.ts +3 -1
  168. package/dist/server/prod-server.js +50 -13
  169. package/dist/server/request-pipeline.d.ts +3 -15
  170. package/dist/server/request-pipeline.js +58 -47
  171. package/dist/server/rsc-stream-hints.d.ts +5 -1
  172. package/dist/server/rsc-stream-hints.js +6 -1
  173. package/dist/server/seed-cache.js +10 -18
  174. package/dist/server/static-file-cache.js +16 -4
  175. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  176. package/dist/shims/app-router-scroll-state.js +14 -2
  177. package/dist/shims/app-router-scroll.d.ts +3 -0
  178. package/dist/shims/app-router-scroll.js +28 -18
  179. package/dist/shims/before-interactive-context.d.ts +14 -3
  180. package/dist/shims/cache-runtime.js +3 -2
  181. package/dist/shims/cache.d.ts +1 -0
  182. package/dist/shims/cache.js +1 -1
  183. package/dist/shims/cdn-cache.d.ts +5 -5
  184. package/dist/shims/document.d.ts +15 -20
  185. package/dist/shims/document.js +5 -8
  186. package/dist/shims/dynamic-preload-chunks.js +6 -4
  187. package/dist/shims/error-boundary.d.ts +2 -0
  188. package/dist/shims/error-boundary.js +7 -0
  189. package/dist/shims/error.js +3 -2
  190. package/dist/shims/error.react-server.d.ts +9 -0
  191. package/dist/shims/error.react-server.js +6 -0
  192. package/dist/shims/fetch-cache.d.ts +3 -1
  193. package/dist/shims/fetch-cache.js +45 -20
  194. package/dist/shims/hash-scroll.js +6 -1
  195. package/dist/shims/headers.js +29 -4
  196. package/dist/shims/image.js +9 -2
  197. package/dist/shims/internal/als-registry.js +28 -1
  198. package/dist/shims/internal/app-route-detection.js +8 -17
  199. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  200. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  201. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  202. package/dist/shims/internal/navigation-untracked.js +55 -0
  203. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  204. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  205. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  206. package/dist/shims/internal/pages-data-target.js +17 -8
  207. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  208. package/dist/shims/internal/pages-router-accessor.js +13 -0
  209. package/dist/shims/internal/router-context.d.ts +2 -1
  210. package/dist/shims/internal/router-context.js +3 -1
  211. package/dist/shims/link.js +47 -19
  212. package/dist/shims/metadata.js +4 -4
  213. package/dist/shims/navigation.d.ts +8 -2
  214. package/dist/shims/navigation.js +63 -31
  215. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  216. package/dist/shims/ppr-fallback-shell.js +28 -7
  217. package/dist/shims/router.d.ts +18 -3
  218. package/dist/shims/router.js +512 -142
  219. package/dist/shims/script.js +8 -4
  220. package/dist/shims/server.d.ts +16 -1
  221. package/dist/shims/server.js +44 -12
  222. package/dist/shims/unified-request-context.js +1 -0
  223. package/dist/utils/built-asset-url.d.ts +4 -0
  224. package/dist/utils/built-asset-url.js +11 -0
  225. package/dist/utils/commonjs-loader.d.ts +16 -0
  226. package/dist/utils/commonjs-loader.js +100 -0
  227. package/dist/utils/deployment-id.d.ts +8 -0
  228. package/dist/utils/deployment-id.js +22 -0
  229. package/dist/utils/has-trailing-comma.d.ts +24 -0
  230. package/dist/utils/has-trailing-comma.js +62 -0
  231. package/dist/utils/html-limited-bots.d.ts +18 -1
  232. package/dist/utils/html-limited-bots.js +23 -1
  233. package/dist/utils/parse-cookie.d.ts +13 -0
  234. package/dist/utils/parse-cookie.js +52 -0
  235. package/dist/utils/path.d.ts +7 -1
  236. package/dist/utils/path.js +9 -1
  237. package/dist/utils/text-stream.d.ts +1 -1
  238. package/dist/utils/text-stream.js +2 -2
  239. package/dist/utils/vite-version.d.ts +12 -1
  240. package/dist/utils/vite-version.js +9 -1
  241. package/package.json +2 -2
  242. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  243. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -5,8 +5,9 @@ import { fnv1a52 } from "../utils/hash.js";
5
5
  import { encodeCacheTag } from "../utils/encode-cache-tag.js";
6
6
  import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
7
7
  import { buildMissIsrCacheControl } from "./isr-decision.js";
8
+ import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
8
9
  import { withScriptNonce } from "../shims/script-nonce-context.js";
9
- import { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr } from "./html.js";
10
+ import { createNonceAttribute, escapeHtmlAttr } from "./html.js";
10
11
  import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
11
12
  import { readStreamAsText } from "../utils/text-stream.js";
12
13
  import { loadUserDocumentInitialProps, runDocumentRenderPage } from "./pages-document-initial-props.js";
@@ -62,14 +63,14 @@ function requestsNoCache(cacheControl) {
62
63
  function buildPagesFontHeadHtml(fontLinks, fontPreloads, fontStyles, scriptNonce) {
63
64
  let html = "";
64
65
  const nonceAttr = createNonceAttribute(scriptNonce);
65
- for (const link of fontLinks) html += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(link)}" />\n `;
66
- for (const preload of fontPreloads) html += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(preload.href)}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n `;
66
+ for (const link of fontLinks) html += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(link))}" />\n `;
67
+ for (const preload of fontPreloads) html += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(preload.href))}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n `;
67
68
  if (fontStyles.length > 0) html += `<style data-vinext-fonts${nonceAttr}>${fontStyles.join("\n")}</style>\n `;
68
69
  return html;
69
70
  }
70
71
  function buildPagesNextDataScript(options) {
71
72
  const nextDataPayload = {
72
- props: { pageProps: options.pageProps },
73
+ props: options.props ?? { pageProps: options.pageProps },
73
74
  page: options.routePattern,
74
75
  query: options.params,
75
76
  buildId: options.buildId,
@@ -88,8 +89,7 @@ function buildPagesNextDataScript(options) {
88
89
  ...options.nextData?.__vinext,
89
90
  ...options.vinext
90
91
  };
91
- 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)}` : "";
92
- return createInlineScriptTag(`window.__NEXT_DATA__ = ${options.safeJsonStringify(nextDataPayload)}${localeGlobals}`, options.scriptNonce);
92
+ return `<script id="__NEXT_DATA__" type="application/json"${createNonceAttribute(options.scriptNonce)}>${options.safeJsonStringify(nextDataPayload)}<\/script>`;
93
93
  }
94
94
  async function buildPagesShellHtml(bodyMarker, fontHeadHTML, nextDataScript, options) {
95
95
  if (options.DocumentComponent) {
@@ -171,6 +171,7 @@ function applyGsspHeaders(headers, gsspRes, statusCode) {
171
171
  return statusCode ?? gsspRes.statusCode;
172
172
  }
173
173
  async function renderPagesPageResponse(options) {
174
+ const renderProps = options.props ?? { pageProps: options.pageProps };
174
175
  options.resetSSRHead?.();
175
176
  await options.flushPreloads?.();
176
177
  const fontHeadHTML = buildPagesFontHeadHtml(options.getFontLinks(), options.fontPreloads, options.getFontStyles(), options.scriptNonce);
@@ -179,6 +180,7 @@ async function renderPagesPageResponse(options) {
179
180
  i18n: options.i18n,
180
181
  isFallback: options.isFallback,
181
182
  pageProps: options.pageProps,
183
+ props: renderProps,
182
184
  params: options.params,
183
185
  routePattern: options.routePattern,
184
186
  safeJsonStringify: options.safeJsonStringify,
@@ -194,8 +196,9 @@ async function renderPagesPageResponse(options) {
194
196
  renderStylesToString: async (element) => readStreamAsText(await options.renderToReadableStream(element)),
195
197
  scriptNonce: options.scriptNonce,
196
198
  context: {
199
+ err: options.err,
197
200
  pathname: options.routePattern,
198
- query: options.params,
201
+ query: options.query ?? options.params,
199
202
  asPath: options.routeUrl
200
203
  }
201
204
  });
@@ -205,7 +208,7 @@ async function renderPagesPageResponse(options) {
205
208
  controller.close();
206
209
  } });
207
210
  else {
208
- const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(options.pageProps)), options.scriptNonce);
211
+ const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(renderProps)), options.scriptNonce);
209
212
  bodyStream = await options.renderToReadableStream(pageElement);
210
213
  }
211
214
  if (documentRenderPage.status === "skipped") await callDocumentGetInitialProps(options.DocumentComponent, options.setDocumentInitialHead);
@@ -10,7 +10,7 @@ function buildPagesReadinessNextData(options) {
10
10
  const hasAppGip = typeof options.appComponent?.getInitialProps === "function";
11
11
  return {
12
12
  gssp: hasPageGssp,
13
- gsp: hasPageGsp,
13
+ gsp: hasPageGsp ? true : void 0,
14
14
  gip: hasPageGip,
15
15
  appGip: hasAppGip,
16
16
  autoExport: !hasPageGssp && !hasPageGsp && !hasPageGip && !hasAppGip,
@@ -5,7 +5,10 @@ import { HeaderRecord } from "./request-pipeline.js";
5
5
  type PagesRenderOptions = {
6
6
  isDataReq?: boolean;
7
7
  renderErrorPageOnMiss?: boolean;
8
+ originalUrl?: string;
8
9
  };
10
+ type FilesystemRoutePhase = "direct" | "beforeFiles" | "afterFiles" | "fallback";
11
+ declare function fetchWorkerFilesystemRoute(request: Request, requestPathname: string, phase: FilesystemRoutePhase, fetchAsset: (request: Request) => Promise<Response>): Promise<Response | false>;
9
12
  type MiddlewareResult = {
10
13
  continue: boolean;
11
14
  redirectUrl?: string;
@@ -52,15 +55,13 @@ type PagesPipelineDeps = {
52
55
  */
53
56
  proxyExternal?: ((currentRequest: Request, externalUrl: string) => Promise<Response>) | null;
54
57
  /**
55
- * Optional public-directory static file server (Node prod only).
58
+ * Optional filesystem/static-asset probe supplied by each runtime adapter.
56
59
  * Called post-middleware (so middleware can intercept/redirect public files) with the
57
60
  * original basePath-stripped pathname and the staged middleware response headers.
58
- * The callback writes the file to its own output (Node `res`) and resolves `true` when
59
- * it served the request; the pipeline then returns `{ type: "handled" }`. Resolves `false`
60
- * to fall through to rewrites/render. Worker/dev adapters omit this — their public files
61
- * are served by the asset binding / Vite respectively.
61
+ * Node may write directly to `res` and return true; dev/Workers return a Response.
62
+ * Resolves false to continue through rewrites, API routes, and page rendering.
62
63
  */
63
- serveStaticFile?: ((requestPathname: string, stagedHeaders: HeaderRecord) => Promise<boolean>) | null;
64
+ serveFilesystemRoute?: ((requestPathname: string, stagedHeaders: HeaderRecord, phase: FilesystemRoutePhase) => Promise<boolean | Response>) | null;
64
65
  };
65
66
  /**
66
67
  * Wrap an adapter's `runMiddleware` callback so middleware receives the original
@@ -110,4 +111,4 @@ type PagesPipelineResult = {
110
111
  */
111
112
  declare function runPagesRequest(request: Request, deps: PagesPipelineDeps): Promise<PagesPipelineResult>;
112
113
  //#endregion
113
- export { MiddlewareResult, PagesPipelineDeps, PagesPipelineResult, PagesRenderOptions, runPagesRequest, wrapMiddlewareWithBasePath };
114
+ export { FilesystemRoutePhase, MiddlewareResult, PagesPipelineDeps, PagesPipelineResult, PagesRenderOptions, fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath };
@@ -1,10 +1,18 @@
1
1
  import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
2
2
  import { applyMiddlewareRequestHeaders, isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
3
- import { applyConfigHeadersToHeaderRecord, normalizeTrailingSlash } from "./request-pipeline.js";
3
+ import { applyConfigHeadersToHeaderRecord, cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
4
4
  import { mergeRewriteQuery } from "../utils/query.js";
5
5
  import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
6
6
  import { mergeHeaders } from "./worker-utils.js";
7
7
  //#region src/server/pages-request-pipeline.ts
8
+ async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset) {
9
+ if (phase === "direct" || request.method !== "GET" && request.method !== "HEAD" || requestPathname === "/api" || requestPathname.startsWith("/api/")) return false;
10
+ const assetUrl = new URL(request.url);
11
+ assetUrl.pathname = requestPathname;
12
+ assetUrl.search = "";
13
+ const response = await fetchAsset(new Request(assetUrl, request));
14
+ return response.status === 404 ? false : response;
15
+ }
8
16
  /**
9
17
  * Wrap an adapter's `runMiddleware` callback so middleware receives the original
10
18
  * (pre-basePath-stripping) URL. Adapters strip the basePath before handing the
@@ -68,9 +76,19 @@ async function runPagesRequest(request, deps) {
68
76
  };
69
77
  }
70
78
  }
71
- let resolvedUrl = pathname + search;
79
+ const originalResolvedUrl = pathname + search;
80
+ let resolvedUrl = originalResolvedUrl;
72
81
  const middlewareHeaders = {};
73
82
  let middlewareStatus;
83
+ const serveFilesystemRoute = async (requestPathname, phase) => {
84
+ if (!deps.serveFilesystemRoute) return null;
85
+ const served = await deps.serveFilesystemRoute(requestPathname, middlewareHeaders, phase);
86
+ if (served instanceof Response) return {
87
+ type: "response",
88
+ response: mergeHeaders(served, middlewareHeaders, middlewareStatus)
89
+ };
90
+ return served ? { type: "handled" } : null;
91
+ };
74
92
  if (typeof deps.runMiddleware === "function") {
75
93
  const result = await deps.runMiddleware(request, deps.ctx ?? null, { isDataRequest });
76
94
  if (result.waitUntilPromises && result.waitUntilPromises.length > 0) {
@@ -114,7 +132,12 @@ async function runPagesRequest(request, deps) {
114
132
  }
115
133
  const { postMwReqCtx, request: postMwReq } = applyMiddlewareRequestHeaders(middlewareHeaders, request, { preserveCredentialHeaders: isExternalUrl(resolvedUrl) });
116
134
  request = postMwReq;
117
- let resolvedPathname = resolvedUrl.split("?")[0];
135
+ const pathnameForResolvedUrl = (value) => value.split("#", 1)[0].split("?", 1)[0];
136
+ const rewriteRequestContext = () => ({
137
+ ...postMwReqCtx,
138
+ query: new URL(resolvedUrl, url).searchParams
139
+ });
140
+ let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
118
141
  const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
119
142
  if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
120
143
  configHeaders,
@@ -126,22 +149,25 @@ async function runPagesRequest(request, deps) {
126
149
  type: "response",
127
150
  response: mergeHeaders(await proxyExternal(request, resolvedUrl), middlewareHeaders, void 0)
128
151
  };
129
- if (deps.serveStaticFile) {
130
- if (await deps.serveStaticFile(pathname, middlewareHeaders)) return { type: "handled" };
131
- }
152
+ const directFilesystemResult = await serveFilesystemRoute(pathname, "direct");
153
+ if (directFilesystemResult) return directFilesystemResult;
132
154
  let configRewriteFired = false;
133
- if (configRewrites.beforeFiles?.length) {
134
- const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), configRewrites.beforeFiles, postMwReqCtx, basePathState);
155
+ for (const rewrite of configRewrites.beforeFiles ?? []) {
156
+ const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
135
157
  if (rewritten) {
136
158
  if (isExternalUrl(rewritten)) return {
137
159
  type: "response",
138
160
  response: await proxyExternal(request, rewritten)
139
161
  };
140
162
  resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
141
- resolvedPathname = resolvedUrl.split("?")[0];
163
+ resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
142
164
  configRewriteFired = true;
143
165
  }
144
166
  }
167
+ if (configRewriteFired) {
168
+ const beforeFilesResult = await serveFilesystemRoute(resolvedPathname, "beforeFiles");
169
+ if (beforeFilesResult) return beforeFilesResult;
170
+ }
145
171
  if (basePath && !hadBasePath && !configRewriteFired) return {
146
172
  type: "response",
147
173
  response: new Response("This page could not be found", {
@@ -149,36 +175,77 @@ async function runPagesRequest(request, deps) {
149
175
  headers: { "Content-Type": "text/html; charset=utf-8" }
150
176
  })
151
177
  };
152
- const apiLookupUrl = stripI18nLocaleForApiRoute(resolvedUrl, i18nConfig);
153
- const apiLookupPathname = apiLookupUrl.split("?")[0];
154
- if (apiLookupPathname.startsWith("/api/") || apiLookupPathname === "/api") if (typeof deps.handleApi === "function") return {
155
- type: "response",
156
- defaultContentType: "application/octet-stream",
157
- response: mergeHeaders(await deps.handleApi(request, apiLookupUrl, deps.ctx ?? null), middlewareHeaders, middlewareStatus)
158
- };
159
- else return {
160
- type: "api",
161
- apiUrl: apiLookupUrl,
162
- stagedHeaders: middlewareHeaders,
163
- requestHeaders: request.headers,
164
- middlewareStatus
178
+ const handleResolvedApiRoute = async () => {
179
+ const apiLookupUrl = stripI18nLocaleForApiRoute(resolvedUrl, i18nConfig);
180
+ const apiLookupPathname = apiLookupUrl.split("?")[0];
181
+ if (!apiLookupPathname.startsWith("/api/") && apiLookupPathname !== "/api") return null;
182
+ if (typeof deps.handleApi === "function") {
183
+ let apiRequest = request;
184
+ if (basePath && hadBasePath) {
185
+ const apiRequestUrl = new URL(request.url);
186
+ apiRequestUrl.pathname = addBasePathToPathname(apiRequestUrl.pathname, basePath);
187
+ apiRequest = cloneRequestWithUrl(request, apiRequestUrl.toString());
188
+ }
189
+ return {
190
+ type: "response",
191
+ defaultContentType: "application/octet-stream",
192
+ response: mergeHeaders(await deps.handleApi(apiRequest, apiLookupUrl, deps.ctx ?? null), middlewareHeaders, middlewareStatus)
193
+ };
194
+ }
195
+ return {
196
+ type: "api",
197
+ apiUrl: apiLookupUrl,
198
+ stagedHeaders: middlewareHeaders,
199
+ requestHeaders: request.headers,
200
+ middlewareStatus
201
+ };
165
202
  };
166
- const pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
203
+ const apiResult = await handleResolvedApiRoute();
204
+ if (apiResult) return apiResult;
205
+ let pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
167
206
  let resolvedPathnameChanged = false;
168
- if ((!pageMatch || pageMatch.route.isDynamic) && configRewrites.afterFiles?.length) {
169
- const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), configRewrites.afterFiles, postMwReqCtx, basePathState);
207
+ if (!pageMatch || pageMatch.route.isDynamic) for (const rewrite of configRewrites.afterFiles ?? []) {
208
+ const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
170
209
  if (rewritten) {
171
210
  if (isExternalUrl(rewritten)) return {
172
211
  type: "response",
173
212
  response: await proxyExternal(request, rewritten)
174
213
  };
175
214
  resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
176
- resolvedPathname = resolvedUrl.split("?")[0];
215
+ resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
177
216
  resolvedPathnameChanged = true;
217
+ const afterFilesFilesystemResult = await serveFilesystemRoute(resolvedPathname, "afterFiles");
218
+ if (afterFilesFilesystemResult) return afterFilesFilesystemResult;
219
+ const afterFilesApiResult = await handleResolvedApiRoute();
220
+ if (afterFilesApiResult) return afterFilesApiResult;
221
+ pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
222
+ if (pageMatch) break;
178
223
  }
179
224
  }
225
+ const refreshDataRewriteHeader = () => {
226
+ if ((isDataReq || isDataRequest) && resolvedUrl !== originalResolvedUrl && !isExternalUrl(resolvedUrl)) middlewareHeaders["x-nextjs-rewrite"] = resolvedUrl;
227
+ else delete middlewareHeaders["x-nextjs-rewrite"];
228
+ };
229
+ refreshDataRewriteHeader();
180
230
  if (typeof deps.renderPage === "function") {
181
- const renderPageMatch = resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch;
231
+ let renderPageMatch = pageMatch;
232
+ if ((isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
233
+ const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
234
+ if (!fallbackRewrite) continue;
235
+ if (isExternalUrl(fallbackRewrite)) return {
236
+ type: "response",
237
+ response: await proxyExternal(request, fallbackRewrite)
238
+ };
239
+ resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
240
+ resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
241
+ const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
242
+ if (fallbackFilesystemResult) return fallbackFilesystemResult;
243
+ const fallbackApiResult = await handleResolvedApiRoute();
244
+ if (fallbackApiResult) return fallbackApiResult;
245
+ renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
246
+ refreshDataRewriteHeader();
247
+ if (renderPageMatch) break;
248
+ }
182
249
  const shouldDeferErrorPageOnMiss = !isDataReq && !isDataRequest && !!deps.matchPageRoute && !renderPageMatch;
183
250
  const initialRenderOptions = shouldDeferErrorPageOnMiss ? { renderErrorPageOnMiss: false } : isDataReq ? { isDataReq: true } : void 0;
184
251
  const stagedHeaders = new Headers();
@@ -186,16 +253,22 @@ async function runPagesRequest(request, deps) {
186
253
  else stagedHeaders.set(k, v);
187
254
  let response = await deps.renderPage(request, resolvedUrl, initialRenderOptions, stagedHeaders);
188
255
  let matchedFallbackRewrite = false;
189
- if (response.status === 404 && shouldDeferErrorPageOnMiss && configRewrites.fallback?.length) {
190
- const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), configRewrites.fallback, postMwReqCtx, basePathState);
191
- if (fallbackRewrite) {
192
- if (isExternalUrl(fallbackRewrite)) return {
193
- type: "response",
194
- response: await proxyExternal(request, fallbackRewrite)
195
- };
196
- response = await deps.renderPage(request, mergeRewriteQuery(resolvedUrl, fallbackRewrite), void 0, stagedHeaders);
197
- matchedFallbackRewrite = true;
198
- }
256
+ if (response.status === 404 && shouldDeferErrorPageOnMiss && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
257
+ const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
258
+ if (!fallbackRewrite) continue;
259
+ if (isExternalUrl(fallbackRewrite)) return {
260
+ type: "response",
261
+ response: await proxyExternal(request, fallbackRewrite)
262
+ };
263
+ resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
264
+ resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
265
+ const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
266
+ if (fallbackFilesystemResult) return fallbackFilesystemResult;
267
+ const fallbackApiResult = await handleResolvedApiRoute();
268
+ if (fallbackApiResult) return fallbackApiResult;
269
+ response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
270
+ matchedFallbackRewrite = true;
271
+ if (response.status !== 404) break;
199
272
  }
200
273
  if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
201
274
  const merged = mergeHeaders(response, middlewareHeaders, middlewareStatus);
@@ -206,16 +279,22 @@ async function runPagesRequest(request, deps) {
206
279
  defaultContentType: "text/html"
207
280
  };
208
281
  }
209
- if (!(resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch) && configRewrites.fallback?.length) {
210
- const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), configRewrites.fallback, postMwReqCtx, basePathState);
211
- if (fallbackRewrite) {
212
- if (isExternalUrl(fallbackRewrite)) return {
213
- type: "response",
214
- response: await proxyExternal(request, fallbackRewrite)
215
- };
216
- resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
217
- }
282
+ if (!(resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch) && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
283
+ const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
284
+ if (!fallbackRewrite) continue;
285
+ if (isExternalUrl(fallbackRewrite)) return {
286
+ type: "response",
287
+ response: await proxyExternal(request, fallbackRewrite)
288
+ };
289
+ resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
290
+ resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
291
+ const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
292
+ if (fallbackFilesystemResult) return fallbackFilesystemResult;
293
+ const fallbackApiResult = await handleResolvedApiRoute();
294
+ if (fallbackApiResult) return fallbackApiResult;
295
+ if (deps.matchPageRoute?.(resolvedPathname, request)) break;
218
296
  }
297
+ refreshDataRewriteHeader();
219
298
  return {
220
299
  type: "render",
221
300
  resolvedUrl,
@@ -227,4 +306,4 @@ async function runPagesRequest(request, deps) {
227
306
  };
228
307
  }
229
308
  //#endregion
230
- export { runPagesRequest, wrapMiddlewareWithBasePath };
309
+ export { fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath };
@@ -4,28 +4,12 @@ declare global {
4
4
  }
5
5
  declare function normalizePregeneratedPathname(pathname: string): string;
6
6
  declare function clearPregeneratedConcretePaths(): void;
7
- /**
8
- * Records a concrete URL path for a route pattern. The pathname is normalized
9
- * here so this is the single source of truth: every caller — the Worker global
10
- * table and the Node `seed-cache.ts` path — stores the canonical form that
11
- * matches the runtime `cleanPathname` lookup without having to pre-normalize.
12
- */
13
7
  declare function addPregeneratedConcretePath(routePattern: string, pathname: string): void;
14
- /**
15
- * Returns the live backing `Set` for a route pattern (not a copy) to keep
16
- * lookups allocation-free on the serving hot path. The `ReadonlySet` type
17
- * forbids mutation at compile time. Callers must treat the result as
18
- * point-in-time and must NOT retain it across a re-seed: each
19
- * `initPregeneratedPathsFromGlobals` call runs `clearPregeneratedConcretePaths`,
20
- * which empties the map, leaving any previously-returned reference stale. Read
21
- * it, use it, drop it — never cache the reference.
22
- */
23
8
  declare function getRenderedConcreteUrlPathsForRoute(routePattern: string): ReadonlySet<string> | undefined;
24
9
  /**
25
10
  * Populate the registry from `globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS`.
26
11
  * No-op when the global is not set (Node path — seed-cache handles it later).
27
- * `addPregeneratedConcretePath` normalizes each pathname so it matches the
28
- * runtime `cleanPathname`.
12
+ * Pathnames are normalised so they match the runtime `cleanPathname`.
29
13
  */
30
14
  declare function initPregeneratedPathsFromGlobals(): void;
31
15
  //#endregion
@@ -16,38 +16,21 @@ const concreteUrlPathsByRoute = /* @__PURE__ */ new Map();
16
16
  function clearPregeneratedConcretePaths() {
17
17
  concreteUrlPathsByRoute.clear();
18
18
  }
19
- /**
20
- * Records a concrete URL path for a route pattern. The pathname is normalized
21
- * here so this is the single source of truth: every caller — the Worker global
22
- * table and the Node `seed-cache.ts` path — stores the canonical form that
23
- * matches the runtime `cleanPathname` lookup without having to pre-normalize.
24
- */
25
19
  function addPregeneratedConcretePath(routePattern, pathname) {
26
- const normalized = normalizePregeneratedPathname(pathname);
27
20
  let paths = concreteUrlPathsByRoute.get(routePattern);
28
21
  if (!paths) {
29
22
  paths = /* @__PURE__ */ new Set();
30
23
  concreteUrlPathsByRoute.set(routePattern, paths);
31
24
  }
32
- paths.add(normalized);
25
+ paths.add(normalizePregeneratedPathname(pathname));
33
26
  }
34
- /**
35
- * Returns the live backing `Set` for a route pattern (not a copy) to keep
36
- * lookups allocation-free on the serving hot path. The `ReadonlySet` type
37
- * forbids mutation at compile time. Callers must treat the result as
38
- * point-in-time and must NOT retain it across a re-seed: each
39
- * `initPregeneratedPathsFromGlobals` call runs `clearPregeneratedConcretePaths`,
40
- * which empties the map, leaving any previously-returned reference stale. Read
41
- * it, use it, drop it — never cache the reference.
42
- */
43
27
  function getRenderedConcreteUrlPathsForRoute(routePattern) {
44
28
  return concreteUrlPathsByRoute.get(routePattern);
45
29
  }
46
30
  /**
47
31
  * Populate the registry from `globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS`.
48
32
  * No-op when the global is not set (Node path — seed-cache handles it later).
49
- * `addPregeneratedConcretePath` normalizes each pathname so it matches the
50
- * runtime `cleanPathname`.
33
+ * Pathnames are normalised so they match the runtime `cleanPathname`.
51
34
  */
52
35
  function initPregeneratedPathsFromGlobals() {
53
36
  const raw = globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS;
@@ -0,0 +1,33 @@
1
+ //#region src/server/prerender-manifest.d.ts
2
+ type PrerenderManifestRoute = {
3
+ route: string;
4
+ status?: string;
5
+ revalidate?: number | false;
6
+ expire?: number;
7
+ path?: string;
8
+ router?: string;
9
+ fallback?: boolean;
10
+ };
11
+ type PrerenderManifest = {
12
+ buildId?: string;
13
+ trailingSlash?: boolean;
14
+ routes?: PrerenderManifestRoute[];
15
+ };
16
+ declare function readPrerenderManifest(manifestPath: string): PrerenderManifest | null;
17
+ declare function getRenderedAppRoutes(routes: PrerenderManifestRoute[]): PrerenderManifestRoute[];
18
+ /**
19
+ * Returns true when `pathname` contains bracket-delimited route params,
20
+ * indicating it is a fallback-shell placeholder (e.g. `/en/blog/[slug]`)
21
+ * rather than a concrete rendered URL.
22
+ */
23
+ declare function isFallbackShellArtifactPath(pathname: string, route?: PrerenderManifestRoute): boolean;
24
+ /**
25
+ * Build the pregenerated concrete-path payload table from a prerender manifest.
26
+ *
27
+ * Filters out fallback-shell placeholder paths and groups remaining concrete
28
+ * paths by route pattern. Returns an empty array when the manifest has no
29
+ * rendered App routes or all routes are fallback-shell artifacts.
30
+ */
31
+ declare function buildPregeneratedConcretePathTable(manifest: PrerenderManifest): Array<[string, string[]]>;
32
+ //#endregion
33
+ export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
@@ -0,0 +1,54 @@
1
+ import fs from "node:fs";
2
+ //#region src/server/prerender-manifest.ts
3
+ function readPrerenderManifest(manifestPath) {
4
+ if (!fs.existsSync(manifestPath)) return null;
5
+ try {
6
+ return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
7
+ } catch (error) {
8
+ console.warn(`[vinext] Failed to read prerender manifest at ${manifestPath}:`, error);
9
+ return null;
10
+ }
11
+ }
12
+ function getRenderedAppRoutes(routes) {
13
+ return routes.filter((r) => r.status === "rendered" && r.router === "app");
14
+ }
15
+ function groupRoutesByPattern(routes) {
16
+ const byPattern = /* @__PURE__ */ new Map();
17
+ for (const r of routes) {
18
+ const pathname = r.path ?? r.route;
19
+ const existing = byPattern.get(r.route);
20
+ if (existing) existing.push(pathname);
21
+ else byPattern.set(r.route, [pathname]);
22
+ }
23
+ return byPattern;
24
+ }
25
+ /**
26
+ * Returns true when `pathname` contains bracket-delimited route params,
27
+ * indicating it is a fallback-shell placeholder (e.g. `/en/blog/[slug]`)
28
+ * rather than a concrete rendered URL.
29
+ */
30
+ function isFallbackShellArtifactPath(pathname, route) {
31
+ if (route?.fallback === true) return true;
32
+ if (route?.fallback === void 0) {
33
+ if (process.env.NODE_ENV !== "production") console.warn("[vinext] Legacy manifest detected: missing `fallback` flag for route. Using bracket heuristic for fallback-shell detection. A concrete URL containing literal brackets may be misclassified as a fallback shell.");
34
+ return pathname.includes("[") || pathname.includes("]");
35
+ }
36
+ return false;
37
+ }
38
+ /**
39
+ * Build the pregenerated concrete-path payload table from a prerender manifest.
40
+ *
41
+ * Filters out fallback-shell placeholder paths and groups remaining concrete
42
+ * paths by route pattern. Returns an empty array when the manifest has no
43
+ * rendered App routes or all routes are fallback-shell artifacts.
44
+ */
45
+ function buildPregeneratedConcretePathTable(manifest) {
46
+ const routes = manifest?.routes;
47
+ if (!routes?.length) return [];
48
+ const concreteRoutes = getRenderedAppRoutes(routes).filter((r) => {
49
+ return !isFallbackShellArtifactPath(r.path ?? r.route, r);
50
+ });
51
+ return Array.from(groupRoutesByPattern(concreteRoutes).entries());
52
+ }
53
+ //#endregion
54
+ export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
@@ -5,7 +5,6 @@ type PrerenderRouteParamsPayload = {
5
5
  params: PrerenderRouteParams;
6
6
  routePattern: string;
7
7
  };
8
- /** @public exported for #1716 serving consumers; not yet referenced in-repo */
9
8
  type PrerenderRouteParamsRouteMatch = {
10
9
  kind: "exact";
11
10
  params: PrerenderRouteParams;
@@ -21,4 +20,4 @@ declare function prerenderRouteParamsPayloadMatchesRoute(payload: PrerenderRoute
21
20
  declare function matchPrerenderRouteParamsPayload(payload: PrerenderRouteParamsPayload | null, routePattern: string, params: PrerenderRouteParams): PrerenderRouteParamsRouteMatch | null;
22
21
  declare function encodePrerenderRouteParams(pattern: string, params: PrerenderRouteParams, fallbackParamNames?: readonly string[]): PrerenderRouteParamsPayload | null;
23
22
  //#endregion
24
- export { PrerenderRouteParams, PrerenderRouteParamsPayload, PrerenderRouteParamsRouteMatch, encodePrerenderRouteParams, matchPrerenderRouteParamsPayload, prerenderRouteParamsPayloadMatchesRoute, readTrustedPrerenderRouteParams, readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader };
23
+ export { PrerenderRouteParams, PrerenderRouteParamsPayload, encodePrerenderRouteParams, matchPrerenderRouteParamsPayload, prerenderRouteParamsPayloadMatchesRoute, readTrustedPrerenderRouteParams, readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader };
@@ -41,6 +41,8 @@ import { IncomingMessage, ServerResponse } from "node:http";
41
41
  */
42
42
  declare function resolveServerEntryImportUrl(entryPath: string): string;
43
43
  declare function importServerEntryModule(entryPath: string): Promise<any>;
44
+ /** Convert a Node.js IncomingMessage into a ReadableStream for Web Request body. */
45
+ declare function readNodeStream(req: IncomingMessage): ReadableStream<Uint8Array>;
44
46
  type ProdServerOptions = {
45
47
  /** Port to listen on */port?: number; /** Host to bind to */
46
48
  host?: string; /** Path to the build output directory */
@@ -143,4 +145,4 @@ declare function resolveAppRouterPrerenderSeeder(entryModule: unknown): AppRoute
143
145
  */
144
146
  declare function resolveAppRouterAssetPath(pathname: string, assetPathPrefix: string, assetPrefix: string): string | null;
145
147
  //#endregion
146
- export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
148
+ export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };