vinext 0.1.8 → 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 (237) 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.js +40 -2
  17. package/dist/cli-args.d.ts +1 -2
  18. package/dist/cli-args.js +1 -1
  19. package/dist/cli-dev-config.d.ts +12 -0
  20. package/dist/cli-dev-config.js +23 -0
  21. package/dist/cli.js +111 -95
  22. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  23. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  24. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  25. package/dist/{server → client}/dev-error-overlay.js +2 -2
  26. package/dist/client/navigation-runtime.d.ts +2 -0
  27. package/dist/client/navigation-runtime.js +3 -1
  28. package/dist/client/window-next.d.ts +2 -1
  29. package/dist/cloudflare/index.d.ts +2 -2
  30. package/dist/cloudflare/index.js +2 -2
  31. package/dist/config/config-matchers.js +14 -10
  32. package/dist/config/next-config.d.ts +5 -3
  33. package/dist/config/next-config.js +44 -1
  34. package/dist/config/prerender.d.ts +34 -0
  35. package/dist/config/prerender.js +55 -0
  36. package/dist/entries/app-rsc-entry.d.ts +2 -1
  37. package/dist/entries/app-rsc-entry.js +40 -10
  38. package/dist/entries/app-rsc-manifest.js +2 -0
  39. package/dist/entries/pages-client-entry.d.ts +3 -0
  40. package/dist/entries/pages-client-entry.js +15 -1
  41. package/dist/entries/pages-server-entry.js +5 -2
  42. package/dist/image/image-adapters-virtual.d.ts +59 -0
  43. package/dist/image/image-adapters-virtual.js +59 -0
  44. package/dist/index.d.ts +33 -0
  45. package/dist/index.js +167 -100
  46. package/dist/init-cloudflare.d.ts +43 -0
  47. package/dist/init-cloudflare.js +839 -0
  48. package/dist/init-platform.d.ts +40 -0
  49. package/dist/init-platform.js +195 -0
  50. package/dist/init.d.ts +16 -38
  51. package/dist/init.js +209 -99
  52. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  53. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  54. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  55. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  56. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
  57. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  58. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  59. package/dist/packages/cloudflare/src/deploy.js +276 -0
  60. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  61. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
  62. package/dist/plugins/ast-scope.d.ts +16 -0
  63. package/dist/plugins/ast-scope.js +62 -0
  64. package/dist/plugins/ast-utils.d.ts +27 -1
  65. package/dist/plugins/ast-utils.js +32 -1
  66. package/dist/plugins/css-module-imports.d.ts +14 -0
  67. package/dist/plugins/css-module-imports.js +59 -0
  68. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  69. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  70. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  71. package/dist/plugins/typeof-window.d.ts +1 -1
  72. package/dist/plugins/typeof-window.js +28 -56
  73. package/dist/routing/app-route-graph.d.ts +23 -2
  74. package/dist/routing/app-route-graph.js +126 -32
  75. package/dist/routing/file-matcher.d.ts +3 -0
  76. package/dist/routing/file-matcher.js +3 -0
  77. package/dist/routing/pages-router.js +2 -2
  78. package/dist/server/api-handler.js +9 -14
  79. package/dist/server/app-browser-action-result.d.ts +4 -1
  80. package/dist/server/app-browser-action-result.js +8 -1
  81. package/dist/server/app-browser-entry.js +161 -52
  82. package/dist/server/app-browser-interception-context.d.ts +1 -0
  83. package/dist/server/app-browser-interception-context.js +4 -2
  84. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  85. package/dist/server/app-browser-navigation-controller.js +60 -31
  86. package/dist/server/app-browser-server-action-client.d.ts +1 -1
  87. package/dist/server/app-browser-server-action-client.js +3 -4
  88. package/dist/server/app-browser-state.d.ts +11 -1
  89. package/dist/server/app-browser-state.js +25 -8
  90. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  91. package/dist/server/app-browser-visible-commit.js +43 -25
  92. package/dist/server/app-elements-wire.d.ts +9 -2
  93. package/dist/server/app-elements-wire.js +8 -1
  94. package/dist/server/app-elements.d.ts +2 -2
  95. package/dist/server/app-elements.js +4 -3
  96. package/dist/server/app-fallback-renderer.d.ts +2 -1
  97. package/dist/server/app-fallback-renderer.js +10 -6
  98. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  99. package/dist/server/app-hydration-cache-publication.js +43 -0
  100. package/dist/server/app-middleware.d.ts +4 -3
  101. package/dist/server/app-middleware.js +8 -3
  102. package/dist/server/app-optimistic-routing.js +11 -4
  103. package/dist/server/app-page-cache-finalizer.js +2 -1
  104. package/dist/server/app-page-cache-render.d.ts +1 -0
  105. package/dist/server/app-page-cache-render.js +8 -4
  106. package/dist/server/app-page-cache.d.ts +1 -0
  107. package/dist/server/app-page-cache.js +5 -2
  108. package/dist/server/app-page-dispatch.js +1 -0
  109. package/dist/server/app-page-element-builder.d.ts +2 -1
  110. package/dist/server/app-page-element-builder.js +58 -4
  111. package/dist/server/app-page-probe.js +5 -0
  112. package/dist/server/app-page-render-identity.d.ts +1 -0
  113. package/dist/server/app-page-render-identity.js +1 -1
  114. package/dist/server/app-page-render.js +18 -0
  115. package/dist/server/app-page-request.d.ts +14 -0
  116. package/dist/server/app-page-request.js +69 -4
  117. package/dist/server/app-page-route-wiring.d.ts +8 -1
  118. package/dist/server/app-page-route-wiring.js +32 -18
  119. package/dist/server/app-page-segment-state.d.ts +2 -1
  120. package/dist/server/app-page-segment-state.js +3 -1
  121. package/dist/server/app-page-stream.d.ts +5 -0
  122. package/dist/server/app-page-stream.js +3 -1
  123. package/dist/server/app-route-handler-execution.js +5 -1
  124. package/dist/server/app-route-handler-response.js +1 -0
  125. package/dist/server/app-route-handler-runtime.js +1 -1
  126. package/dist/server/app-router-entry.js +9 -2
  127. package/dist/server/app-rsc-handler.d.ts +1 -0
  128. package/dist/server/app-rsc-handler.js +62 -31
  129. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  130. package/dist/server/app-rsc-request-normalization.js +6 -3
  131. package/dist/server/app-segment-config.d.ts +11 -0
  132. package/dist/server/app-segment-config.js +62 -6
  133. package/dist/server/app-server-action-execution.d.ts +1 -0
  134. package/dist/server/app-server-action-execution.js +58 -28
  135. package/dist/server/app-ssr-entry.d.ts +3 -0
  136. package/dist/server/app-ssr-entry.js +15 -7
  137. package/dist/server/app-ssr-stream.d.ts +7 -3
  138. package/dist/server/app-ssr-stream.js +10 -6
  139. package/dist/server/app-visited-response-cache.d.ts +6 -0
  140. package/dist/server/app-visited-response-cache.js +3 -1
  141. package/dist/server/client-trace-metadata.js +26 -0
  142. package/dist/server/default-global-not-found-module.d.ts +14 -0
  143. package/dist/server/default-global-not-found-module.js +14 -0
  144. package/dist/server/dev-route-files.js +4 -0
  145. package/dist/server/dev-server.js +19 -18
  146. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  147. package/dist/server/dev-stack-sourcemap.js +1 -1
  148. package/dist/server/fetch-handler.d.ts +2 -0
  149. package/dist/server/fetch-handler.js +18 -0
  150. package/dist/server/headers.d.ts +3 -15
  151. package/dist/server/headers.js +2 -15
  152. package/dist/server/image-optimization.d.ts +51 -1
  153. package/dist/server/image-optimization.js +52 -2
  154. package/dist/server/implicit-tags.js +1 -1
  155. package/dist/server/isr-cache.d.ts +1 -1
  156. package/dist/server/isr-cache.js +2 -2
  157. package/dist/server/metadata-routes.d.ts +3 -1
  158. package/dist/server/metadata-routes.js +12 -2
  159. package/dist/server/middleware-runtime.js +6 -1
  160. package/dist/server/navigation-planner.d.ts +1 -0
  161. package/dist/server/navigation-planner.js +14 -3
  162. package/dist/server/pages-api-route.js +2 -2
  163. package/dist/server/pages-asset-tags.d.ts +4 -6
  164. package/dist/server/pages-asset-tags.js +12 -12
  165. package/dist/server/pages-client-assets.d.ts +12 -0
  166. package/dist/server/pages-client-assets.js +10 -0
  167. package/dist/server/pages-node-compat.d.ts +8 -1
  168. package/dist/server/pages-node-compat.js +32 -4
  169. package/dist/server/pages-page-data.d.ts +24 -1
  170. package/dist/server/pages-page-data.js +45 -24
  171. package/dist/server/pages-page-handler.d.ts +2 -1
  172. package/dist/server/pages-page-handler.js +19 -12
  173. package/dist/server/pages-page-response.d.ts +7 -0
  174. package/dist/server/pages-page-response.js +4 -1
  175. package/dist/server/pages-request-pipeline.d.ts +2 -0
  176. package/dist/server/pages-request-pipeline.js +25 -1
  177. package/dist/server/pages-router-entry.d.ts +30 -0
  178. package/dist/server/pages-router-entry.js +108 -0
  179. package/dist/server/prerender-manifest.d.ts +3 -1
  180. package/dist/server/prerender-route-params.js +1 -1
  181. package/dist/server/prod-server.d.ts +1 -1
  182. package/dist/server/prod-server.js +33 -20
  183. package/dist/server/request-pipeline.js +1 -0
  184. package/dist/server/seed-cache.js +4 -4
  185. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  186. package/dist/shims/app-router-scroll-state.js +1 -0
  187. package/dist/shims/app-router-scroll.js +2 -1
  188. package/dist/shims/cache.js +19 -15
  189. package/dist/shims/cdn-cache.js +1 -1
  190. package/dist/shims/dynamic-preload-chunks.js +2 -1
  191. package/dist/shims/form.d.ts +3 -1
  192. package/dist/shims/form.js +37 -43
  193. package/dist/shims/headers.d.ts +7 -1
  194. package/dist/shims/headers.js +17 -3
  195. package/dist/shims/image.js +75 -14
  196. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  197. package/dist/shims/internal/app-route-detection.js +4 -17
  198. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  199. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  200. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
  201. package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
  202. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
  203. package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
  204. package/dist/shims/internal/pages-data-target.d.ts +10 -9
  205. package/dist/shims/internal/pages-data-target.js +91 -12
  206. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  207. package/dist/shims/internal/pages-router-components.js +13 -0
  208. package/dist/shims/layout-segment-context.d.ts +4 -1
  209. package/dist/shims/layout-segment-context.js +18 -4
  210. package/dist/shims/link.js +55 -26
  211. package/dist/shims/navigation.d.ts +5 -1
  212. package/dist/shims/navigation.js +45 -10
  213. package/dist/shims/navigation.react-server.js +1 -1
  214. package/dist/shims/root-params.d.ts +15 -1
  215. package/dist/shims/root-params.js +21 -1
  216. package/dist/shims/router.d.ts +5 -7
  217. package/dist/shims/router.js +362 -93
  218. package/dist/shims/server.js +3 -2
  219. package/dist/shims/slot.js +3 -6
  220. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  221. package/dist/utils/client-runtime-metadata.js +31 -22
  222. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  223. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  224. package/dist/utils/domain-locale.d.ts +6 -3
  225. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  226. package/dist/{server → utils}/middleware-request-headers.js +2 -2
  227. package/dist/utils/project.d.ts +48 -2
  228. package/dist/utils/project.js +225 -4
  229. package/dist/utils/protocol-headers.d.ts +17 -0
  230. package/dist/utils/protocol-headers.js +17 -0
  231. package/dist/utils/react-version.d.ts +4 -0
  232. package/dist/utils/react-version.js +44 -0
  233. package/package.json +47 -2
  234. package/dist/deploy.d.ts +0 -197
  235. package/dist/deploy.js +0 -1040
  236. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  237. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -197,6 +197,7 @@ type ResolvePagesPageDataOptions = {
197
197
  };
