vinext 0.1.8 → 0.2.1

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 (285) hide show
  1. package/README.md +51 -30
  2. package/dist/build/css-url-assets.d.ts +3 -1
  3. package/dist/build/css-url-assets.js +18 -1
  4. package/dist/build/inject-pregenerated-paths.d.ts +7 -0
  5. package/dist/build/inject-pregenerated-paths.js +21 -0
  6. package/dist/build/layout-classification.js +1 -1
  7. package/dist/build/nitro-route-rules.js +1 -1
  8. package/dist/build/pages-client-assets-module.d.ts +11 -0
  9. package/dist/build/pages-client-assets-module.js +27 -0
  10. package/dist/build/prerender-server-entry.d.ts +1 -0
  11. package/dist/build/prerender-server-entry.js +49 -0
  12. package/dist/build/prerender-server-pool.d.ts +44 -0
  13. package/dist/build/prerender-server-pool.js +194 -0
  14. package/dist/build/prerender.d.ts +2 -1
  15. package/dist/build/prerender.js +98 -27
  16. package/dist/build/report.d.ts +13 -2
  17. package/dist/build/report.js +99 -2
  18. package/dist/build/run-prerender.d.ts +7 -0
  19. package/dist/build/run-prerender.js +12 -2
  20. package/dist/build/standalone.js +2 -0
  21. package/dist/cache/cache-adapters-virtual.js +3 -3
  22. package/dist/check.d.ts +4 -6
  23. package/dist/check.js +48 -11
  24. package/dist/cli-args.d.ts +1 -2
  25. package/dist/cli-args.js +1 -1
  26. package/dist/cli-dev-config.d.ts +12 -0
  27. package/dist/cli-dev-config.js +23 -0
  28. package/dist/cli.js +112 -96
  29. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  30. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  31. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  32. package/dist/{server → client}/dev-error-overlay.js +2 -2
  33. package/dist/client/navigation-runtime.d.ts +2 -0
  34. package/dist/client/navigation-runtime.js +3 -1
  35. package/dist/client/vinext-next-data.d.ts +4 -1
  36. package/dist/client/window-next.d.ts +2 -1
  37. package/dist/cloudflare/index.d.ts +2 -2
  38. package/dist/cloudflare/index.js +2 -2
  39. package/dist/config/config-matchers.js +45 -19
  40. package/dist/config/next-config.d.ts +41 -9
  41. package/dist/config/next-config.js +60 -3
  42. package/dist/config/prerender.d.ts +34 -0
  43. package/dist/config/prerender.js +55 -0
  44. package/dist/entries/app-browser-entry.js +5 -1
  45. package/dist/entries/app-rsc-entry.d.ts +5 -3
  46. package/dist/entries/app-rsc-entry.js +44 -10
  47. package/dist/entries/app-rsc-manifest.js +2 -0
  48. package/dist/entries/pages-client-entry.d.ts +3 -0
  49. package/dist/entries/pages-client-entry.js +28 -3
  50. package/dist/entries/pages-server-entry.js +23 -6
  51. package/dist/image/image-adapters-virtual.d.ts +59 -0
  52. package/dist/image/image-adapters-virtual.js +59 -0
  53. package/dist/index.d.ts +33 -0
  54. package/dist/index.js +482 -120
  55. package/dist/init-cloudflare.d.ts +43 -0
  56. package/dist/init-cloudflare.js +839 -0
  57. package/dist/init-platform.d.ts +40 -0
  58. package/dist/init-platform.js +195 -0
  59. package/dist/init.d.ts +16 -38
  60. package/dist/init.js +209 -99
  61. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  62. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  63. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  64. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  65. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
  66. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  67. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  68. package/dist/packages/cloudflare/src/deploy.js +272 -0
  69. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  70. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
  71. package/dist/plugins/ast-scope.d.ts +16 -0
  72. package/dist/plugins/ast-scope.js +62 -0
  73. package/dist/plugins/ast-utils.d.ts +27 -1
  74. package/dist/plugins/ast-utils.js +32 -1
  75. package/dist/plugins/css-module-imports.d.ts +14 -0
  76. package/dist/plugins/css-module-imports.js +59 -0
  77. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  78. package/dist/plugins/fonts.js +1 -1
  79. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  80. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  81. package/dist/plugins/og-assets.js +2 -1
  82. package/dist/plugins/optimize-imports.js +1 -1
  83. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  84. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  85. package/dist/plugins/sass.d.ts +17 -1
  86. package/dist/plugins/sass.js +74 -1
  87. package/dist/plugins/styled-jsx.d.ts +16 -0
  88. package/dist/plugins/styled-jsx.js +149 -0
  89. package/dist/plugins/typeof-window.d.ts +1 -1
  90. package/dist/plugins/typeof-window.js +28 -56
  91. package/dist/routing/app-route-graph.d.ts +23 -2
  92. package/dist/routing/app-route-graph.js +138 -38
  93. package/dist/routing/file-matcher.d.ts +11 -1
  94. package/dist/routing/file-matcher.js +18 -3
  95. package/dist/routing/pages-router.js +2 -2
  96. package/dist/server/api-handler.js +9 -14
  97. package/dist/server/app-browser-action-result.d.ts +4 -1
  98. package/dist/server/app-browser-action-result.js +8 -1
  99. package/dist/server/app-browser-entry.js +198 -57
  100. package/dist/server/app-browser-interception-context.d.ts +1 -0
  101. package/dist/server/app-browser-interception-context.js +4 -2
  102. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  103. package/dist/server/app-browser-navigation-controller.js +60 -31
  104. package/dist/server/app-browser-server-action-client.d.ts +1 -1
  105. package/dist/server/app-browser-server-action-client.js +8 -7
  106. package/dist/server/app-browser-state.d.ts +12 -1
  107. package/dist/server/app-browser-state.js +25 -8
  108. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  109. package/dist/server/app-browser-visible-commit.js +42 -24
  110. package/dist/server/app-elements-wire.d.ts +9 -2
  111. package/dist/server/app-elements-wire.js +8 -1
  112. package/dist/server/app-elements.d.ts +2 -2
  113. package/dist/server/app-elements.js +4 -3
  114. package/dist/server/app-fallback-renderer.d.ts +2 -1
  115. package/dist/server/app-fallback-renderer.js +10 -6
  116. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  117. package/dist/server/app-hydration-cache-publication.js +43 -0
  118. package/dist/server/app-middleware.d.ts +4 -3
  119. package/dist/server/app-middleware.js +8 -3
  120. package/dist/server/app-optimistic-routing.js +11 -4
  121. package/dist/server/app-page-boundary.js +2 -1
  122. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  123. package/dist/server/app-page-cache-finalizer.js +5 -4
  124. package/dist/server/app-page-cache-render.d.ts +1 -0
  125. package/dist/server/app-page-cache-render.js +8 -4
  126. package/dist/server/app-page-cache.d.ts +1 -0
  127. package/dist/server/app-page-cache.js +27 -7
  128. package/dist/server/app-page-dispatch.d.ts +1 -0
  129. package/dist/server/app-page-dispatch.js +26 -8
  130. package/dist/server/app-page-element-builder.d.ts +2 -1
  131. package/dist/server/app-page-element-builder.js +59 -4
  132. package/dist/server/app-page-execution.js +2 -1
  133. package/dist/server/app-page-probe.js +5 -0
  134. package/dist/server/app-page-render-identity.d.ts +2 -0
  135. package/dist/server/app-page-render-identity.js +3 -2
  136. package/dist/server/app-page-render.d.ts +2 -0
  137. package/dist/server/app-page-render.js +85 -16
  138. package/dist/server/app-page-request.d.ts +14 -0
  139. package/dist/server/app-page-request.js +69 -4
  140. package/dist/server/app-page-response.d.ts +7 -0
  141. package/dist/server/app-page-response.js +16 -4
  142. package/dist/server/app-page-route-wiring.d.ts +8 -1
  143. package/dist/server/app-page-route-wiring.js +32 -18
  144. package/dist/server/app-page-segment-state.d.ts +2 -1
  145. package/dist/server/app-page-segment-state.js +3 -1
  146. package/dist/server/app-page-stream.d.ts +7 -1
  147. package/dist/server/app-page-stream.js +3 -1
  148. package/dist/server/app-route-handler-execution.js +5 -1
  149. package/dist/server/app-route-handler-response.js +1 -0
  150. package/dist/server/app-route-handler-runtime.js +1 -1
  151. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  152. package/dist/server/app-route-tree-prefetch.js +187 -0
  153. package/dist/server/app-router-entry.js +9 -2
  154. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  155. package/dist/server/app-rsc-cache-busting.js +9 -4
  156. package/dist/server/app-rsc-handler.d.ts +7 -0
  157. package/dist/server/app-rsc-handler.js +148 -39
  158. package/dist/server/app-rsc-render-mode.d.ts +3 -2
  159. package/dist/server/app-rsc-render-mode.js +4 -1
  160. package/dist/server/app-rsc-request-normalization.d.ts +6 -6
  161. package/dist/server/app-rsc-request-normalization.js +10 -8
  162. package/dist/server/app-segment-config.d.ts +11 -0
  163. package/dist/server/app-segment-config.js +62 -6
  164. package/dist/server/app-server-action-execution.d.ts +1 -0
  165. package/dist/server/app-server-action-execution.js +61 -30
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +13 -5
  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-visited-response-cache.d.ts +6 -0
  171. package/dist/server/app-visited-response-cache.js +3 -1
  172. package/dist/server/cache-control.d.ts +3 -1
  173. package/dist/server/cache-control.js +13 -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.d.ts +11 -1
  179. package/dist/server/dev-server.js +94 -35
  180. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  181. package/dist/server/dev-stack-sourcemap.js +1 -1
  182. package/dist/server/fetch-handler.d.ts +2 -0
  183. package/dist/server/fetch-handler.js +18 -0
  184. package/dist/server/headers.d.ts +7 -15
  185. package/dist/server/headers.js +11 -18
  186. package/dist/server/image-optimization.d.ts +51 -1
  187. package/dist/server/image-optimization.js +52 -2
  188. package/dist/server/implicit-tags.js +1 -1
  189. package/dist/server/isr-cache.d.ts +3 -2
  190. package/dist/server/isr-cache.js +9 -5
  191. package/dist/server/metadata-routes.d.ts +3 -1
  192. package/dist/server/metadata-routes.js +12 -2
  193. package/dist/server/middleware-runtime.js +6 -1
  194. package/dist/server/navigation-planner.d.ts +1 -0
  195. package/dist/server/navigation-planner.js +14 -3
  196. package/dist/server/pages-api-route.js +2 -2
  197. package/dist/server/pages-asset-tags.d.ts +4 -6
  198. package/dist/server/pages-asset-tags.js +12 -12
  199. package/dist/server/pages-client-assets.d.ts +12 -0
  200. package/dist/server/pages-client-assets.js +10 -0
  201. package/dist/server/pages-data-route.d.ts +4 -2
  202. package/dist/server/pages-data-route.js +18 -4
  203. package/dist/server/pages-dev-module-url.d.ts +2 -1
  204. package/dist/server/pages-dev-module-url.js +6 -3
  205. package/dist/server/pages-node-compat.d.ts +19 -1
  206. package/dist/server/pages-node-compat.js +81 -4
  207. package/dist/server/pages-page-data.d.ts +33 -1
  208. package/dist/server/pages-page-data.js +62 -33
  209. package/dist/server/pages-page-handler.d.ts +2 -1
  210. package/dist/server/pages-page-handler.js +38 -19
  211. package/dist/server/pages-page-response.d.ts +8 -0
  212. package/dist/server/pages-page-response.js +7 -3
  213. package/dist/server/pages-request-pipeline.d.ts +9 -5
  214. package/dist/server/pages-request-pipeline.js +55 -7
  215. package/dist/server/pages-router-entry.d.ts +30 -0
  216. package/dist/server/pages-router-entry.js +108 -0
  217. package/dist/server/prerender-manifest.d.ts +3 -1
  218. package/dist/server/prerender-route-params.js +1 -1
  219. package/dist/server/prod-server.d.ts +5 -3
  220. package/dist/server/prod-server.js +68 -39
  221. package/dist/server/request-pipeline.js +2 -1
  222. package/dist/server/seed-cache.js +4 -4
  223. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  224. package/dist/shims/app-router-scroll-state.js +1 -0
  225. package/dist/shims/app-router-scroll.js +2 -1
  226. package/dist/shims/cache-handler.js +8 -1
  227. package/dist/shims/cache.js +22 -15
  228. package/dist/shims/cdn-cache.js +1 -1
  229. package/dist/shims/dynamic-preload-chunks.js +2 -1
  230. package/dist/shims/fetch-cache.d.ts +3 -1
  231. package/dist/shims/fetch-cache.js +77 -52
  232. package/dist/shims/form.d.ts +4 -2
  233. package/dist/shims/form.js +37 -43
  234. package/dist/shims/headers.d.ts +7 -1
  235. package/dist/shims/headers.js +17 -3
  236. package/dist/shims/image.js +75 -14
  237. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  238. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  239. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  240. package/dist/shims/internal/app-route-detection.js +4 -17
  241. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  242. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  243. package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
  244. package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
  245. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
  247. package/dist/shims/internal/pages-data-target.d.ts +18 -12
  248. package/dist/shims/internal/pages-data-target.js +97 -13
  249. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  250. package/dist/shims/internal/pages-router-components.js +13 -0
  251. package/dist/shims/layout-segment-context.d.ts +4 -1
  252. package/dist/shims/layout-segment-context.js +18 -4
  253. package/dist/shims/link.d.ts +1 -1
  254. package/dist/shims/link.js +224 -58
  255. package/dist/shims/navigation.d.ts +19 -3
  256. package/dist/shims/navigation.js +245 -47
  257. package/dist/shims/request-context.js +18 -0
  258. package/dist/shims/root-params.d.ts +15 -1
  259. package/dist/shims/root-params.js +21 -1
  260. package/dist/shims/router.d.ts +5 -7
  261. package/dist/shims/router.js +387 -102
  262. package/dist/shims/server.js +3 -2
  263. package/dist/shims/slot.js +3 -6
  264. package/dist/shims/unified-request-context.js +1 -0
  265. package/dist/typegen.js +1 -1
  266. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  267. package/dist/utils/client-runtime-metadata.js +31 -22
  268. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  269. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  270. package/dist/utils/domain-locale.d.ts +6 -3
  271. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  272. package/dist/{server → utils}/middleware-request-headers.js +3 -3
  273. package/dist/utils/project.d.ts +48 -2
  274. package/dist/utils/project.js +225 -4
  275. package/dist/utils/protocol-headers.d.ts +23 -0
  276. package/dist/utils/protocol-headers.js +23 -0
  277. package/dist/utils/react-version.d.ts +4 -0
  278. package/dist/utils/react-version.js +44 -0
  279. package/dist/utils/vite-version.d.ts +2 -0
  280. package/dist/utils/vite-version.js +11 -1
  281. package/package.json +47 -2
  282. package/dist/deploy.d.ts +0 -197
  283. package/dist/deploy.js +0 -1040
  284. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  285. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -1,8 +1,10 @@
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";
5
6
  import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
