vinext 1.0.0-beta.0 → 1.0.0-beta.2

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 (305) hide show
  1. package/README.md +21 -2
  2. package/dist/build/assets-ignore.js +1 -1
  3. package/dist/build/clean-output.js +1 -1
  4. package/dist/build/client-build-config.js +7 -4
  5. package/dist/build/css-url-assets.js +3 -3
  6. package/dist/build/google-fonts/fallback-metrics.js +1 -1
  7. package/dist/build/google-fonts/font-metadata.js +1 -1
  8. package/dist/build/inject-pregenerated-paths.js +1 -1
  9. package/dist/build/inline-css.js +2 -5
  10. package/dist/build/module-dependency-cache.d.ts +4 -0
  11. package/dist/build/module-dependency-cache.js +13 -0
  12. package/dist/build/next-client-runtime-manifests.js +1 -1
  13. package/dist/build/pages-client-assets-module.js +1 -1
  14. package/dist/build/precompress.js +7 -7
  15. package/dist/build/prerender-paths.d.ts +2 -2
  16. package/dist/build/prerender-paths.js +10 -15
  17. package/dist/build/prerender-server-pool.js +2 -2
  18. package/dist/build/prerender.js +1 -1
  19. package/dist/build/preview-credentials.d.ts +11 -0
  20. package/dist/build/preview-credentials.js +19 -0
  21. package/dist/build/report.d.ts +8 -4
  22. package/dist/build/report.js +14 -6
  23. package/dist/build/run-prerender.d.ts +2 -11
  24. package/dist/build/run-prerender.js +2 -10
  25. package/dist/build/server-manifest.js +1 -1
  26. package/dist/build/ssr-manifest.d.ts +4 -0
  27. package/dist/build/ssr-manifest.js +10 -6
  28. package/dist/build/standalone.js +37 -37
  29. package/dist/cache/cache-adapters-virtual.d.ts +1 -17
  30. package/dist/cache/cache-adapters-virtual.js +20 -11
  31. package/dist/check.d.ts +0 -16
  32. package/dist/check.js +27 -36
  33. package/dist/cli.js +61 -55
  34. package/dist/client/instrumentation-client-inject.js +1 -1
  35. package/dist/client/pages-router-link-navigation.js +1 -1
  36. package/dist/config/config-matchers.d.ts +13 -37
  37. package/dist/config/config-matchers.js +33 -123
  38. package/dist/config/dotenv.js +1 -1
  39. package/dist/config/next-config.d.ts +7 -3
  40. package/dist/config/next-config.js +84 -15
  41. package/dist/config/prerender.d.ts +2 -2
  42. package/dist/config/prerender.js +7 -15
  43. package/dist/config/request-context.d.ts +14 -0
  44. package/dist/config/request-context.js +26 -0
  45. package/dist/config/server-external-packages.js +1 -1
  46. package/dist/config/tsconfig-paths.js +2 -2
  47. package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
  48. package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
  49. package/dist/entries/app-rsc-entry.js +39 -14
  50. package/dist/entries/app-rsc-manifest.js +21 -4
  51. package/dist/entries/pages-client-entry.js +6 -5
  52. package/dist/entries/pages-server-entry.js +18 -28
  53. package/dist/entries/runtime-entry-module.js +2 -2
  54. package/dist/index.js +314 -230
  55. package/dist/init-cloudflare.js +1 -1
  56. package/dist/init-platform.js +1 -1
  57. package/dist/init.d.ts +6 -4
  58. package/dist/init.js +25 -27
  59. package/dist/plugins/ast-utils.js +1 -1
  60. package/dist/plugins/dynamic-preload-metadata.js +7 -7
  61. package/dist/plugins/extensionless-dynamic-import.js +1 -1
  62. package/dist/plugins/fonts.js +3 -3
  63. package/dist/plugins/ignore-dynamic-requests.js +13 -8
  64. package/dist/plugins/import-meta-url.js +16 -17
  65. package/dist/plugins/middleware-export-validation.js +1 -1
  66. package/dist/plugins/middleware-server-only.js +2 -2
  67. package/dist/plugins/og-asset-ownership.js +7 -6
  68. package/dist/plugins/og-assets.js +5 -6
  69. package/dist/plugins/optimize-imports.js +12 -13
  70. package/dist/plugins/postcss.js +1 -1
  71. package/dist/plugins/remove-console.js +1 -1
  72. package/dist/plugins/require-context.js +1 -1
  73. package/dist/plugins/sass.js +2 -2
  74. package/dist/plugins/server-externals-manifest.js +1 -1
  75. package/dist/plugins/strip-server-exports.js +1 -1
  76. package/dist/plugins/styled-jsx.js +3 -2
  77. package/dist/plugins/typeof-window.js +1 -1
  78. package/dist/routing/app-route-graph.d.ts +16 -15
  79. package/dist/routing/app-route-graph.js +86 -88
  80. package/dist/routing/app-router.d.ts +0 -5
  81. package/dist/routing/app-router.js +12 -11
  82. package/dist/routing/file-matcher.d.ts +13 -28
  83. package/dist/routing/file-matcher.js +31 -44
  84. package/dist/routing/pages-router.js +26 -32
  85. package/dist/routing/route-matching.d.ts +14 -1
  86. package/dist/routing/route-matching.js +13 -1
  87. package/dist/routing/route-pattern.d.ts +2 -1
  88. package/dist/routing/route-pattern.js +7 -4
  89. package/dist/routing/route-trie.d.ts +5 -1
  90. package/dist/routing/route-trie.js +5 -2
  91. package/dist/server/api-handler.js +41 -33
  92. package/dist/server/app-browser-entry.js +18 -11
  93. package/dist/server/app-browser-history-controller.d.ts +1 -1
  94. package/dist/server/app-browser-history-controller.js +3 -3
  95. package/dist/server/app-browser-navigation-controller.js +4 -2
  96. package/dist/server/app-browser-server-action-client.js +1 -1
  97. package/dist/server/app-elements-wire.d.ts +2 -1
  98. package/dist/server/app-fallback-renderer.d.ts +11 -0
  99. package/dist/server/app-fallback-renderer.js +16 -2
  100. package/dist/server/app-middleware.js +2 -1
  101. package/dist/server/app-page-boundary-render.d.ts +26 -2
  102. package/dist/server/app-page-boundary-render.js +190 -55
  103. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  104. package/dist/server/app-page-cache.d.ts +1 -1
  105. package/dist/server/app-page-dispatch.d.ts +12 -2
  106. package/dist/server/app-page-dispatch.js +37 -51
  107. package/dist/server/app-page-element-builder.d.ts +8 -2
  108. package/dist/server/app-page-element-builder.js +112 -27
  109. package/dist/server/app-page-execution.d.ts +3 -1
  110. package/dist/server/app-page-execution.js +31 -39
  111. package/dist/server/app-page-head.d.ts +54 -2
  112. package/dist/server/app-page-head.js +164 -78
  113. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  114. package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
  115. package/dist/server/app-page-render.d.ts +2 -2
  116. package/dist/server/app-page-render.js +1 -1
  117. package/dist/server/app-page-request.d.ts +12 -0
  118. package/dist/server/app-page-request.js +134 -14
  119. package/dist/server/app-page-route-wiring.d.ts +9 -0
  120. package/dist/server/app-page-route-wiring.js +44 -4
  121. package/dist/server/app-post-middleware-context.d.ts +1 -1
  122. package/dist/server/app-post-middleware-context.js +1 -1
  123. package/dist/server/app-route-handler-dispatch.js +31 -17
  124. package/dist/server/app-route-handler-execution.d.ts +6 -1
  125. package/dist/server/app-route-handler-execution.js +41 -15
  126. package/dist/server/app-route-handler-policy.d.ts +2 -0
  127. package/dist/server/app-route-handler-policy.js +3 -3
  128. package/dist/server/app-route-module-loader.d.ts +3 -1
  129. package/dist/server/app-route-module-loader.js +1 -0
  130. package/dist/server/app-route-tree-prefetch.js +1 -1
  131. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  132. package/dist/server/app-rsc-cache-busting.js +1 -1
  133. package/dist/server/app-rsc-errors.d.ts +1 -1
  134. package/dist/server/app-rsc-errors.js +12 -2
  135. package/dist/server/app-rsc-handler.d.ts +10 -5
  136. package/dist/server/app-rsc-handler.js +51 -23
  137. package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
  138. package/dist/server/app-rsc-redirect-flight.js +71 -0
  139. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  140. package/dist/server/app-rsc-request-normalization.js +8 -2
  141. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  142. package/dist/server/app-rsc-response-finalizer.js +5 -11
  143. package/dist/server/app-rsc-route-matching.d.ts +20 -0
  144. package/dist/server/app-rsc-route-matching.js +87 -11
  145. package/dist/server/app-segment-config.js +15 -5
  146. package/dist/server/app-server-action-execution.d.ts +3 -1
  147. package/dist/server/app-server-action-execution.js +8 -6
  148. package/dist/server/app-ssr-entry.js +4 -1
  149. package/dist/server/app-ssr-stream.d.ts +2 -7
  150. package/dist/server/app-ssr-stream.js +5 -10
  151. package/dist/server/cache-proof.js +1 -1
  152. package/dist/server/config-headers.d.ts +24 -0
  153. package/dist/server/config-headers.js +52 -0
  154. package/dist/server/default-global-error-module.d.ts +3 -1
  155. package/dist/server/default-not-found-module.d.ts +3 -1
  156. package/dist/server/dev-initial-server-error.d.ts +1 -1
  157. package/dist/server/dev-lockfile.js +2 -3
  158. package/dist/server/dev-route-files.js +1 -1
  159. package/dist/server/dev-server.js +281 -173
  160. package/dist/server/dev-stack-sourcemap.js +4 -3
  161. package/dist/server/headers.d.ts +3 -1
  162. package/dist/server/headers.js +3 -1
  163. package/dist/server/image-optimization.js +2 -2
  164. package/dist/server/implicit-tags.js +2 -1
  165. package/dist/server/instrumentation.js +2 -2
  166. package/dist/server/isr-cache.d.ts +1 -1
  167. package/dist/server/isr-cache.js +1 -1
  168. package/dist/server/metadata-routes.js +4 -4
  169. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  170. package/dist/server/middleware-matcher-pattern.js +219 -0
  171. package/dist/server/middleware-matcher.d.ts +2 -7
  172. package/dist/server/middleware-matcher.js +13 -60
  173. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  174. package/dist/server/middleware-path-to-regexp.js +228 -0
  175. package/dist/server/middleware-response-headers.js +1 -1
  176. package/dist/server/middleware-runtime.js +5 -4
  177. package/dist/server/middleware.d.ts +2 -1
  178. package/dist/server/middleware.js +3 -2
  179. package/dist/server/navigation-planner.d.ts +2 -0
  180. package/dist/server/navigation-planner.js +8 -2
  181. package/dist/server/next-error-digest.d.ts +9 -24
  182. package/dist/server/next-error-digest.js +23 -15
  183. package/dist/server/operation-token.js +1 -1
  184. package/dist/server/pages-body-parser-config.js +2 -1
  185. package/dist/server/pages-data-route.d.ts +11 -1
  186. package/dist/server/pages-data-route.js +16 -1
  187. package/dist/server/pages-dev-hydration.d.ts +14 -0
  188. package/dist/server/pages-dev-hydration.js +83 -0
  189. package/dist/server/pages-dev-module-url.js +2 -2
  190. package/dist/server/pages-get-initial-props.d.ts +15 -2
  191. package/dist/server/pages-get-initial-props.js +16 -6
  192. package/dist/server/pages-node-compat.d.ts +13 -6
  193. package/dist/server/pages-node-compat.js +44 -45
  194. package/dist/server/pages-page-data.d.ts +4 -2
  195. package/dist/server/pages-page-data.js +20 -10
  196. package/dist/server/pages-page-handler.d.ts +4 -2
  197. package/dist/server/pages-page-handler.js +74 -43
  198. package/dist/server/pages-page-response.d.ts +2 -2
  199. package/dist/server/pages-page-response.js +1 -1
  200. package/dist/server/pages-preview.d.ts +26 -0
  201. package/dist/server/pages-preview.js +165 -0
  202. package/dist/server/pages-readiness.d.ts +5 -4
  203. package/dist/server/pages-readiness.js +4 -2
  204. package/dist/server/pages-request-pipeline.d.ts +1 -0
  205. package/dist/server/pages-request-pipeline.js +25 -11
  206. package/dist/server/pages-router-entry.js +6 -0
  207. package/dist/server/prerender-route-params.js +2 -2
  208. package/dist/server/prod-server.d.ts +1 -4
  209. package/dist/server/prod-server.js +44 -30
  210. package/dist/server/request-pipeline.d.ts +15 -29
  211. package/dist/server/request-pipeline.js +25 -60
  212. package/dist/server/rsc-stream-hints.js +122 -18
  213. package/dist/server/seed-cache.js +1 -1
  214. package/dist/server/socket-error-backstop.js +1 -1
  215. package/dist/server/static-file-cache.js +7 -8
  216. package/dist/server/worker-utils.js +1 -1
  217. package/dist/shims/app.d.ts +1 -1
  218. package/dist/shims/cache-request-state.d.ts +27 -1
  219. package/dist/shims/cache-request-state.js +60 -1
  220. package/dist/shims/cache-runtime.d.ts +12 -1
  221. package/dist/shims/cache-runtime.js +22 -7
  222. package/dist/shims/cache.d.ts +5 -5
  223. package/dist/shims/cache.js +28 -11
  224. package/dist/shims/constants.js +1 -1
  225. package/dist/shims/document.d.ts +42 -83
  226. package/dist/shims/document.js +62 -53
  227. package/dist/shims/dynamic.d.ts +5 -25
  228. package/dist/shims/dynamic.js +29 -8
  229. package/dist/shims/error-boundary.d.ts +4 -4
  230. package/dist/shims/error.d.ts +22 -6
  231. package/dist/shims/error.js +53 -15
  232. package/dist/shims/fetch-cache.js +13 -4
  233. package/dist/shims/font-google-base.d.ts +11 -4
  234. package/dist/shims/font-local.d.ts +10 -3
  235. package/dist/shims/font-utils.js +1 -1
  236. package/dist/shims/form.d.ts +1 -1
  237. package/dist/shims/head.d.ts +13 -2
  238. package/dist/shims/head.js +6 -6
  239. package/dist/shims/headers.d.ts +28 -31
  240. package/dist/shims/headers.js +115 -53
  241. package/dist/shims/image.d.ts +27 -37
  242. package/dist/shims/image.js +21 -14
  243. package/dist/shims/internal/cookie-serialize.d.ts +3 -1
  244. package/dist/shims/internal/cookie-serialize.js +3 -1
  245. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
  247. package/dist/shims/internal/utils.d.ts +3 -3
  248. package/dist/shims/layout-segment-context.d.ts +1 -1
  249. package/dist/shims/legacy-image.d.ts +3 -37
  250. package/dist/shims/legacy-image.js +6 -16
  251. package/dist/shims/link.d.ts +16 -21
  252. package/dist/shims/link.js +25 -13
  253. package/dist/shims/navigation-context-state.d.ts +1 -1
  254. package/dist/shims/navigation-errors.d.ts +2 -1
  255. package/dist/shims/navigation-errors.js +9 -13
  256. package/dist/shims/navigation.d.ts +8 -4
  257. package/dist/shims/navigation.js +29 -18
  258. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  259. package/dist/shims/next-shims-public.d.ts +1 -0
  260. package/dist/shims/public-shim-map.json.js +103 -0
  261. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  262. package/dist/shims/readonly-url-search-params.js +3 -3
  263. package/dist/shims/request-state-types.d.ts +1 -1
  264. package/dist/shims/router-state.d.ts +1 -0
  265. package/dist/shims/router.d.ts +57 -22
  266. package/dist/shims/router.js +178 -46
  267. package/dist/shims/script.d.ts +6 -10
  268. package/dist/shims/script.js +7 -4
  269. package/dist/shims/server.d.ts +45 -22
  270. package/dist/shims/server.js +46 -7
  271. package/dist/shims/slot.d.ts +1 -1
  272. package/dist/shims/thenable-params.js +1 -1
  273. package/dist/shims/unified-request-context.d.ts +1 -1
  274. package/dist/shims/unified-request-context.js +2 -0
  275. package/dist/shims/url-safety.d.ts +1 -1
  276. package/dist/shims/url-safety.js +2 -2
  277. package/dist/typegen.d.ts +8 -2
  278. package/dist/typegen.js +84 -25
  279. package/dist/utils/client-build-manifest.js +2 -2
  280. package/dist/utils/client-entry-manifest.js +1 -1
  281. package/dist/utils/client-runtime-metadata.js +1 -1
  282. package/dist/utils/commonjs-loader.js +3 -3
  283. package/dist/utils/domain-locale.d.ts +2 -2
  284. package/dist/utils/external-url.d.ts +5 -0
  285. package/dist/utils/external-url.js +7 -0
  286. package/dist/utils/mdx-scan.js +1 -1
  287. package/dist/utils/path.d.ts +1 -13
  288. package/dist/utils/path.js +1 -15
  289. package/dist/utils/plugin-options.d.ts +4 -0
  290. package/dist/utils/plugin-options.js +8 -0
  291. package/dist/utils/project.d.ts +0 -6
  292. package/dist/utils/project.js +2 -8
  293. package/dist/utils/public-routes.js +2 -2
  294. package/dist/utils/react-version.js +1 -1
  295. package/dist/utils/redirect-digest.d.ts +9 -0
  296. package/dist/utils/redirect-digest.js +25 -0
  297. package/dist/utils/regex-safety.d.ts +8 -0
  298. package/dist/utils/regex-safety.js +737 -0
  299. package/dist/utils/vinext-root.js +1 -1
  300. package/dist/utils/vite-version.d.ts +5 -2
  301. package/dist/utils/vite-version.js +43 -17
  302. package/package.json +16 -4
  303. /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
  304. /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
  305. /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
