vinext 0.0.50 → 0.0.52

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 (462) hide show
  1. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  2. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  3. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  4. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  5. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  6. package/dist/build/precompress.d.ts +13 -2
  7. package/dist/build/precompress.js +23 -13
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +4 -15
  10. package/dist/build/prerender.js +83 -53
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.d.ts +5 -4
  13. package/dist/build/report.js +196 -348
  14. package/dist/build/report.js.map +1 -1
  15. package/dist/check.js +5 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli-args.d.ts +1 -0
  18. package/dist/cli-args.js +5 -0
  19. package/dist/cli-args.js.map +1 -1
  20. package/dist/cli.js +99 -3
  21. package/dist/cli.js.map +1 -1
  22. package/dist/client/navigation-runtime.d.ts +47 -0
  23. package/dist/client/navigation-runtime.js +156 -0
  24. package/dist/client/navigation-runtime.js.map +1 -0
  25. package/dist/client/pages-router-link-navigation.d.ts +26 -0
  26. package/dist/client/pages-router-link-navigation.js +14 -0
  27. package/dist/client/pages-router-link-navigation.js.map +1 -0
  28. package/dist/client/vinext-next-data.d.ts +12 -2
  29. package/dist/client/vinext-next-data.js +50 -1
  30. package/dist/client/vinext-next-data.js.map +1 -0
  31. package/dist/client/window-next.d.ts +3 -1
  32. package/dist/client/window-next.js.map +1 -1
  33. package/dist/cloudflare/kv-cache-handler.js +2 -1
  34. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  35. package/dist/config/config-matchers.d.ts +63 -16
  36. package/dist/config/config-matchers.js +143 -8
  37. package/dist/config/config-matchers.js.map +1 -1
  38. package/dist/config/dotenv.d.ts +11 -1
  39. package/dist/config/dotenv.js.map +1 -1
  40. package/dist/config/next-config.d.ts +107 -5
  41. package/dist/config/next-config.js +233 -7
  42. package/dist/config/next-config.js.map +1 -1
  43. package/dist/config/tsconfig-paths.d.ts +13 -0
  44. package/dist/config/tsconfig-paths.js +117 -0
  45. package/dist/config/tsconfig-paths.js.map +1 -0
  46. package/dist/deploy.js +104 -41
  47. package/dist/deploy.js.map +1 -1
  48. package/dist/entries/app-browser-entry.d.ts +2 -2
  49. package/dist/entries/app-browser-entry.js +34 -3
  50. package/dist/entries/app-browser-entry.js.map +1 -1
  51. package/dist/entries/app-rsc-entry.d.ts +19 -1
  52. package/dist/entries/app-rsc-entry.js +89 -23
  53. package/dist/entries/app-rsc-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  55. package/dist/entries/app-rsc-manifest.js +57 -7
  56. package/dist/entries/app-rsc-manifest.js.map +1 -1
  57. package/dist/entries/app-ssr-entry.d.ts +3 -3
  58. package/dist/entries/app-ssr-entry.js +4 -4
  59. package/dist/entries/app-ssr-entry.js.map +1 -1
  60. package/dist/entries/pages-client-entry.js +21 -7
  61. package/dist/entries/pages-client-entry.js.map +1 -1
  62. package/dist/entries/pages-server-entry.js +77 -9
  63. package/dist/entries/pages-server-entry.js.map +1 -1
  64. package/dist/entries/runtime-entry-module.d.ts +2 -1
  65. package/dist/entries/runtime-entry-module.js +9 -3
  66. package/dist/entries/runtime-entry-module.js.map +1 -1
  67. package/dist/index.js +260 -75
  68. package/dist/index.js.map +1 -1
  69. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  70. package/dist/plugins/client-reference-dedup.js +138 -16
  71. package/dist/plugins/client-reference-dedup.js.map +1 -1
  72. package/dist/plugins/css-data-url.d.ts +7 -0
  73. package/dist/plugins/css-data-url.js +81 -0
  74. package/dist/plugins/css-data-url.js.map +1 -0
  75. package/dist/plugins/fonts.d.ts +2 -2
  76. package/dist/plugins/fonts.js +20 -9
  77. package/dist/plugins/fonts.js.map +1 -1
  78. package/dist/plugins/middleware-server-only.d.ts +54 -0
  79. package/dist/plugins/middleware-server-only.js +91 -0
  80. package/dist/plugins/middleware-server-only.js.map +1 -0
  81. package/dist/plugins/optimize-imports.js +4 -4
  82. package/dist/plugins/optimize-imports.js.map +1 -1
  83. package/dist/plugins/sass.d.ts +34 -0
  84. package/dist/plugins/sass.js +22 -0
  85. package/dist/plugins/sass.js.map +1 -0
  86. package/dist/plugins/strip-server-exports.js +5 -8
  87. package/dist/plugins/strip-server-exports.js.map +1 -1
  88. package/dist/routing/app-route-graph.d.ts +50 -2
  89. package/dist/routing/app-route-graph.js +140 -16
  90. package/dist/routing/app-route-graph.js.map +1 -1
  91. package/dist/routing/app-router.d.ts +2 -2
  92. package/dist/routing/app-router.js +2 -2
  93. package/dist/routing/app-router.js.map +1 -1
  94. package/dist/routing/route-pattern.d.ts +56 -1
  95. package/dist/routing/route-pattern.js +60 -1
  96. package/dist/routing/route-pattern.js.map +1 -1
  97. package/dist/routing/utils.d.ts +2 -1
  98. package/dist/routing/utils.js +4 -1
  99. package/dist/routing/utils.js.map +1 -1
  100. package/dist/server/api-handler.js +139 -37
  101. package/dist/server/api-handler.js.map +1 -1
  102. package/dist/server/app-browser-action-result.d.ts +27 -2
  103. package/dist/server/app-browser-action-result.js +63 -2
  104. package/dist/server/app-browser-action-result.js.map +1 -1
  105. package/dist/server/app-browser-entry.js +493 -195
  106. package/dist/server/app-browser-entry.js.map +1 -1
  107. package/dist/server/app-browser-hydration.d.ts +13 -1
  108. package/dist/server/app-browser-hydration.js +9 -1
  109. package/dist/server/app-browser-hydration.js.map +1 -1
  110. package/dist/server/app-browser-interception-context.d.ts +24 -0
  111. package/dist/server/app-browser-interception-context.js +32 -0
  112. package/dist/server/app-browser-interception-context.js.map +1 -0
  113. package/dist/server/app-browser-navigation-controller.d.ts +17 -2
  114. package/dist/server/app-browser-navigation-controller.js +33 -10
  115. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  116. package/dist/server/app-browser-popstate.d.ts +16 -0
  117. package/dist/server/app-browser-popstate.js +17 -0
  118. package/dist/server/app-browser-popstate.js.map +1 -0
  119. package/dist/server/app-browser-rsc-redirect.d.ts +29 -0
  120. package/dist/server/app-browser-rsc-redirect.js +37 -0
  121. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  122. package/dist/server/app-browser-state.d.ts +28 -7
  123. package/dist/server/app-browser-state.js +63 -27
  124. package/dist/server/app-browser-state.js.map +1 -1
  125. package/dist/server/app-browser-stream.d.ts +9 -17
  126. package/dist/server/app-browser-stream.js +18 -13
  127. package/dist/server/app-browser-stream.js.map +1 -1
  128. package/dist/server/app-browser-visible-commit.d.ts +7 -1
  129. package/dist/server/app-browser-visible-commit.js +39 -5
  130. package/dist/server/app-browser-visible-commit.js.map +1 -1
  131. package/dist/server/app-elements-wire.d.ts +43 -6
  132. package/dist/server/app-elements-wire.js +189 -7
  133. package/dist/server/app-elements-wire.js.map +1 -1
  134. package/dist/server/app-elements.d.ts +3 -2
  135. package/dist/server/app-elements.js +3 -2
  136. package/dist/server/app-elements.js.map +1 -1
  137. package/dist/server/app-fallback-renderer.d.ts +10 -1
  138. package/dist/server/app-fallback-renderer.js +41 -3
  139. package/dist/server/app-fallback-renderer.js.map +1 -1
  140. package/dist/server/app-history-state.d.ts +26 -0
  141. package/dist/server/app-history-state.js +53 -0
  142. package/dist/server/app-history-state.js.map +1 -0
  143. package/dist/server/app-middleware.d.ts +13 -0
  144. package/dist/server/app-middleware.js +3 -1
  145. package/dist/server/app-middleware.js.map +1 -1
  146. package/dist/server/app-optimistic-routing.d.ts +54 -0
  147. package/dist/server/app-optimistic-routing.js +200 -0
  148. package/dist/server/app-optimistic-routing.js.map +1 -0
  149. package/dist/server/app-page-boundary-render.d.ts +10 -1
  150. package/dist/server/app-page-boundary-render.js +13 -6
  151. package/dist/server/app-page-boundary-render.js.map +1 -1
  152. package/dist/server/app-page-boundary.js +3 -2
  153. package/dist/server/app-page-boundary.js.map +1 -1
  154. package/dist/server/app-page-cache.d.ts +26 -1
  155. package/dist/server/app-page-cache.js +86 -14
  156. package/dist/server/app-page-cache.js.map +1 -1
  157. package/dist/server/app-page-dispatch.d.ts +7 -0
  158. package/dist/server/app-page-dispatch.js +96 -12
  159. package/dist/server/app-page-dispatch.js.map +1 -1
  160. package/dist/server/app-page-element-builder.d.ts +7 -0
  161. package/dist/server/app-page-element-builder.js +34 -5
  162. package/dist/server/app-page-element-builder.js.map +1 -1
  163. package/dist/server/app-page-execution.d.ts +28 -1
  164. package/dist/server/app-page-execution.js +91 -7
  165. package/dist/server/app-page-execution.js.map +1 -1
  166. package/dist/server/app-page-head.d.ts +7 -0
  167. package/dist/server/app-page-head.js +23 -3
  168. package/dist/server/app-page-head.js.map +1 -1
  169. package/dist/server/app-page-probe.d.ts +23 -1
  170. package/dist/server/app-page-probe.js +29 -1
  171. package/dist/server/app-page-probe.js.map +1 -1
  172. package/dist/server/app-page-render-observation.d.ts +35 -0
  173. package/dist/server/app-page-render-observation.js +68 -0
  174. package/dist/server/app-page-render-observation.js.map +1 -0
  175. package/dist/server/app-page-render.d.ts +7 -1
  176. package/dist/server/app-page-render.js +81 -4
  177. package/dist/server/app-page-render.js.map +1 -1
  178. package/dist/server/app-page-request.d.ts +1 -0
  179. package/dist/server/app-page-request.js.map +1 -1
  180. package/dist/server/app-page-response.js +7 -5
  181. package/dist/server/app-page-response.js.map +1 -1
  182. package/dist/server/app-page-route-wiring.d.ts +3 -1
  183. package/dist/server/app-page-route-wiring.js +59 -24
  184. package/dist/server/app-page-route-wiring.js.map +1 -1
  185. package/dist/server/app-page-stream.d.ts +5 -0
  186. package/dist/server/app-page-stream.js +2 -0
  187. package/dist/server/app-page-stream.js.map +1 -1
  188. package/dist/server/app-prerender-static-params.d.ts +2 -1
  189. package/dist/server/app-prerender-static-params.js +44 -8
  190. package/dist/server/app-prerender-static-params.js.map +1 -1
  191. package/dist/server/app-route-handler-cache.d.ts +2 -2
  192. package/dist/server/app-route-handler-cache.js +3 -2
  193. package/dist/server/app-route-handler-cache.js.map +1 -1
  194. package/dist/server/app-route-handler-dispatch.d.ts +6 -1
  195. package/dist/server/app-route-handler-dispatch.js +1 -1
  196. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  197. package/dist/server/app-route-handler-execution.d.ts +17 -2
  198. package/dist/server/app-route-handler-execution.js.map +1 -1
  199. package/dist/server/app-route-handler-response.js +5 -4
  200. package/dist/server/app-route-handler-response.js.map +1 -1
  201. package/dist/server/app-router-entry.js +7 -15
  202. package/dist/server/app-router-entry.js.map +1 -1
  203. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  204. package/dist/server/app-rsc-cache-busting.js +36 -1
  205. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  206. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  207. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  208. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  209. package/dist/server/app-rsc-errors.d.ts +4 -1
  210. package/dist/server/app-rsc-errors.js +1 -1
  211. package/dist/server/app-rsc-errors.js.map +1 -1
  212. package/dist/server/app-rsc-handler.d.ts +21 -5
  213. package/dist/server/app-rsc-handler.js +38 -15
  214. package/dist/server/app-rsc-handler.js.map +1 -1
  215. package/dist/server/app-rsc-render-mode.d.ts +4 -3
  216. package/dist/server/app-rsc-render-mode.js +7 -1
  217. package/dist/server/app-rsc-render-mode.js.map +1 -1
  218. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  219. package/dist/server/app-rsc-request-normalization.js +4 -1
  220. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  221. package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
  222. package/dist/server/app-rsc-response-finalizer.js +10 -3
  223. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  224. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  225. package/dist/server/app-rsc-route-matching.js +47 -25
  226. package/dist/server/app-rsc-route-matching.js.map +1 -1
  227. package/dist/server/app-server-action-execution.d.ts +35 -3
  228. package/dist/server/app-server-action-execution.js +87 -33
  229. package/dist/server/app-server-action-execution.js.map +1 -1
  230. package/dist/server/app-ssr-entry.d.ts +3 -0
  231. package/dist/server/app-ssr-entry.js +83 -58
  232. package/dist/server/app-ssr-entry.js.map +1 -1
  233. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  234. package/dist/server/app-ssr-error-meta.js +50 -0
  235. package/dist/server/app-ssr-error-meta.js.map +1 -0
  236. package/dist/server/app-ssr-stream.d.ts +7 -2
  237. package/dist/server/app-ssr-stream.js +26 -15
  238. package/dist/server/app-ssr-stream.js.map +1 -1
  239. package/dist/server/artifact-compatibility.d.ts +13 -3
  240. package/dist/server/artifact-compatibility.js +12 -8
  241. package/dist/server/artifact-compatibility.js.map +1 -1
  242. package/dist/server/cache-headers.d.ts +7 -0
  243. package/dist/server/cache-headers.js +19 -0
  244. package/dist/server/cache-headers.js.map +1 -0
  245. package/dist/server/cache-proof.d.ts +170 -5
  246. package/dist/server/cache-proof.js +472 -18
  247. package/dist/server/cache-proof.js.map +1 -1
  248. package/dist/server/client-reuse-manifest.d.ts +99 -0
  249. package/dist/server/client-reuse-manifest.js +212 -0
  250. package/dist/server/client-reuse-manifest.js.map +1 -0
  251. package/dist/server/default-global-error-module.d.ts +20 -0
  252. package/dist/server/default-global-error-module.js +20 -0
  253. package/dist/server/default-global-error-module.js.map +1 -0
  254. package/dist/server/dev-lockfile.d.ts +110 -0
  255. package/dist/server/dev-lockfile.js +180 -0
  256. package/dist/server/dev-lockfile.js.map +1 -0
  257. package/dist/server/dev-server.d.ts +9 -1
  258. package/dist/server/dev-server.js +76 -19
  259. package/dist/server/dev-server.js.map +1 -1
  260. package/dist/server/edge-api-runtime.d.ts +5 -0
  261. package/dist/server/edge-api-runtime.js +8 -0
  262. package/dist/server/edge-api-runtime.js.map +1 -0
  263. package/dist/server/file-based-metadata.d.ts +13 -0
  264. package/dist/server/file-based-metadata.js +49 -2
  265. package/dist/server/file-based-metadata.js.map +1 -1
  266. package/dist/server/headers.d.ts +20 -1
  267. package/dist/server/headers.js +22 -2
  268. package/dist/server/headers.js.map +1 -1
  269. package/dist/server/html.js +1 -1
  270. package/dist/server/html.js.map +1 -1
  271. package/dist/server/http-error-responses.d.ts +26 -1
  272. package/dist/server/http-error-responses.js +32 -2
  273. package/dist/server/http-error-responses.js.map +1 -1
  274. package/dist/server/isr-cache.d.ts +8 -3
  275. package/dist/server/isr-cache.js +24 -6
  276. package/dist/server/isr-cache.js.map +1 -1
  277. package/dist/server/metadata-route-response.js +22 -5
  278. package/dist/server/metadata-route-response.js.map +1 -1
  279. package/dist/server/metadata-routes.js +27 -8
  280. package/dist/server/metadata-routes.js.map +1 -1
  281. package/dist/server/middleware-runtime.d.ts +15 -0
  282. package/dist/server/middleware-runtime.js +60 -7
  283. package/dist/server/middleware-runtime.js.map +1 -1
  284. package/dist/server/middleware.d.ts +13 -1
  285. package/dist/server/middleware.js +16 -2
  286. package/dist/server/middleware.js.map +1 -1
  287. package/dist/server/navigation-planner.d.ts +26 -6
  288. package/dist/server/navigation-planner.js +358 -24
  289. package/dist/server/navigation-planner.js.map +1 -1
  290. package/dist/server/navigation-trace.d.ts +9 -1
  291. package/dist/server/navigation-trace.js +8 -0
  292. package/dist/server/navigation-trace.js.map +1 -1
  293. package/dist/server/normalize-path.d.ts +2 -1
  294. package/dist/server/normalize-path.js +4 -1
  295. package/dist/server/normalize-path.js.map +1 -1
  296. package/dist/server/pages-api-route.d.ts +27 -1
  297. package/dist/server/pages-api-route.js +25 -3
  298. package/dist/server/pages-api-route.js.map +1 -1
  299. package/dist/server/pages-data-route.d.ts +77 -0
  300. package/dist/server/pages-data-route.js +97 -0
  301. package/dist/server/pages-data-route.js.map +1 -0
  302. package/dist/server/pages-i18n.d.ts +51 -1
  303. package/dist/server/pages-i18n.js +61 -1
  304. package/dist/server/pages-i18n.js.map +1 -1
  305. package/dist/server/pages-page-data.d.ts +32 -4
  306. package/dist/server/pages-page-data.js +52 -19
  307. package/dist/server/pages-page-data.js.map +1 -1
  308. package/dist/server/pages-page-response.d.ts +11 -1
  309. package/dist/server/pages-page-response.js +6 -4
  310. package/dist/server/pages-page-response.js.map +1 -1
  311. package/dist/server/prod-server.d.ts +26 -1
  312. package/dist/server/prod-server.js +150 -44
  313. package/dist/server/prod-server.js.map +1 -1
  314. package/dist/server/request-pipeline.d.ts +11 -2
  315. package/dist/server/request-pipeline.js +28 -11
  316. package/dist/server/request-pipeline.js.map +1 -1
  317. package/dist/server/seed-cache.d.ts +12 -31
  318. package/dist/server/seed-cache.js +22 -35
  319. package/dist/server/seed-cache.js.map +1 -1
  320. package/dist/server/server-action-not-found.d.ts +16 -3
  321. package/dist/server/server-action-not-found.js +27 -4
  322. package/dist/server/server-action-not-found.js.map +1 -1
  323. package/dist/server/server-globals.d.ts +5 -0
  324. package/dist/server/server-globals.js +37 -0
  325. package/dist/server/server-globals.js.map +1 -0
  326. package/dist/server/skip-cache-proof.d.ts +41 -0
  327. package/dist/server/skip-cache-proof.js +101 -0
  328. package/dist/server/skip-cache-proof.js.map +1 -0
  329. package/dist/server/static-file-cache.d.ts +1 -1
  330. package/dist/server/static-file-cache.js +7 -6
  331. package/dist/server/static-file-cache.js.map +1 -1
  332. package/dist/shims/cache-runtime.d.ts +19 -2
  333. package/dist/shims/cache-runtime.js +67 -11
  334. package/dist/shims/cache-runtime.js.map +1 -1
  335. package/dist/shims/cache.d.ts +5 -18
  336. package/dist/shims/cache.js +2 -0
  337. package/dist/shims/cache.js.map +1 -1
  338. package/dist/shims/client-locale.d.ts +15 -0
  339. package/dist/shims/client-locale.js +13 -0
  340. package/dist/shims/client-locale.js.map +1 -0
  341. package/dist/shims/default-global-error.d.ts +32 -0
  342. package/dist/shims/default-global-error.js +181 -0
  343. package/dist/shims/default-global-error.js.map +1 -0
  344. package/dist/shims/document.d.ts +59 -3
  345. package/dist/shims/document.js +36 -5
  346. package/dist/shims/document.js.map +1 -1
  347. package/dist/shims/error-boundary.d.ts +2 -2
  348. package/dist/shims/error-boundary.js +6 -8
  349. package/dist/shims/error-boundary.js.map +1 -1
  350. package/dist/shims/error.d.ts +18 -1
  351. package/dist/shims/error.js +56 -1
  352. package/dist/shims/error.js.map +1 -1
  353. package/dist/shims/fetch-cache.d.ts +4 -1
  354. package/dist/shims/fetch-cache.js +40 -5
  355. package/dist/shims/fetch-cache.js.map +1 -1
  356. package/dist/shims/font-google-base.d.ts +22 -8
  357. package/dist/shims/font-google-base.js +41 -71
  358. package/dist/shims/font-google-base.js.map +1 -1
  359. package/dist/shims/font-local.d.ts +3 -20
  360. package/dist/shims/font-local.js +23 -75
  361. package/dist/shims/font-local.js.map +1 -1
  362. package/dist/shims/font-utils.d.ts +51 -0
  363. package/dist/shims/font-utils.js +97 -0
  364. package/dist/shims/font-utils.js.map +1 -0
  365. package/dist/shims/form.js +13 -6
  366. package/dist/shims/form.js.map +1 -1
  367. package/dist/shims/hash-scroll.d.ts +7 -0
  368. package/dist/shims/hash-scroll.js +30 -0
  369. package/dist/shims/hash-scroll.js.map +1 -0
  370. package/dist/shims/headers.d.ts +8 -11
  371. package/dist/shims/headers.js +22 -2
  372. package/dist/shims/headers.js.map +1 -1
  373. package/dist/shims/image.d.ts +1 -0
  374. package/dist/shims/image.js +144 -78
  375. package/dist/shims/image.js.map +1 -1
  376. package/dist/shims/internal/app-router-context.d.ts +6 -6
  377. package/dist/shims/internal/app-router-context.js +17 -6
  378. package/dist/shims/internal/app-router-context.js.map +1 -1
  379. package/dist/shims/link-prefetch.d.ts +9 -1
  380. package/dist/shims/link-prefetch.js +11 -6
  381. package/dist/shims/link-prefetch.js.map +1 -1
  382. package/dist/shims/link.d.ts +33 -5
  383. package/dist/shims/link.js +205 -50
  384. package/dist/shims/link.js.map +1 -1
  385. package/dist/shims/metadata.d.ts +16 -30
  386. package/dist/shims/metadata.js +91 -32
  387. package/dist/shims/metadata.js.map +1 -1
  388. package/dist/shims/navigation.d.ts +164 -17
  389. package/dist/shims/navigation.js +355 -84
  390. package/dist/shims/navigation.js.map +1 -1
  391. package/dist/shims/navigation.react-server.d.ts +3 -2
  392. package/dist/shims/navigation.react-server.js +5 -2
  393. package/dist/shims/navigation.react-server.js.map +1 -1
  394. package/dist/shims/og.d.ts +18 -2
  395. package/dist/shims/og.js +49 -1
  396. package/dist/shims/og.js.map +1 -0
  397. package/dist/shims/pages-router-runtime.d.ts +7 -0
  398. package/dist/shims/pages-router-runtime.js +16 -0
  399. package/dist/shims/pages-router-runtime.js.map +1 -0
  400. package/dist/shims/request-state-types.d.ts +1 -1
  401. package/dist/shims/root-params.d.ts +3 -1
  402. package/dist/shims/root-params.js +11 -3
  403. package/dist/shims/root-params.js.map +1 -1
  404. package/dist/shims/router-state.d.ts +1 -0
  405. package/dist/shims/router-state.js.map +1 -1
  406. package/dist/shims/router.d.ts +40 -7
  407. package/dist/shims/router.js +355 -250
  408. package/dist/shims/router.js.map +1 -1
  409. package/dist/shims/script.js +110 -32
  410. package/dist/shims/script.js.map +1 -1
  411. package/dist/shims/server.d.ts +21 -4
  412. package/dist/shims/server.js +31 -10
  413. package/dist/shims/server.js.map +1 -1
  414. package/dist/shims/slot.d.ts +1 -0
  415. package/dist/shims/slot.js +45 -1
  416. package/dist/shims/slot.js.map +1 -1
  417. package/dist/shims/unified-request-context.d.ts +1 -1
  418. package/dist/shims/unified-request-context.js +2 -0
  419. package/dist/shims/unified-request-context.js.map +1 -1
  420. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  421. package/dist/shims/unrecognized-action-error.js +41 -0
  422. package/dist/shims/unrecognized-action-error.js.map +1 -0
  423. package/dist/shims/url-safety.d.ts +23 -1
  424. package/dist/shims/url-safety.js +29 -2
  425. package/dist/shims/url-safety.js.map +1 -1
  426. package/dist/shims/url-utils.d.ts +21 -1
  427. package/dist/shims/url-utils.js +67 -3
  428. package/dist/shims/url-utils.js.map +1 -1
  429. package/dist/typegen.d.ts +10 -0
  430. package/dist/typegen.js +242 -0
  431. package/dist/typegen.js.map +1 -0
  432. package/dist/utils/asset-prefix.d.ts +97 -0
  433. package/dist/utils/asset-prefix.js +124 -0
  434. package/dist/utils/asset-prefix.js.map +1 -0
  435. package/dist/utils/base-path.d.ts +7 -1
  436. package/dist/utils/base-path.js +10 -1
  437. package/dist/utils/base-path.js.map +1 -1
  438. package/dist/utils/cache-control-metadata.d.ts +2 -1
  439. package/dist/utils/cache-control-metadata.js +1 -3
  440. package/dist/utils/cache-control-metadata.js.map +1 -1
  441. package/dist/utils/domain-locale.d.ts +2 -1
  442. package/dist/utils/domain-locale.js +9 -1
  443. package/dist/utils/domain-locale.js.map +1 -1
  444. package/dist/utils/lazy-chunks.d.ts +1 -1
  445. package/dist/utils/lazy-chunks.js +1 -1
  446. package/dist/utils/lazy-chunks.js.map +1 -1
  447. package/dist/utils/navigation-signal.d.ts +1 -2
  448. package/dist/utils/navigation-signal.js +1 -1
  449. package/dist/utils/navigation-signal.js.map +1 -1
  450. package/dist/utils/prerender-output-paths.d.ts +15 -0
  451. package/dist/utils/prerender-output-paths.js +24 -0
  452. package/dist/utils/prerender-output-paths.js.map +1 -0
  453. package/dist/utils/query.d.ts +17 -1
  454. package/dist/utils/query.js +36 -1
  455. package/dist/utils/query.js.map +1 -1
  456. package/dist/utils/record.d.ts +5 -0
  457. package/dist/utils/record.js +8 -0
  458. package/dist/utils/record.js.map +1 -0
  459. package/dist/utils/sorted-array.d.ts +9 -0
  460. package/dist/utils/sorted-array.js +22 -0
  461. package/dist/utils/sorted-array.js.map +1 -0
  462. package/package.json +13 -5