7
+ import { buildMiddlewarePrefetchSkipResponse } from "./pages-data-route.js";
6
8
  import { mergeHeaders } from "./worker-utils.js";
7
9
  //#region src/server/pages-request-pipeline.ts
8
10
  async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset) {
@@ -141,6 +143,22 @@ async function runPagesRequest(request, deps) {
141
143
  });
142
144
  let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
143
145
  const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
146
+ const matchedPathnameForRoute = (routePattern) => {
147
+ const matchedPathname = routePattern ? patternToNextFormat(routePattern) : resolvedPathname;
148
+ if (!i18nConfig) return matchedPathname;
149
+ const resolvedLocale = resolvedPathname.split("/", 3)[1];
150
+ if (resolvedLocale && i18nConfig.locales.includes(resolvedLocale)) return matchedPathname === "/" ? `/${resolvedLocale}` : `/${resolvedLocale}${matchedPathname}`;
151
+ return matchResolvedPathname(matchedPathname);
152
+ };
153
+ const buildMiddlewarePrefetchSkipResult = (match) => {
154
+ if (!match) return null;
155
+ if (match.route.dataKind !== "server" || !isDataRequest || !deps.hasMiddleware || request.headers.get("x-middleware-prefetch") !== "1") return null;
156
+ return {
157
+ type: "response",
158
+ response: mergeHeaders(buildMiddlewarePrefetchSkipResponse(matchedPathnameForRoute(match.route.pattern)), middlewareHeaders, void 0),
159
+ defaultContentType: "application/json"
160
+ };
161
+ };
144
162
  if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