198
198
  type ResolvePagesPageDataRenderResult = {
199
199
  kind: "render";
200
+ documentReqRes: PagesGsspContextResponse | null;
200
201
  gsspRes: PagesGsspResponse | null;
201
202
  isrRevalidateSeconds: number | null;
202
203
  pageProps: Record<string, unknown>;
@@ -217,7 +218,29 @@ type ResolvePagesPageDataNotFoundResult = {
217
218
  kind: "notFound";
218
219
  };
219
220
  type ResolvePagesPageDataResult = ResolvePagesPageDataRenderResult | ResolvePagesPageDataResponseResult | ResolvePagesPageDataNotFoundResult;
221
+ /**
222
+ * Compare a `getStaticPaths` entry against the actual request params.
223
+ *
224
+ * Handles both shapes Next.js allows:
225
+ * - { params: { ... } }
226
+ * - "string-path"
227
+ *
228
+ * For a string entry, compare the entry against the current request URL using
229
+ * the shared `normalizeStaticPathname` helper from
230
+ * `../routing/route-pattern.ts` (which mirrors the Next.js
231
+ * `removeTrailingSlash` behaviour in
232
+ * `.nextjs-ref/packages/next/src/build/static-paths/pages.ts`). For an object
233
+ * entry with a missing `params` key, return false rather than throwing — the
234
+ * caller will respond with a 404 just like Next.js does for unlisted paths.
235
+ */
236
+ type PagesRouteParam = {
237
+ key: string;
238
+ repeat: boolean;
239
+ optional: boolean;
240
+ };
241
+ declare function getPagesRouteParams(routePattern: string): PagesRouteParam[];
242
+ declare function matchesPagesStaticPath(pathEntry: PagesStaticPathsEntry, params: Record<string, unknown>, routeParams: PagesRouteParam[], routeUrl: string): boolean;
220
243
  declare function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string>;
221
244
  declare function resolvePagesPageData(options: ResolvePagesPageDataOptions): Promise<ResolvePagesPageDataResult>;
222
245
  //#endregion
223
- export { PagesPageModule, ResolvePagesPageDataOptions, renderPagesIsrHtml, resolvePagesPageData };
246
+ export { PagesPageModule, PagesRouteParam, PagesStaticPathsEntry, ResolvePagesPageDataOptions, getPagesRouteParams, matchesPagesStaticPath, renderPagesIsrHtml, resolvePagesPageData };
@@ -1,15 +1,15 @@
1
1
  import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
2
- import { normalizeStaticPathname } from "../routing/route-pattern.js";
3
2
  import { buildCacheStateHeaders } from "./cache-headers.js";
4
3
  import { isUnknownRecord } from "../utils/record.js";
5
4
  import { applyCdnResponseHeaders } from "./cache-control.js";
6
5
  import { decideIsr } from "./isr-decision.js";
7
6
  import { buildPagesCacheValue } from "./isr-cache.js";
8
- import { isSerializableProps } from "./pages-serializable-props.js";
7
+ import { normalizeStaticPathname } from "../routing/route-pattern.js";
8
+ import { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
9
9
  import { hasPagesGetInitialProps, isResponseSent, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
10
- import { isBotUserAgent } from "../utils/html-limited-bots.js";
11
10
  import { buildNextDataPropsJsonResponse } from "./pages-data-route.js";
12
- import { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
11
+ import { isSerializableProps } from "./pages-serializable-props.js";
12
+ import { isBotUserAgent } from "../utils/html-limited-bots.js";
13
13
  //#region src/server/pages-page-data.ts
14
14
  function buildPagesDataNotFoundResponse(deploymentId) {
15
15
  const headers = { "Content-Type": "application/json" };
@@ -128,28 +128,45 @@ function buildPagesRedirectResponse(redirect, options, props = { pageProps: {} }
128
128
  headers: { Location: destination }
129
129
  });
130
130
  }
131
- /**
132
- * Compare a `getStaticPaths` entry against the actual request params.
133
- *
134
- * Handles both shapes Next.js allows:
135
- * - { params: { ... } }
136
- * - "string-path"
137
- *
138
- * For a string entry, compare the entry against the current request URL using
139
- * the shared `normalizeStaticPathname` helper from
140
- * `../routing/route-pattern.ts` (which mirrors the Next.js
141
- * `removeTrailingSlash` behaviour in
142
- * `.nextjs-ref/packages/next/src/build/static-paths/pages.ts`). For an object
143
- * entry with a missing `params` key, return false rather than throwing — the
144
- * caller will respond with a 404 just like Next.js does for unlisted paths.
145
- */
146
- function matchesPagesStaticPath(pathEntry, params, routeUrl) {
131
+ function getPagesRouteParams(routePattern) {
132
+ return routePattern.split("/").map((segment) => {
133
+ const optionalCatchAll = segment.match(/^\[\[\.\.\.(.+)\]\]$/);
134
+ if (optionalCatchAll) return {
135
+ key: optionalCatchAll[1],
136
+ repeat: true,
137
+ optional: true
138
+ };
139
+ const requiredCatchAll = segment.match(/^\[\.\.\.(.+)\]$/);
140
+ if (requiredCatchAll) return {
141
+ key: requiredCatchAll[1],
142
+ repeat: true,
143
+ optional: false
144
+ };
145
+ const dynamic = segment.match(/^\[(.+)\]$/);
146
+ if (dynamic) return {
147
+ key: dynamic[1],
148
+ repeat: false,
149
+ optional: false
150
+ };
151
+ return null;
152
+ }).filter((param) => param !== null);
153
+ }
154
+ function matchesPagesStaticPath(pathEntry, params, routeParams, routeUrl) {
147
155
  if (typeof pathEntry === "string") return normalizeStaticPathname(pathEntry) === normalizeStaticPathname(routeUrl);
148
156
  const entryParams = pathEntry.params;
149
157
  if (entryParams === void 0 || entryParams === null) return false;
150
- return Object.entries(entryParams).every(([key, value]) => {
158
+ return routeParams.every(({ key, repeat, optional }) => {
159
+ if (!Object.hasOwn(entryParams, key)) return false;
160
+ let value = entryParams[key];
161
+ if (optional && (value === null || value === void 0 || value === false)) value = [];
162
+ if (repeat) {
163
+ if (!Array.isArray(value) || !optional && value.length === 0) return false;
164
+ } else if (typeof value !== "string") return false;
151
165
  const actual = params[key];
152
- if (Array.isArray(value)) return Array.isArray(actual) && value.join("/") === actual.join("/");
166
+ if (Array.isArray(value)) {
167
+ if (optional && value.length === 0 && actual === void 0) return true;
168
+ return Array.isArray(actual) && value.join("/") === actual.join("/");
169
+ }
153
170
  return String(value) === String(actual);
154
171
  });
155
172
  }
@@ -237,7 +254,9 @@ async function resolvePagesPageData(options) {
237
254
  defaultLocale: options.i18n.defaultLocale ?? ""
238
255
  });
239
256
  const fallback = pathsResult?.fallback ?? false;
240
- const isValidPath = (pathsResult?.paths ?? []).some((pathEntry) => matchesPagesStaticPath(pathEntry, options.params, options.routeUrl));
257
+ const paths = pathsResult?.paths ?? [];
258
+ const routeParams = getPagesRouteParams(options.routePattern);
259
+ const isValidPath = paths.some((pathEntry) => matchesPagesStaticPath(pathEntry, options.params, routeParams, options.routeUrl));
241
260
  if (fallback === false && !isValidPath) return buildPagesNotFoundResult(options);
242
261
  const isBotRequest = !!options.userAgent && isBotUserAgent(options.userAgent, options.htmlLimitedBots);
243
262
  if (fallback === true && !isValidPath && !options.isDataReq && !isBotRequest) isFallback = true;
@@ -273,6 +292,7 @@ async function resolvePagesPageData(options) {
273
292
  };
274
293
  return {
275
294
  kind: "render",
295
+ documentReqRes: sharedReqRes,
276
296
  gsspRes: null,
277
297
  isrRevalidateSeconds: null,
278
298
  pageProps,
@@ -473,6 +493,7 @@ async function resolvePagesPageData(options) {
473
493
  }
474
494
  return {
475
495
  kind: "render",
496
+ documentReqRes: sharedReqRes,
476
497
  gsspRes,
477
498
  isrRevalidateSeconds,
478
499
  pageProps,
@@ -481,4 +502,4 @@ async function resolvePagesPageData(options) {
481
502
  };
482
503
  }
483
504
  //#endregion
484
- export { renderPagesIsrHtml, resolvePagesPageData };
505
+ export { getPagesRouteParams, matchesPagesStaticPath, renderPagesIsrHtml, resolvePagesPageData };
@@ -35,6 +35,7 @@ type VinextConfigSubset = {
35
35
  clientTraceMetadata?: readonly string[];
36
36
  disableOptimizedLoading: boolean;
37
37
  };
38
+ declare function shouldEmitPagesClientTraceMetadata(pageModule: PagesPageModule, appComponent: unknown): boolean;
38
39
  /**
39
40
  * Options accepted by `createPagesPageHandler`.
40
41
  *
@@ -97,4 +98,4 @@ type RenderPageOptions = {
97
98
  */
98
99
  declare function createPagesPageHandler(opts: CreatePagesPageHandlerOptions): (request: Request, url: string, manifest: Record<string, string[]> | null | undefined, middlewareHeaders: Headers | null | undefined, options: RenderPageOptions | null | undefined) => Promise<Response>;
99
100
  //#endregion
100
- export { CreatePagesPageHandlerOptions, createPagesPageHandler };
101
+ export { CreatePagesPageHandlerOptions, createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
@@ -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
  /**