vinext 1.0.1 → 1.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 (334) hide show
  1. package/README.md +93 -10
  2. package/dist/build/app-page-static-eligibility.d.ts +15 -0
  3. package/dist/build/app-page-static-eligibility.js +82 -0
  4. package/dist/build/client-build-config.d.ts +10 -0
  5. package/dist/build/client-build-config.js +18 -2
  6. package/dist/build/pages-client-assets-module.d.ts +8 -0
  7. package/dist/build/pages-client-assets-module.js +21 -1
  8. package/dist/build/prerender-paths.js +8 -81
  9. package/dist/build/prerender.js +33 -8
  10. package/dist/build/run-prerender.js +1 -1
  11. package/dist/build/server-manifest.d.ts +7 -0
  12. package/dist/build/server-manifest.js +11 -1
  13. package/dist/build/ssr-manifest.d.ts +2 -0
  14. package/dist/build/ssr-manifest.js +6 -2
  15. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  16. package/dist/cache/cache-adapters-virtual.js +3 -3
  17. package/dist/check.js +7 -6
  18. package/dist/cli.js +2 -1
  19. package/dist/client/client-redirect-matcher.d.ts +14 -0
  20. package/dist/client/client-redirect-matcher.js +37 -0
  21. package/dist/client/client-redirects.d.ts +27 -0
  22. package/dist/client/client-redirects.js +28 -0
  23. package/dist/client/client-rewrites.d.ts +2 -1
  24. package/dist/client/client-rewrites.js +1 -1
  25. package/dist/client/navigation-runtime.d.ts +11 -0
  26. package/dist/client/navigation-runtime.js +1 -1
  27. package/dist/config/config-matchers.d.ts +26 -11
  28. package/dist/config/config-matchers.js +81 -82
  29. package/dist/config/destination-params.d.ts +47 -0
  30. package/dist/config/destination-params.js +116 -0
  31. package/dist/config/next-config.d.ts +14 -0
  32. package/dist/config/next-config.js +21 -3
  33. package/dist/entries/app-rsc-entry.d.ts +6 -0
  34. package/dist/entries/app-rsc-entry.js +84 -49
  35. package/dist/entries/pages-client-entry.js +3 -1
  36. package/dist/entries/pages-server-entry.js +13 -37
  37. package/dist/index.d.ts +7 -2
  38. package/dist/index.js +193 -73
  39. package/dist/init-cloudflare.d.ts +9 -0
  40. package/dist/init-cloudflare.js +107 -31
  41. package/dist/init-platform.d.ts +4 -0
  42. package/dist/init-platform.js +27 -2
  43. package/dist/init.d.ts +1 -0
  44. package/dist/init.js +67 -3
  45. package/dist/plugins/ast-scope.d.ts +7 -0
  46. package/dist/plugins/ast-scope.js +59 -3
  47. package/dist/plugins/cache-flight-codec.d.ts +19 -0
  48. package/dist/plugins/cache-flight-codec.js +68 -0
  49. package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
  50. package/dist/plugins/commonjs-esm-facade.js +80 -0
  51. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  52. package/dist/plugins/dynamic-preload-metadata.js +9 -8
  53. package/dist/plugins/fonts.d.ts +8 -11
  54. package/dist/plugins/fonts.js +71 -34
  55. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  56. package/dist/plugins/ignore-dynamic-requests.js +3 -4
  57. package/dist/plugins/middleware-server-only.d.ts +5 -4
  58. package/dist/plugins/middleware-server-only.js +8 -5
  59. package/dist/plugins/pages-node-externals.js +1 -1
  60. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  61. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  62. package/dist/plugins/strip-server-exports.js +262 -98
  63. package/dist/plugins/transform-result.d.ts +9 -5
  64. package/dist/plugins/transitive-externals.js +1 -1
  65. package/dist/plugins/typeof-window.d.ts +2 -2
  66. package/dist/plugins/use-cache-callable.js +8 -2
  67. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  68. package/dist/plugins/worker-server-only-imports.js +31 -0
  69. package/dist/plugins/worker-use-server.d.ts +25 -0
  70. package/dist/plugins/worker-use-server.js +129 -0
  71. package/dist/routing/file-matcher.d.ts +1 -0
  72. package/dist/routing/file-matcher.js +1 -1
  73. package/dist/server/api-handler.d.ts +1 -0
  74. package/dist/server/api-handler.js +19 -8
  75. package/dist/server/app-browser-action-result.d.ts +1 -1
  76. package/dist/server/app-browser-action-result.js +9 -2
  77. package/dist/server/app-browser-entry.js +11 -7
  78. package/dist/server/app-browser-history-controller.d.ts +2 -0
  79. package/dist/server/app-browser-history-controller.js +8 -0
  80. package/dist/server/app-browser-interception-context.js +26 -2
  81. package/dist/server/app-browser-navigation-controller.d.ts +7 -1
  82. package/dist/server/app-browser-navigation-controller.js +94 -11
  83. package/dist/server/app-browser-server-action-client.js +1 -1
  84. package/dist/server/app-fallback-renderer.d.ts +2 -0
  85. package/dist/server/app-fallback-renderer.js +1 -0
  86. package/dist/server/app-history-state.d.ts +3 -0
  87. package/dist/server/app-history-state.js +7 -0
  88. package/dist/server/app-middleware.d.ts +11 -0
  89. package/dist/server/app-middleware.js +19 -3
  90. package/dist/server/app-optimistic-routing.js +1 -1
  91. package/dist/server/app-page-boundary-render.d.ts +5 -0
  92. package/dist/server/app-page-boundary-render.js +6 -4
  93. package/dist/server/app-page-cache-finalizer.d.ts +11 -0
  94. package/dist/server/app-page-cache-finalizer.js +41 -7
  95. package/dist/server/app-page-cache-render.d.ts +18 -0
  96. package/dist/server/app-page-cache-render.js +63 -43
  97. package/dist/server/app-page-cache.d.ts +6 -1
  98. package/dist/server/app-page-cache.js +28 -8
  99. package/dist/server/app-page-dispatch.d.ts +12 -2
  100. package/dist/server/app-page-dispatch.js +51 -33
  101. package/dist/server/app-page-element-builder.d.ts +7 -0
  102. package/dist/server/app-page-element-builder.js +27 -42
  103. package/dist/server/app-page-execution.d.ts +15 -12
  104. package/dist/server/app-page-execution.js +30 -40
  105. package/dist/server/app-page-head.d.ts +5 -0
  106. package/dist/server/app-page-head.js +9 -3
  107. package/dist/server/app-page-ppr-runtime.js +1 -1
  108. package/dist/server/app-page-probe.d.ts +0 -109
  109. package/dist/server/app-page-probe.js +3 -136
  110. package/dist/server/app-page-render-identity.d.ts +0 -1
  111. package/dist/server/app-page-render-identity.js +1 -1
  112. package/dist/server/app-page-render-observation.js +3 -3
  113. package/dist/server/app-page-render.d.ts +13 -5
  114. package/dist/server/app-page-render.js +219 -119
  115. package/dist/server/app-page-request.d.ts +0 -1
  116. package/dist/server/app-page-request.js +54 -17
  117. package/dist/server/app-page-response.d.ts +4 -3
  118. package/dist/server/app-page-response.js +4 -3
  119. package/dist/server/app-page-route-wiring.d.ts +17 -5
  120. package/dist/server/app-page-route-wiring.js +57 -35
  121. package/dist/server/app-page-rsc-render-status.d.ts +48 -0
  122. package/dist/server/app-page-rsc-render-status.js +54 -0
  123. package/dist/server/app-page-stream.d.ts +15 -8
  124. package/dist/server/app-page-stream.js +6 -0
  125. package/dist/server/app-pages-bridge.d.ts +1 -1
  126. package/dist/server/app-pages-bridge.js +2 -3
  127. package/dist/server/app-prerender-endpoints.js +9 -6
  128. package/dist/server/app-request-stage-dispatch.js +7 -3
  129. package/dist/server/app-request-stage-independent-entry.js +29 -9
  130. package/dist/server/app-response-header-provenance.d.ts +2 -0
  131. package/dist/server/app-response-header-provenance.js +10 -4
  132. package/dist/server/app-response-stage-entry.js +10 -2
  133. package/dist/server/app-route-handler-cache.d.ts +1 -0
  134. package/dist/server/app-route-handler-cache.js +1 -0
  135. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  136. package/dist/server/app-route-handler-dispatch.js +6 -3
  137. package/dist/server/app-route-handler-execution.d.ts +1 -0
  138. package/dist/server/app-route-handler-execution.js +1 -0
  139. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  140. package/dist/server/app-route-handler-runtime.js +45 -24
  141. package/dist/server/app-router-entry.js +27 -8
  142. package/dist/server/app-rsc-cache-busting.js +1 -1
  143. package/dist/server/app-rsc-errors.js +20 -16
  144. package/dist/server/app-rsc-handler.d.ts +11 -0
  145. package/dist/server/app-rsc-handler.js +291 -125
  146. package/dist/server/app-rsc-request-normalization.d.ts +3 -1
  147. package/dist/server/app-rsc-request-normalization.js +4 -2
  148. package/dist/server/app-rsc-response-stage.d.ts +1 -1
  149. package/dist/server/app-rsc-response-stage.js +10 -6
  150. package/dist/server/app-rsc-route-matching.d.ts +9 -1
  151. package/dist/server/app-rsc-route-matching.js +36 -19
  152. package/dist/server/app-segment-config.d.ts +2 -1
  153. package/dist/server/app-server-action-execution.d.ts +2 -1
  154. package/dist/server/app-server-action-execution.js +62 -23
  155. package/dist/server/app-ssr-entry.d.ts +3 -2
  156. package/dist/server/app-ssr-entry.js +8 -5
  157. package/dist/server/app-ssr-stream.d.ts +6 -1
  158. package/dist/server/app-ssr-stream.js +34 -15
  159. package/dist/server/app-worker-stages.d.ts +7 -2
  160. package/dist/server/app-worker-stages.js +4 -4
  161. package/dist/server/cacheability-request.js +11 -7
  162. package/dist/server/client-build-files.d.ts +16 -0
  163. package/dist/server/client-build-files.js +36 -0
  164. package/dist/server/client-reuse-manifest.js +1 -1
  165. package/dist/server/config-headers.js +2 -0
  166. package/dist/server/dev-server.js +50 -29
  167. package/dist/server/dev-stack-sourcemap.js +18 -23
  168. package/dist/server/document-initial-head.d.ts +0 -11
  169. package/dist/server/document-initial-head.js +1 -1
  170. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  171. package/dist/server/forwarded-middleware-context.js +22 -0
  172. package/dist/server/headers.d.ts +18 -1
  173. package/dist/server/headers.js +19 -2
  174. package/dist/server/http-conditional.d.ts +11 -0
  175. package/dist/server/http-conditional.js +10 -1
  176. package/dist/server/http-error-responses.d.ts +1 -1
  177. package/dist/server/image-optimization.d.ts +54 -0
  178. package/dist/server/image-optimization.js +118 -9
  179. package/dist/server/isr-cache.d.ts +10 -0
  180. package/dist/server/isr-cache.js +43 -8
  181. package/dist/server/metadata-route-response.js +9 -8
  182. package/dist/server/middleware-matcher-pattern.js +8 -4
  183. package/dist/server/middleware-matcher.d.ts +2 -0
  184. package/dist/server/middleware-matcher.js +23 -2
  185. package/dist/server/middleware-response-headers.js +2 -0
  186. package/dist/server/middleware-runtime.d.ts +13 -0
  187. package/dist/server/middleware-runtime.js +33 -20
  188. package/dist/server/middleware.d.ts +1 -1
  189. package/dist/server/middleware.js +3 -1
  190. package/dist/server/multi-stage.d.ts +19 -0
  191. package/dist/server/navigation-planner.js +1 -1
  192. package/dist/server/node-response-signal.d.ts +16 -0
  193. package/dist/server/node-response-signal.js +26 -0
  194. package/dist/server/normalize-path.d.ts +0 -13
  195. package/dist/server/normalize-path.js +1 -34
  196. package/dist/server/open-redirect.d.ts +47 -0
  197. package/dist/server/open-redirect.js +74 -1
  198. package/dist/server/pages-api-route.d.ts +3 -2
  199. package/dist/server/pages-api-route.js +4 -3
  200. package/dist/server/pages-cache-tag.d.ts +12 -0
  201. package/dist/server/pages-cache-tag.js +19 -0
  202. package/dist/server/pages-client-assets.d.ts +2 -0
  203. package/dist/server/pages-data-route.d.ts +10 -0
  204. package/dist/server/pages-data-route.js +19 -2
  205. package/dist/server/pages-document-asset-props.d.ts +5 -1
  206. package/dist/server/pages-document-asset-props.js +13 -5
  207. package/dist/server/pages-document-splice.d.ts +19 -0
  208. package/dist/server/pages-document-splice.js +55 -0
  209. package/dist/server/pages-i18n.d.ts +12 -1
  210. package/dist/server/pages-i18n.js +18 -4
  211. package/dist/server/pages-node-compat.d.ts +16 -5
  212. package/dist/server/pages-node-compat.js +20 -12
  213. package/dist/server/pages-page-data.d.ts +32 -24
  214. package/dist/server/pages-page-data.js +50 -120
  215. package/dist/server/pages-page-handler.d.ts +0 -6
  216. package/dist/server/pages-page-handler.js +209 -130
  217. package/dist/server/pages-page-response.d.ts +12 -6
  218. package/dist/server/pages-page-response.js +41 -34
  219. package/dist/server/pages-request-pipeline.d.ts +10 -2
  220. package/dist/server/pages-request-pipeline.js +37 -18
  221. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  222. package/dist/server/pages-request-stage-entry.js +79 -16
  223. package/dist/server/pages-response-stage-entry.js +4 -0
  224. package/dist/server/pages-revalidate.js +1 -1
  225. package/dist/server/pages-router-entry.js +4 -3
  226. package/dist/server/prerender-manifest.d.ts +3 -3
  227. package/dist/server/prerender-manifest.js +4 -3
  228. package/dist/server/prerender-work-unit-setup.js +4 -0
  229. package/dist/server/prod-server.d.ts +20 -7
  230. package/dist/server/prod-server.js +343 -129
  231. package/dist/server/proper-error.d.ts +4 -0
  232. package/dist/server/proper-error.js +31 -0
  233. package/dist/server/request-pipeline.d.ts +24 -9
  234. package/dist/server/request-pipeline.js +24 -9
  235. package/dist/server/response-compression.d.ts +43 -0
  236. package/dist/server/response-compression.js +111 -0
  237. package/dist/server/revalidation-request.d.ts +1 -0
  238. package/dist/server/revalidation-request.js +1 -1
  239. package/dist/server/rsc-stream-hints.js +31 -2
  240. package/dist/server/seed-cache.d.ts +1 -0
  241. package/dist/server/seed-cache.js +15 -11
  242. package/dist/server/server-reference-loader.d.ts +4 -0
  243. package/dist/server/server-reference-loader.js +29 -0
  244. package/dist/server/socket-error-backstop.d.ts +23 -1
  245. package/dist/server/socket-error-backstop.js +69 -17
  246. package/dist/server/static-file-signal.d.ts +15 -4
  247. package/dist/server/static-file-signal.js +46 -12
  248. package/dist/server/worker-image-optimization.d.ts +34 -0
  249. package/dist/server/worker-image-optimization.js +86 -0
  250. package/dist/server/worker-stages.d.ts +1 -1
  251. package/dist/server/worker-stages.js +2 -2
  252. package/dist/server/worker-utils.d.ts +8 -3
  253. package/dist/server/worker-utils.js +12 -7
  254. package/dist/shims/app-router-scroll.js +4 -1
  255. package/dist/shims/app-router-tree-context.d.ts +5 -0
  256. package/dist/shims/app-router-tree-context.js +27 -0
  257. package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
  258. package/dist/shims/cache-adapter-instantiate.js +118 -0
  259. package/dist/shims/cache-callable-runtime.d.ts +6 -42
  260. package/dist/shims/cache-callable-runtime.js +65 -174
  261. package/dist/shims/cache-flight-arguments.d.ts +22 -0
  262. package/dist/shims/cache-flight-arguments.js +56 -0
  263. package/dist/shims/cache-handler.js +1 -9
  264. package/dist/shims/cache-request-state.d.ts +15 -0
  265. package/dist/shims/cache-request-state.js +31 -8
  266. package/dist/shims/cache-runtime.d.ts +12 -20
  267. package/dist/shims/cache-runtime.js +166 -225
  268. package/dist/shims/cache.d.ts +4 -4
  269. package/dist/shims/cache.js +44 -16
  270. package/dist/shims/cacheability-classification.d.ts +7 -0
  271. package/dist/shims/cdn-cache.d.ts +8 -0
  272. package/dist/shims/cdn-cache.js +17 -1
  273. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  274. package/dist/shims/disable-smooth-scroll.js +36 -0
  275. package/dist/shims/document-placeholders.d.ts +19 -0
  276. package/dist/shims/document-placeholders.js +45 -0
  277. package/dist/shims/document.js +21 -5
  278. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  279. package/dist/shims/dynamic-preload-chunks.js +13 -9
  280. package/dist/shims/dynamic.d.ts +1 -1
  281. package/dist/shims/dynamic.js +60 -8
  282. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  283. package/dist/shims/error-boundary-navigation.js +19 -1
  284. package/dist/shims/error-boundary.d.ts +10 -10
  285. package/dist/shims/error-boundary.js +26 -7
  286. package/dist/shims/fetch-cache-state.d.ts +66 -0
  287. package/dist/shims/fetch-cache-state.js +92 -0
  288. package/dist/shims/fetch-cache.d.ts +3 -61
  289. package/dist/shims/fetch-cache.js +161 -108
  290. package/dist/shims/form.js +1 -1
  291. package/dist/shims/head.d.ts +10 -6
  292. package/dist/shims/head.js +15 -13
  293. package/dist/shims/headers.d.ts +13 -0
  294. package/dist/shims/headers.js +47 -4
  295. package/dist/shims/image.js +2 -1
  296. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
  297. package/dist/shims/internal/app-page-props-cache-key.js +24 -15
  298. package/dist/shims/internal/headers-state.d.ts +0 -1
  299. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  300. package/dist/shims/internal/work-store-scope.js +24 -0
  301. package/dist/shims/metadata.js +3 -3
  302. package/dist/shims/navigation-errors.d.ts +6 -0
  303. package/dist/shims/navigation-errors.js +11 -1
  304. package/dist/shims/navigation.d.ts +7 -0
  305. package/dist/shims/navigation.js +45 -9
  306. package/dist/shims/request-context.d.ts +11 -0
  307. package/dist/shims/request-state-types.d.ts +2 -1
  308. package/dist/shims/router.js +12 -20
  309. package/dist/shims/server.d.ts +16 -0
  310. package/dist/shims/server.js +24 -4
  311. package/dist/shims/thenable-params.d.ts +4 -0
  312. package/dist/shims/thenable-params.js +25 -3
  313. package/dist/shims/unified-request-context.d.ts +1 -1
  314. package/dist/shims/unified-request-context.js +1 -0
  315. package/dist/shims/url-utils.d.ts +2 -0
  316. package/dist/shims/url-utils.js +3 -1
  317. package/dist/utils/client-runtime-metadata.js +1 -1
  318. package/dist/utils/hash.d.ts +7 -0
  319. package/dist/utils/hash.js +11 -1
  320. package/dist/utils/mdx-scan.d.ts +5 -0
  321. package/dist/utils/mdx-scan.js +8 -1
  322. package/dist/utils/package-name.d.ts +6 -0
  323. package/dist/utils/package-name.js +12 -1
  324. package/dist/utils/plugin-rsc-version.d.ts +4 -0
  325. package/dist/utils/plugin-rsc-version.js +15 -0
  326. package/dist/utils/prerender-output-paths.js +15 -4
  327. package/dist/utils/public-file-path.d.ts +10 -2
  328. package/dist/utils/public-file-path.js +13 -9
  329. package/dist/utils/public-routes.js +2 -2
  330. package/dist/utils/react-version.d.ts +3 -0
  331. package/dist/utils/react-version.js +1 -1
  332. package/dist/utils/regex-safety.d.ts +10 -0
  333. package/dist/utils/regex-safety.js +70 -18
  334. package/package.json +9 -5
