vinext 0.1.7 → 0.2.0

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 (279) hide show
  1. package/README.md +51 -30
  2. package/dist/build/inject-pregenerated-paths.d.ts +4 -0
  3. package/dist/build/inject-pregenerated-paths.js +18 -0
  4. package/dist/build/layout-classification.js +1 -1
  5. package/dist/build/nitro-route-rules.js +1 -1
  6. package/dist/build/pages-client-assets-module.d.ts +11 -0
  7. package/dist/build/pages-client-assets-module.js +27 -0
  8. package/dist/build/prerender.d.ts +2 -1
  9. package/dist/build/prerender.js +13 -6
  10. package/dist/build/report.d.ts +13 -2
  11. package/dist/build/report.js +99 -2
  12. package/dist/build/run-prerender.d.ts +7 -0
  13. package/dist/build/run-prerender.js +10 -1
  14. package/dist/build/standalone.js +2 -0
  15. package/dist/cache/cache-adapters-virtual.js +3 -3
  16. package/dist/check.d.ts +18 -0
  17. package/dist/check.js +77 -19
  18. package/dist/cli-args.d.ts +1 -2
  19. package/dist/cli-args.js +1 -1
  20. package/dist/cli-dev-config.d.ts +12 -0
  21. package/dist/cli-dev-config.js +23 -0
  22. package/dist/cli.js +113 -97
  23. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  24. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  25. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  26. package/dist/{server → client}/dev-error-overlay.js +2 -2
  27. package/dist/client/navigation-runtime.d.ts +2 -0
  28. package/dist/client/navigation-runtime.js +3 -1
  29. package/dist/client/window-next.d.ts +2 -1
  30. package/dist/cloudflare/index.d.ts +2 -2
  31. package/dist/cloudflare/index.js +2 -2
  32. package/dist/config/config-matchers.js +14 -10
  33. package/dist/config/next-config.d.ts +6 -3
  34. package/dist/config/next-config.js +47 -1
  35. package/dist/config/prerender.d.ts +34 -0
  36. package/dist/config/prerender.js +55 -0
  37. package/dist/config/server-external-packages.d.ts +4 -0
  38. package/dist/config/server-external-packages.js +91 -0
  39. package/dist/entries/app-rsc-entry.d.ts +2 -1
  40. package/dist/entries/app-rsc-entry.js +89 -15
  41. package/dist/entries/app-rsc-manifest.js +10 -0
  42. package/dist/entries/pages-client-entry.d.ts +3 -0
  43. package/dist/entries/pages-client-entry.js +16 -1
  44. package/dist/entries/pages-server-entry.js +6 -2
  45. package/dist/image/image-adapters-virtual.d.ts +59 -0
  46. package/dist/image/image-adapters-virtual.js +59 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.js +211 -118
  49. package/dist/init-cloudflare.d.ts +43 -0
  50. package/dist/init-cloudflare.js +839 -0
  51. package/dist/init-platform.d.ts +40 -0
  52. package/dist/init-platform.js +195 -0
  53. package/dist/init.d.ts +16 -38
  54. package/dist/init.js +208 -97
  55. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  56. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  57. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  58. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  59. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
  60. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  61. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  62. package/dist/packages/cloudflare/src/deploy.js +276 -0
  63. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  64. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
  65. package/dist/plugins/ast-scope.d.ts +16 -0
  66. package/dist/plugins/ast-scope.js +62 -0
  67. package/dist/plugins/ast-utils.d.ts +27 -1
  68. package/dist/plugins/ast-utils.js +32 -1
  69. package/dist/plugins/css-module-imports.d.ts +14 -0
  70. package/dist/plugins/css-module-imports.js +59 -0
  71. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  72. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  73. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  74. package/dist/plugins/middleware-server-only.d.ts +8 -6
  75. package/dist/plugins/middleware-server-only.js +8 -7
  76. package/dist/plugins/optimize-imports.js +1 -1
  77. package/dist/plugins/typeof-window.d.ts +1 -1
  78. package/dist/plugins/typeof-window.js +28 -56
  79. package/dist/routing/app-route-graph.d.ts +29 -4
  80. package/dist/routing/app-route-graph.js +182 -40
  81. package/dist/routing/app-router.d.ts +5 -0
  82. package/dist/routing/app-router.js +5 -0
  83. package/dist/routing/file-matcher.d.ts +8 -0
  84. package/dist/routing/file-matcher.js +10 -1
  85. package/dist/routing/pages-router.js +2 -2
  86. package/dist/server/api-handler.js +9 -14
  87. package/dist/server/app-browser-action-result.d.ts +4 -1
  88. package/dist/server/app-browser-action-result.js +8 -1
  89. package/dist/server/app-browser-entry.js +194 -190
  90. package/dist/server/app-browser-history-controller.d.ts +2 -1
  91. package/dist/server/app-browser-history-controller.js +6 -2
  92. package/dist/server/app-browser-interception-context.d.ts +1 -0
  93. package/dist/server/app-browser-interception-context.js +4 -2
  94. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  95. package/dist/server/app-browser-navigation-controller.js +60 -31
  96. package/dist/server/app-browser-server-action-client.d.ts +32 -0
  97. package/dist/server/app-browser-server-action-client.js +127 -0
  98. package/dist/server/app-browser-state.d.ts +11 -1
  99. package/dist/server/app-browser-state.js +25 -8
  100. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  101. package/dist/server/app-browser-visible-commit.js +43 -25
  102. package/dist/server/app-elements-wire.d.ts +9 -2
  103. package/dist/server/app-elements-wire.js +8 -1
  104. package/dist/server/app-elements.d.ts +2 -2
  105. package/dist/server/app-elements.js +4 -3
  106. package/dist/server/app-fallback-renderer.d.ts +5 -2
  107. package/dist/server/app-fallback-renderer.js +15 -7
  108. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  109. package/dist/server/app-hydration-cache-publication.js +43 -0
  110. package/dist/server/app-middleware.d.ts +4 -3
  111. package/dist/server/app-middleware.js +8 -3
  112. package/dist/server/app-optimistic-routing.js +11 -4
  113. package/dist/server/app-page-boundary-render.d.ts +3 -0
  114. package/dist/server/app-page-boundary-render.js +14 -3
  115. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  116. package/dist/server/app-page-cache-finalizer.js +10 -3
  117. package/dist/server/app-page-cache-render.d.ts +1 -0
  118. package/dist/server/app-page-cache-render.js +8 -4
  119. package/dist/server/app-page-cache.d.ts +1 -0
  120. package/dist/server/app-page-cache.js +5 -2
  121. package/dist/server/app-page-dispatch.d.ts +33 -4
  122. package/dist/server/app-page-dispatch.js +63 -90
  123. package/dist/server/app-page-element-builder.d.ts +9 -2
  124. package/dist/server/app-page-element-builder.js +114 -23
  125. package/dist/server/app-page-head.d.ts +16 -1
  126. package/dist/server/app-page-head.js +44 -22
  127. package/dist/server/app-page-params.d.ts +2 -1
  128. package/dist/server/app-page-params.js +8 -1
  129. package/dist/server/app-page-ppr-runtime.d.ts +7 -0
  130. package/dist/server/app-page-ppr-runtime.js +70 -0
  131. package/dist/server/app-page-probe.d.ts +1 -0
  132. package/dist/server/app-page-probe.js +6 -1
  133. package/dist/server/app-page-render-identity.d.ts +1 -0
  134. package/dist/server/app-page-render-identity.js +1 -1
  135. package/dist/server/app-page-render.d.ts +4 -1
  136. package/dist/server/app-page-render.js +26 -3
  137. package/dist/server/app-page-request.d.ts +22 -1
  138. package/dist/server/app-page-request.js +92 -15
  139. package/dist/server/app-page-route-wiring.d.ts +14 -2
  140. package/dist/server/app-page-route-wiring.js +61 -25
  141. package/dist/server/app-page-search-params-observation.d.ts +4 -2
  142. package/dist/server/app-page-search-params-observation.js +11 -7
  143. package/dist/server/app-page-segment-state.d.ts +2 -1
  144. package/dist/server/app-page-segment-state.js +3 -1
  145. package/dist/server/app-page-stream.d.ts +5 -0
  146. package/dist/server/app-page-stream.js +3 -1
  147. package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
  148. package/dist/server/app-route-handler-dispatch.js +1 -0
  149. package/dist/server/app-route-handler-execution.js +7 -2
  150. package/dist/server/app-route-handler-response.js +1 -0
  151. package/dist/server/app-route-handler-runtime.js +1 -1
  152. package/dist/server/app-route-module-loader.d.ts +2 -0
  153. package/dist/server/app-route-module-loader.js +1 -0
  154. package/dist/server/app-router-entry.js +16 -8
  155. package/dist/server/app-rsc-errors.js +7 -1
  156. package/dist/server/app-rsc-handler.d.ts +3 -1
  157. package/dist/server/app-rsc-handler.js +67 -39
  158. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  159. package/dist/server/app-rsc-request-normalization.js +6 -3
  160. package/dist/server/app-rsc-route-matching.d.ts +7 -0
  161. package/dist/server/app-rsc-route-matching.js +36 -3
  162. package/dist/server/app-segment-config.d.ts +12 -0
  163. package/dist/server/app-segment-config.js +91 -5
  164. package/dist/server/app-server-action-execution.d.ts +5 -0
  165. package/dist/server/app-server-action-execution.js +94 -33
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +19 -8
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-static-generation.d.ts +1 -0
  171. package/dist/server/app-static-generation.js +1 -0
  172. package/dist/server/app-visited-response-cache.d.ts +6 -0
  173. package/dist/server/app-visited-response-cache.js +3 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.js +19 -18
  179. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  180. package/dist/server/dev-stack-sourcemap.js +1 -1
  181. package/dist/server/fetch-handler.d.ts +2 -0
  182. package/dist/server/fetch-handler.js +18 -0
  183. package/dist/server/headers.d.ts +5 -15
  184. package/dist/server/headers.js +4 -15
  185. package/dist/server/image-optimization.d.ts +51 -1
  186. package/dist/server/image-optimization.js +52 -2
  187. package/dist/server/implicit-tags.js +1 -1
  188. package/dist/server/isr-cache.d.ts +1 -1
  189. package/dist/server/isr-cache.js +2 -2
  190. package/dist/server/metadata-routes.d.ts +3 -1
  191. package/dist/server/metadata-routes.js +12 -2
  192. package/dist/server/middleware-runtime.js +6 -1
  193. package/dist/server/navigation-planner.d.ts +1 -0
  194. package/dist/server/navigation-planner.js +14 -3
  195. package/dist/server/pages-api-route.js +2 -2
  196. package/dist/server/pages-asset-tags.d.ts +4 -6
  197. package/dist/server/pages-asset-tags.js +12 -12
  198. package/dist/server/pages-client-assets.d.ts +12 -0
  199. package/dist/server/pages-client-assets.js +10 -0
  200. package/dist/server/pages-node-compat.d.ts +8 -1
  201. package/dist/server/pages-node-compat.js +32 -4
  202. package/dist/server/pages-page-data.d.ts +24 -1
  203. package/dist/server/pages-page-data.js +45 -24
  204. package/dist/server/pages-page-handler.d.ts +2 -1
  205. package/dist/server/pages-page-handler.js +19 -12
  206. package/dist/server/pages-page-response.d.ts +7 -0
  207. package/dist/server/pages-page-response.js +4 -1
  208. package/dist/server/pages-request-pipeline.d.ts +2 -0
  209. package/dist/server/pages-request-pipeline.js +25 -1
  210. package/dist/server/pages-router-entry.d.ts +30 -0
  211. package/dist/server/pages-router-entry.js +108 -0
  212. package/dist/server/prerender-manifest.d.ts +3 -1
  213. package/dist/server/prerender-route-params.js +1 -1
  214. package/dist/server/prod-server.d.ts +1 -1
  215. package/dist/server/prod-server.js +48 -26
  216. package/dist/server/request-pipeline.js +1 -0
  217. package/dist/server/seed-cache.js +4 -4
  218. package/dist/server/worker-utils.d.ts +2 -1
  219. package/dist/server/worker-utils.js +7 -1
  220. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  221. package/dist/shims/app-router-scroll-state.js +1 -0
  222. package/dist/shims/app-router-scroll.js +2 -1
  223. package/dist/shims/cache.js +19 -15
  224. package/dist/shims/cdn-cache.js +1 -1
  225. package/dist/shims/dynamic-preload-chunks.js +2 -1
  226. package/dist/shims/error-boundary.d.ts +19 -1
  227. package/dist/shims/error-boundary.js +11 -1
  228. package/dist/shims/form.d.ts +3 -1
  229. package/dist/shims/form.js +37 -43
  230. package/dist/shims/headers.d.ts +9 -1
  231. package/dist/shims/headers.js +31 -6
  232. package/dist/shims/image.js +75 -14
  233. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  234. package/dist/shims/internal/app-route-detection.js +4 -17
  235. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  236. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  237. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
  238. package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
  239. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
  240. package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
  241. package/dist/shims/internal/pages-data-target.d.ts +10 -9
  242. package/dist/shims/internal/pages-data-target.js +91 -12
  243. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  244. package/dist/shims/internal/pages-router-components.js +13 -0
  245. package/dist/shims/layout-segment-context.d.ts +4 -1
  246. package/dist/shims/layout-segment-context.js +18 -4
  247. package/dist/shims/link.js +70 -37
  248. package/dist/shims/metadata.d.ts +3 -2
  249. package/dist/shims/metadata.js +8 -4
  250. package/dist/shims/navigation.d.ts +5 -1
  251. package/dist/shims/navigation.js +45 -10
  252. package/dist/shims/navigation.react-server.js +1 -1
  253. package/dist/shims/root-params.d.ts +15 -1
  254. package/dist/shims/root-params.js +21 -1
  255. package/dist/shims/router.d.ts +5 -7
  256. package/dist/shims/router.js +374 -94
  257. package/dist/shims/server.js +3 -2
  258. package/dist/shims/slot.js +3 -6
  259. package/dist/typegen.js +6 -5
  260. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  261. package/dist/utils/client-runtime-metadata.js +31 -22
  262. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  263. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  264. package/dist/utils/domain-locale.d.ts +6 -3
  265. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  266. package/dist/{server → utils}/middleware-request-headers.js +2 -2
  267. package/dist/utils/path.d.ts +2 -1
  268. package/dist/utils/path.js +1 -1
  269. package/dist/utils/project.d.ts +52 -2
  270. package/dist/utils/project.js +230 -5
  271. package/dist/utils/protocol-headers.d.ts +17 -0
  272. package/dist/utils/protocol-headers.js +17 -0
  273. package/dist/utils/react-version.d.ts +4 -0
  274. package/dist/utils/react-version.js +44 -0
  275. package/package.json +53 -4
  276. package/dist/deploy.d.ts +0 -190
  277. package/dist/deploy.js +0 -1033
  278. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  279. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -14,12 +14,18 @@ import { resolvePagesI18nRequest } from "./pages-i18n.js";