@@ -1,10 +1,17 @@
1
- import { NextHeader } from "../config/next-config.js";
1
+ import { NextHeader, NextI18nConfig } from "../config/next-config.js";
2
2
  import { RequestContext } from "../config/config-matchers.js";
3
3
 
4
4
  //#region src/server/app-rsc-response-finalizer.d.ts
5
5
  type FinalizeAppRscResponseOptions = {
6
6
  basePath: string;
7
7
  configHeaders: NextHeader[];
8
+ /**
9
+ * i18n config used to splice the default locale into unprefixed paths
10
+ * before config header matching, so locale-aware `has`/`missing` rules
11
+ * with `:locale` placeholders or `locale: false` overrides still match
12
+ * default-locale URLs (issue #1336, item 4).
13
+ */
14
+ i18nConfig: NextI18nConfig | null;
8
15
  /**
9
16
  * Original pre-middleware request context.
10
17
  * Next.js evaluates config header has/missing conditions against the
@@ -1,9 +1,10 @@
1
1
  import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
- import { stripBasePath } from "../utils/base-path.js";
2
+ import { hasBasePath, stripBasePath } from "../utils/base-path.js";
3
3
  import "./headers.js";
4
4
  import { normalizePath } from "./normalize-path.js";
5
5
  import { applyConfigHeadersToResponse } from "./request-pipeline.js";
6
6
  import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
7
+ import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
7
8
  import { mergeVaryHeader } from "./middleware-response-headers.js";
8
9
  //#region src/server/app-rsc-response-finalizer.ts
9
10
  /**
@@ -29,11 +30,17 @@ function finalizeAppRscResponse(response, request, options) {
29
30
  } catch {
30
31
  pathname = url.pathname;
31
32
  }
33
+ const hadBasePath = !options.basePath || hasBasePath(pathname, options.basePath);
32
34
  pathname = stripBasePath(pathname, options.basePath);
35
+ const matchPathname = options.i18nConfig ? normalizeDefaultLocalePathname(pathname, options.i18nConfig, { hostname: url.hostname }) : pathname;
33
36
  applyConfigHeadersToResponse(response.headers, {
34
37
  configHeaders: options.configHeaders,
35
- pathname,
36
- requestContext: options.requestContext
38
+ pathname: matchPathname,
39
+ requestContext: options.requestContext,
40
+ basePathState: {
41
+ basePath: options.basePath,
42
+ hadBasePath
43
+ }
37
44
  });
38
45
  return response;
39
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app-rsc-response-finalizer.js","names":[],"sources":["../../src/server/app-rsc-response-finalizer.ts"],"sourcesContent":["import type { NextHeader } from \"../config/next-config.js\";\nimport type { RequestContext } from \"../config/config-matchers.js\";\nimport { VINEXT_STATIC_FILE_HEADER } from \"./headers.js\";\nimport { applyConfigHeadersToResponse } from \"./request-pipeline.js\";\nimport { VINEXT_RSC_VARY_HEADER } from \"./app-rsc-cache-busting.js\";\nimport { mergeVaryHeader } from \"./middleware-response-headers.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport { normalizePath } from \"./normalize-path.js\";\nimport { normalizePathnameForRouteMatch } from \"../routing/utils.js\";\n\ntype FinalizeAppRscResponseOptions = {\n basePath: string;\n configHeaders: NextHeader[];\n /**\n * Original pre-middleware request context.\n * Next.js evaluates config header has/missing conditions against the\n * unmodified incoming request, so callers must pass the snapshot taken\n * before middleware runs.\n */\n requestContext: RequestContext;\n};\n\n/**\n * Apply App Router response finalization that must happen outside individual\n * route dispatchers.\n *\n * Called once per request in the outer handler() wrapper, after all route\n * handling, so that every response path (page, route handler, server action,\n * metadata, not-found) gets headers applied consistently.\n *\n * Skips 3xx redirect responses. Response.redirect() creates immutable\n * headers that throw on mutation, and Next.js does not apply config headers\n * to redirects regardless.\n */\nexport function finalizeAppRscResponse(\n response: Response,\n request: Request,\n options: FinalizeAppRscResponseOptions,\n): Response {\n // 3xx responses: Response.redirect() headers are immutable (throws on write),\n // and Next.js deliberately excludes config headers from redirect responses.\n if (response.status >= 300 && response.status < 400) {\n return response;\n }\n\n if (!response.headers.has(VINEXT_STATIC_FILE_HEADER)) {\n mergeVaryHeader(response.headers, VINEXT_RSC_VARY_HEADER);\n }\n\n if (!options.configHeaders.length) {\n return response;\n }\n\n const url = new URL(request.url);\n let pathname: string;\n try {\n pathname = normalizePath(normalizePathnameForRouteMatch(url.pathname));\n } catch {\n // Malformed percent-encoding. The request reached this point only because\n // normalizePathnameForRouteMatchStrict ran earlier and returned 400 for\n // truly-malformed paths. This catch exists as a safety net for edge cases;\n // keep the historical raw-path fallback rather than crashing the response.\n pathname = url.pathname;\n }\n\n // Config header sources are defined without basePath prefix. Strip basePath\n // at a segment boundary (not a string prefix) so /app2/page with basePath\n // /app is not incorrectly treated as /app with suffix /2/page.\n pathname = stripBasePath(pathname, options.basePath);\n\n applyConfigHeadersToResponse(response.headers, {\n configHeaders: options.configHeaders,\n pathname,\n requestContext: options.requestContext,\n });\n\n return response;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,uBACd,UACA,SACA,SACU;CAGV,IAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAC9C,OAAO;CAGT,IAAI,CAAC,SAAS,QAAQ,IAAA,uBAA8B,EAClD,gBAAgB,SAAS,SAAS,uBAAuB;CAG3D,IAAI,CAAC,QAAQ,cAAc,QACzB,OAAO;CAGT,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,IAAI;CACJ,IAAI;EACF,WAAW,cAAc,+BAA+B,IAAI,SAAS,CAAC;SAChE;EAKN,WAAW,IAAI;;CAMjB,WAAW,cAAc,UAAU,QAAQ,SAAS;CAEpD,6BAA6B,SAAS,SAAS;EAC7C,eAAe,QAAQ;EACvB;EACA,gBAAgB,QAAQ;EACzB,CAAC;CAEF,OAAO"}
1
+ {"version":3,"file":"app-rsc-response-finalizer.js","names":[],"sources":["../../src/server/app-rsc-response-finalizer.ts"],"sourcesContent":["import type { NextHeader, NextI18nConfig } from \"../config/next-config.js\";\nimport type { RequestContext } from \"../config/config-matchers.js\";\nimport { VINEXT_STATIC_FILE_HEADER } from \"./headers.js\";\nimport { applyConfigHeadersToResponse } from \"./request-pipeline.js\";\nimport { VINEXT_RSC_VARY_HEADER } from \"./app-rsc-cache-busting.js\";\nimport { mergeVaryHeader } from \"./middleware-response-headers.js\";\nimport { hasBasePath, stripBasePath } from \"../utils/base-path.js\";\nimport { normalizePath } from \"./normalize-path.js\";\nimport { normalizePathnameForRouteMatch } from \"../routing/utils.js\";\nimport { normalizeDefaultLocalePathname } from \"./pages-i18n.js\";\n\ntype FinalizeAppRscResponseOptions = {\n basePath: string;\n configHeaders: NextHeader[];\n /**\n * i18n config used to splice the default locale into unprefixed paths\n * before config header matching, so locale-aware `has`/`missing` rules\n * with `:locale` placeholders or `locale: false` overrides still match\n * default-locale URLs (issue #1336, item 4).\n */\n i18nConfig: NextI18nConfig | null;\n /**\n * Original pre-middleware request context.\n * Next.js evaluates config header has/missing conditions against the\n * unmodified incoming request, so callers must pass the snapshot taken\n * before middleware runs.\n */\n requestContext: RequestContext;\n};\n\n/**\n * Apply App Router response finalization that must happen outside individual\n * route dispatchers.\n *\n * Called once per request in the outer handler() wrapper, after all route\n * handling, so that every response path (page, route handler, server action,\n * metadata, not-found) gets headers applied consistently.\n *\n * Skips 3xx redirect responses. Response.redirect() creates immutable\n * headers that throw on mutation, and Next.js does not apply config headers\n * to redirects regardless.\n */\nexport function finalizeAppRscResponse(\n response: Response,\n request: Request,\n options: FinalizeAppRscResponseOptions,\n): Response {\n // 3xx responses: Response.redirect() headers are immutable (throws on write),\n // and Next.js deliberately excludes config headers from redirect responses.\n if (response.status >= 300 && response.status < 400) {\n return response;\n }\n\n if (!response.headers.has(VINEXT_STATIC_FILE_HEADER)) {\n mergeVaryHeader(response.headers, VINEXT_RSC_VARY_HEADER);\n }\n\n if (!options.configHeaders.length) {\n return response;\n }\n\n const url = new URL(request.url);\n let pathname: string;\n try {\n pathname = normalizePath(normalizePathnameForRouteMatch(url.pathname));\n } catch {\n // Malformed percent-encoding. The request reached this point only because\n // normalizePathnameForRouteMatchStrict ran earlier and returned 400 for\n // truly-malformed paths. This catch exists as a safety net for edge cases;\n // keep the historical raw-path fallback rather than crashing the response.\n pathname = url.pathname;\n }\n\n // Config header sources are defined without basePath prefix. Strip basePath\n // at a segment boundary (not a string prefix) so /app2/page with basePath\n // /app is not incorrectly treated as /app with suffix /2/page.\n const hadBasePath = !options.basePath || hasBasePath(pathname, options.basePath);\n pathname = stripBasePath(pathname, options.basePath);\n\n // Default-locale path normalisation (issue #1336, item 4). Splice in the\n // (domain-aware) default locale on unprefixed paths so locale-aware\n // `has`/`missing` rules with `:locale` placeholders or `locale: false`\n // overrides still match default-locale URLs. Mirrors the call sites in\n // `prod-server.ts`, `deploy.ts`, and `app-rsc-handler.ts`.\n const matchPathname = options.i18nConfig\n ? normalizeDefaultLocalePathname(pathname, options.i18nConfig, { hostname: url.hostname })\n : pathname;\n\n applyConfigHeadersToResponse(response.headers, {\n configHeaders: options.configHeaders,\n pathname: matchPathname,\n requestContext: options.requestContext,\n basePathState: { basePath: options.basePath, hadBasePath },\n });\n\n return response;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,uBACd,UACA,SACA,SACU;CAGV,IAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAC9C,OAAO;CAGT,IAAI,CAAC,SAAS,QAAQ,IAAA,uBAA8B,EAClD,gBAAgB,SAAS,SAAS,uBAAuB;CAG3D,IAAI,CAAC,QAAQ,cAAc,QACzB,OAAO;CAGT,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,IAAI;CACJ,IAAI;EACF,WAAW,cAAc,+BAA+B,IAAI,SAAS,CAAC;SAChE;EAKN,WAAW,IAAI;;CAMjB,MAAM,cAAc,CAAC,QAAQ,YAAY,YAAY,UAAU,QAAQ,SAAS;CAChF,WAAW,cAAc,UAAU,QAAQ,SAAS;CAOpD,MAAM,gBAAgB,QAAQ,aAC1B,+BAA+B,UAAU,QAAQ,YAAY,EAAE,UAAU,IAAI,UAAU,CAAC,GACxF;CAEJ,6BAA6B,SAAS,SAAS;EAC7C,eAAe,QAAQ;EACvB,UAAU;EACV,gBAAgB,QAAQ;EACxB,eAAe;GAAE,UAAU,QAAQ;GAAU;GAAa;EAC3D,CAAC;CAEF,OAAO"}
@@ -4,11 +4,31 @@ import { RoutePatternParams } from "../routing/route-pattern.js";
4
4
  type AppRscRouteParams = RoutePatternParams;
5
5
  type AppRscInterceptForMatching = {
6
6
  targetPattern: string;
7
+ /**
8
+ * URL pattern of the *intercepting route* (the path that owns the slot,
9
+ * with route groups and `@slot` segments stripped). Mirrors Next.js'
10
+ * `interceptingRoute` from `extractInterceptionRouteInformation`.
11
+ *
12
+ * Next.js implements interception as a rewrite that fires only when the
13
+ * `Next-URL` header matches `^<sourceMatchPattern>(?:/.*)?$`. vinext's
14
+ * matcher enforces the same constraint at `findIntercept`: an intercept
15
+ * whose `targetPattern` matches the request URL is only valid when the
16
+ * provided source pathname (X-Vinext-Interception-Context / Next-URL)
17
+ * matches this pattern, with descendants allowed.
18
+ *
19
+ * Optional for backwards compat: when absent or empty, the matcher falls
20
+ * back to the legacy behavior of matching by target alone (still gated on
21
+ * a non-null source pathname).
22
+ *
23
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/generate-interception-routes-rewrites.ts
24
+ */
25
+ sourceMatchPattern?: string;
7
26
  interceptLayouts: readonly unknown[];
8
27
  page: unknown;
9
28
  params: readonly string[];
10
29
  };
11
30
  type AppRscSlotForMatching = {
31
+ id?: string | null;
12
32
  intercepts?: readonly AppRscInterceptForMatching[];
13
33
  };
14
34
  type AppRscRouteForMatching = {
@@ -23,9 +43,12 @@ type AppRscInterceptLookupEntry = {
23
43
  slotKey: string;
24
44
  targetPattern: string;
25
45
  targetPatternParts: string[];
46
+ sourceMatchPattern: string | null;
47
+ sourceMatchPatternParts: string[] | null;
26
48
  interceptLayouts: readonly unknown[];
27
49
  page: unknown;
28
50
  params: readonly string[];
51
+ slotId: string | null;
29
52
  };
30
53
  declare function createAppRscRouteMatcher<Route extends AppRscRouteForMatching>(routes: Route[]): {
31
54
  matchRoute(url: string): {
@@ -1,13 +1,13 @@
1
- import { normalizePathnameForRouteMatch } from "../routing/utils.js";
1
+ import { splitPathnameForRouteMatch } from "../routing/utils.js";
2
2
  import { buildRouteTrie, trieMatch } from "../routing/route-trie.js";
3
- import { matchRoutePattern } from "../routing/route-pattern.js";
3
+ import { matchRoutePattern, matchRoutePatternPrefix } from "../routing/route-pattern.js";
4
4
  //#region src/server/app-rsc-route-matching.ts
5
5
  function createRouteParams() {
6
6
  return Object.create(null);
7
7
  }
8
8
  function appRscPathnameParts(pathname) {
9
9
  const pathOnly = pathname.split("?")[0];
10
- return normalizePathnameForRouteMatch(pathOnly === "/" ? "/" : pathOnly.replace(/\/$/, "")).split("/").filter(Boolean);
10
+ return splitPathnameForRouteMatch(pathOnly === "/" ? "/" : pathOnly.replace(/\/$/, ""));
11
11
  }
12
12
  function createAppRscRouteMatcher(routes) {
13
13
  const routeTrie = buildRouteTrie(routes);
@@ -17,27 +17,42 @@ function createAppRscRouteMatcher(routes) {
17
17
  return trieMatch(routeTrie, appRscPathnameParts(url));
18
18
  },
19
19
  findIntercept(pathname, sourcePathname = null) {
20
+ if (sourcePathname === null) return null;
20
21
  const urlParts = appRscPathnameParts(pathname);
22
+ const sourceParts = appRscPathnameParts(sourcePathname);
21
23
  for (const entry of interceptLookup) {
24
+ if (!matchInterceptSource(sourceParts, entry)) continue;
22
25
  const params = matchAppRscRoutePattern(urlParts, entry.targetPatternParts);
23
- if (params !== null) {
24
- let sourceParams = createRouteParams();
25
- if (sourcePathname !== null) {
26
- const sourceRoute = routes[entry.sourceRouteIndex];
27
- const sourceParts = appRscPathnameParts(sourcePathname);
28
- const matchedSourceParams = sourceRoute ? matchAppRscRoutePattern(sourceParts, sourceRoute.patternParts) : null;
29
- if (matchedSourceParams !== null) sourceParams = matchedSourceParams;
30
- }
31
- return {
32
- ...entry,
33
- matchedParams: mergeMatchedParams(sourceParams, params)
34
- };
35
- }
26
+ if (params === null) continue;
27
+ const sourceRoute = routes[entry.sourceRouteIndex];
28
+ const matchedSourceParams = sourceRoute ? matchAppRscRoutePattern(sourceParts, sourceRoute.patternParts) : null;
29
+ if (matchedSourceParams === null && entry.sourceMatchPatternParts === null) continue;
30
+ const sourceParams = matchedSourceParams ?? createRouteParams();
31
+ return {
32
+ ...entry,
33
+ matchedParams: mergeMatchedParams(sourceParams, params)
34
+ };
36
35
  }
37
36
  return null;
38
37
  }
39
38
  };
40
39
  }
40
+ /**
41
+ * Check whether the request's source pathname (Next-URL / interception
42
+ * context) satisfies the intercept entry's intercepting-route pattern, with
43
+ * descendants allowed. Mirrors the header regex shape Next.js emits for the
44
+ * generated interception rewrite: `^<pattern>(?:/.*)?$`.
45
+ *
46
+ * When the entry has no declared `sourceMatchPatternParts`, fall back to the
47
+ * legacy behavior of accepting any source (we still require the source to be
48
+ * non-null at the caller — see `findIntercept`).
49
+ */
50
+ function matchInterceptSource(sourceParts, entry) {
51
+ const patternParts = entry.sourceMatchPatternParts;
52
+ if (!patternParts) return true;
53
+ if (patternParts.length === 0) return true;
54
+ return matchRoutePatternPrefix(sourceParts, patternParts);
55
+ }
41
56
  function createInterceptLookup(routes) {
42
57
  const interceptLookup = [];
43
58
  for (let routeIndex = 0; routeIndex < routes.length; routeIndex++) {
@@ -45,15 +60,22 @@ function createInterceptLookup(routes) {
45
60
  if (!route.slots) continue;
46
61
  for (const [slotKey, slotModule] of Object.entries(route.slots)) {
47
62
  if (!slotModule.intercepts) continue;
48
- for (const intercept of slotModule.intercepts) interceptLookup.push({
49
- sourceRouteIndex: routeIndex,
50
- slotKey,
51
- targetPattern: intercept.targetPattern,
52
- targetPatternParts: intercept.targetPattern.split("/").filter(Boolean),
53
- interceptLayouts: intercept.interceptLayouts,
54
- page: intercept.page,
55
- params: intercept.params
56
- });
63
+ for (const intercept of slotModule.intercepts) {
64
+ const sourceMatchPattern = intercept.sourceMatchPattern ?? null;
65
+ const sourceMatchPatternParts = sourceMatchPattern ? sourceMatchPattern.split("/").filter(Boolean) : null;
66
+ interceptLookup.push({
67
+ sourceRouteIndex: routeIndex,
68
+ slotKey,
69
+ slotId: typeof slotModule.id === "string" ? slotModule.id : null,
70
+ targetPattern: intercept.targetPattern,
71
+ targetPatternParts: intercept.targetPattern.split("/").filter(Boolean),
72
+ sourceMatchPattern,
73
+ sourceMatchPatternParts,
74
+ interceptLayouts: intercept.interceptLayouts,
75
+ page: intercept.page,
76
+ params: intercept.params
77
+ });
78
+ }
57
79
  }
58
80
  }
59
81
  return interceptLookup;
@@ -1 +1 @@
1
- {"version":3,"file":"app-rsc-route-matching.js","names":[],"sources":["../../src/server/app-rsc-route-matching.ts"],"sourcesContent":["import { buildRouteTrie, trieMatch } from \"../routing/route-trie.js\";\nimport { matchRoutePattern, type RoutePatternParams } from \"../routing/route-pattern.js\";\nimport { normalizePathnameForRouteMatch } from \"../routing/utils.js\";\n\ntype AppRscRouteParams = RoutePatternParams;\n\ntype AppRscInterceptForMatching = {\n targetPattern: string;\n interceptLayouts: readonly unknown[];\n page: unknown;\n params: readonly string[];\n};\n\ntype AppRscSlotForMatching = {\n intercepts?: readonly AppRscInterceptForMatching[];\n};\n\ntype AppRscRouteForMatching = {\n patternParts: string[];\n slots?: Record<string, AppRscSlotForMatching>;\n};\n\ntype AppRscInterceptMatch = AppRscInterceptLookupEntry & {\n matchedParams: AppRscRouteParams;\n};\n\ntype AppRscInterceptLookupEntry = {\n sourceRouteIndex: number;\n slotKey: string;\n targetPattern: string;\n targetPatternParts: string[];\n interceptLayouts: readonly unknown[];\n page: unknown;\n params: readonly string[];\n};\n\nfunction createRouteParams(): AppRscRouteParams {\n return Object.create(null);\n}\n\nfunction appRscPathnameParts(pathname: string): string[] {\n const pathOnly = pathname.split(\"?\")[0];\n const normalized = pathOnly === \"/\" ? \"/\" : pathOnly.replace(/\\/$/, \"\");\n return normalizePathnameForRouteMatch(normalized).split(\"/\").filter(Boolean);\n}\n\nexport function createAppRscRouteMatcher<Route extends AppRscRouteForMatching>(\n routes: Route[],\n): {\n matchRoute(url: string): { route: Route; params: AppRscRouteParams } | null;\n findIntercept(pathname: string, sourcePathname?: string | null): AppRscInterceptMatch | null;\n} {\n const routeTrie = buildRouteTrie(routes);\n const interceptLookup = createInterceptLookup(routes);\n\n return {\n matchRoute(url) {\n return trieMatch(routeTrie, appRscPathnameParts(url));\n },\n findIntercept(pathname, sourcePathname = null) {\n const urlParts = appRscPathnameParts(pathname);\n for (const entry of interceptLookup) {\n const params = matchAppRscRoutePattern(urlParts, entry.targetPatternParts);\n if (params !== null) {\n let sourceParams = createRouteParams();\n if (sourcePathname !== null) {\n const sourceRoute = routes[entry.sourceRouteIndex];\n const sourceParts = appRscPathnameParts(sourcePathname);\n const matchedSourceParams = sourceRoute\n ? matchAppRscRoutePattern(sourceParts, sourceRoute.patternParts)\n : null;\n if (matchedSourceParams !== null) {\n sourceParams = matchedSourceParams;\n }\n }\n return { ...entry, matchedParams: mergeMatchedParams(sourceParams, params) };\n }\n }\n return null;\n },\n };\n}\n\nfunction createInterceptLookup<Route extends AppRscRouteForMatching>(\n routes: Route[],\n): AppRscInterceptLookupEntry[] {\n const interceptLookup: AppRscInterceptLookupEntry[] = [];\n for (let routeIndex = 0; routeIndex < routes.length; routeIndex++) {\n const route = routes[routeIndex];\n if (!route.slots) continue;\n for (const [slotKey, slotModule] of Object.entries(route.slots)) {\n if (!slotModule.intercepts) continue;\n for (const intercept of slotModule.intercepts) {\n interceptLookup.push({\n sourceRouteIndex: routeIndex,\n slotKey,\n targetPattern: intercept.targetPattern,\n targetPatternParts: intercept.targetPattern.split(\"/\").filter(Boolean),\n interceptLayouts: intercept.interceptLayouts,\n page: intercept.page,\n params: intercept.params,\n });\n }\n }\n }\n return interceptLookup;\n}\n\nexport function matchAppRscRoutePattern(\n urlParts: string[],\n patternParts: string[],\n): AppRscRouteParams | null {\n return matchRoutePattern(urlParts, patternParts);\n}\n\nfunction mergeMatchedParams(\n sourceParams: AppRscRouteParams,\n targetParams: AppRscRouteParams,\n): AppRscRouteParams {\n return Object.assign(createRouteParams(), sourceParams, targetParams);\n}\n"],"mappings":";;;;AAoCA,SAAS,oBAAuC;CAC9C,OAAO,OAAO,OAAO,KAAK;;AAG5B,SAAS,oBAAoB,UAA4B;CACvD,MAAM,WAAW,SAAS,MAAM,IAAI,CAAC;CAErC,OAAO,+BADY,aAAa,MAAM,MAAM,SAAS,QAAQ,OAAO,GAAG,CACtB,CAAC,MAAM,IAAI,CAAC,OAAO,QAAQ;;AAG9E,SAAgB,yBACd,QAIA;CACA,MAAM,YAAY,eAAe,OAAO;CACxC,MAAM,kBAAkB,sBAAsB,OAAO;CAErD,OAAO;EACL,WAAW,KAAK;GACd,OAAO,UAAU,WAAW,oBAAoB,IAAI,CAAC;;EAEvD,cAAc,UAAU,iBAAiB,MAAM;GAC7C,MAAM,WAAW,oBAAoB,SAAS;GAC9C,KAAK,MAAM,SAAS,iBAAiB;IACnC,MAAM,SAAS,wBAAwB,UAAU,MAAM,mBAAmB;IAC1E,IAAI,WAAW,MAAM;KACnB,IAAI,eAAe,mBAAmB;KACtC,IAAI,mBAAmB,MAAM;MAC3B,MAAM,cAAc,OAAO,MAAM;MACjC,MAAM,cAAc,oBAAoB,eAAe;MACvD,MAAM,sBAAsB,cACxB,wBAAwB,aAAa,YAAY,aAAa,GAC9D;MACJ,IAAI,wBAAwB,MAC1B,eAAe;;KAGnB,OAAO;MAAE,GAAG;MAAO,eAAe,mBAAmB,cAAc,OAAO;MAAE;;;GAGhF,OAAO;;EAEV;;AAGH,SAAS,sBACP,QAC8B;CAC9B,MAAM,kBAAgD,EAAE;CACxD,KAAK,IAAI,aAAa,GAAG,aAAa,OAAO,QAAQ,cAAc;EACjE,MAAM,QAAQ,OAAO;EACrB,IAAI,CAAC,MAAM,OAAO;EAClB,KAAK,MAAM,CAAC,SAAS,eAAe,OAAO,QAAQ,MAAM,MAAM,EAAE;GAC/D,IAAI,CAAC,WAAW,YAAY;GAC5B,KAAK,MAAM,aAAa,WAAW,YACjC,gBAAgB,KAAK;IACnB,kBAAkB;IAClB;IACA,eAAe,UAAU;IACzB,oBAAoB,UAAU,cAAc,MAAM,IAAI,CAAC,OAAO,QAAQ;IACtE,kBAAkB,UAAU;IAC5B,MAAM,UAAU;IAChB,QAAQ,UAAU;IACnB,CAAC;;;CAIR,OAAO;;AAGT,SAAgB,wBACd,UACA,cAC0B;CAC1B,OAAO,kBAAkB,UAAU,aAAa;;AAGlD,SAAS,mBACP,cACA,cACmB;CACnB,OAAO,OAAO,OAAO,mBAAmB,EAAE,cAAc,aAAa"}
1
+ {"version":3,"file":"app-rsc-route-matching.js","names":[],"sources":["../../src/server/app-rsc-route-matching.ts"],"sourcesContent":["import { buildRouteTrie, trieMatch } from \"../routing/route-trie.js\";\nimport {\n matchRoutePattern,\n matchRoutePatternPrefix,\n type RoutePatternParams,\n} from \"../routing/route-pattern.js\";\nimport { splitPathnameForRouteMatch } from \"../routing/utils.js\";\n\ntype AppRscRouteParams = RoutePatternParams;\n\ntype AppRscInterceptForMatching = {\n targetPattern: string;\n /**\n * URL pattern of the *intercepting route* (the path that owns the slot,\n * with route groups and `@slot` segments stripped). Mirrors Next.js'\n * `interceptingRoute` from `extractInterceptionRouteInformation`.\n *\n * Next.js implements interception as a rewrite that fires only when the\n * `Next-URL` header matches `^<sourceMatchPattern>(?:/.*)?$`. vinext's\n * matcher enforces the same constraint at `findIntercept`: an intercept\n * whose `targetPattern` matches the request URL is only valid when the\n * provided source pathname (X-Vinext-Interception-Context / Next-URL)\n * matches this pattern, with descendants allowed.\n *\n * Optional for backwards compat: when absent or empty, the matcher falls\n * back to the legacy behavior of matching by target alone (still gated on\n * a non-null source pathname).\n *\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/generate-interception-routes-rewrites.ts\n */\n sourceMatchPattern?: string;\n interceptLayouts: readonly unknown[];\n page: unknown;\n params: readonly string[];\n};\n\ntype AppRscSlotForMatching = {\n id?: string | null;\n intercepts?: readonly AppRscInterceptForMatching[];\n};\n\ntype AppRscRouteForMatching = {\n patternParts: string[];\n slots?: Record<string, AppRscSlotForMatching>;\n};\n\ntype AppRscInterceptMatch = AppRscInterceptLookupEntry & {\n matchedParams: AppRscRouteParams;\n};\n\ntype AppRscInterceptLookupEntry = {\n sourceRouteIndex: number;\n slotKey: string;\n targetPattern: string;\n targetPatternParts: string[];\n sourceMatchPattern: string | null;\n sourceMatchPatternParts: string[] | null;\n interceptLayouts: readonly unknown[];\n page: unknown;\n params: readonly string[];\n slotId: string | null;\n};\n\nfunction createRouteParams(): AppRscRouteParams {\n return Object.create(null);\n}\n\nfunction appRscPathnameParts(pathname: string): string[] {\n const pathOnly = pathname.split(\"?\")[0];\n const normalized = pathOnly === \"/\" ? \"/\" : pathOnly.replace(/\\/$/, \"\");\n return splitPathnameForRouteMatch(normalized);\n}\n\nexport function createAppRscRouteMatcher<Route extends AppRscRouteForMatching>(\n routes: Route[],\n): {\n matchRoute(url: string): { route: Route; params: AppRscRouteParams } | null;\n findIntercept(pathname: string, sourcePathname?: string | null): AppRscInterceptMatch | null;\n} {\n const routeTrie = buildRouteTrie(routes);\n const interceptLookup = createInterceptLookup(routes);\n\n return {\n matchRoute(url) {\n return trieMatch(routeTrie, appRscPathnameParts(url));\n },\n findIntercept(pathname, sourcePathname = null) {\n // Mirror Next.js' rewrite semantics: interception only fires when the\n // Next-URL header is present AND matches the intercepting route's regex\n // (with descendants allowed). Without a source pathname there is no\n // header for the rewrite to gate on, so we render the direct route.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/generate-interception-routes-rewrites.ts\n if (sourcePathname === null) return null;\n\n const urlParts = appRscPathnameParts(pathname);\n const sourceParts = appRscPathnameParts(sourcePathname);\n\n for (const entry of interceptLookup) {\n // Primary gate: when the intercept declares a `sourceMatchPattern`\n // (the intercepting route's path, descendants allowed), require the\n // request's source pathname to satisfy it. This mirrors Next.js'\n // `^<interceptingRoute>(?:/.*)?$` header regex precisely and is the\n // authoritative gate when the manifest carries the pattern.\n if (!matchInterceptSource(sourceParts, entry)) continue;\n\n const params = matchAppRscRoutePattern(urlParts, entry.targetPatternParts);\n if (params === null) continue;\n\n const sourceRoute = routes[entry.sourceRouteIndex];\n const matchedSourceParams = sourceRoute\n ? matchAppRscRoutePattern(sourceParts, sourceRoute.patternParts)\n : null;\n\n // Secondary gate (from #1249): when the entry has no\n // `sourceMatchPatternParts` declared (older manifest shapes), reject\n // sources that don't match the slot owner's route pattern exactly.\n // This is the safety net that keeps unrelated sources from pulling\n // in a modal they have no slot for. When `sourceMatchPatternParts`\n // *is* declared, `matchInterceptSource` above has already approved\n // the source (including descendants), so a stricter exact-match\n // check on the slot-owner route here would defeat the descendant\n // semantics — fall back to empty params instead.\n if (matchedSourceParams === null && entry.sourceMatchPatternParts === null) {\n continue;\n }\n const sourceParams = matchedSourceParams ?? createRouteParams();\n return { ...entry, matchedParams: mergeMatchedParams(sourceParams, params) };\n }\n return null;\n },\n };\n}\n\n/**\n * Check whether the request's source pathname (Next-URL / interception\n * context) satisfies the intercept entry's intercepting-route pattern, with\n * descendants allowed. Mirrors the header regex shape Next.js emits for the\n * generated interception rewrite: `^<pattern>(?:/.*)?$`.\n *\n * When the entry has no declared `sourceMatchPatternParts`, fall back to the\n * legacy behavior of accepting any source (we still require the source to be\n * non-null at the caller — see `findIntercept`).\n */\nfunction matchInterceptSource(sourceParts: string[], entry: AppRscInterceptLookupEntry): boolean {\n const patternParts = entry.sourceMatchPatternParts;\n if (!patternParts) return true;\n // Root pattern (`/`) matches any source.\n if (patternParts.length === 0) return true;\n return matchRoutePatternPrefix(sourceParts, patternParts);\n}\n\nfunction createInterceptLookup<Route extends AppRscRouteForMatching>(\n routes: Route[],\n): AppRscInterceptLookupEntry[] {\n const interceptLookup: AppRscInterceptLookupEntry[] = [];\n for (let routeIndex = 0; routeIndex < routes.length; routeIndex++) {\n const route = routes[routeIndex];\n if (!route.slots) continue;\n for (const [slotKey, slotModule] of Object.entries(route.slots)) {\n if (!slotModule.intercepts) continue;\n for (const intercept of slotModule.intercepts) {\n const sourceMatchPattern = intercept.sourceMatchPattern ?? null;\n const sourceMatchPatternParts = sourceMatchPattern\n ? sourceMatchPattern.split(\"/\").filter(Boolean)\n : null;\n interceptLookup.push({\n sourceRouteIndex: routeIndex,\n slotKey,\n slotId: typeof slotModule.id === \"string\" ? slotModule.id : null,\n targetPattern: intercept.targetPattern,\n targetPatternParts: intercept.targetPattern.split(\"/\").filter(Boolean),\n sourceMatchPattern,\n sourceMatchPatternParts,\n interceptLayouts: intercept.interceptLayouts,\n page: intercept.page,\n params: intercept.params,\n });\n }\n }\n }\n return interceptLookup;\n}\n\nexport function matchAppRscRoutePattern(\n urlParts: string[],\n patternParts: string[],\n): AppRscRouteParams | null {\n return matchRoutePattern(urlParts, patternParts);\n}\n\nfunction mergeMatchedParams(\n sourceParams: AppRscRouteParams,\n targetParams: AppRscRouteParams,\n): AppRscRouteParams {\n return Object.assign(createRouteParams(), sourceParams, targetParams);\n}\n"],"mappings":";;;;AA+DA,SAAS,oBAAuC;CAC9C,OAAO,OAAO,OAAO,KAAK;;AAG5B,SAAS,oBAAoB,UAA4B;CACvD,MAAM,WAAW,SAAS,MAAM,IAAI,CAAC;CAErC,OAAO,2BADY,aAAa,MAAM,MAAM,SAAS,QAAQ,OAAO,GAAG,CAC1B;;AAG/C,SAAgB,yBACd,QAIA;CACA,MAAM,YAAY,eAAe,OAAO;CACxC,MAAM,kBAAkB,sBAAsB,OAAO;CAErD,OAAO;EACL,WAAW,KAAK;GACd,OAAO,UAAU,WAAW,oBAAoB,IAAI,CAAC;;EAEvD,cAAc,UAAU,iBAAiB,MAAM;GAM7C,IAAI,mBAAmB,MAAM,OAAO;GAEpC,MAAM,WAAW,oBAAoB,SAAS;GAC9C,MAAM,cAAc,oBAAoB,eAAe;GAEvD,KAAK,MAAM,SAAS,iBAAiB;IAMnC,IAAI,CAAC,qBAAqB,aAAa,MAAM,EAAE;IAE/C,MAAM,SAAS,wBAAwB,UAAU,MAAM,mBAAmB;IAC1E,IAAI,WAAW,MAAM;IAErB,MAAM,cAAc,OAAO,MAAM;IACjC,MAAM,sBAAsB,cACxB,wBAAwB,aAAa,YAAY,aAAa,GAC9D;IAWJ,IAAI,wBAAwB,QAAQ,MAAM,4BAA4B,MACpE;IAEF,MAAM,eAAe,uBAAuB,mBAAmB;IAC/D,OAAO;KAAE,GAAG;KAAO,eAAe,mBAAmB,cAAc,OAAO;KAAE;;GAE9E,OAAO;;EAEV;;;;;;;;;;;;AAaH,SAAS,qBAAqB,aAAuB,OAA4C;CAC/F,MAAM,eAAe,MAAM;CAC3B,IAAI,CAAC,cAAc,OAAO;CAE1B,IAAI,aAAa,WAAW,GAAG,OAAO;CACtC,OAAO,wBAAwB,aAAa,aAAa;;AAG3D,SAAS,sBACP,QAC8B;CAC9B,MAAM,kBAAgD,EAAE;CACxD,KAAK,IAAI,aAAa,GAAG,aAAa,OAAO,QAAQ,cAAc;EACjE,MAAM,QAAQ,OAAO;EACrB,IAAI,CAAC,MAAM,OAAO;EAClB,KAAK,MAAM,CAAC,SAAS,eAAe,OAAO,QAAQ,MAAM,MAAM,EAAE;GAC/D,IAAI,CAAC,WAAW,YAAY;GAC5B,KAAK,MAAM,aAAa,WAAW,YAAY;IAC7C,MAAM,qBAAqB,UAAU,sBAAsB;IAC3D,MAAM,0BAA0B,qBAC5B,mBAAmB,MAAM,IAAI,CAAC,OAAO,QAAQ,GAC7C;IACJ,gBAAgB,KAAK;KACnB,kBAAkB;KAClB;KACA,QAAQ,OAAO,WAAW,OAAO,WAAW,WAAW,KAAK;KAC5D,eAAe,UAAU;KACzB,oBAAoB,UAAU,cAAc,MAAM,IAAI,CAAC,OAAO,QAAQ;KACtE;KACA;KACA,kBAAkB,UAAU;KAC5B,MAAM,UAAU;KAChB,QAAQ,UAAU;KACnB,CAAC;;;;CAIR,OAAO;;AAGT,SAAgB,wBACd,UACA,cAC0B;CAC1B,OAAO,kBAAkB,UAAU,aAAa;;AAGlD,SAAS,mBACP,cACA,cACmB;CACnB,OAAO,OAAO,OAAO,mBAAmB,EAAE,cAAc,aAAa"}
@@ -31,6 +31,11 @@ type AppServerActionRoute = {
31
31
  type ProgressiveServerActionResult = {
32
32
  formState: ReactFormState | null;
33
33
  kind: "form-state";
34
+ } | {
35
+ actionError: unknown;
36
+ actionFailed: true;
37
+ formState: null;
38
+ kind: "form-state";
34
39
  };
35
40
  type AppServerActionMatch<TRoute extends AppServerActionRoute> = {
36
41
  params: AppPageParams;
@@ -39,6 +44,7 @@ type AppServerActionMatch<TRoute extends AppServerActionRoute> = {
39
44
  type AppServerActionIntercept<TPage = unknown> = {
40
45
  matchedParams: AppPageParams;
41
46
  page: TPage;
47
+ slotId?: string | null;
42
48
  slotKey: string;
43
49
  sourceRouteIndex: number;
44
50
  };
@@ -71,7 +77,8 @@ type DecodeServerActionReplyOptions<TTemporaryReferences> = {
71
77
  };
72
78
  type HandleProgressiveServerActionRequestOptions = {
73
79
  actionId: string | null;
74
- allowedOrigins: string[];
80
+ allowedOrigins: string[]; /** Configured next.config `basePath`. Prefixed onto progressive Location targets. */
81
+ basePath?: string;
75
82
  cleanPathname: string;
76
83
  clearRequestContext: () => void;
77
84
  contentType: string;
@@ -88,7 +95,8 @@ type HandleProgressiveServerActionRequestOptions = {
88
95
  };
89
96
  type HandleServerActionRscRequestOptions<TElement, TRoute extends AppServerActionRoute, TInterceptOpts, TTemporaryReferences, TPage = unknown> = {
90
97
  actionId: string | null;
91
- allowedOrigins: string[];
98
+ allowedOrigins: string[]; /** Configured next.config `basePath`. Prefixed onto ACTION_REDIRECT_HEADER targets. */
99
+ basePath?: string;
92
100
  buildPageElement: (options: BuildServerActionPageElementOptions<TRoute, TInterceptOpts>) => TElement;
93
101
  cleanPathname: string;
94
102
  clearRequestContext: () => void;
@@ -128,9 +136,33 @@ type HandleServerActionRscRequestOptions<TElement, TRoute extends AppServerActio
128
136
  };
129
137
  declare function readActionBodyWithLimit(request: Request, maxBytes: number): Promise<string>;
130
138
  declare function readActionFormDataWithLimit(request: Request, maxBytes: number): Promise<FormData>;
139
+ /**
140
+ * Prepend the configured next.config `basePath` to a server-action redirect
141
+ * target before it goes on the wire.
142
+ *
143
+ * `redirect("/foo")` called from a server action mounted at `/base/...` must
144
+ * land the browser at `/base/foo`, mirroring how Next.js threads basePath
145
+ * through `addPathPrefix(getURLFromRedirectError(err), basePath)` in
146
+ * `app-render.tsx` for SSR redirects and in `action-handler.ts` for action
147
+ * redirects.
148
+ *
149
+ * Idempotent and external-aware:
150
+ * - Empty basePath → returned unchanged.
151
+ * - External URLs (`http://`, `https://`, `data:`, protocol-relative `//`)
152
+ * are returned unchanged because the framework does not own those routes.
153
+ * - Targets that already start with the configured basePath are returned
154
+ * unchanged so this helper can be applied at any layer without risk of
155
+ * double-prefixing (`/base/base/foo`).
156
+ *
157
+ * Exported for tests. Used by both the progressive (no-JS form POST) and
158
+ * RSC (`ACTION_REDIRECT_HEADER`) action redirect paths below.
159
+ *
160
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/action-handler.ts
161
+ */
162
+ declare function applyActionRedirectBasePath(url: string, basePath: string): string;
131
163
  declare function isProgressiveServerActionRequest(request: Pick<Request, "method">, contentType: string, actionId: string | null): boolean;
132
164
  declare function handleProgressiveServerActionRequest(options: HandleProgressiveServerActionRequestOptions): Promise<Response | ProgressiveServerActionResult | null>;
133
165
  declare function handleServerActionRscRequest<TElement, TRoute extends AppServerActionRoute, TInterceptOpts, TTemporaryReferences, TPage = unknown>(options: HandleServerActionRscRequestOptions<TElement, TRoute, TInterceptOpts, TTemporaryReferences, TPage>): Promise<Response | null>;
134
166
  //#endregion
135
- export { HandleProgressiveServerActionRequestOptions, HandleServerActionRscRequestOptions, handleProgressiveServerActionRequest, handleServerActionRscRequest, isProgressiveServerActionRequest, readActionBodyWithLimit, readActionFormDataWithLimit };
167
+ export { HandleProgressiveServerActionRequestOptions, HandleServerActionRscRequestOptions, applyActionRedirectBasePath, handleProgressiveServerActionRequest, handleServerActionRscRequest, isProgressiveServerActionRequest, readActionBodyWithLimit, readActionFormDataWithLimit };
136
168
  //# sourceMappingURL=app-server-action-execution.d.ts.map
@@ -1,14 +1,16 @@
1
+ import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
1
2
  import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER } from "./headers.js";
3
+ import { isExternalUrl } from "../config/config-matchers.js";
2
4
  import { internalServerErrorResponse, payloadTooLargeResponse } from "./http-error-responses.js";
3
5
  import { validateCsrfOrigin, validateServerActionPayload } from "./request-pipeline.js";
4
6
  import { getAndClearActionRevalidationKind } from "../shims/cache.js";
5
7
  import { APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI } from "./app-rsc-render-mode.js";
6
8
  import { setCurrentFetchCacheMode } from "../shims/fetch-cache.js";
7
- import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
8
- import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
9
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
9
10
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
10
11
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
11
12
  import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
13
+ import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
12
14
  import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
13
15
  //#region src/server/app-server-action-execution.ts
14
16
  /**
@@ -71,24 +73,6 @@ async function readActionFormDataWithLimit(request, maxBytes) {
71
73
  }
72
74
  return new Response(combined, { headers: { "Content-Type": request.headers.get("content-type") || "" } }).formData();
73
75
  }
74
- function getActionControlResponse(error) {
75
- const digest = getNextErrorDigest(error);
76
- if (!digest) return null;
77
- const redirect = parseNextRedirectDigest(digest);
78
- if (redirect) return {
79
- kind: "redirect",
80
- url: redirect.url
81
- };
82
- const httpError = parseNextHttpErrorDigest(digest);
83
- if (httpError) {
84
- if (!Number.isInteger(httpError.status)) return null;
85
- return {
86
- kind: "status",
87
- statusCode: httpError.status
88
- };
89
- }
90
- return null;
91
- }
92
76
  function getActionRedirect(error) {
93
77
  const digest = getNextErrorDigest(error);
94
78
  if (!digest) return null;
@@ -100,6 +84,41 @@ function getActionRedirect(error) {
100
84
  url: redirect.url
101
85
  };
102
86
  }
87
+ /**
88
+ * Prepend the configured next.config `basePath` to a server-action redirect
89
+ * target before it goes on the wire.
90
+ *
91
+ * `redirect("/foo")` called from a server action mounted at `/base/...` must
92
+ * land the browser at `/base/foo`, mirroring how Next.js threads basePath
93
+ * through `addPathPrefix(getURLFromRedirectError(err), basePath)` in
94
+ * `app-render.tsx` for SSR redirects and in `action-handler.ts` for action
95
+ * redirects.
96
+ *
97
+ * Idempotent and external-aware:
98
+ * - Empty basePath → returned unchanged.
99
+ * - External URLs (`http://`, `https://`, `data:`, protocol-relative `//`)
100
+ * are returned unchanged because the framework does not own those routes.
101
+ * - Targets that already start with the configured basePath are returned
102
+ * unchanged so this helper can be applied at any layer without risk of
103
+ * double-prefixing (`/base/base/foo`).
104
+ *
105
+ * Exported for tests. Used by both the progressive (no-JS form POST) and
106
+ * RSC (`ACTION_REDIRECT_HEADER`) action redirect paths below.
107
+ *
108
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/action-handler.ts
109
+ */
110
+ function applyActionRedirectBasePath(url, basePath) {
111
+ if (!basePath) return url;
112
+ if (isExternalUrl(url)) return url;
113
+ if (hasBasePath(url, basePath)) return url;
114
+ if (!url.startsWith("/")) return url;
115
+ const queryIndex = url.indexOf("?");
116
+ const hashIndex = url.indexOf("#");
117
+ const splitAt = queryIndex === -1 ? hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
118
+ const pathname = splitAt === -1 ? url : url.slice(0, splitAt);
119
+ const suffix = splitAt === -1 ? "" : url.slice(splitAt);
120
+ return `${addBasePathToPathname(pathname, basePath)}${suffix}`;
121
+ }
103
122
  function getActionHttpFallbackStatus(error) {
104
123
  const digest = getNextErrorDigest(error);
105
124
  if (!digest) return null;
@@ -133,6 +152,10 @@ function isProgressiveServerActionRequest(request, contentType, actionId) {
133
152
  }
134
153
  async function handleProgressiveServerActionRequest(options) {
135
154
  if (!isProgressiveServerActionRequest(options.request, options.contentType, options.actionId)) return null;
155
+ if (options.request.headers.get("x-action-forwarded")) return createActionNotFoundResponse(null, {
156
+ clearRequestContext: options.clearRequestContext,
157
+ getAndClearPendingCookies: options.getAndClearPendingCookies
158
+ });
136
159
  const csrfResponse = validateCsrfOrigin(options.request, options.allowedOrigins);
137
160
  if (csrfResponse) return csrfResponse;
138
161
  if (parseInt(options.request.headers.get("content-length") || "0", 10) > options.maxActionBodySize) {
@@ -157,19 +180,42 @@ async function handleProgressiveServerActionRequest(options) {
157
180
  }
158
181
  const action = await options.decodeAction(body);
159
182
  if (!isAppServerActionFunction(action)) return null;
160
- let actionControlResponse = null;
183
+ let actionRedirect = null;
184
+ let actionError = void 0;
185
+ let actionFailed = false;
161
186
  let actionResult;
162
187
  const previousHeadersPhase = options.setHeadersAccessPhase("action");
163
188
  try {
164
189
  actionResult = await action();
165
190
  } catch (error) {
166
- actionControlResponse = getActionControlResponse(error);
167
- if (!actionControlResponse) throw error;
191
+ actionRedirect = getActionRedirect(error);
192
+ if (!actionRedirect) {
193
+ actionError = error;
194
+ actionFailed = true;
195
+ if (!(getActionHttpFallbackStatus(error) !== null || isServerActionNotFoundError(error, null))) {
196
+ console.error("[vinext] Server action error:", error);
197
+ options.reportRequestError(normalizeError(error), {
198
+ path: options.cleanPathname,
199
+ method: options.request.method,
200
+ headers: Object.fromEntries(options.request.headers.entries())
201
+ }, {
202
+ routerKind: "App Router",
203
+ routePath: options.cleanPathname,
204
+ routeType: "action"
205
+ });
206
+ }
207
+ }
168
208
  } finally {
169
209
  options.setHeadersAccessPhase(previousHeadersPhase);
170
210
  }
171
- if (!actionControlResponse) {
211
+ if (!actionRedirect) {
172
212
  getAndClearActionRevalidationKind();
213
+ if (actionFailed) return {
214
+ kind: "form-state",
215
+ formState: null,
216
+ actionError,
217
+ actionFailed
218
+ };
173
219
  return {
174
220
  kind: "form-state",
175
221
  formState: await options.decodeFormState(actionResult, body) ?? null
@@ -180,13 +226,14 @@ async function handleProgressiveServerActionRequest(options) {
180
226
  const actionRevalidationKind = resolveActionRevalidationKind(actionPendingCookies.length > 0 || Boolean(actionDraftCookie));
181
227
  options.clearRequestContext();
182
228
  const headers = new Headers();
183
- if (actionControlResponse.kind === "redirect") headers.set("Location", new URL(actionControlResponse.url, options.request.url).toString());
229
+ const prefixedRedirectUrl = applyActionRedirectBasePath(actionRedirect.url, options.basePath ?? "");
230
+ headers.set("Location", new URL(prefixedRedirectUrl, options.request.url).toString());
184
231
  mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders);
185
232
  for (const cookie of actionPendingCookies) headers.append("Set-Cookie", cookie);
186
233
  if (actionDraftCookie) headers.append("Set-Cookie", actionDraftCookie);
187
234
  setActionRevalidatedHeader(headers, actionRevalidationKind);
188
235
  return new Response(null, {
189
- status: actionControlResponse.kind === "redirect" ? 303 : actionControlResponse.statusCode,
236
+ status: 303,
190
237
  headers
191
238
  });
192
239
  } catch (error) {
@@ -196,7 +243,7 @@ async function handleProgressiveServerActionRequest(options) {
196
243
  });
197
244
  getAndClearActionRevalidationKind();
198
245
  options.getAndClearPendingCookies();
199
- console.error("[vinext] Server action error:", error);
246
+ console.error("[vinext] Server action payload parsing error:", error);
200
247
  options.reportRequestError(normalizeError(error), {
201
248
  path: options.cleanPathname,
202
249
  method: options.request.method,
@@ -207,11 +254,15 @@ async function handleProgressiveServerActionRequest(options) {
207
254
  routeType: "action"
208
255
  });
209
256
  options.clearRequestContext();
210
- return internalServerErrorResponse(process.env.NODE_ENV === "production" ? void 0 : "Server action failed: " + getServerActionFailureMessage(error));
257
+ return internalServerErrorResponse(process.env.NODE_ENV === "production" ? void 0 : "Server action parsing failed: " + getServerActionFailureMessage(error));
211
258
  }
212
259
  }
213
260
  async function handleServerActionRscRequest(options) {
214
261
  if (options.request.method.toUpperCase() !== "POST" || !options.actionId) return null;
262
+ if (options.request.headers.get("x-action-forwarded")) return createActionNotFoundResponse(options.actionId, {
263
+ clearRequestContext: options.clearRequestContext,
264
+ getAndClearPendingCookies: options.getAndClearPendingCookies
265
+ });
215
266
  const csrfResponse = validateCsrfOrigin(options.request, options.allowedOrigins);
216
267
  if (csrfResponse) return csrfResponse;
217
268
  if (parseInt(options.request.headers.get("content-length") || "0", 10) > options.maxActionBodySize) {
@@ -293,11 +344,12 @@ async function handleServerActionRscRequest(options) {
293
344
  const actionRevalidationKind = resolveActionRevalidationKind(actionPendingCookies.length > 0 || Boolean(actionDraftCookie));
294
345
  options.clearRequestContext();
295
346
  const redirectHeaders = new Headers({
296
- "Content-Type": "text/x-component; charset=utf-8",
347
+ "Content-Type": VINEXT_RSC_CONTENT_TYPE,
297
348
  Vary: VINEXT_RSC_VARY_HEADER
298
349
  });
299
350
  mergeMiddlewareResponseHeaders(redirectHeaders, options.middlewareHeaders);
300
- redirectHeaders.set(ACTION_REDIRECT_HEADER, actionRedirect.url);
351
+ applyRscCompatibilityIdHeader(redirectHeaders);
352
+ redirectHeaders.set(ACTION_REDIRECT_HEADER, applyActionRedirectBasePath(actionRedirect.url, options.basePath ?? ""));
301
353
  redirectHeaders.set(ACTION_REDIRECT_TYPE_HEADER, actionRedirect.type);
302
354
  redirectHeaders.set(ACTION_REDIRECT_STATUS_HEADER, String(actionRedirect.status));
303
355
  for (const cookie of actionPendingCookies) redirectHeaders.append("Set-Cookie", cookie);
@@ -319,10 +371,11 @@ async function handleServerActionRscRequest(options) {
319
371
  });
320
372
  options.clearRequestContext();
321
373
  const actionHeaders = new Headers({
322
- "Content-Type": "text/x-component; charset=utf-8",
374
+ "Content-Type": VINEXT_RSC_CONTENT_TYPE,
323
375
  Vary: VINEXT_RSC_VARY_HEADER
324
376
  });
325
377
  mergeMiddlewareResponseHeaders(actionHeaders, options.middlewareHeaders);
378
+ applyRscCompatibilityIdHeader(actionHeaders);
326
379
  return new Response(rscStream, {
327
380
  status: options.middlewareStatus ?? actionStatus,
328
381
  headers: actionHeaders
@@ -374,10 +427,11 @@ async function handleServerActionRscRequest(options) {
374
427
  onError: onRenderError
375
428
  });
376
429
  const actionHeaders = new Headers({
377
- "Content-Type": "text/x-component; charset=utf-8",
430
+ "Content-Type": VINEXT_RSC_CONTENT_TYPE,
378
431
  Vary: VINEXT_RSC_VARY_HEADER
379
432
  });
380
433
  mergeMiddlewareResponseHeaders(actionHeaders, options.middlewareHeaders);
434
+ applyRscCompatibilityIdHeader(actionHeaders);
381
435
  setActionRevalidatedHeader(actionHeaders, actionRevalidationKind);
382
436
  const actionResponse = new Response(rscStream, {
383
437
  status: options.middlewareStatus ?? actionStatus,
@@ -400,6 +454,6 @@ async function handleServerActionRscRequest(options) {
400
454
  }
401
455
  }
402
456
  //#endregion
403
- export { handleProgressiveServerActionRequest, handleServerActionRscRequest, isProgressiveServerActionRequest, readActionBodyWithLimit, readActionFormDataWithLimit };
457
+ export { applyActionRedirectBasePath, handleProgressiveServerActionRequest, handleServerActionRscRequest, isProgressiveServerActionRequest, readActionBodyWithLimit, readActionFormDataWithLimit };
404
458
 
405
459
  //# sourceMappingURL=app-server-action-execution.js.map