145
163
  configHeaders,
146
164
  pathname: matchPathname,
@@ -170,14 +188,16 @@ async function runPagesRequest(request, deps) {
170
188
  const beforeFilesResult = await serveFilesystemRoute(resolvedPathname, "beforeFiles");
171
189
  if (beforeFilesResult) return beforeFilesResult;
172
190
  }
173
- if (basePath && !hadBasePath && !configRewriteFired) return {
191
+ const isOutsideBasePathUnclaimed = () => basePath && !hadBasePath && !configRewriteFired;
192
+ const outOfBasePathNotFound = () => ({
174
193
  type: "response",
175
194
  response: new Response("This page could not be found", {
176
195
  status: 404,
177
196
  headers: { "Content-Type": "text/html; charset=utf-8" }
178
197
  })
179
- };
198
+ });
180
199
  const handleResolvedApiRoute = async () => {
200
+ if (isOutsideBasePathUnclaimed()) return null;
181
201
  const apiLookupUrl = stripI18nLocaleForApiRoute(resolvedUrl, i18nConfig);
182
202
  const apiLookupPathname = apiLookupUrl.split("?")[0];
183
203
  if (!apiLookupPathname.startsWith("/api/") && apiLookupPathname !== "/api") return null;
@@ -204,7 +224,7 @@ async function runPagesRequest(request, deps) {
204
224
  };
205
225
  const apiResult = await handleResolvedApiRoute();
206
226
  if (apiResult) return apiResult;
207
- let pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
227
+ let pageMatch = !isOutsideBasePathUnclaimed() && deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
208
228
  let resolvedPathnameChanged = false;
209
229
  if (!pageMatch || pageMatch.route.isDynamic) for (const rewrite of configRewrites.afterFiles ?? []) {
210
230
  const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
@@ -215,6 +235,7 @@ async function runPagesRequest(request, deps) {
215
235
  };
216
236
  resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
217
237
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
238
+ configRewriteFired = true;
218
239
  resolvedPathnameChanged = true;
219
240
  const afterFilesFilesystemResult = await serveFilesystemRoute(resolvedPathname, "afterFiles");
220
241
  if (afterFilesFilesystemResult) return afterFilesFilesystemResult;
@@ -231,7 +252,7 @@ async function runPagesRequest(request, deps) {
231
252
  refreshDataRewriteHeader();
232
253
  if (typeof deps.renderPage === "function") {
233
254
  let renderPageMatch = pageMatch;
234
- if ((isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
255
+ if ((isOutsideBasePathUnclaimed() || isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
235
256
  const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
236
257
  if (!fallbackRewrite) continue;
237
258
  if (isExternalUrl(fallbackRewrite)) return {
@@ -240,6 +261,7 @@ async function runPagesRequest(request, deps) {
240
261
  };
241
262
  resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
242
263
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
264
+ configRewriteFired = true;
243
265
  const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
244
266
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
245
267
  const fallbackApiResult = await handleResolvedApiRoute();
@@ -248,6 +270,9 @@ async function runPagesRequest(request, deps) {
248
270
  refreshDataRewriteHeader();
249
271
  if (renderPageMatch) break;
250
272
  }
273
+ const prefetchSkipResult = buildMiddlewarePrefetchSkipResult(renderPageMatch);
274
+ if (prefetchSkipResult) return prefetchSkipResult;
275
+ if (isOutsideBasePathUnclaimed()) return outOfBasePathNotFound();
251
276
  const shouldDeferErrorPageOnMiss = !isDataReq && !isDataRequest && !!deps.matchPageRoute && !renderPageMatch;
252
277
  const initialRenderOptions = shouldDeferErrorPageOnMiss ? { renderErrorPageOnMiss: false } : isDataReq ? { isDataReq: true } : void 0;
253
278
  const stagedHeaders = new Headers();
@@ -264,16 +289,33 @@ async function runPagesRequest(request, deps) {
264
289
  };
265
290
  resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
266
291
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
292
+ configRewriteFired = true;
267
293
  const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
268
294
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
269
295
  const fallbackApiResult = await handleResolvedApiRoute();
270
296
  if (fallbackApiResult) return fallbackApiResult;
297
+ renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
271
298
  response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
272
299
  matchedFallbackRewrite = true;
273
300
  if (response.status !== 404) break;
274
301
  }
275
302
  if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
276
- const merged = mergeHeaders(response, middlewareHeaders, middlewareStatus);
303
+ const matchedPathHeaders = { ...middlewareHeaders };
304
+ if ((isDataReq || isDataRequest) && deps.hasMiddleware && !renderPageMatch && response.status === 404 && (middlewareStatus === void 0 || middlewareStatus === 200 || middlewareStatus === 404)) {
305
+ const headers = new Headers(response.headers);
306
+ headers.set("content-type", "application/json");
307
+ headers.set("x-nextjs-matched-path", matchResolvedPathname(pathname));
308
+ return {
309
+ type: "response",
310
+ response: mergeHeaders(new Response("{}", {
311
+ status: 200,
312
+ headers
313
+ }), matchedPathHeaders, void 0),
314
+ defaultContentType: "application/json"
315
+ };
316
+ }
317
+ if ((isDataReq || isDataRequest) && renderPageMatch && (middlewareStatus ?? response.status) === 200) matchedPathHeaders["x-nextjs-matched-path"] = matchedPathnameForRoute(renderPageMatch?.route.pattern);
318
+ const merged = mergeHeaders(response, matchedPathHeaders, middlewareStatus);
277
319
  if (merged !== response) merged.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
278
320
  return {
279
321
  type: "response",
@@ -281,7 +323,8 @@ async function runPagesRequest(request, deps) {
281
323
  defaultContentType: "text/html"
282
324
  };
283
325
  }
284
- if (!(resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch) && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
326
+ let devPageMatch = isOutsideBasePathUnclaimed() ? null : resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch;
327
+ if (!devPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
285
328
  const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
286
329
  if (!fallbackRewrite) continue;
287
330
  if (isExternalUrl(fallbackRewrite)) return {
@@ -290,12 +333,17 @@ async function runPagesRequest(request, deps) {
290
333
  };
291
334
  resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
292
335
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
336
+ configRewriteFired = true;
293
337
  const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
294
338
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
295
339
  const fallbackApiResult = await handleResolvedApiRoute();
296
340
  if (fallbackApiResult) return fallbackApiResult;
297
- if (deps.matchPageRoute?.(resolvedPathname, request)) break;
341
+ devPageMatch = deps.matchPageRoute?.(resolvedPathname, request) ?? null;
342
+ if (devPageMatch) break;
298
343
  }
344
+ const prefetchSkipResult = buildMiddlewarePrefetchSkipResult(devPageMatch);
345
+ if (prefetchSkipResult) return prefetchSkipResult;
346
+ if (isOutsideBasePathUnclaimed()) return outOfBasePathNotFound();
299
347
  refreshDataRewriteHeader();
300
348
  return {
301
349
  type: "render",
@@ -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 { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
6
+ import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.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) {
@@ -41,6 +41,7 @@ import { IncomingMessage, ServerResponse } from "node:http";
41
41
  * Exported for direct unit testing of the URL choice.
42
42
  */
43
43
  declare function resolveServerEntryImportUrl(entryPath: string): string;
44
+ declare function rememberCurrentServerEntryImportMtime(entryPath: string): void;
44
45
  declare function importServerEntryModule(entryPath: string): Promise<any>;
45
46
  /** Convert a Node.js IncomingMessage into a ReadableStream for Web Request body. */
46
47
  declare function readNodeStream(req: IncomingMessage): ReadableStream<Uint8Array>;
@@ -54,7 +55,8 @@ type ProdServerOptions = {
54
55
  * Omitted for normal `vinext start` so the existing production-server output
55
56
  * remains stable.
56
57
  */
57
- purpose?: "prerender";
58
+ purpose?: "prerender"; /** Suppress the startup log for internal child-process servers. */
59
+ silent?: boolean;
58
60
  };
59
61
  /** Content types that benefit from compression. */
60
62
  declare const COMPRESSIBLE_TYPES: Set<string>;
@@ -74,7 +76,7 @@ declare function mergeResponseHeaders(middlewareHeaders: Record<string, string |
74
76
  * arguments in (headers, response) order. The request path now calls
75
77
  * `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
76
78
  * 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.)
79
+ * implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
78
80
  */
79
81
  declare function mergeWebResponse(middlewareHeaders: Record<string, string | string[]>, response: Response, statusOverride?: number): Response;
80
82
  /**
@@ -145,4 +147,4 @@ declare function resolveAppRouterPrerenderSeeder(entryModule: unknown): AppRoute
145
147
  */
146
148
  declare function resolveAppRouterAssetPath(pathname: string, assetPathPrefix: string, assetPrefix: string): string | null;
147
149
  //#endregion
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 };
150
+ export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, rememberCurrentServerEntryImportMtime, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
@@ -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, VINEXT_PRERENDER_SPECULATIVE_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, normalizeNextDataPagePathname, parseNextDataPathname } from "./pages-data-route.js";
11
+ import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
12
+ import { setPagesClientAssets } from "./pages-client-assets.js";
9
13
  import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
10
14
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, isSafeImageContentType, parseImageParams } from "./image-optimization.js";
11
15
  import { installSocketErrorBackstop } from "./socket-error-backstop.js";
12
- import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
13
16
  import { CONTENT_TYPES, StaticFileCache, etagFromFilenameHash } from "./static-file-cache.js";
14
- import { buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname } from "./pages-data-route.js";
15
17
  import { collectInlineCssManifest } from "../build/inline-css.js";
16
18
  import { mergeHeaders } from "./worker-utils.js";
17
19
  import { runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
18
- import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
19
20
  import { computeClientRuntimeMetadata } from "../utils/client-runtime-metadata.js";
21
+ import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.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.
@@ -54,6 +56,18 @@ import { Readable, pipeline } from "node:stream";
54
56
  * through a cache-busted URL instead.
55
57
  */
56
58
  const bareServerEntryMtimes = /* @__PURE__ */ new Map();
59
+ function resolveCanonicalServerEntry(entryPath) {
60
+ let canonicalEntryPath;
61
+ try {
62
+ canonicalEntryPath = fs.realpathSync.native(entryPath);
63
+ } catch {
64
+ canonicalEntryPath = entryPath;
65
+ }
66
+ return {
67
+ href: pathToFileURL(canonicalEntryPath).href,
68
+ mtime: fs.statSync(canonicalEntryPath).mtimeMs
69
+ };
70
+ }
57
71
  /**
58
72
  * Import a built server entry module (App Router RSC entry or Pages Router
59
73
  * server entry) by absolute file path.
@@ -91,14 +105,7 @@ const bareServerEntryMtimes = /* @__PURE__ */ new Map();
91
105
  * Exported for direct unit testing of the URL choice.
92
106
  */
93
107
  function resolveServerEntryImportUrl(entryPath) {
94
- let canonicalEntryPath;
95
- try {
96
- canonicalEntryPath = fs.realpathSync.native(entryPath);
97
- } catch {
98
- canonicalEntryPath = entryPath;
99
- }
100
- const href = pathToFileURL(canonicalEntryPath).href;
101
- const mtime = fs.statSync(canonicalEntryPath).mtimeMs;
108
+ const { href, mtime } = resolveCanonicalServerEntry(entryPath);
102
109
  const bareMtime = bareServerEntryMtimes.get(href);
103
110
  if (bareMtime === void 0 || bareMtime === mtime) {
104
111
  bareServerEntryMtimes.set(href, mtime);
@@ -106,6 +113,10 @@ function resolveServerEntryImportUrl(entryPath) {
106
113
  }
107
114
  return `${href}?t=${mtime}`;
108
115
  }
116
+ function rememberCurrentServerEntryImportMtime(entryPath) {
117
+ const { href, mtime } = resolveCanonicalServerEntry(entryPath);
118
+ bareServerEntryMtimes.set(href, mtime);
119
+ }
109
120
  async function importServerEntryModule(entryPath) {
110
121
  return import(resolveServerEntryImportUrl(entryPath));
111
122
  }
@@ -275,8 +286,11 @@ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
275
286
  assetBase,
276
287
  assetPrefix
277
288
  });
278
- globalThis.__VINEXT_LAZY_CHUNKS__ = metadata.lazyChunks;
279
- globalThis.__VINEXT_DYNAMIC_PRELOADS__ = metadata.dynamicPreloads;
289
+ setPagesClientAssets({
290
+ appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
291
+ lazyChunks: metadata.lazyChunks,
292
+ dynamicPreloads: metadata.dynamicPreloads
293
+ });
280
294
  }
281
295
  function isNoBodyResponseStatus(status) {
282
296
  return NO_BODY_RESPONSE_STATUSES.has(status);
@@ -305,7 +319,7 @@ function logProdServerStarted(host, port, purpose) {
305
319
  * arguments in (headers, response) order. The request path now calls
306
320
  * `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
307
321
  * 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.)
322
+ * implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
309
323
  */
310
324
  function mergeWebResponse(middlewareHeaders, response, statusOverride) {
311
325
  return mergeHeaders(response, middlewareHeaders, statusOverride);
@@ -552,9 +566,11 @@ function nodeToWebRequest(req, urlOverride, prerenderSecret) {
552
566
  const url = new URL(urlOverride ?? req.url ?? "/", origin);
553
567
  const rawHeaders = nodeHeadersToWebHeaders(req.headers);
554
568
  const prerenderRouteParamsPayload = readTrustedPrerenderRouteParamsFromHeaders(rawHeaders, prerenderSecret);
569
+ const isTrustedSpeculativePrerender = process.env.VINEXT_PRERENDER === "1" && prerenderSecret !== void 0 && rawHeaders.get("x-vinext-prerender-secret") === prerenderSecret && rawHeaders.get("x-vinext-prerender-speculative") === "1";
555
570
  const headers = filterInternalHeaders(rawHeaders);
556
571
  const prerenderRouteParamsHeader = serializePrerenderRouteParamsHeader(prerenderRouteParamsPayload);
557
572
  if (prerenderRouteParamsHeader !== null) headers.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
573
+ if (isTrustedSpeculativePrerender) headers.set(VINEXT_PRERENDER_SPECULATIVE_HEADER, "1");
558
574
  const method = req.method ?? "GET";
559
575
  const hasBody = method !== "GET" && method !== "HEAD";
560
576
  const init = {
@@ -617,7 +633,7 @@ async function sendWebResponse(webResponse, req, res, compress) {
617
633
  */
618
634
  async function startProdServer(options = {}) {
619
635
  installSocketErrorBackstop();
620
- const { port = process.env.PORT ? parseInt(process.env.PORT) : 3e3, host = "0.0.0.0", outDir = path.resolve("dist"), noCompression = false, purpose } = options;
636
+ const { port = process.env.PORT ? parseInt(process.env.PORT) : 3e3, host = "0.0.0.0", outDir = path.resolve("dist"), noCompression = false, purpose, silent = false } = options;
621
637
  const compress = !noCompression;
622
638
  const resolvedOutDir = path.resolve(outDir);
623
639
  const clientDir = path.join(resolvedOutDir, "client");
@@ -635,7 +651,8 @@ async function startProdServer(options = {}) {
635
651
  clientDir,
636
652
  rscEntryPath,
637
653
  compress,
638
- purpose
654
+ purpose,
655
+ silent
639
656
  });
640
657
  return startPagesRouterServer({
641
658
  port,
@@ -643,7 +660,8 @@ async function startProdServer(options = {}) {
643
660
  clientDir,
644
661
  serverEntryPath,
645
662
  compress,
646
- purpose
663
+ purpose,
664
+ silent
647
665
  });
648
666
  }
649
667
  function createNodeExecutionContext() {
@@ -736,18 +754,21 @@ function readSsrManifest(clientDir) {
736
754
  }
737
755
  return parsed;
738
756
  }
739
- function installPagesClientAssetGlobals(options) {
757
+ function installPagesClientAssets(options) {
740
758
  const ssrManifest = readSsrManifest(options.clientDir);
741
- globalThis.__VINEXT_SSR_MANIFEST__ = Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0;
742
759
  const metadata = computeClientRuntimeMetadata({
743
760
  clientDir: options.clientDir,
744
761
  assetBase: options.assetBase,
745
762
  assetPrefix: options.assetPrefix,
746
763
  includeClientEntry: options.clientEntryLookup === "pages-client-entry" ? "pages-client-entry" : true
747
764
  });
748
- globalThis.__VINEXT_CLIENT_ENTRY__ = metadata.clientEntryFile;
749
- globalThis.__VINEXT_LAZY_CHUNKS__ = metadata.lazyChunks;
750
- globalThis.__VINEXT_DYNAMIC_PRELOADS__ = metadata.dynamicPreloads;
765
+ setPagesClientAssets({
766
+ clientEntry: metadata.clientEntryFile,
767
+ appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
768
+ ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
769
+ lazyChunks: metadata.lazyChunks,
770
+ dynamicPreloads: metadata.dynamicPreloads
771
+ });
751
772
  return ssrManifest;
752
773
  }
753
774
  /**
@@ -768,12 +789,7 @@ function installPagesClientAssetGlobals(options) {
768
789
  * 4. Stream the Web Response back (with optional compression)
769
790
  */
770
791
  async function startAppRouterServer(options) {
771
- 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 {}
792
+ const { port, host, clientDir, rscEntryPath, compress, purpose, silent } = options;
777
793
  const prerenderSecret = readPrerenderSecret(path.dirname(rscEntryPath));
778
794
  const rscModule = await importServerEntryModule(rscEntryPath);
779
795
  const rscHandler = resolveAppRouterHandler(rscModule.default);
@@ -781,10 +797,18 @@ async function startAppRouterServer(options) {
781
797
  const appRouterBasePath = typeof rscModule.__basePath === "string" ? rscModule.__basePath : "";
782
798
  const appRouterInlineCss = rscModule.__inlineCss === true;
783
799
  const appRouterHasPagesDir = rscModule.__hasPagesDir === true;
800
+ const appImageAllowedWidths = Array.isArray(rscModule.__imageAllowedWidths) ? rscModule.__imageAllowedWidths : [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES];
801
+ let imageConfig = typeof rscModule.__imageConfig === "object" && rscModule.__imageConfig !== null ? rscModule.__imageConfig : void 0;
802
+ if (imageConfig === void 0) {
803
+ const imageConfigPath = path.join(path.dirname(rscEntryPath), "image-config.json");
804
+ if (fs.existsSync(imageConfigPath)) try {
805
+ imageConfig = JSON.parse(fs.readFileSync(imageConfigPath, "utf-8"));
806
+ } catch {}
807
+ }
784
808
  globalThis.__VINEXT_INLINE_CSS__ = appRouterInlineCss ? collectInlineCssManifest(clientDir, appRouterAssetPrefix) : void 0;
785
809
  const appAssetPathPrefix = assetPrefixPathname(appRouterAssetPrefix);
786
810
  const appAssetBase = appRouterBasePath ? `${appRouterBasePath}/` : "/";
787
- if (appRouterHasPagesDir) installPagesClientAssetGlobals({
811
+ if (appRouterHasPagesDir) installPagesClientAssets({
788
812
  clientDir,
789
813
  assetPrefix: appRouterAssetPrefix,
790
814
  assetBase: appAssetBase,
@@ -828,7 +852,7 @@ async function startAppRouterServer(options) {
828
852
  }
829
853
  }
830
854
  if (isImageOptimizationPath(pathname)) {
831
- const params = parseImageParams(new URL(rawUrl, "http://localhost"), [...imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES], imageConfig?.qualities);
855
+ const params = parseImageParams(new URL(rawUrl, "http://localhost"), appImageAllowedWidths, imageConfig?.qualities);
832
856
  if (!params) {
833
857
  res.writeHead(400);
834
858
  res.end("Bad Request");
@@ -888,7 +912,8 @@ async function startAppRouterServer(options) {
888
912
  await new Promise((resolve) => {
889
913
  server.listen(port, host, () => {
890
914
  const addr = server.address();
891
- logProdServerStarted(host, typeof addr === "object" && addr ? addr.port : port, purpose);
915
+ const actualPort = typeof addr === "object" && addr ? addr.port : port;
916
+ if (!silent) logProdServerStarted(host, actualPort, purpose);
892
917
  resolve();
893
918
  });
894
919
  });
@@ -919,10 +944,11 @@ function readPagesServerEntryPageRoutes(value) {
919
944
  * - vinextConfig — embedded next.config.js settings
920
945
  */
921
946
  async function startPagesRouterServer(options) {
922
- const { port, host, clientDir, serverEntryPath, compress, purpose } = options;
947
+ const { port, host, clientDir, serverEntryPath, compress, purpose, silent } = options;
923
948
  const serverEntry = await importServerEntryModule(serverEntryPath);
924
949
  const { renderPage, handleApiRoute: handleApi, runMiddleware, vinextConfig, buildId: pagesBuildId } = serverEntry;
925
950
  const matchPageRoute = typeof serverEntry.matchPageRoute === "function" ? serverEntry.matchPageRoute : void 0;
951
+ const hasMiddleware = serverEntry.hasMiddleware === true;
926
952
  const pageRoutes = readPagesServerEntryPageRoutes(serverEntry.pageRoutes);
927
953
  const prerenderSecret = readPrerenderSecret(path.dirname(serverEntryPath));
928
954
  const basePath = vinextConfig?.basePath ?? "";
@@ -946,7 +972,7 @@ async function startPagesRouterServer(options) {
946
972
  contentDispositionType: vinextConfig.images.contentDispositionType,
947
973
  contentSecurityPolicy: vinextConfig.images.contentSecurityPolicy
948
974
  } : void 0;
949
- const ssrManifest = installPagesClientAssetGlobals({
975
+ const ssrManifest = installPagesClientAssets({
950
976
  clientDir,
951
977
  assetPrefix,
952
978
  assetBase,
@@ -1050,8 +1076,9 @@ async function startPagesRouterServer(options) {
1050
1076
  }
1051
1077
  isDataReq = true;
1052
1078
  const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
1053
- url = dataMatch.pagePathname + qs;
1054
- pathname = dataMatch.pagePathname;
1079
+ const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, hasMiddleware && trailingSlash);
1080
+ url = pagePathname + qs;
1081
+ pathname = pagePathname;
1055
1082
  }
1056
1083
  const protocol = resolveRequestProtocol(req);
1057
1084
  const hostHeader = resolveRequestHost(req, `${host}:${port}`);
@@ -1075,6 +1102,7 @@ async function startPagesRouterServer(options) {
1075
1102
  hadBasePath,
1076
1103
  isDataReq,
1077
1104
  isDataRequest,
1105
+ hasMiddleware,
1078
1106
  ctx: void 0,
1079
1107
  rawSearch: rawQs,
1080
1108
  matchPageRoute: matchPageRoute ?? null,
@@ -1131,7 +1159,8 @@ async function startPagesRouterServer(options) {
1131
1159
  await new Promise((resolve) => {
1132
1160
  server.listen(port, host, () => {
1133
1161
  const addr = server.address();
1134
- logProdServerStarted(host, typeof addr === "object" && addr ? addr.port : port, purpose);
1162
+ const actualPort = typeof addr === "object" && addr ? addr.port : port;
1163
+ if (!silent) logProdServerStarted(host, actualPort, purpose);
1135
1164
  resolve();
1136
1165
  });
1137
1166
  });
@@ -1142,4 +1171,4 @@ async function startPagesRouterServer(options) {
1142
1171
  };
1143
1172
  }
1144
1173
  //#endregion
1145
- export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
1174
+ export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, rememberCurrentServerEntryImportMtime, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
@@ -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";
@@ -337,7 +338,7 @@ function isOriginAllowed(origin, allowed) {
337
338
  */
338
339
  function processMiddlewareHeaders(headers) {
339
340
  const keysToDelete = [];
340
- for (const key of headers.keys()) if (key.startsWith("x-middleware-")) keysToDelete.push(key);
341
+ for (const key of headers.keys()) if (key.startsWith("x-middleware-") && key !== "x-middleware-cache") keysToDelete.push(key);
341
342
  for (const key of keysToDelete) headers.delete(key);
342
343
  }
343
344
  const STRIPPED_INTERNAL_HEADERS = new Set([...INTERNAL_HEADERS, ...VINEXT_INTERNAL_HEADERS]);