14
14
  import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
15
15
  import { buildPagesReadinessNextData } from "./pages-readiness.js";
16
16
  import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
17
+ import { renderPagesPageResponse } from "./pages-page-response.js";
18
+ import { hasPagesGetInitialProps } from "./pages-get-initial-props.js";
17
19
  import { buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, normalizePagesDataRequest, parseNextDataPathname } from "./pages-data-route.js";
20
+ import { resolvePagesPageData } from "./pages-page-data.js";
18
21
  import { createPagesReqRes } from "./pages-node-compat.js";
19
22
  import { collectAssetTags, resolveClientModuleUrl } from "./pages-asset-tags.js";
20
- import { renderPagesPageResponse } from "./pages-page-response.js";
21
- import { resolvePagesPageData } from "./pages-page-data.js";
22
23
  //#region src/server/pages-page-handler.ts
24
+ function shouldEmitPagesClientTraceMetadata(pageModule, appComponent) {
25
+ if (typeof pageModule.getServerSideProps === "function") return true;
26
+ if (typeof pageModule.getStaticProps === "function") return false;
27
+ return hasPagesGetInitialProps(pageModule.default) || hasPagesGetInitialProps(appComponent);
28
+ }
23
29
  function buildI18nRenderContext(i18nConfig, locale, currentDefaultLocale, domainLocales) {
24
30
  return {
25
31
  locale,
@@ -182,6 +188,12 @@ function createPagesPageHandler(opts) {
182
188
  if (allFontPreloads.length > 0) fontLinkHeader = allFontPreloads.map((p) => "<" + appendAssetDeploymentIdQuery(p.href) + ">; rel=preload; as=font; type=" + p.type + "; crossorigin").join(", ");
183
189
  } catch {}
184
190
  const pagesResolvedUrl = (new URL(routeUrl, originalRequestUrl).pathname || "/") + originalRequestUrl.search;
191
+ const createPageReqRes = () => createPagesReqRes({
192
+ body: void 0,
193
+ query,
194
+ request,
195
+ url: originalRequestPathAndSearch
196
+ });
185
197
  const pageDataResult = await resolvePagesPageData({
186
198
  isDataReq,
187
199
  err: err instanceof Error ? err : void 0,
@@ -189,14 +201,7 @@ function createPagesPageHandler(opts) {
189
201
  buildId,
190
202
  deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
191
203
  htmlLimitedBots: vinextConfig.htmlLimitedBots,
192
- createGsspReqRes() {
193
- return createPagesReqRes({
194
- body: void 0,
195
- query,
196
- request,
197
- url: originalRequestPathAndSearch
198
- });
199
- },
204
+ createGsspReqRes: createPageReqRes,
200
205
  createAppTree(appTreeProps) {
201
206
  const el = createPageElement(PageComponent, AppComponent, appTreeProps);
202
207
  return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
@@ -264,6 +269,7 @@ function createPagesPageHandler(opts) {
264
269
  };
265
270
  }
266
271
  const gsspRes = pageDataResult.gsspRes;
272
+ const documentReqRes = serializedPagesNextData.autoExport === true ? null : pageDataResult.documentReqRes ?? createPageReqRes();
267
273
  const isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;
268
274
  const isFallbackRender = pageDataResult.isFallback === true;
269
275
  if (isFallbackRender && typeof setSSRContext === "function") setSSRContext({
@@ -334,7 +340,8 @@ function createPagesPageHandler(opts) {
334
340
  getFontLinks,
335
341
  getFontStyles,
336
342
  getSSRHeadHTML: typeof getSSRHeadHTML === "function" ? getSSRHeadHTML : void 0,
337
- clientTraceMetadata: vinextConfig.clientTraceMetadata,
343
+ clientTraceMetadata: shouldEmitPagesClientTraceMetadata(pageModule, AppComponent) ? vinextConfig.clientTraceMetadata : void 0,
344
+ documentReqRes,
338
345
  gsspRes,
339
346
  isrCacheKey: pageIsrCacheKey,
340
347
  expireSeconds: vinextConfig.expireTime,
@@ -400,4 +407,4 @@ function createPagesPageHandler(opts) {
400
407
  return renderPage;
401
408
  }
402
409
  //#endregion
403
- export { createPagesPageHandler };
410
+ export { createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
@@ -45,9 +45,15 @@ type PagesI18nRenderContext = {
45
45
  domainLocales?: unknown;
46
46
  };
47
47
  type PagesGsspResponse = {
48
+ headersSent?: boolean;
48
49
  statusCode: number;
49
50
  getHeaders(): Record<string, string | number | boolean | string[]>;
50
51
  };
52
+ type PagesDocumentReqRes = {
53
+ req: unknown;
54
+ res: PagesGsspResponse;
55
+ responsePromise?: Promise<Response>;
56
+ };
51
57
  type RenderPagesPageResponseOptions = {
52
58
  assetTags: string;
53
59
  buildId: string | null;
@@ -80,6 +86,7 @@ type RenderPagesPageResponseOptions = {
80
86
  */
81
87
  clientTraceMetadata?: readonly string[] | undefined;
82
88
  setDocumentInitialHead?: ((head: ReactNode[]) => void) | undefined;
89
+ documentReqRes?: PagesDocumentReqRes | null;
83
90
  gsspRes: PagesGsspResponse | null;
84
91
  isrCacheKey: (router: string, pathname: string) => string;
85
92
  expireSeconds?: number;
@@ -197,11 +197,14 @@ async function renderPagesPageResponse(options) {
197
197
  scriptNonce: options.scriptNonce,
198
198
  context: {
199
199
  err: options.err,
200
+ req: options.documentReqRes?.req,
201
+ res: options.documentReqRes?.res,
200
202
  pathname: options.routePattern,
201
203
  query: options.query ?? options.params,
202
204
  asPath: options.routeUrl
203
205
  }
204
206
  });
207
+ if (options.documentReqRes?.res.headersSent && options.documentReqRes.responsePromise) return options.documentReqRes.responsePromise;
205
208
  let bodyStream;
206
209
  if (documentRenderPage.status === "rendered") bodyStream = new ReadableStream({ start(controller) {
207
210
  controller.enqueue(new TextEncoder().encode(documentRenderPage.bodyHtml));
@@ -230,7 +233,7 @@ async function renderPagesPageResponse(options) {
230
233
  const shellPrefix = shellHtml.slice(0, markerIndex);
231
234
  const shellSuffix = shellHtml.slice(markerIndex + 25);
232
235
  const responseHeaders = new Headers({ "Content-Type": "text/html" });
233
- const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes, options.statusCode);
236
+ const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes ?? options.documentReqRes?.res ?? null, options.statusCode);
234
237
  let responseBodyStream = bodyStream;
235
238
  if (!options.scriptNonce && options.isrRevalidateSeconds !== null && options.isrRevalidateSeconds > 0) {
236
239
  const cacheBodyStreamPair = bodyStream.tee();
@@ -34,11 +34,13 @@ type PagesPipelineDeps = {
34
34
  hadBasePath: boolean;
35
35
  isDataReq: boolean;
36
36
  isDataRequest: boolean;
37
+ hasMiddleware: boolean;
37
38
  ctx?: unknown;
38
39
  rawSearch?: string;
39
40
  matchPageRoute?: ((pathname: string, request: Request) => {
40
41
  route: {
41
42
  isDynamic: boolean;
43
+ pattern?: string;
42
44
  };
43
45
  } | null) | null;
44
46
  runMiddleware?: ((request: Request, ctx: unknown, opts: {
@@ -1,4 +1,5 @@
1
1
  import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
2
+ import { patternToNextFormat } from "../routing/route-validation.js";
2
3
  import { applyMiddlewareRequestHeaders, isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
3
4
  import { applyConfigHeadersToHeaderRecord, cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
4
5
  import { mergeRewriteQuery } from "../utils/query.js";
@@ -141,6 +142,13 @@ async function runPagesRequest(request, deps) {
141
142
  });
142
143
  let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
143
144
  const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
145
+ const matchedPathnameForRoute = (routePattern) => {
146
+ const matchedPathname = routePattern ? patternToNextFormat(routePattern) : resolvedPathname;
147
+ if (!i18nConfig) return matchedPathname;
148
+ const resolvedLocale = resolvedPathname.split("/", 3)[1];
149
+ if (resolvedLocale && i18nConfig.locales.includes(resolvedLocale)) return matchedPathname === "/" ? `/${resolvedLocale}` : `/${resolvedLocale}${matchedPathname}`;
150
+ return matchResolvedPathname(matchedPathname);
151
+ };
144
152
  if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
145
153
  configHeaders,
146
154
  pathname: matchPathname,
@@ -268,12 +276,28 @@ async function runPagesRequest(request, deps) {
268
276
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
269
277
  const fallbackApiResult = await handleResolvedApiRoute();
270
278
  if (fallbackApiResult) return fallbackApiResult;
279
+ renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
271
280
  response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
272
281
  matchedFallbackRewrite = true;
273
282
  if (response.status !== 404) break;
274
283
  }
275
284
  if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
276
- const merged = mergeHeaders(response, middlewareHeaders, middlewareStatus);
285
+ const matchedPathHeaders = { ...middlewareHeaders };
286
+ if ((isDataReq || isDataRequest) && deps.hasMiddleware && !renderPageMatch && response.status === 404 && (middlewareStatus === void 0 || middlewareStatus === 200 || middlewareStatus === 404)) {
287
+ const headers = new Headers(response.headers);
288
+ headers.set("content-type", "application/json");
289
+ headers.set("x-nextjs-matched-path", matchResolvedPathname(pathname));
290
+ return {
291
+ type: "response",
292
+ response: mergeHeaders(new Response("{}", {
293
+ status: 200,
294
+ headers
295
+ }), matchedPathHeaders, void 0),
296
+ defaultContentType: "application/json"
297
+ };
298
+ }
299
+ if ((isDataReq || isDataRequest) && renderPageMatch && (middlewareStatus ?? response.status) === 200) matchedPathHeaders["x-nextjs-matched-path"] = matchedPathnameForRoute(renderPageMatch?.route.pattern);
300
+ const merged = mergeHeaders(response, matchedPathHeaders, middlewareStatus);
277
301
  if (merged !== response) merged.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
278
302
  return {
279
303
  type: "response",
@@ -0,0 +1,30 @@
1
+ //#region src/server/pages-router-entry.d.ts
2
+ /**
3
+ * Router-specific Cloudflare Worker entry point for vinext Pages Router.
4
+ *
5
+ * New projects should usually use the router-selected entry in wrangler.jsonc:
6
+ * "main": "vinext/server/fetch-handler"
7
+ *
8
+ * This Pages Router entry remains available for existing configs and for custom
9
+ * workers that need to opt into the Pages Router handler explicitly:
10
+ * "main": "vinext/server/pages-router-entry"
11
+ *
12
+ * Or import and delegate to it from a custom worker:
13
+ * import handler from "vinext/server/pages-router-entry";
14
+ * return handler.fetch(request, env, ctx);
15
+ */
16
+ type AssetFetcher = {
17
+ fetch(request: Request): Promise<Response> | Response;
18
+ };
19
+ type PagesWorkerEnv = {
20
+ ASSETS?: AssetFetcher;
21
+ } & Record<string, unknown>;
22
+ type PagesWorkerExecutionContext = {
23
+ waitUntil?(promise: Promise<unknown>): void;
24
+ passThroughOnException?(): void;
25
+ };
26
+ declare const _default: {
27
+ fetch(request: Request, env?: PagesWorkerEnv, ctx?: PagesWorkerExecutionContext): Promise<Response>;
28
+ };
29
+ //#endregion
30
+ export { _default as default };
@@ -0,0 +1,108 @@
1
+ import { hasBasePath, stripBasePath } from "../utils/base-path.js";
2
+ import { notFoundStaticAssetResponse } from "./http-error-responses.js";
3
+ import { isOpenRedirectShaped } from "./open-redirect.js";
4
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders } from "./request-pipeline.js";
5
+ import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
6
+ import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
7
+ import { finalizeMissingStaticAssetResponse } from "./worker-utils.js";
8
+ import { fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
9
+ import { registerConfiguredCacheAdapters } from "virtual:vinext-cache-adapters";
10
+ import { registerConfiguredImageOptimizer } from "virtual:vinext-image-adapters";
11
+ import * as pagesEntry from "virtual:vinext-server-entry";
12
+ //#region src/server/pages-router-entry.ts
13
+ /**
14
+ * Router-specific Cloudflare Worker entry point for vinext Pages Router.
15
+ *
16
+ * New projects should usually use the router-selected entry in wrangler.jsonc:
17
+ * "main": "vinext/server/fetch-handler"
18
+ *
19
+ * This Pages Router entry remains available for existing configs and for custom
20
+ * workers that need to opt into the Pages Router handler explicitly:
21
+ * "main": "vinext/server/pages-router-entry"
22
+ *
23
+ * Or import and delegate to it from a custom worker:
24
+ * import handler from "vinext/server/pages-router-entry";
25
+ * return handler.fetch(request, env, ctx);
26
+ */
27
+ const { handleApiRoute, hasMiddleware, matchPageRoute, normalizeDataRequest, renderPage, runMiddleware, vinextConfig } = pagesEntry;
28
+ const basePath = vinextConfig?.basePath ?? "";
29
+ const assetPathPrefix = assetPrefixPathname(vinextConfig?.assetPrefix ?? "");
30
+ const trailingSlash = vinextConfig?.trailingSlash ?? false;
31
+ const i18nConfig = vinextConfig?.i18n ?? null;
32
+ const configRedirects = vinextConfig?.redirects ?? [];
33
+ const configRewrites = vinextConfig?.rewrites ?? {
34
+ beforeFiles: [],
35
+ afterFiles: [],
36
+ fallback: []
37
+ };
38
+ const configHeaders = vinextConfig?.headers ?? [];
39
+ const imageConfig = vinextConfig?.images ? {
40
+ qualities: vinextConfig.images.qualities,
41
+ dangerouslyAllowSVG: vinextConfig.images.dangerouslyAllowSVG,
42
+ dangerouslyAllowLocalIP: vinextConfig.images.dangerouslyAllowLocalIP,
43
+ contentDispositionType: vinextConfig.images.contentDispositionType,
44
+ contentSecurityPolicy: vinextConfig.images.contentSecurityPolicy
45
+ } : void 0;
46
+ var pages_router_entry_default = { async fetch(request, env, ctx) {
47
+ return handleRequest(request, env, ctx);
48
+ } };
49
+ async function handleRequest(request, env, ctx) {
50
+ registerConfiguredCacheAdapters(env);
51
+ registerConfiguredImageOptimizer(env);
52
+ try {
53
+ let pathname = new URL(request.url).pathname;
54
+ if (isOpenRedirectShaped(pathname)) return new Response("This page could not be found", { status: 404 });
55
+ const missingBuildAsset = isNextStaticPath(pathname, basePath, assetPathPrefix);
56
+ request = cloneRequestWithHeaders(request, filterInternalHeaders(request.headers));
57
+ const hadBasePath = !basePath || hasBasePath(pathname, basePath);
58
+ {
59
+ const stripped = stripBasePath(pathname, basePath);
60
+ if (stripped !== pathname) {
61
+ const strippedUrl = new URL(request.url);
62
+ strippedUrl.pathname = stripped;
63
+ request = cloneRequestWithUrl(request, strippedUrl.toString());
64
+ pathname = stripped;
65
+ }
66
+ }
67
+ const dataNorm = normalizeDataRequest(request);
68
+ if (dataNorm.notFoundResponse) return dataNorm.notFoundResponse;
69
+ const isDataReq = dataNorm.isDataReq;
70
+ if (isDataReq) {
71
+ request = dataNorm.request;
72
+ pathname = dataNorm.normalizedPathname;
73
+ }
74
+ if (isImageOptimizationPath(pathname) && env?.ASSETS) {
75
+ const allowedWidths = [...vinextConfig?.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...vinextConfig?.images?.imageSizes ?? DEFAULT_IMAGE_SIZES];
76
+ return handleConfiguredImageOptimization(request, (assetPath) => Promise.resolve(env.ASSETS.fetch(new Request(new URL(assetPath, request.url)))), allowedWidths, imageConfig);
77
+ }
78
+ const deps = {
79
+ basePath,
80
+ trailingSlash,
81
+ i18nConfig,
82
+ configRedirects,
83
+ configRewrites,
84
+ configHeaders,
85
+ hadBasePath,
86
+ isDataReq,
87
+ isDataRequest: isDataReq,
88
+ hasMiddleware,
89
+ ctx,
90
+ matchPageRoute: typeof matchPageRoute === "function" ? matchPageRoute : null,
91
+ runMiddleware: typeof runMiddleware === "function" ? wrapMiddlewareWithBasePath(runMiddleware, basePath, hadBasePath) : null,
92
+ renderPage: typeof renderPage === "function" ? (req, resolvedUrl, options, stagedHeaders) => renderPage(req, resolvedUrl, null, ctx, stagedHeaders, options) : null,
93
+ handleApi: typeof handleApiRoute === "function" ? (req, apiUrl) => handleApiRoute(req, apiUrl, ctx) : null,
94
+ serveFilesystemRoute: async (requestPathname, _stagedHeaders, phase) => {
95
+ if (!env?.ASSETS) return false;
96
+ return fetchWorkerFilesystemRoute(request, requestPathname, phase, (assetRequest) => Promise.resolve(env.ASSETS.fetch(assetRequest)));
97
+ }
98
+ };
99
+ const result = await runPagesRequest(request, deps);
100
+ if (result.type === "response") return finalizeMissingStaticAssetResponse(result.response, missingBuildAsset);
101
+ return missingBuildAsset ? notFoundStaticAssetResponse() : new Response("This page could not be found", { status: 404 });
102
+ } catch (error) {
103
+ console.error("[vinext] Worker error:", error);
104
+ return new Response("Internal Server Error", { status: 500 });
105
+ }
106
+ }
107
+ //#endregion
108
+ export { pages_router_entry_default as default };
@@ -7,11 +7,13 @@ type PrerenderManifestRoute = {
7
7
  path?: string;
8
8
  router?: string;
9
9
  fallback?: boolean;
10
+ headers?: Record<string, string>;
10
11
  };
11
12
  type PrerenderManifest = {
12
13
  buildId?: string;
13
14
  trailingSlash?: boolean;
14
15
  routes?: PrerenderManifestRoute[];
16
+ pregeneratedConcretePaths?: Array<[string, string[]]>;
15
17
  };
16
18
  declare function readPrerenderManifest(manifestPath: string): PrerenderManifest | null;
17
19
  declare function getRenderedAppRoutes(routes: PrerenderManifestRoute[]): PrerenderManifestRoute[];
@@ -30,4 +32,4 @@ declare function isFallbackShellArtifactPath(pathname: string, route?: Prerender
30
32
  */
31
33
  declare function buildPregeneratedConcretePathTable(manifest: PrerenderManifest): Array<[string, string[]]>;
32
34
  //#endregion
33
- export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
35
+ export { PrerenderManifest, buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
@@ -1,4 +1,4 @@
1
- import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "./headers.js";
1
+ import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
2
2
  import { isUnknownRecord } from "../utils/record.js";
3
3
  //#region src/server/prerender-route-params.ts
4
4
  function isPrerenderRouteParams(value) {
@@ -74,7 +74,7 @@ declare function mergeResponseHeaders(middlewareHeaders: Record<string, string |
74
74
  * arguments in (headers, response) order. The request path now calls
75
75
  * `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
76
76
  * only for its existing tests and any external callers, so there is a single
77
- * implementation to keep in sync. (deploy.ts still emits its own generated copy.)
77
+ * implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
78
78
  */
79
79
  declare function mergeWebResponse(middlewareHeaders: Record<string, string | string[]>, response: Response, statusOverride?: number): Response;
80
80
  /**
@@ -1,22 +1,24 @@
1
1
  import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
2
2
  import { hasBasePath, stripBasePath } from "../utils/base-path.js";
3
- import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_STATIC_FILE_HEADER } from "./headers.js";
3
+ import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
4
+ import { VINEXT_STATIC_FILE_HEADER } from "./headers.js";
4
5
  import { normalizePath } from "./normalize-path.js";
5
6
  import { notFoundResponse } from "./http-error-responses.js";
6
7
  import { isOpenRedirectShaped } from "./open-redirect.js";
7
8
  import { filterInternalHeaders } from "./request-pipeline.js";
8
9
  import { isUnknownRecord } from "../utils/record.js";
10
+ import { buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname } from "./pages-data-route.js";
9
11
  import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
10
12
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, isSafeImageContentType, parseImageParams } from "./image-optimization.js";
11
13
  import { installSocketErrorBackstop } from "./socket-error-backstop.js";
12
14
  import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
13
15
  import { CONTENT_TYPES, StaticFileCache, etagFromFilenameHash } from "./static-file-cache.js";
14
- import { buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname } from "./pages-data-route.js";
15
16
  import { collectInlineCssManifest } from "../build/inline-css.js";
16
17
  import { mergeHeaders } from "./worker-utils.js";
17
18
  import { runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
18
- import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
19
19
  import { computeClientRuntimeMetadata } from "../utils/client-runtime-metadata.js";
20
+ import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
21
+ import { setPagesClientAssets } from "./pages-client-assets.js";
20
22
  import { readPrerenderSecret } from "../build/server-manifest.js";
21
23
  import { seedMemoryCacheFromPrerender } from "./seed-cache.js";
22
24
  import { negotiateEncoding, parseAcceptedEncodings, selectContentEncoding } from "./accept-encoding.js";
@@ -24,9 +26,9 @@ import fs from "node:fs";
24
26
  import path from "node:path";
25
27
  import fs$1 from "node:fs/promises";
26
28
  import { pathToFileURL } from "node:url";
29
+ import { Readable, pipeline } from "node:stream";
27
30
  import zlib from "node:zlib";
28
31
  import { createServer } from "node:http";
29
- import { Readable, pipeline } from "node:stream";
30
32
  //#region src/server/prod-server.ts
31
33
  /**
32
34
  * Production server for vinext.
@@ -275,8 +277,11 @@ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
275
277
  assetBase,
276
278
  assetPrefix
277
279
  });
278
- globalThis.__VINEXT_LAZY_CHUNKS__ = metadata.lazyChunks;
279
- globalThis.__VINEXT_DYNAMIC_PRELOADS__ = metadata.dynamicPreloads;
280
+ setPagesClientAssets({
281
+ appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
282
+ lazyChunks: metadata.lazyChunks,
283
+ dynamicPreloads: metadata.dynamicPreloads
284
+ });
280
285
  }
281
286
  function isNoBodyResponseStatus(status) {
282
287
  return NO_BODY_RESPONSE_STATUSES.has(status);
@@ -305,7 +310,7 @@ function logProdServerStarted(host, port, purpose) {
305
310
  * arguments in (headers, response) order. The request path now calls
306
311
  * `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
307
312
  * only for its existing tests and any external callers, so there is a single
308
- * implementation to keep in sync. (deploy.ts still emits its own generated copy.)
313
+ * implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
309
314
  */
310
315
  function mergeWebResponse(middlewareHeaders, response, statusOverride) {
311
316
  return mergeHeaders(response, middlewareHeaders, statusOverride);
@@ -736,18 +741,21 @@ function readSsrManifest(clientDir) {
736
741
  }
737
742
  return parsed;
738
743
  }
739
- function installPagesClientAssetGlobals(options) {
744
+ function installPagesClientAssets(options) {
740
745
  const ssrManifest = readSsrManifest(options.clientDir);
741
- globalThis.__VINEXT_SSR_MANIFEST__ = Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0;
742
746
  const metadata = computeClientRuntimeMetadata({
743
747
  clientDir: options.clientDir,
744
748
  assetBase: options.assetBase,
745
749
  assetPrefix: options.assetPrefix,
746
750
  includeClientEntry: options.clientEntryLookup === "pages-client-entry" ? "pages-client-entry" : true
747
751
  });
748
- globalThis.__VINEXT_CLIENT_ENTRY__ = metadata.clientEntryFile;
749
- globalThis.__VINEXT_LAZY_CHUNKS__ = metadata.lazyChunks;
750
- globalThis.__VINEXT_DYNAMIC_PRELOADS__ = metadata.dynamicPreloads;
752
+ setPagesClientAssets({
753
+ clientEntry: metadata.clientEntryFile,
754
+ appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
755
+ ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
756
+ lazyChunks: metadata.lazyChunks,
757
+ dynamicPreloads: metadata.dynamicPreloads
758
+ });
751
759
  return ssrManifest;
752
760
  }
753
761
  /**
@@ -769,11 +777,6 @@ function installPagesClientAssetGlobals(options) {
769
777
  */
770
778
  async function startAppRouterServer(options) {
771
779
  const { port, host, clientDir, rscEntryPath, compress, purpose } = options;
772
- let imageConfig;
773
- const imageConfigPath = path.join(path.dirname(rscEntryPath), "image-config.json");
774
- if (fs.existsSync(imageConfigPath)) try {
775
- imageConfig = JSON.parse(fs.readFileSync(imageConfigPath, "utf-8"));
776
- } catch {}
777
780
  const prerenderSecret = readPrerenderSecret(path.dirname(rscEntryPath));
778
781
  const rscModule = await importServerEntryModule(rscEntryPath);
779
782
  const rscHandler = resolveAppRouterHandler(rscModule.default);
@@ -781,10 +784,18 @@ async function startAppRouterServer(options) {
781
784
  const appRouterBasePath = typeof rscModule.__basePath === "string" ? rscModule.__basePath : "";
782
785
  const appRouterInlineCss = rscModule.__inlineCss === true;
783
786
  const appRouterHasPagesDir = rscModule.__hasPagesDir === true;
787
+ const appImageAllowedWidths = Array.isArray(rscModule.__imageAllowedWidths) ? rscModule.__imageAllowedWidths : [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES];
788
+ let imageConfig = typeof rscModule.__imageConfig === "object" && rscModule.__imageConfig !== null ? rscModule.__imageConfig : void 0;
789
+ if (imageConfig === void 0) {
790
+ const imageConfigPath = path.join(path.dirname(rscEntryPath), "image-config.json");
791
+ if (fs.existsSync(imageConfigPath)) try {
792
+ imageConfig = JSON.parse(fs.readFileSync(imageConfigPath, "utf-8"));
793
+ } catch {}
794
+ }
784
795
  globalThis.__VINEXT_INLINE_CSS__ = appRouterInlineCss ? collectInlineCssManifest(clientDir, appRouterAssetPrefix) : void 0;
785
796
  const appAssetPathPrefix = assetPrefixPathname(appRouterAssetPrefix);
786
797
  const appAssetBase = appRouterBasePath ? `${appRouterBasePath}/` : "/";
787
- if (appRouterHasPagesDir) installPagesClientAssetGlobals({
798
+ if (appRouterHasPagesDir) installPagesClientAssets({
788
799
  clientDir,
789
800
  assetPrefix: appRouterAssetPrefix,
790
801
  assetBase: appAssetBase,
@@ -819,17 +830,16 @@ async function startAppRouterServer(options) {
819
830
  return;
820
831
  }
821
832
  }
833
+ let missingBuildAsset = false;
822
834
  {
823
835
  const assetLookupPath = resolveAppRouterAssetPath(pathname, appAssetPathPrefix, appRouterAssetPrefix);
824
836
  if (assetLookupPath) {
825
837
  if (await tryServeStatic(req, res, clientDir, assetLookupPath, compress, staticCache)) return;
826
- res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
827
- res.end("Not Found");
828
- return;
838
+ missingBuildAsset = true;
829
839
  }
830
840
  }
831
841
  if (isImageOptimizationPath(pathname)) {
832
- const params = parseImageParams(new URL(rawUrl, "http://localhost"), [...imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES], imageConfig?.qualities);
842
+ const params = parseImageParams(new URL(rawUrl, "http://localhost"), appImageAllowedWidths, imageConfig?.qualities);
833
843
  if (!params) {
834
844
  res.writeHead(400);
835
845
  res.end("Bad Request");
@@ -868,6 +878,12 @@ async function startAppRouterServer(options) {
868
878
  await sendWebResponse(notFoundResponse({ headers: toWebHeaders(staticResponseHeaders) }), req, res, compress);
869
879
  return;
870
880
  }
881
+ if (missingBuildAsset && response.status === 404) {
882
+ cancelResponseBody(response);
883
+ res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
884
+ res.end("Not Found");
885
+ return;
886
+ }
871
887
  await sendWebResponse(response, req, res, compress);
872
888
  } catch (e) {
873
889
  console.error("[vinext] Server error:", e);
@@ -918,6 +934,7 @@ async function startPagesRouterServer(options) {
918
934
  const serverEntry = await importServerEntryModule(serverEntryPath);
919
935
  const { renderPage, handleApiRoute: handleApi, runMiddleware, vinextConfig, buildId: pagesBuildId } = serverEntry;
920
936
  const matchPageRoute = typeof serverEntry.matchPageRoute === "function" ? serverEntry.matchPageRoute : void 0;
937
+ const hasMiddleware = serverEntry.hasMiddleware === true;
921
938
  const pageRoutes = readPagesServerEntryPageRoutes(serverEntry.pageRoutes);
922
939
  const prerenderSecret = readPrerenderSecret(path.dirname(serverEntryPath));
923
940
  const basePath = vinextConfig?.basePath ?? "";
@@ -941,7 +958,7 @@ async function startPagesRouterServer(options) {
941
958
  contentDispositionType: vinextConfig.images.contentDispositionType,
942
959
  contentSecurityPolicy: vinextConfig.images.contentSecurityPolicy
943
960
  } : void 0;
944
- const ssrManifest = installPagesClientAssetGlobals({
961
+ const ssrManifest = installPagesClientAssets({
945
962
  clientDir,
946
963
  assetPrefix,
947
964
  assetBase,
@@ -1000,11 +1017,9 @@ async function startPagesRouterServer(options) {
1000
1017
  }
1001
1018
  const staticLookupPath = stripBasePath(pathname, basePath);
1002
1019
  const pagesAssetLookup = resolveAppRouterAssetPath(pathname, pagesAssetPathPrefix, assetPrefix);
1020
+ const missingBuildAsset = pagesAssetLookup !== null;
1003
1021
  if (pagesAssetLookup) {
1004
1022
  if (await tryServeStatic(req, res, clientDir, pagesAssetLookup, compress, staticCache)) return;
1005
- res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
1006
- res.end("Not Found");
1007
- return;
1008
1023
  }
1009
1024
  if (isImageOptimizationPath(pathname) || isImageOptimizationPath(staticLookupPath)) {
1010
1025
  const params = parseImageParams(new URL(rawUrl, "http://localhost"), allowedImageWidths, pagesImageConfig?.qualities);
@@ -1072,6 +1087,7 @@ async function startPagesRouterServer(options) {
1072
1087
  hadBasePath,
1073
1088
  isDataReq,
1074
1089
  isDataRequest,
1090
+ hasMiddleware,
1075
1091
  ctx: void 0,
1076
1092
  rawSearch: rawQs,
1077
1093
  matchPageRoute: matchPageRoute ?? null,
@@ -1089,6 +1105,12 @@ async function startPagesRouterServer(options) {
1089
1105
  if (result.type === "handled") return;
1090
1106
  if (result.type === "response") {
1091
1107
  const { response } = result;
1108
+ if (missingBuildAsset && response.status === 404) {
1109
+ cancelResponseBody(response);
1110
+ res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
1111
+ res.end("Not Found");
1112
+ return;
1113
+ }
1092
1114
  if (isVinextStreamedHtmlResponse(response) || !response.body || result.defaultContentType === void 0) {
1093
1115
  await sendWebResponse(response, req, res, compress);
1094
1116
  return;
@@ -1,4 +1,5 @@
1
1
  import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
2
+ import "../utils/protocol-headers.js";
2
3
  import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, VINEXT_STATIC_FILE_HEADER } from "./headers.js";
3
4
  import { matchHeaders } from "../config/config-matchers.js";
4
5
  import { forbiddenResponse, notFoundResponse } from "./http-error-responses.js";
@@ -1,8 +1,8 @@
1
1
  import { isrCacheKey, isrSetPrerenderedAppPage } from "./isr-cache.js";
2
+ import { getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest } from "./prerender-manifest.js";
2
3
  import { buildAppPageCacheTags } from "./app-page-cache.js";
3
4
  import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths.js";
4
5
  import { addPregeneratedConcretePath, clearPregeneratedConcretePaths, normalizePregeneratedPathname } from "./pregenerated-concrete-paths.js";
5
- import { getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest } from "./prerender-manifest.js";
6
6
  import fs from "node:fs";
7
7
  import path from "node:path";
8
8
  //#region src/server/seed-cache.ts
@@ -67,7 +67,7 @@ async function seedMemoryCacheFromPrerender(serverDir, options) {
67
67
  const revalidateSeconds = typeof route.revalidate === "number" ? route.revalidate : void 0;
68
68
  const expireSeconds = typeof route.expire === "number" ? route.expire : void 0;
69
69
  const tags = buildAppPageCacheTags(cachePathname, []);
70
- if (await seedHtml(writeAppPageEntry, prerenderDir, htmlKey, artifactPathname, trailingSlash, revalidateSeconds, expireSeconds, tags)) {
70
+ if (await seedHtml(writeAppPageEntry, prerenderDir, htmlKey, artifactPathname, trailingSlash, route.headers, revalidateSeconds, expireSeconds, tags)) {
71
71
  await seedRsc(writeAppPageEntry, prerenderDir, rscKey, artifactPathname, revalidateSeconds, expireSeconds, tags);
72
72
  seeded++;
73
73
  }
@@ -81,7 +81,7 @@ function createDefaultAppPageEntryWriter() {
81
81
  * Seed the HTML cache entry for a single route.
82
82
  * Returns true if the file existed and was seeded.
83
83
  */
84
- async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailingSlash, revalidateSeconds, expireSeconds, tags) {
84
+ async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailingSlash, headers, revalidateSeconds, expireSeconds, tags) {
85
85
  const relPath = getOutputPath(pathname, trailingSlash);
86
86
  const fullPath = path.join(prerenderDir, relPath);
87
87
  if (!fs.existsSync(fullPath)) return false;
@@ -89,7 +89,7 @@ async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailing
89
89
  kind: "APP_PAGE",
90
90
  html: fs.readFileSync(fullPath, "utf-8"),
91
91
  rscData: void 0,
92
- headers: void 0,
92
+ headers,
93
93
  postponed: void 0,
94
94
  status: void 0
95
95
  }, {
@@ -1,7 +1,8 @@
1
1
  //#region src/server/worker-utils.d.ts
2
+ declare function finalizeMissingStaticAssetResponse(response: Response, missingBuildAsset: boolean): Response;
2
3
  declare function mergeHeaders(response: Response, extraHeaders: Record<string, string | string[]>, statusOverride?: number): Response;
3
4
  declare function resolveStaticAssetSignal(signalResponse: Response, options: {
4
5
  fetchAsset(path: string): Promise<Response>;
5
6
  }): Promise<Response | null>;
6
7
  //#endregion
7
- export { mergeHeaders, resolveStaticAssetSignal };
8
+ export { finalizeMissingStaticAssetResponse, mergeHeaders, resolveStaticAssetSignal };
@@ -1,4 +1,5 @@
1
1
  import { VINEXT_STATIC_FILE_HEADER } from "./headers.js";
2
+ import { notFoundStaticAssetResponse } from "./http-error-responses.js";
2
3
  //#region src/server/worker-utils.ts
3
4
  /**
4
5
  * Shared utilities for Cloudflare Worker entries.
@@ -29,6 +30,11 @@ function cancelResponseBody(response) {
29
30
  if (!body || body.locked) return;
30
31
  body.cancel().catch(() => {});
31
32
  }
33
+ function finalizeMissingStaticAssetResponse(response, missingBuildAsset) {
34
+ if (!missingBuildAsset || response.status !== 404) return response;
35
+ cancelResponseBody(response);
36
+ return notFoundStaticAssetResponse();
37
+ }
32
38
  function buildHeaderRecord(response, omitNames = []) {
33
39
  const omitted = new Set(omitNames.map((name) => name.toLowerCase()));
34
40
  const headers = {};
@@ -96,4 +102,4 @@ async function resolveStaticAssetSignal(signalResponse, options) {
96
102
  return mergeHeaders(assetResponse, extraHeaders, assetResponse.ok && signalResponse.status !== 200 ? signalResponse.status : void 0);
97
103
  }
98
104
  //#endregion
99
- export { mergeHeaders, resolveStaticAssetSignal };
105
+ export { finalizeMissingStaticAssetResponse, mergeHeaders, resolveStaticAssetSignal };
@@ -2,6 +2,7 @@
2
2
  type AppRouterScrollIntent = Readonly<{
3
3
  commitId: number | null;
4
4
  hash: string | null;
5
+ headElements: ReadonlySet<Element> | null;
5
6
  id: number;
6
7
  targetHoistedInHead: boolean;
7
8
  }>;