@@ -33,11 +33,11 @@ type PagesFontPreload = {
33
33
  /**
34
34
  * The `__NEXT_DATA__` fields beyond the always-present core that the Pages
35
35
  * renderer serializes: the `__vinext` block plus the readiness flags
36
- * (gssp/gsp/gip/appGip/autoExport/isExperimentalCompile) the client uses to
36
+ * (gssp/gsp/gip/appGip/autoExport/nextExport/isExperimentalCompile) the client uses to
37
37
  * recompute the initial `router.isReady`. Shared by every render path
38
38
  * (initial, ISR regeneration) so they emit identical readiness state.
39
39
  */
40
- type PagesNextDataExtras = Pick<VinextNextData, "__vinext" | "appGip" | "autoExport" | "gip" | "gsp" | "gssp" | "isExperimentalCompile">;
40
+ type PagesNextDataExtras = Pick<VinextNextData, "__vinext" | "appGip" | "autoExport" | "gip" | "gsp" | "gssp" | "isExperimentalCompile" | "nextExport">;
41
41
  type PagesI18nRenderContext = {
42
42
  locale?: string;
43
43
  locales?: string[];
@@ -72,7 +72,7 @@ function buildPagesNextDataScript(options) {
72
72
  const nextDataPayload = {
73
73
  props: options.props ?? { pageProps: options.pageProps },
74
74
  page: options.routePattern,
75
- query: options.params,
75
+ query: options.isFallback === true ? {} : options.params,
76
76
  buildId: options.buildId,
77
77
  isFallback: options.isFallback === true
78
78
  };
@@ -0,0 +1,26 @@
1
+ //#region src/server/pages-preview.d.ts
2
+ declare const PAGES_PREVIEW_CACHE_CONTROL = "private, no-cache, no-store, max-age=0, must-revalidate";
3
+ type PagesPreviewData = object | string;
4
+ type PagesPreviewState = {
5
+ data: PagesPreviewData | false;
6
+ shouldClear: boolean;
7
+ };
8
+ type PreviewResponse = {
9
+ getHeader(name: string): string | number | boolean | string[] | undefined;
10
+ setHeader(name: string, value: string | number | boolean | string[]): unknown;
11
+ };
12
+ declare function getPagesPreviewModeId(): string;
13
+ declare function getPagesPreviewState(cookieHeader: string | string[] | null | undefined, options?: {
14
+ isOnDemandRevalidate?: boolean;
15
+ }): PagesPreviewState;
16
+ declare function setPagesDraftMode(response: PreviewResponse, enabled: boolean): void;
17
+ declare function setPagesPreviewData(response: PreviewResponse, data: PagesPreviewData, options?: {
18
+ maxAge?: number;
19
+ path?: string;
20
+ }): void;
21
+ declare function clearPagesPreviewData(response: PreviewResponse, options?: {
22
+ path?: string;
23
+ }): void;
24
+ declare function appendPagesPreviewClearCookies(headers: Headers): void;
25
+ //#endregion
26
+ export { PAGES_PREVIEW_CACHE_CONTROL, PagesPreviewData, PagesPreviewState, appendPagesPreviewClearCookies, clearPagesPreviewData, getPagesPreviewModeId, getPagesPreviewState, setPagesDraftMode, setPagesPreviewData };
@@ -0,0 +1,165 @@
1
+ import { parseCookieHeader } from "../utils/parse-cookie.js";
2
+ import { createCipheriv, createDecipheriv, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
3
+ //#region src/server/pages-preview.ts
4
+ const PAGES_PREVIEW_CACHE_CONTROL = "private, no-cache, no-store, max-age=0, must-revalidate";
5
+ const pagesPreviewCookiesCleared = Symbol("__prerender_bypass");
6
+ let devCredentials;
7
+ function decodeKey(value) {
8
+ if (!value || !/^[0-9a-f]{64}$/i.test(value)) return null;
9
+ return Buffer.from(value, "hex");
10
+ }
11
+ function getPagesPreviewCredentials() {
12
+ const bypassId = process.env.__VINEXT_PREVIEW_MODE_ID;
13
+ const encryptionKey = decodeKey(process.env.__VINEXT_PREVIEW_MODE_ENCRYPTION_KEY);
14
+ const signingKey = decodeKey(process.env.__VINEXT_PREVIEW_MODE_SIGNING_KEY);
15
+ if (bypassId && encryptionKey && signingKey) return {
16
+ bypassId,
17
+ encryptionKey,
18
+ signingKey
19
+ };
20
+ if (!devCredentials) devCredentials = {
21
+ bypassId: randomBytes(16).toString("hex"),
22
+ encryptionKey: randomBytes(32),
23
+ signingKey: randomBytes(32)
24
+ };
25
+ return devCredentials;
26
+ }
27
+ function getPagesPreviewModeId() {
28
+ return getPagesPreviewCredentials().bypassId;
29
+ }
30
+ function serializeCookie(name, value, options = {}) {
31
+ const parts = [
32
+ `${name}=${encodeURIComponent(value)}`,
33
+ "HttpOnly",
34
+ `Path=${options.path ?? "/"}`,
35
+ process.env.NODE_ENV !== "development" ? "SameSite=None" : "SameSite=Lax"
36
+ ];
37
+ if (process.env.NODE_ENV !== "development") parts.push("Secure");
38
+ if (options.maxAge !== void 0) parts.push(`Max-Age=${Math.trunc(options.maxAge)}`);
39
+ return parts.join("; ");
40
+ }
41
+ function serializeClearedCookie(name, options = {}) {
42
+ return [
43
+ `${name}=`,
44
+ "Expires=Thu, 01 Jan 1970 00:00:00 GMT",
45
+ "HttpOnly",
46
+ `Path=${options.path ?? "/"}`,
47
+ process.env.NODE_ENV !== "development" ? "SameSite=None" : "SameSite=Lax",
48
+ ...process.env.NODE_ENV !== "development" ? ["Secure"] : []
49
+ ].join("; ");
50
+ }
51
+ function normalizeSetCookie(value) {
52
+ if (value === void 0) return [];
53
+ return Array.isArray(value) ? value.map(String) : [String(value)];
54
+ }
55
+ function encodePayload(data, maxAge) {
56
+ const iv = randomBytes(12);
57
+ const credentials = getPagesPreviewCredentials();
58
+ const cipher = createCipheriv("aes-256-gcm", credentials.encryptionKey, iv);
59
+ const plaintext = JSON.stringify({
60
+ data,
61
+ ...maxAge === void 0 ? {} : { expiresAt: Date.now() + maxAge * 1e3 }
62
+ });
63
+ const encryptedToken = [
64
+ iv,
65
+ Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]),
66
+ cipher.getAuthTag()
67
+ ].map((part) => part.toString("base64url")).join(".");
68
+ return `${encryptedToken}.${createHmac("sha256", credentials.signingKey).update(encryptedToken).digest("base64url")}`;
69
+ }
70
+ function decodePayload(payload) {
71
+ try {
72
+ const [ivValue, encryptedValue, tagValue, signatureValue, ...extra] = payload.split(".");
73
+ if (!ivValue || !encryptedValue || !tagValue || !signatureValue || extra.length > 0) return false;
74
+ const encryptedToken = `${ivValue}.${encryptedValue}.${tagValue}`;
75
+ const credentials = getPagesPreviewCredentials();
76
+ const expected = createHmac("sha256", credentials.signingKey).update(encryptedToken).digest();
77
+ const signature = Buffer.from(signatureValue, "base64url");
78
+ if (signature.length !== expected.length || !timingSafeEqual(signature, expected)) return false;
79
+ const decipher = createDecipheriv("aes-256-gcm", credentials.encryptionKey, Buffer.from(ivValue, "base64url"));
80
+ decipher.setAuthTag(Buffer.from(tagValue, "base64url"));
81
+ const decoded = Buffer.concat([decipher.update(Buffer.from(encryptedValue, "base64url")), decipher.final()]).toString("utf8");
82
+ const value = JSON.parse(decoded);
83
+ if (typeof value !== "object" || value === null || !("data" in value)) return false;
84
+ const expiresAt = "expiresAt" in value ? value.expiresAt : void 0;
85
+ if (typeof expiresAt === "number" && Date.now() >= expiresAt) return false;
86
+ const data = value.data;
87
+ return typeof data === "object" && data !== null ? data : String(data);
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+ function getPagesPreviewState(cookieHeader, options = {}) {
93
+ if (options.isOnDemandRevalidate) return {
94
+ data: false,
95
+ shouldClear: false
96
+ };
97
+ const cookies = parseCookieHeader(Array.isArray(cookieHeader) ? cookieHeader.join("; ") : cookieHeader);
98
+ const bypass = cookies.__prerender_bypass;
99
+ const payload = cookies.__next_preview_data;
100
+ if (!bypass && !payload) return {
101
+ data: false,
102
+ shouldClear: false
103
+ };
104
+ if (!bypass || bypass !== getPagesPreviewCredentials().bypassId) return {
105
+ data: false,
106
+ shouldClear: true
107
+ };
108
+ if (!payload) return {
109
+ data: {},
110
+ shouldClear: false
111
+ };
112
+ const data = decodePayload(payload);
113
+ return {
114
+ data,
115
+ shouldClear: data === false
116
+ };
117
+ }
118
+ function setPagesDraftMode(response, enabled) {
119
+ const cookie = enabled ? serializeCookie("__prerender_bypass", getPagesPreviewModeId()) : serializeClearedCookie("__prerender_bypass");
120
+ response.setHeader("Set-Cookie", [...normalizeSetCookie(response.getHeader("Set-Cookie")), cookie]);
121
+ }
122
+ function setPagesPreviewData(response, data, options = {}) {
123
+ const payload = encodePayload(data, options.maxAge);
124
+ if (payload.length > 2048) throw new Error("Preview data is limited to 2KB currently, reduce how much data you are storing as preview data to continue");
125
+ response.setHeader("Set-Cookie", [
126
+ ...normalizeSetCookie(response.getHeader("Set-Cookie")),
127
+ serializeCookie("__prerender_bypass", getPagesPreviewModeId(), options),
128
+ serializeCookie("__next_preview_data", payload, options)
129
+ ]);
130
+ }
131
+ function clearPagesPreviewData(response, options = {}) {
132
+ if (pagesPreviewCookiesCleared in response) return;
133
+ response.setHeader("Set-Cookie", [
134
+ ...normalizeSetCookie(response.getHeader("Set-Cookie")),
135
+ serializeClearedCookie("__prerender_bypass", options),
136
+ serializeClearedCookie("__next_preview_data", options)
137
+ ]);
138
+ Object.defineProperty(response, pagesPreviewCookiesCleared, {
139
+ value: true,
140
+ enumerable: false
141
+ });
142
+ }
143
+ function appendPagesPreviewClearCookies(headers) {
144
+ const cookies = headers.getSetCookie();
145
+ const hasExpiredCookie = (name) => cookies.some((cookie) => {
146
+ const [cookieValue, ...attributes] = cookie.split(";").map((part) => part.trim());
147
+ if (!cookieValue?.startsWith(`${name}=`)) return false;
148
+ let expiresAtEpoch = false;
149
+ let path;
150
+ let hasDomain = false;
151
+ for (const attribute of attributes) {
152
+ const separator = attribute.indexOf("=");
153
+ const attributeName = (separator === -1 ? attribute : attribute.slice(0, separator)).trim().toLowerCase();
154
+ const attributeValue = separator === -1 ? "" : attribute.slice(separator + 1).trim();
155
+ if (attributeName === "expires") expiresAtEpoch = Date.parse(attributeValue) === 0;
156
+ if (attributeName === "path") path = attributeValue;
157
+ if (attributeName === "domain") hasDomain = true;
158
+ }
159
+ return expiresAtEpoch && path === "/" && !hasDomain;
160
+ });
161
+ if (!hasExpiredCookie("__prerender_bypass")) headers.append("Set-Cookie", serializeClearedCookie("__prerender_bypass"));
162
+ if (!hasExpiredCookie("__next_preview_data")) headers.append("Set-Cookie", serializeClearedCookie("__next_preview_data"));
163
+ }
164
+ //#endregion
165
+ export { PAGES_PREVIEW_CACHE_CONTROL, appendPagesPreviewClearCookies, clearPagesPreviewData, getPagesPreviewModeId, getPagesPreviewState, setPagesDraftMode, setPagesPreviewData };
@@ -7,9 +7,9 @@ import { PagesPageModule } from "./pages-page-data.js";
7
7
  *
8
8
  * The initial `router.isReady` value for the `next/navigation` compat hooks is
9
9
  * derived from the page/_app data-fetching exports plus the configured-rewrites
10
- * flag, serialized into `__NEXT_DATA__`. The dev SSR handler and the production
11
- * Pages page handler must compute this identically so server HTML and client
12
- * hydration agree see `getPagesNavigationIsReadyFromSerializedState` in
10
+ * flag. The client recomputes readiness from those flags and its live URL,
11
+ * matching the Pages Router constructor; server-only readiness remains in the
12
+ * request context. See `getPagesNavigationIsReadyFromSerializedState` in
13
13
  * `shims/router.ts`.
14
14
  */
15
15
  /**
@@ -18,7 +18,7 @@ import { PagesPageModule } from "./pages-page-data.js";
18
18
  * The field names/types are projected from the canonical `VinextNextData` so
19
19
  * this stays in lockstep with the `__NEXT_DATA__` shape it feeds into.
20
20
  */
21
- type PagesReadinessNextData = Pick<VinextNextData, "gssp" | "gsp" | "gip" | "appGip" | "autoExport"> & {
21
+ type PagesReadinessNextData = Pick<VinextNextData, "gssp" | "gsp" | "gip" | "appGip" | "autoExport" | "nextExport"> & {
22
22
  __vinext: Pick<NonNullable<VinextNextData["__vinext"]>, "hasRewrites">;
23
23
  };
24
24
  /**
@@ -29,6 +29,7 @@ declare function buildPagesReadinessNextData(options: {
29
29
  pageModule: PagesPageModule;
30
30
  appComponent: {
31
31
  getInitialProps?: unknown;
32
+ origGetInitialProps?: unknown;
32
33
  } | null | undefined;
33
34
  hasRewrites: boolean;
34
35
  }): PagesReadinessNextData;
@@ -7,13 +7,15 @@ function buildPagesReadinessNextData(options) {
7
7
  const hasPageGssp = typeof options.pageModule.getServerSideProps === "function";
8
8
  const hasPageGsp = typeof options.pageModule.getStaticProps === "function";
9
9
  const hasPageGip = typeof options.pageModule.default?.getInitialProps === "function";
10
- const hasAppGip = typeof options.appComponent?.getInitialProps === "function";
10
+ const hasAppGip = typeof options.appComponent?.getInitialProps === "function" && options.appComponent.getInitialProps !== options.appComponent.origGetInitialProps;
11
+ const autoExport = !hasPageGssp && !hasPageGsp && !hasPageGip && !hasAppGip;
11
12
  return {
12
13
  gssp: hasPageGssp,
13
14
  gsp: hasPageGsp ? true : void 0,
14
15
  gip: hasPageGip,
15
16
  appGip: hasAppGip,
16
- autoExport: !hasPageGssp && !hasPageGsp && !hasPageGip && !hasAppGip,
17
+ autoExport,
18
+ nextExport: autoExport ? true : void 0,
17
19
  __vinext: { hasRewrites: options.hasRewrites }
18
20
  };
19
21
  }
@@ -44,6 +44,7 @@ type PagesPipelineDeps = {
44
44
  hasMiddleware: boolean;
45
45
  ctx?: unknown;
46
46
  rawSearch?: string;
47
+ configMatchPathname?: string;
47
48
  matchPageRoute?: ((pathname: string, request: Request) => PageRouteMatch | null) | null;
48
49
  runMiddleware?: ((request: Request, ctx: unknown, opts: {
49
50
  isDataRequest: boolean;
@@ -1,10 +1,13 @@
1
1
  import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
2
2
  import { patternToNextFormat } from "../routing/route-validation.js";
3
- import { applyMiddlewareRequestHeaders, isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
4
- import { applyConfigHeadersToHeaderRecord, cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
3
+ import { requestContextFromRequest } from "../config/request-context.js";
4
+ import { isExternalUrl } from "../utils/external-url.js";
5
+ import { applyMiddlewareRequestHeaders, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, sanitizeDestination } from "../config/config-matchers.js";
6
+ import { cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
5
7
  import { mergeRewriteQuery } from "../utils/query.js";
6
8
  import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
7
9
  import { buildMiddlewarePrefetchSkipResponse } from "./pages-data-route.js";
10
+ import { applyConfigHeadersToHeaderRecord } from "./config-headers.js";
8
11
  import { mergeHeaders } from "./worker-utils.js";
9
12
  //#region src/server/pages-request-pipeline.ts
10
13
  async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset) {
@@ -53,6 +56,7 @@ async function runPagesRequest(request, deps) {
53
56
  const url = new URL(request.url);
54
57
  let pathname = url.pathname;
55
58
  const search = url.search;
59
+ const requestConfigPathname = deps.configMatchPathname ?? pathname;
56
60
  const basePathState = {
57
61
  basePath,
58
62
  hadBasePath
@@ -66,9 +70,9 @@ async function runPagesRequest(request, deps) {
66
70
  }
67
71
  const reqCtx = requestContextFromRequest(request);
68
72
  const requestHostname = i18nConfig ? url.hostname : "";
69
- const matchPathname = i18nConfig ? normalizeDefaultLocalePathname(pathname, i18nConfig, { hostname: requestHostname }) : pathname;
73
+ const requestConfigMatchPathname = i18nConfig ? normalizeDefaultLocalePathname(requestConfigPathname, i18nConfig, { hostname: requestHostname }) : requestConfigPathname;
70
74
  if (configRedirects.length) {
71
- const redirect = matchRedirect(matchPathname, configRedirects, reqCtx, basePathState);
75
+ const redirect = matchRedirect(requestConfigMatchPathname, configRedirects, reqCtx, basePathState);
72
76
  if (redirect) {
73
77
  const location = preserveRedirectDestinationQuery(sanitizeDestination(basePath && hadBasePath && !isExternalUrl(redirect.destination) && !hasBasePath(redirect.destination, basePath) ? basePath + redirect.destination : redirect.destination), deps.rawSearch ?? search);
74
78
  return {
@@ -82,6 +86,7 @@ async function runPagesRequest(request, deps) {
82
86
  }
83
87
  const originalResolvedUrl = pathname + search;
84
88
  let resolvedUrl = originalResolvedUrl;
89
+ let resolvedPathnameIsRequestPathname = true;
85
90
  const middlewareHeaders = {};
86
91
  let middlewareStatus;
87
92
  const serveFilesystemRoute = async (requestPathname, phase) => {
@@ -131,7 +136,10 @@ async function runPagesRequest(request, deps) {
131
136
  else if (existing) middlewareHeaders[key] = [existing, value];
132
137
  else middlewareHeaders[key] = [value];
133
138
  } else middlewareHeaders[key] = value;
134
- if (result.rewriteUrl) resolvedUrl = result.rewriteUrl;
139
+ if (result.rewriteUrl) {
140
+ resolvedUrl = result.rewriteUrl;
141
+ resolvedPathnameIsRequestPathname = false;
142
+ }
135
143
  middlewareStatus = result.status ?? result.rewriteStatus;
136
144
  }
137
145
  const { postMwReqCtx, request: postMwReq } = applyMiddlewareRequestHeaders(middlewareHeaders, request, { preserveCredentialHeaders: isExternalUrl(resolvedUrl) });
@@ -143,6 +151,7 @@ async function runPagesRequest(request, deps) {
143
151
  });
144
152
  let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
145
153
  const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
154
+ const configSourcePathname = () => resolvedPathnameIsRequestPathname ? requestConfigMatchPathname : matchResolvedPathname(resolvedPathname);
146
155
  const matchedPathnameForRoute = (routePattern) => {
147
156
  const matchedPathname = routePattern ? patternToNextFormat(routePattern) : resolvedPathname;
148
157
  if (!i18nConfig) return matchedPathname;
@@ -161,7 +170,7 @@ async function runPagesRequest(request, deps) {
161
170
  };
162
171
  if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
163
172
  configHeaders,
164
- pathname: matchPathname,
173
+ pathname: requestConfigMatchPathname,
165
174
  requestContext: reqCtx,
166
175
  basePathState
167
176
  });
@@ -173,7 +182,7 @@ async function runPagesRequest(request, deps) {
173
182
  if (directFilesystemResult) return directFilesystemResult;
174
183
  let configRewriteFired = false;
175
184
  for (const rewrite of configRewrites.beforeFiles ?? []) {
176
- const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
185
+ const rewritten = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), basePathState);
177
186
  if (rewritten) {
178
187
  if (isExternalUrl(rewritten)) return {
179
188
  type: "response",
@@ -181,6 +190,7 @@ async function runPagesRequest(request, deps) {
181
190
  };
182
191
  resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
183
192
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
193
+ resolvedPathnameIsRequestPathname = false;
184
194
  configRewriteFired = true;
185
195
  }
186
196
  }
@@ -227,7 +237,7 @@ async function runPagesRequest(request, deps) {
227
237
  let pageMatch = !isOutsideBasePathUnclaimed() && deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
228
238
  let resolvedPathnameChanged = false;
229
239
  if (!pageMatch || pageMatch.route.isDynamic) for (const rewrite of configRewrites.afterFiles ?? []) {
230
- const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
240
+ const rewritten = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), basePathState);
231
241
  if (rewritten) {
232
242
  if (isExternalUrl(rewritten)) return {
233
243
  type: "response",
@@ -235,6 +245,7 @@ async function runPagesRequest(request, deps) {
235
245
  };
236
246
  resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
237
247
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
248
+ resolvedPathnameIsRequestPathname = false;
238
249
  configRewriteFired = true;
239
250
  resolvedPathnameChanged = true;
240
251
  const afterFilesFilesystemResult = await serveFilesystemRoute(resolvedPathname, "afterFiles");
@@ -253,7 +264,7 @@ async function runPagesRequest(request, deps) {
253
264
  if (typeof deps.renderPage === "function") {
254
265
  let renderPageMatch = pageMatch;
255
266
  if ((isOutsideBasePathUnclaimed() || isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
256
- const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
267
+ const fallbackRewrite = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), basePathState);
257
268
  if (!fallbackRewrite) continue;
258
269
  if (isExternalUrl(fallbackRewrite)) return {
259
270
  type: "response",
@@ -261,6 +272,7 @@ async function runPagesRequest(request, deps) {
261
272
  };
262
273
  resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
263
274
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
275
+ resolvedPathnameIsRequestPathname = false;
264
276
  configRewriteFired = true;
265
277
  const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
266
278
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
@@ -281,7 +293,7 @@ async function runPagesRequest(request, deps) {
281
293
  let response = await deps.renderPage(request, resolvedUrl, initialRenderOptions, stagedHeaders);
282
294
  let matchedFallbackRewrite = false;
283
295
  if (response.status === 404 && shouldDeferErrorPageOnMiss && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
284
- const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
296
+ const fallbackRewrite = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), basePathState);
285
297
  if (!fallbackRewrite) continue;
286
298
  if (isExternalUrl(fallbackRewrite)) return {
287
299
  type: "response",
@@ -289,6 +301,7 @@ async function runPagesRequest(request, deps) {
289
301
  };
290
302
  resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
291
303
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
304
+ resolvedPathnameIsRequestPathname = false;
292
305
  configRewriteFired = true;
293
306
  const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
294
307
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
@@ -325,7 +338,7 @@ async function runPagesRequest(request, deps) {
325
338
  }
326
339
  let devPageMatch = isOutsideBasePathUnclaimed() ? null : resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch;
327
340
  if (!devPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
328
- const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
341
+ const fallbackRewrite = matchRewrite(configSourcePathname(), [rewrite], rewriteRequestContext(), basePathState);
329
342
  if (!fallbackRewrite) continue;
330
343
  if (isExternalUrl(fallbackRewrite)) return {
331
344
  type: "response",
@@ -333,6 +346,7 @@ async function runPagesRequest(request, deps) {
333
346
  };
334
347
  resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
335
348
  resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
349
+ resolvedPathnameIsRequestPathname = false;
336
350
  configRewriteFired = true;
337
351
  const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
338
352
  if (fallbackFilesystemResult) return fallbackFilesystemResult;
@@ -1,3 +1,4 @@
1
+ import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
1
2
  import { hasBasePath, stripBasePath } from "../utils/base-path.js";
2
3
  import { notFoundStaticAssetResponse } from "./http-error-responses.js";
3
4
  import { isOpenRedirectShaped } from "./open-redirect.js";
@@ -52,6 +53,11 @@ async function handleRequest(request, env, ctx) {
52
53
  try {
53
54
  let pathname = new URL(request.url).pathname;
54
55
  if (isOpenRedirectShaped(pathname)) return new Response("This page could not be found", { status: 404 });
56
+ try {
57
+ normalizePathnameForRouteMatchStrict(pathname);
58
+ } catch {
59
+ return new Response("Bad Request", { status: 400 });
60
+ }
55
61
  const missingBuildAsset = isNextStaticPath(pathname, basePath, assetPathPrefix);
56
62
  request = cloneRequestWithHeaders(request, filterInternalHeaders(request.headers));
57
63
  const hadBasePath = !basePath || hasBasePath(pathname, basePath);
@@ -58,11 +58,11 @@ function decodedPrerenderRouteParamEquals(prerenderValue, matchedValue) {
58
58
  if (prerenderValue.length !== matchedValue.length) return false;
59
59
  return prerenderValue.every((item, index) => {
60
60
  const decoded = decodePrerenderRouteParam(item);
61
- return decoded !== null && decoded === matchedValue[index];
61
+ return item === matchedValue[index] || decoded !== null && decoded === matchedValue[index];
62
62
  });
63
63
  }
64
64
  const decoded = decodePrerenderRouteParam(prerenderValue);
65
- return decoded !== null && decoded === matchedValue;
65
+ return prerenderValue === matchedValue || decoded !== null && decoded === matchedValue;
66
66
  }
67
67
  function prerenderRouteParamsPayloadMatchesRoute(payload, routePattern, params) {
68
68
  return matchPrerenderRouteParamsPayload(payload, routePattern, params)?.kind === "exact";
@@ -101,10 +101,7 @@ declare function tryServeStatic(req: IncomingMessage, res: ServerResponse, clien
101
101
  * Convert a Node.js IncomingMessage to a Web Request object.
102
102
  *
103
103
  * When `urlOverride` is provided, it is used as the path + query string
104
- * instead of `req.url`. This avoids redundant path normalization when the
105
- * caller has already decoded and normalized the pathname (e.g. the App
106
- * Router prod server normalizes before static-asset lookup, and can pass
107
- * the result here so the downstream RSC handler doesn't re-normalize).
104
+ * instead of `req.url`.
108
105
  */
109
106
  declare function nodeToWebRequest(req: IncomingMessage, urlOverride?: string, prerenderSecret?: string): Request;
110
107
  /**
@@ -1,3 +1,4 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
2
3
  import { hasBasePath, stripBasePath } from "../utils/base-path.js";
3
4
  import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
@@ -5,9 +6,9 @@ import { VINEXT_STATIC_FILE_HEADER } from "./headers.js";
5
6
  import { normalizePath } from "./normalize-path.js";
6
7
  import { notFoundResponse } from "./http-error-responses.js";
7
8
  import { isOpenRedirectShaped } from "./open-redirect.js";
8
- import { filterInternalHeaders } from "./request-pipeline.js";
9
+ import { canonicalizeRequestPathname, filterInternalHeaders } from "./request-pipeline.js";
9
10
  import { isUnknownRecord } from "../utils/record.js";
10
- import { buildNextDataNotFoundResponse, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname } from "./pages-data-route.js";
11
+ import { buildNextDataNotFoundResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, urlParserCreatesPagesDataPath } from "./pages-data-route.js";
11
12
  import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
12
13
  import { setPagesClientAssets } from "./pages-client-assets.js";
13
14
  import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
@@ -23,8 +24,7 @@ import { readPrerenderSecret } from "../build/server-manifest.js";
23
24
  import { seedMemoryCacheFromPrerender } from "./seed-cache.js";
24
25
  import { negotiateEncoding, parseAcceptedEncodings, selectContentEncoding } from "./accept-encoding.js";
25
26
  import fs from "node:fs";
26
- import path from "node:path";
27
- import fs$1 from "node:fs/promises";
27
+ import fsp from "node:fs/promises";
28
28
  import { pathToFileURL } from "node:url";
29
29
  import { Readable, pipeline } from "node:stream";
30
30
  import zlib from "node:zlib";
@@ -159,7 +159,7 @@ function readNodeStream(req) {
159
159
  });
160
160
  }
161
161
  /** Content types that benefit from compression. */
162
- const COMPRESSIBLE_TYPES = new Set([
162
+ const COMPRESSIBLE_TYPES = /* @__PURE__ */ new Set([
163
163
  "text/html",
164
164
  "text/css",
165
165
  "text/plain",
@@ -237,13 +237,13 @@ function nodeHeadersToWebHeaders(headersRecord) {
237
237
  for (const [key, value] of Object.entries(headersRecord)) appendWebHeader(headers, key, value);
238
238
  return headers;
239
239
  }
240
- const NO_BODY_RESPONSE_STATUSES = new Set([
240
+ const NO_BODY_RESPONSE_STATUSES = /* @__PURE__ */ new Set([
241
241
  204,
242
242
  205,
243
243
  304
244
244
  ]);
245
- const OMIT_BODY_HEADERS = new Set(["content-length", "content-type"]);
246
- const OMIT_STATIC_RESPONSE_HEADERS = new Set([
245
+ const OMIT_BODY_HEADERS = /* @__PURE__ */ new Set(["content-length", "content-type"]);
246
+ const OMIT_STATIC_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
247
247
  VINEXT_STATIC_FILE_HEADER,
248
248
  "content-encoding",
249
249
  "content-length",
@@ -542,7 +542,7 @@ async function resolveStaticFile(staticFile) {
542
542
  }
543
543
  async function statIfFile(filePath) {
544
544
  try {
545
- const stat = await fs$1.stat(filePath);
545
+ const stat = await fsp.stat(filePath);
546
546
  return stat.isFile() ? {
547
547
  size: stat.size,
548
548
  mtimeMs: stat.mtimeMs
@@ -555,10 +555,7 @@ async function statIfFile(filePath) {
555
555
  * Convert a Node.js IncomingMessage to a Web Request object.
556
556
  *
557
557
  * When `urlOverride` is provided, it is used as the path + query string
558
- * instead of `req.url`. This avoids redundant path normalization when the
559
- * caller has already decoded and normalized the pathname (e.g. the App
560
- * Router prod server normalizes before static-asset lookup, and can pass
561
- * the result here so the downstream RSC handler doesn't re-normalize).
558
+ * instead of `req.url`.
562
559
  */
563
560
  function nodeToWebRequest(req, urlOverride, prerenderSecret) {
564
561
  const origin = `${resolveRequestProtocol(req)}://${resolveRequestHost(req, "localhost")}`;
@@ -873,8 +870,14 @@ async function startAppRouterServer(options) {
873
870
  return;
874
871
  }
875
872
  try {
876
- const qs = rawUrl.includes("?") ? rawUrl.slice(rawUrl.indexOf("?")) : "";
877
- const response = await rscHandler(nodeToWebRequest(req, pathname + qs, prerenderSecret));
873
+ const request = nodeToWebRequest(req, rawUrl, prerenderSecret);
874
+ const response = await rscHandler(request);
875
+ if (missingBuildAsset && response.status === 404) {
876
+ cancelResponseBody(response);
877
+ res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
878
+ res.end("Not Found");
879
+ return;
880
+ }
878
881
  const staticFileSignal = response.headers.get(VINEXT_STATIC_FILE_HEADER);
879
882
  if (staticFileSignal) {
880
883
  let staticFilePath = "/";
@@ -890,12 +893,6 @@ async function startAppRouterServer(options) {
890
893
  await sendWebResponse(notFoundResponse({ headers: toWebHeaders(staticResponseHeaders) }), req, res, compress);
891
894
  return;
892
895
  }
893
- if (missingBuildAsset && response.status === 404) {
894
- cancelResponseBody(response);
895
- res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
896
- res.end("Not Found");
897
- return;
898
- }
899
896
  await sendWebResponse(response, req, res, compress);
900
897
  } catch (e) {
901
898
  console.error("[vinext] Server error:", e);
@@ -986,8 +983,9 @@ async function startPagesRouterServer(options) {
986
983
  res.end("This page could not be found");
987
984
  return;
988
985
  }
989
- const rawPagesPathname = rawPagesPathnameBeforeNormalize.replaceAll("\\", "/");
986
+ const rawPagesPathname = canonicalizeRequestPathname(rawPagesPathnameBeforeNormalize.replaceAll("\\", "/"));
990
987
  const rawQs = rawUrl.includes("?") ? rawUrl.slice(rawUrl.indexOf("?")) : "";
988
+ let requestPathname = normalizePath(rawPagesPathname);
991
989
  let pathname;
992
990
  try {
993
991
  pathname = normalizePath(normalizePathnameForRouteMatchStrict(rawPagesPathname));
@@ -996,7 +994,7 @@ async function startPagesRouterServer(options) {
996
994
  res.end("Bad Request");
997
995
  return;
998
996
  }
999
- let url = pathname + rawQs;
997
+ let url = requestPathname + rawQs;
1000
998
  if (pathname === "/__vinext/prerender/pages-static-paths") {
1001
999
  const secret = req.headers[VINEXT_PRERENDER_SECRET_HEADER];
1002
1000
  if (!prerenderSecret || secret !== prerenderSecret) {
@@ -1057,18 +1055,31 @@ async function startPagesRouterServer(options) {
1057
1055
  return;
1058
1056
  }
1059
1057
  try {
1060
- const hadBasePath = !basePath || hasBasePath(pathname, basePath);
1058
+ const hadBasePath = !basePath || hasBasePath(requestPathname, basePath);
1059
+ let configMatchPathname = stripBasePath(requestPathname, basePath);
1061
1060
  {
1062
- const stripped = stripBasePath(pathname, basePath);
1063
- if (stripped !== pathname) {
1064
- url = stripped + (url.includes("?") ? url.slice(url.indexOf("?")) : "");
1065
- pathname = stripped;
1061
+ const strippedPathname = stripBasePath(pathname, basePath);
1062
+ const strippedRequestPathname = stripBasePath(requestPathname, basePath);
1063
+ pathname = strippedPathname;
1064
+ if (strippedRequestPathname !== requestPathname) {
1065
+ requestPathname = strippedRequestPathname;
1066
+ url = requestPathname + rawQs;
1066
1067
  }
1067
1068
  }
1069
+ if (urlParserCreatesPagesDataPath(pathname)) {
1070
+ res.writeHead(404);
1071
+ res.end("This page could not be found");
1072
+ return;
1073
+ }
1074
+ requestPathname = encodeUrlParserIgnoredCharacters(requestPathname);
1075
+ {
1076
+ const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
1077
+ url = requestPathname + qs;
1078
+ }
1068
1079
  let isDataReq = false;
1069
1080
  const originalRenderUrl = url;
1070
- if (isNextDataPathname(pathname)) {
1071
- const dataMatch = pagesBuildId ? parseNextDataPathname(pathname, pagesBuildId) : null;
1081
+ if (isNextDataPathname(requestPathname)) {
1082
+ const dataMatch = pagesBuildId ? parseNextDataPathname(requestPathname, pagesBuildId) : null;
1072
1083
  if (!dataMatch) {
1073
1084
  await sendWebResponse(buildNextDataNotFoundResponse(), req, res, compress);
1074
1085
  return;
@@ -1077,7 +1088,9 @@ async function startPagesRouterServer(options) {
1077
1088
  const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
1078
1089
  const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, hasMiddleware && trailingSlash);
1079
1090
  url = pagePathname + qs;
1091
+ requestPathname = pagePathname;
1080
1092
  pathname = pagePathname;
1093
+ configMatchPathname = pagePathname;
1081
1094
  }
1082
1095
  const protocol = resolveRequestProtocol(req);
1083
1096
  const hostHeader = resolveRequestHost(req, `${host}:${port}`);
@@ -1104,6 +1117,7 @@ async function startPagesRouterServer(options) {
1104
1117
  hasMiddleware,
1105
1118
  ctx: void 0,
1106
1119
  rawSearch: rawQs,
1120
+ configMatchPathname,
1107
1121
  matchPageRoute: matchPageRoute ?? null,
1108
1122
  runMiddleware: typeof runMiddleware === "function" ? wrapMiddlewareWithBasePath(runMiddleware, basePath, hadBasePath) : null,
1109
1123
  renderPage: typeof renderPage === "function" ? (request, resolvedUrl, options, stagedHeaders) => renderPage(request, resolvedUrl, ssrManifest, void 0, stagedHeaders, {