@@ -0,0 +1,47 @@
1
+ //#region src/config/destination-params.d.ts
2
+ /**
3
+ * Destination param substitution for next.config.js redirects and rewrites.
4
+ *
5
+ * Kept free of server-only imports so the Pages Router client can apply simple
6
+ * beforeFiles rewrites with exactly the same substitution as the server.
7
+ */
8
+ /**
9
+ * Substitute all matched route params into a redirect/rewrite destination.
10
+ *
11
+ * Handles repeated params (e.g. `/api/:id/:id`) and catch-all suffix forms
12
+ * (`:path*`, `:path+`) in a single pass. Unknown params are left intact.
13
+ *
14
+ * Query substitution follows how Next.js consumes each destination kind:
15
+ *
16
+ * - A rewrite's query is parsed into an object before substitution, so the
17
+ * target sees each param verbatim as one value. vinext encodes the whole
18
+ * value so it round-trips back to that verbatim string.
19
+ * - A redirect's query is emitted as Location text with params inserted
20
+ * verbatim, so an already percent-encoded capture is decoded once by the
21
+ * client. vinext inserts redirect params verbatim too.
22
+ *
23
+ * A rewrite's absolute destination is proxied server-side, so params in its
24
+ * authority (`https://:tenant.example.com/`) are percent-encoded, keeping the
25
+ * `%XX` escapes a raw path capture already carries. A decoded `has` capture
26
+ * carrying `#`, `/`, `?`, `@` or `:` then makes the host invalid instead of
27
+ * moving the proxy to another host. Next.js substitutes the hostname verbatim
28
+ * and can be retargeted this way; vinext is stricter.
29
+ *
30
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
31
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/server-route-utils.ts
32
+ */
33
+ export declare function substituteDestinationParams(destination: string, params: Record<string, string>, kind: "redirect" | "rewrite"): string;
34
+ /**
35
+ * Split a redirect destination's query into parts before substituting params,
36
+ * as Next.js's prepareDestination parses the template query first. Each part
37
+ * is `[key, keyText, valueText]`: the texts are the part's template text with
38
+ * params substituted verbatim (`valueText` is `null` without an `=`), and
39
+ * `key` is the decoded key, used only to match request params. Keeping these
40
+ * boundaries means a param containing `&` stays one value when the request
41
+ * query is merged in.
42
+ *
43
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
44
+ */
45
+ export declare function substituteRedirectDestinationQuery(destination: string, params: Record<string, string>): RedirectDestinationQueryPart[];
46
+ export type RedirectDestinationQueryPart = [key: string, keyText: string, valueText: string | null];
47
+ //#endregion
@@ -0,0 +1,116 @@
1
+ //#region src/config/destination-params.ts
2
+ /**
3
+ * Destination param substitution for next.config.js redirects and rewrites.
4
+ *
5
+ * Kept free of server-only imports so the Pages Router client can apply simple
6
+ * beforeFiles rewrites with exactly the same substitution as the server.
7
+ */
8
+ /**
9
+ * Cache for destination substitution regexes in substituteDestinationParams.
10
+ *
11
+ * The regex depends only on the set of param keys captured from the matched
12
+ * source pattern. Caching by sorted key list avoids recompiling a new RegExp
13
+ * for repeated redirect/rewrite calls that use the same param shape.
14
+ */
15
+ const _compiledDestinationParamCache = /* @__PURE__ */ new Map();
16
+ /**
17
+ * Substitute all matched route params into a redirect/rewrite destination.
18
+ *
19
+ * Handles repeated params (e.g. `/api/:id/:id`) and catch-all suffix forms
20
+ * (`:path*`, `:path+`) in a single pass. Unknown params are left intact.
21
+ *
22
+ * Query substitution follows how Next.js consumes each destination kind:
23
+ *
24
+ * - A rewrite's query is parsed into an object before substitution, so the
25
+ * target sees each param verbatim as one value. vinext encodes the whole
26
+ * value so it round-trips back to that verbatim string.
27
+ * - A redirect's query is emitted as Location text with params inserted
28
+ * verbatim, so an already percent-encoded capture is decoded once by the
29
+ * client. vinext inserts redirect params verbatim too.
30
+ *
31
+ * A rewrite's absolute destination is proxied server-side, so params in its
32
+ * authority (`https://:tenant.example.com/`) are percent-encoded, keeping the
33
+ * `%XX` escapes a raw path capture already carries. A decoded `has` capture
34
+ * carrying `#`, `/`, `?`, `@` or `:` then makes the host invalid instead of
35
+ * moving the proxy to another host. Next.js substitutes the hostname verbatim
36
+ * and can be retargeted this way; vinext is stricter.
37
+ *
38
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
39
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/server-route-utils.ts
40
+ */
41
+ function substituteDestinationParams(destination, params, kind) {
42
+ const paramRe = getDestinationParamRegex(params);
43
+ if (!paramRe) return destination;
44
+ const replaceParams = (value, encodeParam) => value.replace(paramRe, (_token, key) => encodeParam(params[key]));
45
+ if (kind === "redirect") return replaceParams(destination, (value) => value);
46
+ const hashIndex = destination.indexOf("#");
47
+ const beforeHash = hashIndex === -1 ? destination : destination.slice(0, hashIndex);
48
+ const hash = hashIndex === -1 ? "" : destination.slice(hashIndex);
49
+ const queryIndex = beforeHash.indexOf("?");
50
+ const beforeQuery = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);
51
+ const authorityEnd = getAbsoluteUrlAuthorityEnd(beforeQuery.replace(paramRe, (token) => "x".repeat(token.length)));
52
+ return `${`${replaceParams(beforeQuery.slice(0, authorityEnd), encodeAuthorityParam)}${replaceParams(beforeQuery.slice(authorityEnd), (value) => value)}`}${queryIndex === -1 ? "" : `?${replaceParams(beforeHash.slice(queryIndex + 1), encodeRewriteQueryParamValue)}`}${replaceParams(hash, (value) => value)}`;
53
+ }
54
+ function getAbsoluteUrlAuthorityEnd(value) {
55
+ const scheme = /^[a-z][a-z0-9+.-]*:[/\\\t\n\r]*/i.exec(value);
56
+ if (!scheme && /^[/\\]/.test(value)) return 0;
57
+ const start = scheme ? scheme[0].length : 0;
58
+ const pathStart = value.slice(start).search(/[/\\]/);
59
+ return pathStart === -1 ? value.length : start + pathStart;
60
+ }
61
+ /**
62
+ * Split a redirect destination's query into parts before substituting params,
63
+ * as Next.js's prepareDestination parses the template query first. Each part
64
+ * is `[key, keyText, valueText]`: the texts are the part's template text with
65
+ * params substituted verbatim (`valueText` is `null` without an `=`), and
66
+ * `key` is the decoded key, used only to match request params. Keeping these
67
+ * boundaries means a param containing `&` stays one value when the request
68
+ * query is merged in.
69
+ *
70
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
71
+ */
72
+ function substituteRedirectDestinationQuery(destination, params) {
73
+ const hashIndex = destination.indexOf("#");
74
+ const beforeHash = hashIndex === -1 ? destination : destination.slice(0, hashIndex);
75
+ const queryIndex = beforeHash.indexOf("?");
76
+ if (queryIndex === -1) return [];
77
+ const paramRe = getDestinationParamRegex(params);
78
+ const substitute = (value) => paramRe ? value.replace(paramRe, (_token, key) => params[key]) : value;
79
+ return beforeHash.slice(queryIndex + 1).split("&").filter(Boolean).map((part) => {
80
+ const equalsIndex = part.indexOf("=");
81
+ const keyText = substitute(equalsIndex === -1 ? part : part.slice(0, equalsIndex));
82
+ const valueText = equalsIndex === -1 ? null : substitute(part.slice(equalsIndex + 1));
83
+ return [
84
+ decodeQueryKey(keyText),
85
+ keyText,
86
+ valueText
87
+ ];
88
+ });
89
+ }
90
+ function decodeQueryKey(keyText) {
91
+ const [entry] = new URLSearchParams(keyText.replace(/[&=]/g, (char) => encodeURIComponent(char)));
92
+ return entry?.[0] ?? "";
93
+ }
94
+ function getDestinationParamRegex(params) {
95
+ const keys = Object.keys(params);
96
+ if (keys.length === 0) return null;
97
+ const sortedKeys = [...keys].sort((a, b) => b.length - a.length);
98
+ const cacheKey = sortedKeys.join("\0");
99
+ let paramRe = _compiledDestinationParamCache.get(cacheKey);
100
+ if (!paramRe) {
101
+ const paramAlternation = sortedKeys.map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
102
+ paramRe = new RegExp(`:(${paramAlternation})([+*])?(?![A-Za-z0-9_])`, "g");
103
+ _compiledDestinationParamCache.set(cacheKey, paramRe);
104
+ }
105
+ return paramRe;
106
+ }
107
+ function encodeAuthorityParam(value) {
108
+ return value.replace(/%(?![0-9a-f]{2})|[^A-Za-z0-9._~%-]/giu, encodeURIComponent);
109
+ }
110
+ function encodeRewriteQueryParamValue(value) {
111
+ const params = new URLSearchParams();
112
+ params.set("", value);
113
+ return params.toString().slice(1);
114
+ }
115
+ //#endregion
116
+ export { substituteDestinationParams, substituteRedirectDestinationQuery };
@@ -111,6 +111,17 @@ export type NextConfig = {
111
111
  crossOrigin?: "anonymous" | "use-credentials";
112
112
  /** Whether to add trailing slashes */
113
113
  trailingSlash?: boolean;
114
+ /**
115
+ * Skip the automatic trailing-slash redirects and keep `<Link>`/router
116
+ * hrefs exactly as written.
117
+ * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/skipTrailingSlashRedirect
118
+ */
119
+ skipTrailingSlashRedirect?: boolean;
120
+ /**
121
+ * Compress responses from the Node production server. Defaults to true.
122
+ * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/compress
123
+ */
124
+ compress?: boolean;
114
125
  /** Keep the original request URL visible to middleware/proxy. */
115
126
  skipProxyUrlNormalize?: boolean;
116
127
  /** @deprecated Use `skipProxyUrlNormalize` instead. */
@@ -312,6 +323,9 @@ export type ResolvedNextConfig = {
312
323
  */
313
324
  assetPrefix: string;
314
325
  trailingSlash: boolean;
326
+ skipTrailingSlashRedirect: boolean;
327
+ /** Whether the Node production server compresses responses (`compress`, default true). */
328
+ compress: boolean;
315
329
  skipProxyUrlNormalize: boolean;
316
330
  typescript: {
317
331
  tsconfigPath?: string;
@@ -1,5 +1,5 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
- import { normalizePageExtensions } from "../routing/file-matcher.js";
2
+ import { DEFAULT_PAGE_EXTENSIONS, normalizePageExtensions } from "../routing/file-matcher.js";
3
3
  import { loadCommonJsModule, shouldRetryAsCommonJs } from "../utils/commonjs-loader.js";
4
4
  import { isUnknownRecord } from "../utils/record.js";
5
5
  import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
@@ -184,11 +184,24 @@ function warnConfigLoadFailure(filename, err) {
184
184
  if (isNextIntlPlugin) console.warn("[vinext] Hint: createNextIntlPlugin() is not needed with vinext. Remove the next-intl/plugin wrapper from your next.config — vinext auto-detects next-intl and registers the i18n config alias automatically.");
185
185
  }
186
186
  /**
187
+ * The `defaultConfig` handed to a function-form next.config. Next.js passes
188
+ * its full `defaultConfig` (packages/next/src/server/config-shared.ts); vinext
189
+ * passes the subset configs are known to read, with values matching Next.js,
190
+ * so `[...defaultConfig.pageExtensions, "page.js"]` works. Fresh per call so a
191
+ * config that mutates it cannot leak into later loads.
192
+ */
193
+ function createFunctionConfigDefaults() {
194
+ return {
195
+ pageExtensions: [...DEFAULT_PAGE_EXTENSIONS],
196
+ compress: true
197
+ };
198
+ }
199
+ /**
187
200
  * Resolve a Next-style config value, calling it if it's a function-form config
188
201
  * (Next.js supports `module.exports = (phase, opts) => config`).
189
202
  */
190
203
  async function resolveConfigValue(config, phase = DEFAULT_PHASE) {
191
- if (typeof config === "function") return await config(phase, { defaultConfig: {} });
204
+ if (typeof config === "function") return await config(phase, { defaultConfig: createFunctionConfigDefaults() });
192
205
  return config;
193
206
  }
194
207
  /**
@@ -360,6 +373,7 @@ function warnDeprecatedConfigOptions(config, root) {
360
373
  ["experimental.instrumentationHook", `\`experimental.instrumentationHook\` is no longer needed, because \`instrumentation.js\` is available by default. You can remove it from ${configFileName}.`]
361
374
  ];
362
375
  for (const [propertyPath, warning] of warnings) if (hasConfigProperty(config, propertyPath)) warnConfigOnce(warning);
376
+ if (readOptionalRecord(config.experimental)?.skipTrailingSlashRedirect != null) warnConfigOnce(`\`experimental.skipTrailingSlashRedirect\` has been moved to \`skipTrailingSlashRedirect\`. Please update your ${configFileName} file accordingly.`);
363
377
  }
364
378
  async function resolveNextConfigInput(config, phase = PHASE_DEVELOPMENT_SERVER) {
365
379
  return await resolveConfigValue(config, phase);
@@ -436,7 +450,7 @@ async function loadNextConfigWithPackageIdentity(root, phase) {
436
450
  },
437
451
  load(id) {
438
452
  if (id !== resolvedVirtualConfigId) return;
439
- return `import * as configModule from ${configPathLiteral};\nconst cjsModule = configModule[${JSON.stringify(VINEXT_CJS_EXPORTS_KEY)}];\nconst cjsInitial = configModule[${JSON.stringify(VINEXT_CJS_INITIAL_KEY)}];\nconst cjsExports = cjsModule && cjsModule.exports;\nconst cjsValue = cjsExports != null && (cjsExports !== cjsInitial || (typeof cjsExports === "object" && Object.keys(cjsExports).length > 0)) ? cjsExports : undefined;\nconst value = cjsValue ?? configModule.default ?? configModule;\nexport default typeof value === "function" ? await value(${phaseLiteral}, { defaultConfig: {} }) : value;\n`;
453
+ return `import * as configModule from ${configPathLiteral};\nconst cjsModule = configModule[${JSON.stringify(VINEXT_CJS_EXPORTS_KEY)}];\nconst cjsInitial = configModule[${JSON.stringify(VINEXT_CJS_INITIAL_KEY)}];\nconst cjsExports = cjsModule && cjsModule.exports;\nconst cjsValue = cjsExports != null && (cjsExports !== cjsInitial || (typeof cjsExports === "object" && Object.keys(cjsExports).length > 0)) ? cjsExports : undefined;\nconst value = cjsValue ?? configModule.default ?? configModule;\nexport default typeof value === "function" ? await value(${phaseLiteral}, { defaultConfig: ${JSON.stringify(createFunctionConfigDefaults())} }) : value;\n`;
440
454
  }
441
455
  },
442
456
  ...isTypeScriptConfig ? [cjsGlobalsInjectorPlugin(configPath)] : [],
@@ -748,6 +762,8 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
748
762
  basePath: "",
749
763
  assetPrefix: "",
750
764
  trailingSlash: false,
765
+ skipTrailingSlashRedirect: false,
766
+ compress: true,
751
767
  skipProxyUrlNormalize: false,
752
768
  typescript: {},
753
769
  output: "",
@@ -933,6 +949,8 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
933
949
  basePath: config.basePath ?? "",
934
950
  assetPrefix: normalizeAssetPrefix(config.assetPrefix),
935
951
  trailingSlash: config.trailingSlash ?? false,
952
+ skipTrailingSlashRedirect: (experimental?.skipTrailingSlashRedirect ?? config.skipTrailingSlashRedirect) === true,
953
+ compress: config.compress !== false,
936
954
  skipProxyUrlNormalize: config.skipProxyUrlNormalize ?? config.skipMiddlewareUrlNormalize ?? false,
937
955
  typescript: typeof config.typescript?.tsconfigPath === "string" ? { tsconfigPath: config.typescript.tsconfigPath } : {},
938
956
  output: output === "export" || output === "standalone" ? output : "",
@@ -60,6 +60,8 @@ type AppRouterConfig = {
60
60
  globalNotFound?: boolean;
61
61
  /** Enables Next.js Cache Components semantics for App Router document HTML. */
62
62
  cacheComponents?: boolean;
63
+ /** Reads an MDX source's ESM exports, as the prerender listing does. */
64
+ readMdxEsm?: ((source: string) => string) | null;
63
65
  /** Resolved `experimental.prefetchInlining` thresholds. */
64
66
  prefetchInlining?: PrefetchInliningConfig;
65
67
  /** Whether the RSC build discovered any server references. Defaults to true. */
@@ -91,6 +93,10 @@ type AppRouterConfig = {
91
93
  draftModeSecret?: string;
92
94
  /** Server-only token used to authorize build-time prerender endpoints. */
93
95
  prerenderSecret?: string;
96
+ /** next.config `skipTrailingSlashRedirect`. */
97
+ skipTrailingSlashRedirect?: boolean;
98
+ /** Dev-only key authenticating the hybrid Pages handler's forwarded middleware context. */
99
+ devForwardedMiddlewareContextKey?: string;
94
100
  };
95
101
  /** Generate the module-free App request stage used by multi-stage Worker outputs. */
96
102
  export declare function generateAppRequestRscEntry(appDir: string, routes: AppRoute[], middlewarePath?: string | null, metadataRoutes?: MetadataFileRoute[], _globalErrorPath?: string | null, basePath?: string, trailingSlash?: boolean, config?: AppRouterConfig, instrumentationPath?: string | null): string;
@@ -2,11 +2,12 @@ import { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index
2
2
  import { appRouteHasMainTreeLoadingBoundary } from "../routing/app-router.js";
3
3
  import { resolveEntryPath } from "./runtime-entry-module.js";
4
4
  import { isProxyFile } from "../server/middleware.js";
5
- import { extractExportConstString } from "../build/report.js";
5
+ import { extractExportConstString, getAppRouteRenderEntryPath } from "../build/report.js";
6
6
  import { routePatternParts } from "../routing/route-pattern.js";
7
7
  import { safeJsonStringify } from "../server/html.js";
8
8
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from "../server/image-optimization.js";
9
9
  import { buildAppRscManifestCode } from "./app-rsc-manifest.js";
10
+ import { classifyAppPageRouteStaticEligibility } from "../build/app-page-static-eligibility.js";
10
11
  import { generateDevOriginCheckCode } from "../server/dev-origin-check.js";
11
12
  import { ACTION_OWNER_MANIFEST_ID } from "../plugins/action-owner-manifest.js";
12
13
  import fs from "node:fs";
@@ -24,12 +25,12 @@ import { randomUUID } from "node:crypto";
24
25
  const DEFAULT_EXPIRE_TIME = 31536e3;
25
26
  const DEFAULT_REACT_MAX_HEADERS_LENGTH = 6e3;
26
27
  const middlewareRequestHeadersPath = resolveEntryPath("../utils/middleware-request-headers.js", import.meta.url);
27
- const normalizePathModulePath = resolveEntryPath("../server/normalize-path.js", import.meta.url);
28
28
  const appRouteHandlerDispatchPath = resolveEntryPath("../server/app-route-handler-dispatch.js", import.meta.url);
29
29
  const appRouteRequestBuiltInsPath = resolveEntryPath("../server/app-route-request-built-ins.js", import.meta.url);
30
30
  const appRouteHandlerResponsePath = resolveEntryPath("../server/app-route-handler-response.js", import.meta.url);
31
31
  const appRouteHandlerMiddlewareContextPath = resolveEntryPath("../server/app-route-handler-middleware-context.js", import.meta.url);
32
32
  const appServerActionExecutionPath = resolveEntryPath("../server/app-server-action-execution.js", import.meta.url);
33
+ const serverReferenceLoaderPath = resolveEntryPath("../server/server-reference-loader.js", import.meta.url);
33
34
  const appActionForwardingPath = resolveEntryPath("../server/app-action-forwarding.js", import.meta.url);
34
35
  const appMiddlewarePath = resolveEntryPath("../server/app-middleware.js", import.meta.url);
35
36
  const metadataRouteResponsePath = resolveEntryPath("../server/metadata-route-response.js", import.meta.url);
@@ -38,7 +39,6 @@ const appPageExecutionPath = resolveEntryPath("../server/app-page-execution.js",
38
39
  const appFallbackRendererPath = resolveEntryPath("../server/app-fallback-renderer.js", import.meta.url);
39
40
  const appElementsPath = resolveEntryPath("../server/app-elements.js", import.meta.url);
40
41
  const appPageRouteWiringPath = resolveEntryPath("../server/app-page-route-wiring.js", import.meta.url);
41
- const appPageProbePath = resolveEntryPath("../server/app-page-probe.js", import.meta.url);
42
42
  const appPageDispatchPath = resolveEntryPath("../server/app-page-dispatch.js", import.meta.url);
43
43
  const appPagePprRuntimePath = resolveEntryPath("../server/app-page-ppr-runtime.js", import.meta.url);
44
44
  const fileBasedMetadataPath = resolveEntryPath("../server/file-based-metadata.js", import.meta.url);
@@ -63,10 +63,10 @@ const appHookWarningSuppressionPath = resolveEntryPath("../server/app-hook-warni
63
63
  const serverGlobalsPath = resolveEntryPath("../server/server-globals.js", import.meta.url);
64
64
  const appPagesBridgePath = resolveEntryPath("../server/app-pages-bridge.js", import.meta.url);
65
65
  const routePatternPath = resolveEntryPath("../routing/route-pattern.js", import.meta.url);
66
- function buildAppRequestRouteMetadata(routes) {
66
+ function createSegmentSourceReader() {
67
67
  const sourceCache = /* @__PURE__ */ new Map();
68
- const forcesDynamic = (filePath) => {
69
- if (!filePath) return false;
68
+ return (filePath) => {
69
+ if (!filePath) return null;
70
70
  let source = sourceCache.get(filePath);
71
71
  if (source === void 0) {
72
72
  try {
@@ -76,19 +76,57 @@ function buildAppRequestRouteMetadata(routes) {
76
76
  }
77
77
  sourceCache.set(filePath, source);
78
78
  }
79
+ return source;
80
+ };
81
+ }
82
+ /** Segment config files of the tree a direct request to a page route renders. */
83
+ function appPageSegmentConfigPaths(route) {
84
+ return [
85
+ ...route.layouts,
86
+ route.pagePath,
87
+ ...route.parallelSlots.flatMap((slot) => [
88
+ slot.layoutPath,
89
+ ...slot.configLayoutPaths ?? [],
90
+ slot.pagePath ?? slot.defaultPath
91
+ ])
92
+ ];
93
+ }
94
+ /**
95
+ * Patterns of the static App pages that answer a request whose raw pathname
96
+ * reaches a dynamic sibling but whose segment-decoded pathname names them, so
97
+ * `/%61` and `/caf%C3%A9` render `/a` and `/café` rather than `/[slug]`.
98
+ *
99
+ * Next.js serves those requests from the response cached under the decoded
100
+ * pathname, which exists only for a page it prerendered. The prerender listing
101
+ * classifies those: a page whose effective segment config renders it
102
+ * dynamically (`dynamic = "force-dynamic"`, `revalidate = 0` or the edge
103
+ * runtime on any segment) and a Route Handler have no such entry, so the
104
+ * dynamic sibling renders. So does a page whose sources can't be read here;
105
+ * its sibling's render stays out of the shared caches. A cacheComponents
106
+ * build lists every page route, as the prerender listing does.
107
+ */
108
+ function buildAppDecodedPathnamePatterns(routes, config) {
109
+ const isPrerenderedPage = (route) => {
110
+ if (config?.cacheComponents) return true;
111
+ try {
112
+ return classifyAppPageRouteStaticEligibility(route, config?.readMdxEsm ?? null) === "eligible";
113
+ } catch {
114
+ return false;
115
+ }
116
+ };
117
+ return routes.filter((route) => !route.isDynamic && !route.routePath && getAppRouteRenderEntryPath(route) !== null && isPrerenderedPage(route)).map((route) => route.pattern);
118
+ }
119
+ function buildAppRequestRouteMetadata(routes) {
120
+ const readSource = createSegmentSourceReader();
121
+ const forcesDynamic = (filePath) => {
122
+ const source = readSource(filePath);
79
123
  return source !== null && extractExportConstString(source, "dynamic") === "force-dynamic";
80
124
  };
81
125
  return routes.map((route) => ({
82
126
  canUseCanonicalLoadingShell: appRouteHasMainTreeLoadingBoundary(route),
83
127
  forceDynamic: route.routePath ? forcesDynamic(route.routePath) : [
84
- ...route.layouts,
85
- route.pagePath,
86
- ...route.parallelSlots.flatMap((slot) => [
87
- slot.layoutPath,
88
- ...slot.configLayoutPaths ?? [],
89
- slot.pagePath ?? slot.defaultPath,
90
- ...slot.interceptingRoutes.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])
91
- ]),
128
+ ...appPageSegmentConfigPaths(route),
129
+ ...route.parallelSlots.flatMap((slot) => slot.interceptingRoutes.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])),
92
130
  ...route.siblingIntercepts.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])
93
131
  ].some(forcesDynamic),
94
132
  ids: route.ids ?? null,
@@ -162,6 +200,7 @@ import { dispatchAppRequestStage as __dispatchAppRequestStage } from ${JSON.stri
162
200
  import { registerConfiguredCacheAdapters as __registerConfiguredCacheAdapters } from "virtual:vinext-cdn-cache-adapter";
163
201
  import { clearAppRequestStageContext as __clearRequestContext, setAppRequestStageNavigationContext as setNavigationContext } from ${JSON.stringify(appRequestStageContextPath)};
164
202
  import { matchRoutePattern as __matchRoutePattern } from ${JSON.stringify(routePatternPath)};
203
+ import __pagesClientAssets from "virtual:vinext-pages-client-assets";
165
204
  ${middlewarePath ? `import { applyAppMiddleware as __applyAppMiddleware } from ${JSON.stringify(appMiddlewarePath)};` : ""}
166
205
  ${instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(toSlash(instrumentationPath))};
167
206
  import { ensureInstrumentationRegistered as __ensureInstrumentationRegistered } from ${JSON.stringify(instrumentationRuntimePath)};
@@ -178,7 +217,6 @@ ${hasPagesDir ? `import { getDraftModeCookieHeader } from "next/headers";
178
217
  import * as __pagesRequestEntry from "virtual:vinext-pages-request-entry";
179
218
  import { renderPagesFallback as __renderPagesFallback } from ${JSON.stringify(appPagesBridgePath)};
180
219
  import { buildRequestHeadersFromMiddlewareResponse as __buildRequestHeadersFromMiddlewareResponse } from ${JSON.stringify(middlewareRequestHeadersPath)};
181
- import { decodePathParams as __decodePathParams } from ${JSON.stringify(normalizePathModulePath)};
182
220
  import { applyRouteHandlerMiddlewareContext as __applyRouteHandlerMiddlewareContext } from ${JSON.stringify(appRouteHandlerMiddlewareContextPath)};` : ""}
183
221
 
184
222
  ${hasPagesDir ? `export function __ensureHybridPagesApplication() {
@@ -200,12 +238,14 @@ export const __imageConfig = ${JSON.stringify({
200
238
  contentDispositionType: config?.imageConfig?.contentDispositionType,
201
239
  contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy
202
240
  })};
241
+ export const __clientBuildFiles = __pagesClientAssets.clientBuildFiles ?? [];
203
242
  const __routes = ${JSON.stringify(requestRoutes)};
204
- const __routeMatcher = __createAppRscRouteMatcher(__routes);
243
+ const __routeMatcher = __createAppRscRouteMatcher(__routes, ${JSON.stringify(buildAppDecodedPathnamePatterns(routes, config))});
205
244
  const __metadataRouteMatchers = ${JSON.stringify(metadataRouteMatchers)};
206
245
 
207
246
  function matchRoute(pathname) { return __routeMatcher.matchRoute(pathname); }
208
247
  function matchRequestRoute(pathname) { return __routeMatcher.matchRequestRoute(pathname); }
248
+ function matchRawRequestRoute(pathname) { return __routeMatcher.matchRawRequestRoute(pathname); }
209
249
  function hasInterceptionId(interceptionId) { return __routeMatcher.hasInterceptionId(interceptionId); }
210
250
  function __isMetadataPath(pathname) {
211
251
  const parts = pathname.split("/").filter(Boolean);
@@ -252,6 +292,7 @@ const __requestHandler = createAppRscRequestHandler({
252
292
  fallback: []
253
293
  })},
254
294
  draftModeSecret: __draftModeSecret,
295
+ devForwardedMiddlewareContextKey: ${JSON.stringify(config?.devForwardedMiddlewareContextKey ?? null)},
255
296
  dispatchMatchedPage() { throw new Error("App request stage attempted to render a page inline"); },
256
297
  dispatchMatchedRouteHandler() { throw new Error("App request stage attempted to render a route handler inline"); },
257
298
  ${instrumentationPath ? "ensureInstrumentation() { return __ensureInstrumentation(); }," : ""}
@@ -262,6 +303,7 @@ const __requestHandler = createAppRscRequestHandler({
262
303
  hasInterceptionId,
263
304
  matchRoute,
264
305
  matchRequestRoute,
306
+ matchRawRequestRoute,
265
307
  matchInterceptRoute(pathname, sourcePathname, interceptionId) {
266
308
  const intercept = __routeMatcher.findIntercept(pathname, sourcePathname, interceptionId);
267
309
  if (!intercept) return null;
@@ -293,6 +335,7 @@ const __requestHandler = createAppRscRequestHandler({
293
335
  middlewareRequest,
294
336
  module: middlewareModule,
295
337
  request,
338
+ skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
296
339
  trailingSlash: __trailingSlash,
297
340
  validateExternalRewriteRequest,
298
341
  });
@@ -318,7 +361,6 @@ const __requestHandler = createAppRscRequestHandler({
318
361
  };
319
362
  },
320
363
  buildRequestHeaders: __buildRequestHeadersFromMiddlewareResponse,
321
- decodePathParams: __decodePathParams,
322
364
  applyRouteHandlerMiddlewareContext: __applyRouteHandlerMiddlewareContext,
323
365
  getDraftModeCookieHeader,
324
366
  }
@@ -326,6 +368,7 @@ const __requestHandler = createAppRscRequestHandler({
326
368
  },` : ""}
327
369
  rootParamNamesByPattern: {},
328
370
  setNavigationContext,
371
+ skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
329
372
  staticParamsMap: {},
330
373
  trailingSlash: __trailingSlash,
331
374
  validateDevRequestOrigin: __validateDevRequestOrigin,
@@ -480,14 +523,15 @@ import { registerConfiguredCacheAdapters as __registerConfiguredCacheAdapters }
480
523
  import __pagesClientAssets from "virtual:vinext-pages-client-assets";
481
524
  ${actionOwners === void 0 ? `import __vinextActionOwners from ${JSON.stringify(ACTION_OWNER_MANIFEST_ID)};` : ""}
482
525
  import { setPagesClientAssets as __setPagesClientAssets } from "vinext/server/pages-client-assets";
483
- import { decodePathParams as __decodePathParams } from ${JSON.stringify(normalizePathModulePath)};
484
526
  import { buildRequestHeadersFromMiddlewareResponse as __buildRequestHeadersFromMiddlewareResponse } from ${JSON.stringify(middlewareRequestHeadersPath)};
485
527
  ${hasPagesDir ? `import {
486
528
  applyRouteHandlerMiddlewareContext as __applyRouteHandlerMiddlewareContext,
487
529
  } from ${JSON.stringify(appRouteHandlerResponsePath)};` : ""}
488
530
  const __loadAppRouteHandlerDispatch = () => import(${JSON.stringify(appRouteHandlerDispatchPath)});
489
531
  ${hasServerActions ? `const __loadAppServerActionExecution = () => import(${JSON.stringify(appServerActionExecutionPath)});
490
- const __loadAppActionForwarding = () => import(${JSON.stringify(appActionForwardingPath)});` : ""}
532
+ const __loadAppActionForwarding = () => import(${JSON.stringify(appActionForwardingPath)});
533
+ import { isolateServerReferenceLoads as __isolateServerReferenceLoads } from ${JSON.stringify(serverReferenceLoaderPath)};
534
+ __isolateServerReferenceLoads();` : ""}
491
535
  ${(metadataRoutes?.length ?? 0) > 0 ? `const __loadMetadataRouteResponse = () => import(${JSON.stringify(metadataRouteResponsePath)});` : ""}
492
536
  ${(metadataRoutes?.length ?? 0) > 0 ? `const __loadFileBasedMetadata = () => import(${JSON.stringify(fileBasedMetadataPath)});
493
537
  async function __applyFileBasedMetadata(...args) {
@@ -513,7 +557,6 @@ import {
513
557
  resolveAppPageChildSegments as __resolveAppPageChildSegments,
514
558
  } from ${JSON.stringify(appPageRouteWiringPath)};
515
559
  import { buildPageElements as __buildPageElements } from ${JSON.stringify(appPageElementBuilderPath)};
516
- import { buildAppPageProbes as __buildAppPageProbes } from ${JSON.stringify(appPageProbePath)};
517
560
  import {
518
561
  dispatchAppPage as __dispatchAppPage,
519
562
  } from ${JSON.stringify(appPageDispatchPath)};
@@ -539,6 +582,8 @@ import {
539
582
  SIBLING_PAGE_INTERCEPT_SLOT_KEY as __SIBLING_PAGE_INTERCEPT_SLOT_KEY,
540
583
  } from ${JSON.stringify(appRscRouteMatchingPath)};
541
584
  import {
585
+ appIsrFallbackShellHtmlKey as __isrFallbackShellHtmlKey,
586
+ appIsrFallbackShellKey as __isrFallbackShellKey,
542
587
  appIsrHtmlKey as __isrHtmlKey,
543
588
  appIsrRscKey as __isrRscKey,
544
589
  appIsrRouteKey as __isrRouteKey,
@@ -566,7 +611,7 @@ import { suppressHookWarningAls } from ${JSON.stringify(appHookWarningSuppressio
566
611
  import { clearAppRequestContext as __clearRequestContext, setAppNavigationContext as setNavigationContext } from ${JSON.stringify(appRequestContextPath)};
567
612
  __configureMemoryCacheHandler({ cacheMaxMemorySize: ${JSON.stringify(cacheMaxMemorySize)} });
568
613
  import { createAppPrerenderStaticParamsResolver as __createAppPrerenderStaticParamsResolver } from ${JSON.stringify(appPrerenderStaticParamsPath)};
569
- import { ensureAppRouteModulesLoaded as __ensureRouteLoaded, loadAppInterceptPage as __loadAppInterceptPage } from ${JSON.stringify(appRouteModuleLoaderPath)};
614
+ import { ensureAppRouteModulesLoaded as __ensureRouteLoaded } from ${JSON.stringify(appRouteModuleLoaderPath)};
570
615
  import {
571
616
  getRenderedConcreteUrlPathsForRoute as __getRenderedConcreteUrlPathsForRoute,
572
617
  initPregeneratedPathsFromGlobals as __initPregeneratedPathsFromGlobals,
@@ -744,7 +789,7 @@ function __VINEXT_CLASS_REASONS(routeIdx) {
744
789
  const routes = [
745
790
  ${routeEntries.join(",\n")}
746
791
  ];
747
- const __routeMatcher = __createAppRscRouteMatcher(routes);
792
+ const __routeMatcher = __createAppRscRouteMatcher(routes, ${JSON.stringify(buildAppDecodedPathnamePatterns(routes, config))});
748
793
 
749
794
  ${instrumentationPath ? "let metadataRoutes;" : `const metadataRoutes = [
750
795
  ${metaRouteEntries.join(",\n")}
@@ -841,6 +886,10 @@ function matchRequestRoute(url) {
841
886
  return __routeMatcher.matchRequestRoute(url);
842
887
  }
843
888
 
889
+ function matchRawRequestRoute(url) {
890
+ return __routeMatcher.matchRawRequestRoute(url);
891
+ }
892
+
844
893
  /**
845
894
  * Check if a pathname matches any intercepting route.
846
895
  * Returns the match info or null.
@@ -906,6 +955,9 @@ export async function seedMemoryCacheFromPrerender(serverDir) {
906
955
  buildAppPageHtmlKey(pathname) {
907
956
  return __isrHtmlKey(pathname);
908
957
  },
958
+ buildAppPageFallbackShellKey(pathname, suffix) {
959
+ return __isrFallbackShellKey(pathname, suffix);
960
+ },
909
961
  buildAppPageRscKey(pathname) {
910
962
  return __isrRscKey(pathname);
911
963
  },
@@ -950,6 +1002,7 @@ ${rootParamNameEntries.join("\n")}
950
1002
  };
951
1003
 
952
1004
  __setPagesClientAssets(__pagesClientAssets);
1005
+ export const __clientBuildFiles = __pagesClientAssets.clientBuildFiles ?? [];
953
1006
  function __VINEXT_ACTION_OWNERS() { return ${actionOwners === void 0 ? "__vinextActionOwners" : safeJsonStringify(actionOwners)}; }
954
1007
  ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandler = createAppRscHandler({"}
955
1008
  assetPrefix: __assetPrefix,
@@ -970,6 +1023,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
970
1023
  imageConfig: __runtimeImageConfig,
971
1024
  isDev: process.env.NODE_ENV !== "production",
972
1025
  draftModeSecret: __draftModeSecret,
1026
+ devForwardedMiddlewareContextKey: ${JSON.stringify(config?.devForwardedMiddlewareContextKey ?? null)},
973
1027
  dispatchMatchedPage({
974
1028
  bypassInterceptionContextCache,
975
1029
  cachePathname,
@@ -1000,6 +1054,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1000
1054
  scriptNonce,
1001
1055
  searchParams,
1002
1056
  renderMode,
1057
+ renderWholeDocument,
1003
1058
  }) {
1004
1059
  const PageComponent = route.page?.default;
1005
1060
  const __segmentConfigBranches = __resolveRouteSegmentConfigBranches(route);
@@ -1021,7 +1076,6 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1021
1076
  routePatternParts: route.patternParts,
1022
1077
  routeSegments: route.routeSegments,
1023
1078
  });
1024
- const _asyncRouteParams = makeThenableParams(params);
1025
1079
  return __dispatchAppPage({
1026
1080
  basePath: __basePath,
1027
1081
  bypassInterceptionContextCache,
@@ -1040,6 +1094,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1040
1094
  observePageSearchParamsAccess: buildOptions?.observePageSearchParamsAccess === true,
1041
1095
  isForceStatic: buildOptions?.isForceStatic === true,
1042
1096
  serveStreamingMetadata: buildOptions?.serveStreamingMetadata,
1097
+ placeStreamedMetadataInHead: buildOptions?.placeStreamedMetadataInHead === true,
1043
1098
  isProduction: process.env.NODE_ENV === "production",
1044
1099
  }, layoutParamAccess, displayPathname, scriptNonce);
1045
1100
  },
@@ -1092,6 +1147,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1092
1147
  isRscRequest,
1093
1148
  isrDebug: __isrDebug,
1094
1149
  isrGet: __isrGet,
1150
+ isrFallbackShellHtmlKey: __isrFallbackShellHtmlKey,
1095
1151
  isrHtmlKey(pathname) {
1096
1152
  return __isrHtmlKey(pathname === cleanPathname ? cachePathname : pathname);
1097
1153
  },
@@ -1127,31 +1183,6 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1127
1183
  route,
1128
1184
  });
1129
1185
  },
1130
- async probePage(probeSearchParams = searchParams) {
1131
- const __probeIntercept = findIntercept(
1132
- interceptionPathname,
1133
- interceptionContext,
1134
- interceptionId,
1135
- );
1136
- // The intercepting-route page module is lazy (page: null + __pageLoader).
1137
- // Resolve it before probing so buildAppPageProbes inspects the real page
1138
- // component for dynamic bailout — matching the render path, which also
1139
- // hydrates it (resolveAppPageInterceptState). Without this the intercept
1140
- // probe branch silently inspects an undefined component and never
1141
- // observes the page's searchParams/headers access. Shared loader, so
1142
- // the import is isolated from the request context here too.
1143
- if (__probeIntercept) await __loadAppInterceptPage(__probeIntercept);
1144
- return Promise.all(__buildAppPageProbes({
1145
- route,
1146
- pageComponent: PageComponent,
1147
- asyncRouteParams: _asyncRouteParams,
1148
- searchParams: probeSearchParams,
1149
- intercept: __probeIntercept,
1150
- isRscRequest,
1151
- matchedParams: params,
1152
- makeThenableParams,
1153
- }));
1154
- },
1155
1186
  renderErrorBoundaryPage(renderErr, errorOrigin) {
1156
1187
  const __activeIntercept = findIntercept(
1157
1188
  interceptionPathname,
@@ -1210,6 +1241,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1210
1241
  searchParams,
1211
1242
  setNavigationContext,
1212
1243
  renderMode,
1244
+ renderWholeDocument,
1213
1245
  });
1214
1246
  },
1215
1247
  async dispatchMatchedRouteHandler({
@@ -1234,6 +1266,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1234
1266
  draftModeSecret: __draftModeSecret,
1235
1267
  i18n: __i18nConfig,
1236
1268
  trailingSlash: __trailingSlash,
1269
+ skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
1237
1270
  isrDebug: __isrDebug,
1238
1271
  isrGet: __isrGet,
1239
1272
  isrRouteKey(pathname) {
@@ -1564,6 +1597,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1564
1597
  },` : ""}
1565
1598
  matchRoute,
1566
1599
  matchRequestRoute,
1600
+ matchRawRequestRoute,
1567
1601
  hasInterceptionId,
1568
1602
  matchInterceptRoute(pathname, sourcePathname, interceptionId) {
1569
1603
  const intercept = findIntercept(pathname, sourcePathname, interceptionId);
@@ -1596,6 +1630,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1596
1630
  middlewareRequest,
1597
1631
  module: middlewareModule,
1598
1632
  request,
1633
+ skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
1599
1634
  trailingSlash: __trailingSlash,
1600
1635
  validateExternalRewriteRequest,
1601
1636
  });
@@ -1634,7 +1669,6 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1634
1669
  };
1635
1670
  },
1636
1671
  buildRequestHeaders: __buildRequestHeadersFromMiddlewareResponse,
1637
- decodePathParams: __decodePathParams,
1638
1672
  applyRouteHandlerMiddlewareContext: __applyRouteHandlerMiddlewareContext,
1639
1673
  getDraftModeCookieHeader,
1640
1674
  }
@@ -1642,6 +1676,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1642
1676
  },` : ""}
1643
1677
  rootParamNamesByPattern: rootParamNamesMap,
1644
1678
  setNavigationContext,
1679
+ skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
1645
1680
  staticParamsMap: generateStaticParamsMap,
1646
1681
  trailingSlash: __trailingSlash,
1647
1682
  validateDevRequestOrigin: __validateDevRequestOrigin,