vinext 0.0.50 → 0.0.51

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 (309) 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 +12 -3
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +1 -1
  10. package/dist/build/prerender.js +44 -14
  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 +1 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli.js +60 -3
  18. package/dist/cli.js.map +1 -1
  19. package/dist/client/window-next.d.ts +3 -1
  20. package/dist/client/window-next.js.map +1 -1
  21. package/dist/config/dotenv.d.ts +11 -1
  22. package/dist/config/dotenv.js.map +1 -1
  23. package/dist/config/next-config.d.ts +87 -3
  24. package/dist/config/next-config.js +222 -6
  25. package/dist/config/next-config.js.map +1 -1
  26. package/dist/config/tsconfig-paths.d.ts +13 -0
  27. package/dist/config/tsconfig-paths.js +117 -0
  28. package/dist/config/tsconfig-paths.js.map +1 -0
  29. package/dist/deploy.js +3 -2
  30. package/dist/deploy.js.map +1 -1
  31. package/dist/entries/app-browser-entry.d.ts +2 -2
  32. package/dist/entries/app-browser-entry.js +26 -1
  33. package/dist/entries/app-browser-entry.js.map +1 -1
  34. package/dist/entries/app-rsc-entry.d.ts +19 -1
  35. package/dist/entries/app-rsc-entry.js +38 -12
  36. package/dist/entries/app-rsc-entry.js.map +1 -1
  37. package/dist/entries/app-rsc-manifest.d.ts +9 -0
  38. package/dist/entries/app-rsc-manifest.js +4 -1
  39. package/dist/entries/app-rsc-manifest.js.map +1 -1
  40. package/dist/entries/pages-client-entry.js +3 -5
  41. package/dist/entries/pages-client-entry.js.map +1 -1
  42. package/dist/entries/pages-server-entry.js +19 -1
  43. package/dist/entries/pages-server-entry.js.map +1 -1
  44. package/dist/index.js +130 -37
  45. package/dist/index.js.map +1 -1
  46. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  47. package/dist/plugins/client-reference-dedup.js +138 -16
  48. package/dist/plugins/client-reference-dedup.js.map +1 -1
  49. package/dist/plugins/fonts.d.ts +2 -2
  50. package/dist/plugins/fonts.js +15 -6
  51. package/dist/plugins/fonts.js.map +1 -1
  52. package/dist/plugins/sass.d.ts +34 -0
  53. package/dist/plugins/sass.js +22 -0
  54. package/dist/plugins/sass.js.map +1 -0
  55. package/dist/routing/app-route-graph.d.ts +31 -2
  56. package/dist/routing/app-route-graph.js +82 -10
  57. package/dist/routing/app-route-graph.js.map +1 -1
  58. package/dist/routing/route-pattern.d.ts +56 -1
  59. package/dist/routing/route-pattern.js +60 -1
  60. package/dist/routing/route-pattern.js.map +1 -1
  61. package/dist/server/app-browser-action-result.d.ts +27 -2
  62. package/dist/server/app-browser-action-result.js +63 -2
  63. package/dist/server/app-browser-action-result.js.map +1 -1
  64. package/dist/server/app-browser-entry.js +262 -108
  65. package/dist/server/app-browser-entry.js.map +1 -1
  66. package/dist/server/app-browser-hydration.d.ts +13 -1
  67. package/dist/server/app-browser-hydration.js +9 -1
  68. package/dist/server/app-browser-hydration.js.map +1 -1
  69. package/dist/server/app-browser-navigation-controller.d.ts +14 -1
  70. package/dist/server/app-browser-navigation-controller.js +28 -9
  71. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  72. package/dist/server/app-browser-popstate.d.ts +16 -0
  73. package/dist/server/app-browser-popstate.js +17 -0
  74. package/dist/server/app-browser-popstate.js.map +1 -0
  75. package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
  76. package/dist/server/app-browser-rsc-redirect.js +37 -0
  77. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  78. package/dist/server/app-browser-state.d.ts +11 -7
  79. package/dist/server/app-browser-state.js +45 -27
  80. package/dist/server/app-browser-state.js.map +1 -1
  81. package/dist/server/app-browser-stream.d.ts +5 -4
  82. package/dist/server/app-browser-stream.js +5 -6
  83. package/dist/server/app-browser-stream.js.map +1 -1
  84. package/dist/server/app-browser-visible-commit.d.ts +5 -0
  85. package/dist/server/app-browser-visible-commit.js +38 -5
  86. package/dist/server/app-browser-visible-commit.js.map +1 -1
  87. package/dist/server/app-elements-wire.d.ts +38 -6
  88. package/dist/server/app-elements-wire.js +106 -6
  89. package/dist/server/app-elements-wire.js.map +1 -1
  90. package/dist/server/app-elements.d.ts +2 -2
  91. package/dist/server/app-elements.js +2 -2
  92. package/dist/server/app-elements.js.map +1 -1
  93. package/dist/server/app-fallback-renderer.d.ts +10 -1
  94. package/dist/server/app-fallback-renderer.js +37 -1
  95. package/dist/server/app-fallback-renderer.js.map +1 -1
  96. package/dist/server/app-history-state.d.ts +26 -0
  97. package/dist/server/app-history-state.js +53 -0
  98. package/dist/server/app-history-state.js.map +1 -0
  99. package/dist/server/app-page-boundary-render.d.ts +10 -1
  100. package/dist/server/app-page-boundary-render.js +13 -6
  101. package/dist/server/app-page-boundary-render.js.map +1 -1
  102. package/dist/server/app-page-boundary.js +3 -2
  103. package/dist/server/app-page-boundary.js.map +1 -1
  104. package/dist/server/app-page-cache.d.ts +13 -0
  105. package/dist/server/app-page-cache.js +25 -8
  106. package/dist/server/app-page-cache.js.map +1 -1
  107. package/dist/server/app-page-dispatch.d.ts +5 -0
  108. package/dist/server/app-page-dispatch.js +68 -11
  109. package/dist/server/app-page-dispatch.js.map +1 -1
  110. package/dist/server/app-page-element-builder.d.ts +7 -0
  111. package/dist/server/app-page-element-builder.js +32 -4
  112. package/dist/server/app-page-element-builder.js.map +1 -1
  113. package/dist/server/app-page-execution.js +2 -3
  114. package/dist/server/app-page-execution.js.map +1 -1
  115. package/dist/server/app-page-head.d.ts +7 -0
  116. package/dist/server/app-page-head.js +2 -1
  117. package/dist/server/app-page-head.js.map +1 -1
  118. package/dist/server/app-page-probe.d.ts +23 -1
  119. package/dist/server/app-page-probe.js +29 -1
  120. package/dist/server/app-page-probe.js.map +1 -1
  121. package/dist/server/app-page-render-observation.d.ts +35 -0
  122. package/dist/server/app-page-render-observation.js +68 -0
  123. package/dist/server/app-page-render-observation.js.map +1 -0
  124. package/dist/server/app-page-render.d.ts +5 -1
  125. package/dist/server/app-page-render.js +79 -3
  126. package/dist/server/app-page-render.js.map +1 -1
  127. package/dist/server/app-page-request.d.ts +1 -0
  128. package/dist/server/app-page-request.js.map +1 -1
  129. package/dist/server/app-page-response.js +3 -2
  130. package/dist/server/app-page-response.js.map +1 -1
  131. package/dist/server/app-page-route-wiring.d.ts +3 -1
  132. package/dist/server/app-page-route-wiring.js +42 -14
  133. package/dist/server/app-page-route-wiring.js.map +1 -1
  134. package/dist/server/app-page-stream.d.ts +2 -0
  135. package/dist/server/app-page-stream.js +1 -0
  136. package/dist/server/app-page-stream.js.map +1 -1
  137. package/dist/server/app-router-entry.js +1 -13
  138. package/dist/server/app-router-entry.js.map +1 -1
  139. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  140. package/dist/server/app-rsc-cache-busting.js +36 -1
  141. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  142. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  143. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  144. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  145. package/dist/server/app-rsc-errors.d.ts +4 -1
  146. package/dist/server/app-rsc-errors.js +1 -1
  147. package/dist/server/app-rsc-errors.js.map +1 -1
  148. package/dist/server/app-rsc-handler.d.ts +12 -4
  149. package/dist/server/app-rsc-handler.js +6 -1
  150. package/dist/server/app-rsc-handler.js.map +1 -1
  151. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  152. package/dist/server/app-rsc-route-matching.js +45 -23
  153. package/dist/server/app-rsc-route-matching.js.map +1 -1
  154. package/dist/server/app-server-action-execution.d.ts +35 -3
  155. package/dist/server/app-server-action-execution.js +87 -33
  156. package/dist/server/app-server-action-execution.js.map +1 -1
  157. package/dist/server/app-ssr-entry.d.ts +1 -0
  158. package/dist/server/app-ssr-entry.js +37 -13
  159. package/dist/server/app-ssr-entry.js.map +1 -1
  160. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  161. package/dist/server/app-ssr-error-meta.js +50 -0
  162. package/dist/server/app-ssr-error-meta.js.map +1 -0
  163. package/dist/server/app-ssr-stream.d.ts +1 -1
  164. package/dist/server/app-ssr-stream.js +9 -12
  165. package/dist/server/app-ssr-stream.js.map +1 -1
  166. package/dist/server/artifact-compatibility.d.ts +12 -2
  167. package/dist/server/artifact-compatibility.js +12 -8
  168. package/dist/server/artifact-compatibility.js.map +1 -1
  169. package/dist/server/cache-proof.d.ts +124 -5
  170. package/dist/server/cache-proof.js +416 -18
  171. package/dist/server/cache-proof.js.map +1 -1
  172. package/dist/server/dev-lockfile.d.ts +110 -0
  173. package/dist/server/dev-lockfile.js +180 -0
  174. package/dist/server/dev-lockfile.js.map +1 -0
  175. package/dist/server/dev-server.js +15 -5
  176. package/dist/server/dev-server.js.map +1 -1
  177. package/dist/server/file-based-metadata.d.ts +13 -0
  178. package/dist/server/file-based-metadata.js +49 -2
  179. package/dist/server/file-based-metadata.js.map +1 -1
  180. package/dist/server/headers.d.ts +3 -1
  181. package/dist/server/headers.js +5 -2
  182. package/dist/server/headers.js.map +1 -1
  183. package/dist/server/html.js +1 -1
  184. package/dist/server/html.js.map +1 -1
  185. package/dist/server/http-error-responses.d.ts +10 -0
  186. package/dist/server/http-error-responses.js +11 -1
  187. package/dist/server/http-error-responses.js.map +1 -1
  188. package/dist/server/isr-cache.d.ts +2 -1
  189. package/dist/server/isr-cache.js +4 -2
  190. package/dist/server/isr-cache.js.map +1 -1
  191. package/dist/server/metadata-route-response.js +22 -5
  192. package/dist/server/metadata-route-response.js.map +1 -1
  193. package/dist/server/metadata-routes.js +27 -8
  194. package/dist/server/metadata-routes.js.map +1 -1
  195. package/dist/server/middleware-runtime.js +1 -0
  196. package/dist/server/middleware-runtime.js.map +1 -1
  197. package/dist/server/middleware.d.ts +12 -0
  198. package/dist/server/middleware.js +12 -0
  199. package/dist/server/middleware.js.map +1 -1
  200. package/dist/server/navigation-planner.d.ts +19 -5
  201. package/dist/server/navigation-planner.js +278 -17
  202. package/dist/server/navigation-planner.js.map +1 -1
  203. package/dist/server/navigation-trace.d.ts +8 -1
  204. package/dist/server/navigation-trace.js +7 -0
  205. package/dist/server/navigation-trace.js.map +1 -1
  206. package/dist/server/normalize-path.d.ts +2 -1
  207. package/dist/server/normalize-path.js +4 -1
  208. package/dist/server/normalize-path.js.map +1 -1
  209. package/dist/server/pages-api-route.js +1 -0
  210. package/dist/server/pages-api-route.js.map +1 -1
  211. package/dist/server/pages-page-data.d.ts +3 -2
  212. package/dist/server/pages-page-data.js +22 -3
  213. package/dist/server/pages-page-data.js.map +1 -1
  214. package/dist/server/pages-page-response.js +1 -1
  215. package/dist/server/prod-server.d.ts +28 -1
  216. package/dist/server/prod-server.js +62 -9
  217. package/dist/server/prod-server.js.map +1 -1
  218. package/dist/server/server-action-not-found.d.ts +16 -3
  219. package/dist/server/server-action-not-found.js +19 -1
  220. package/dist/server/server-action-not-found.js.map +1 -1
  221. package/dist/server/server-globals.d.ts +5 -0
  222. package/dist/server/server-globals.js +37 -0
  223. package/dist/server/server-globals.js.map +1 -0
  224. package/dist/server/static-file-cache.js +1 -1
  225. package/dist/server/static-file-cache.js.map +1 -1
  226. package/dist/shims/cache-runtime.d.ts +19 -2
  227. package/dist/shims/cache-runtime.js +67 -11
  228. package/dist/shims/cache-runtime.js.map +1 -1
  229. package/dist/shims/cache.d.ts +5 -18
  230. package/dist/shims/cache.js +2 -0
  231. package/dist/shims/cache.js.map +1 -1
  232. package/dist/shims/error-boundary.js +6 -8
  233. package/dist/shims/error-boundary.js.map +1 -1
  234. package/dist/shims/error.d.ts +18 -1
  235. package/dist/shims/error.js +56 -1
  236. package/dist/shims/error.js.map +1 -1
  237. package/dist/shims/fetch-cache.d.ts +4 -1
  238. package/dist/shims/fetch-cache.js +40 -5
  239. package/dist/shims/fetch-cache.js.map +1 -1
  240. package/dist/shims/font-google-base.d.ts +22 -8
  241. package/dist/shims/font-google-base.js +41 -71
  242. package/dist/shims/font-google-base.js.map +1 -1
  243. package/dist/shims/font-local.d.ts +3 -20
  244. package/dist/shims/font-local.js +23 -75
  245. package/dist/shims/font-local.js.map +1 -1
  246. package/dist/shims/font-utils.d.ts +51 -0
  247. package/dist/shims/font-utils.js +97 -0
  248. package/dist/shims/font-utils.js.map +1 -0
  249. package/dist/shims/hash-scroll.d.ts +7 -0
  250. package/dist/shims/hash-scroll.js +30 -0
  251. package/dist/shims/hash-scroll.js.map +1 -0
  252. package/dist/shims/headers.d.ts +8 -11
  253. package/dist/shims/headers.js +22 -2
  254. package/dist/shims/headers.js.map +1 -1
  255. package/dist/shims/image.d.ts +1 -0
  256. package/dist/shims/image.js +144 -78
  257. package/dist/shims/image.js.map +1 -1
  258. package/dist/shims/internal/app-router-context.d.ts +6 -6
  259. package/dist/shims/internal/app-router-context.js +17 -6
  260. package/dist/shims/internal/app-router-context.js.map +1 -1
  261. package/dist/shims/link-prefetch.d.ts +9 -1
  262. package/dist/shims/link-prefetch.js +11 -6
  263. package/dist/shims/link-prefetch.js.map +1 -1
  264. package/dist/shims/link.d.ts +12 -2
  265. package/dist/shims/link.js +78 -32
  266. package/dist/shims/link.js.map +1 -1
  267. package/dist/shims/metadata.d.ts +16 -30
  268. package/dist/shims/metadata.js +87 -28
  269. package/dist/shims/metadata.js.map +1 -1
  270. package/dist/shims/navigation.d.ts +158 -17
  271. package/dist/shims/navigation.js +324 -74
  272. package/dist/shims/navigation.js.map +1 -1
  273. package/dist/shims/navigation.react-server.d.ts +3 -2
  274. package/dist/shims/navigation.react-server.js +5 -2
  275. package/dist/shims/navigation.react-server.js.map +1 -1
  276. package/dist/shims/pages-router-runtime.d.ts +7 -0
  277. package/dist/shims/pages-router-runtime.js +16 -0
  278. package/dist/shims/pages-router-runtime.js.map +1 -0
  279. package/dist/shims/router.d.ts +32 -6
  280. package/dist/shims/router.js +197 -242
  281. package/dist/shims/router.js.map +1 -1
  282. package/dist/shims/script.js +110 -32
  283. package/dist/shims/script.js.map +1 -1
  284. package/dist/shims/server.js +2 -1
  285. package/dist/shims/server.js.map +1 -1
  286. package/dist/shims/slot.d.ts +1 -0
  287. package/dist/shims/slot.js +41 -1
  288. package/dist/shims/slot.js.map +1 -1
  289. package/dist/shims/unified-request-context.js +2 -0
  290. package/dist/shims/unified-request-context.js.map +1 -1
  291. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  292. package/dist/shims/unrecognized-action-error.js +41 -0
  293. package/dist/shims/unrecognized-action-error.js.map +1 -0
  294. package/dist/shims/url-utils.d.ts +21 -1
  295. package/dist/shims/url-utils.js +67 -3
  296. package/dist/shims/url-utils.js.map +1 -1
  297. package/dist/utils/asset-prefix.d.ts +69 -0
  298. package/dist/utils/asset-prefix.js +91 -0
  299. package/dist/utils/asset-prefix.js.map +1 -0
  300. package/dist/utils/base-path.d.ts +7 -1
  301. package/dist/utils/base-path.js +10 -1
  302. package/dist/utils/base-path.js.map +1 -1
  303. package/dist/utils/navigation-signal.d.ts +1 -2
  304. package/dist/utils/navigation-signal.js +1 -1
  305. package/dist/utils/navigation-signal.js.map +1 -1
  306. package/dist/utils/sorted-array.d.ts +9 -0
  307. package/dist/utils/sorted-array.js +22 -0
  308. package/dist/utils/sorted-array.js.map +1 -0
  309. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"app-rsc-errors.js","names":[],"sources":["../../src/server/app-rsc-errors.ts"],"sourcesContent":["import { resolveAppPageSpecialError } from \"./app-page-execution.js\";\n\ntype DigestError = Error & { digest?: string };\n\ntype RscRequestInfo = {\n path: string;\n method: string;\n headers: Record<string, string>;\n};\n\ntype RscErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"render\";\n};\n\ntype RscErrorReporter = (\n error: Error,\n requestInfo: RscRequestInfo,\n errorContext: RscErrorContext,\n) => void;\n\ntype CreateRscOnErrorHandlerOptions = {\n errorContext: RscErrorContext | null;\n nodeEnv?: string;\n reportRequestError: RscErrorReporter;\n requestInfo: RscRequestInfo | null;\n};\n\nfunction hasDigest(error: unknown): error is { digest: unknown } {\n return Boolean(error && typeof error === \"object\" && \"digest\" in error);\n}\n\nfunction getThrownValueMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction getThrownValueStack(error: unknown): string {\n return error instanceof Error ? error.stack || \"\" : \"\";\n}\n\n/**\n * djb2 hash matching Next.js's string-hash package for RSC error digests.\n */\nexport function errorDigest(input: string): string {\n let hash = 5381;\n for (let i = input.length - 1; i >= 0; i--) {\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n return (hash >>> 0).toString();\n}\n\nexport function sanitizeErrorForClient(error: unknown, nodeEnv = process.env.NODE_ENV): unknown {\n if (resolveAppPageSpecialError(error)) {\n return error;\n }\n\n if (nodeEnv !== \"production\") {\n return error;\n }\n\n const sanitized: DigestError = new Error(\n \"An error occurred in the Server Components render. \" +\n \"The specific message is omitted in production builds to avoid leaking sensitive details. \" +\n \"A digest property is included on this error instance which may provide additional details about the nature of the error.\",\n );\n sanitized.digest = errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n return sanitized;\n}\n\nexport function createRscOnErrorHandler(\n options: CreateRscOnErrorHandlerOptions,\n): (error: unknown) => string | undefined {\n return (error) => {\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;\n\n if (hasDigest(error)) {\n return String(error.digest);\n }\n\n if (\n nodeEnv !== \"production\" &&\n error instanceof Error &&\n error.message.includes(\n \"Only plain objects, and a few built-ins, can be passed to Client Components\",\n )\n ) {\n console.error(\n \"[vinext] RSC serialization error: a non-plain object was passed from a Server Component to a Client Component.\\n\" +\n \"\\n\" +\n \"Common causes:\\n\" +\n \" * Passing a module namespace (import * as X) directly as a prop.\\n\" +\n \" Unlike Next.js (webpack), Vite produces real ESM module namespace objects\\n\" +\n \" which are not serializable. Fix: pass individual values instead,\\n\" +\n \" e.g. <Comp value={module.value} />\\n\" +\n \" * Passing a class instance (new Foo()) as a prop.\\n\" +\n \" Fix: convert to a plain object, e.g. { id: foo.id, name: foo.name }\\n\" +\n \" * Passing a Date, Map, or Set. Use .toISOString(), [...map.entries()], etc.\\n\" +\n \" * Passing Object.create(null). Use { ...obj } to restore a prototype.\\n\" +\n \"\\n\" +\n \"Original error:\",\n error.message,\n );\n return undefined;\n }\n\n if (options.requestInfo && options.errorContext && error) {\n options.reportRequestError(\n error instanceof Error ? error : new Error(getThrownValueMessage(error)),\n options.requestInfo,\n options.errorContext,\n );\n }\n\n if (nodeEnv === \"production\" && error) {\n return errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n }\n\n return undefined;\n };\n}\n"],"mappings":";;AA6BA,SAAS,UAAU,OAA8C;CAC/D,OAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,YAAY,MAAM;;AAGzE,SAAS,sBAAsB,OAAwB;CACrD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;AAG/D,SAAS,oBAAoB,OAAwB;CACnD,OAAO,iBAAiB,QAAQ,MAAM,SAAS,KAAK;;;;;AAMtD,SAAgB,YAAY,OAAuB;CACjD,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KACrC,OAAQ,OAAO,KAAM,MAAM,WAAW,EAAE;CAE1C,QAAQ,SAAS,GAAG,UAAU;;AAGhC,SAAgB,uBAAuB,OAAgB,UAAU,QAAQ,IAAI,UAAmB;CAC9F,IAAI,2BAA2B,MAAM,EACnC,OAAO;CAGT,IAAI,YAAY,cACd,OAAO;CAGT,MAAM,4BAAyB,IAAI,MACjC,uQAGD;CACD,UAAU,SAAS,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC;CACzF,OAAO;;AAGT,SAAgB,wBACd,SACwC;CACxC,QAAQ,UAAU;EAChB,MAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;EAE/C,IAAI,UAAU,MAAM,EAClB,OAAO,OAAO,MAAM,OAAO;EAG7B,IACE,YAAY,gBACZ,iBAAiB,SACjB,MAAM,QAAQ,SACZ,8EACD,EACD;GACA,QAAQ,MACN,8qBAaA,MAAM,QACP;GACD;;EAGF,IAAI,QAAQ,eAAe,QAAQ,gBAAgB,OACjD,QAAQ,mBACN,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,sBAAsB,MAAM,CAAC,EACxE,QAAQ,aACR,QAAQ,aACT;EAGH,IAAI,YAAY,gBAAgB,OAC9B,OAAO,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC"}
1
+ {"version":3,"file":"app-rsc-errors.js","names":[],"sources":["../../src/server/app-rsc-errors.ts"],"sourcesContent":["import { resolveAppPageSpecialError } from \"./app-page-execution.js\";\n\ntype DigestError = Error & { digest?: string };\n\ntype RscRequestInfo = {\n path: string;\n method: string;\n headers: Record<string, string>;\n};\n\ntype RscErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"render\";\n};\n\ntype RscErrorReporter = (\n error: Error,\n requestInfo: RscRequestInfo,\n errorContext: RscErrorContext,\n) => void;\n\ntype CreateRscOnErrorHandlerOptions = {\n errorContext: RscErrorContext | null;\n nodeEnv?: string;\n reportRequestError: RscErrorReporter;\n requestInfo: RscRequestInfo | null;\n};\n\nexport function hasDigest(error: unknown): error is { digest: unknown } {\n return Boolean(error && typeof error === \"object\" && \"digest\" in error);\n}\n\nfunction getThrownValueMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction getThrownValueStack(error: unknown): string {\n return error instanceof Error ? error.stack || \"\" : \"\";\n}\n\n/**\n * djb2 hash matching Next.js's string-hash package for RSC error digests.\n */\nexport function errorDigest(input: string): string {\n let hash = 5381;\n for (let i = input.length - 1; i >= 0; i--) {\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n return (hash >>> 0).toString();\n}\n\nexport function sanitizeErrorForClient(error: unknown, nodeEnv = process.env.NODE_ENV): unknown {\n if (resolveAppPageSpecialError(error)) {\n return error;\n }\n\n if (nodeEnv !== \"production\") {\n return error;\n }\n\n const sanitized: DigestError = new Error(\n \"An error occurred in the Server Components render. \" +\n \"The specific message is omitted in production builds to avoid leaking sensitive details. \" +\n \"A digest property is included on this error instance which may provide additional details about the nature of the error.\",\n );\n sanitized.digest = errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n return sanitized;\n}\n\nexport function createRscOnErrorHandler(\n options: CreateRscOnErrorHandlerOptions,\n): (error: unknown) => string | undefined {\n return (error) => {\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;\n\n if (hasDigest(error)) {\n return String(error.digest);\n }\n\n if (\n nodeEnv !== \"production\" &&\n error instanceof Error &&\n error.message.includes(\n \"Only plain objects, and a few built-ins, can be passed to Client Components\",\n )\n ) {\n console.error(\n \"[vinext] RSC serialization error: a non-plain object was passed from a Server Component to a Client Component.\\n\" +\n \"\\n\" +\n \"Common causes:\\n\" +\n \" * Passing a module namespace (import * as X) directly as a prop.\\n\" +\n \" Unlike Next.js (webpack), Vite produces real ESM module namespace objects\\n\" +\n \" which are not serializable. Fix: pass individual values instead,\\n\" +\n \" e.g. <Comp value={module.value} />\\n\" +\n \" * Passing a class instance (new Foo()) as a prop.\\n\" +\n \" Fix: convert to a plain object, e.g. { id: foo.id, name: foo.name }\\n\" +\n \" * Passing a Date, Map, or Set. Use .toISOString(), [...map.entries()], etc.\\n\" +\n \" * Passing Object.create(null). Use { ...obj } to restore a prototype.\\n\" +\n \"\\n\" +\n \"Original error:\",\n error.message,\n );\n return undefined;\n }\n\n if (options.requestInfo && options.errorContext && error) {\n options.reportRequestError(\n error instanceof Error ? error : new Error(getThrownValueMessage(error)),\n options.requestInfo,\n options.errorContext,\n );\n }\n\n if (nodeEnv === \"production\" && error) {\n return errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n }\n\n return undefined;\n };\n}\n"],"mappings":";;AA6BA,SAAgB,UAAU,OAA8C;CACtE,OAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,YAAY,MAAM;;AAGzE,SAAS,sBAAsB,OAAwB;CACrD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;AAG/D,SAAS,oBAAoB,OAAwB;CACnD,OAAO,iBAAiB,QAAQ,MAAM,SAAS,KAAK;;;;;AAMtD,SAAgB,YAAY,OAAuB;CACjD,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KACrC,OAAQ,OAAO,KAAM,MAAM,WAAW,EAAE;CAE1C,QAAQ,SAAS,GAAG,UAAU;;AAGhC,SAAgB,uBAAuB,OAAgB,UAAU,QAAQ,IAAI,UAAmB;CAC9F,IAAI,2BAA2B,MAAM,EACnC,OAAO;CAGT,IAAI,YAAY,cACd,OAAO;CAGT,MAAM,4BAAyB,IAAI,MACjC,uQAGD;CACD,UAAU,SAAS,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC;CACzF,OAAO;;AAGT,SAAgB,wBACd,SACwC;CACxC,QAAQ,UAAU;EAChB,MAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;EAE/C,IAAI,UAAU,MAAM,EAClB,OAAO,OAAO,MAAM,OAAO;EAG7B,IACE,YAAY,gBACZ,iBAAiB,SACjB,MAAM,QAAQ,SACZ,8EACD,EACD;GACA,QAAQ,MACN,8qBAaA,MAAM,QACP;GACD;;EAGF,IAAI,QAAQ,eAAe,QAAQ,gBAAgB,OACjD,QAAQ,mBACN,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,sBAAsB,MAAM,CAAC,EACxE,QAAQ,aACR,QAAQ,aACT;EAGH,IAAI,YAAY,gBAAgB,OAC9B,OAAO,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC"}
@@ -28,6 +28,8 @@ type AppRscRouteMatch<TRoute> = {
28
28
  type DispatchMatchedPageOptions<TRoute> = {
29
29
  cleanPathname: string;
30
30
  formState: ReactFormState | null;
31
+ actionError?: unknown;
32
+ actionFailed?: boolean;
31
33
  handlerStart: number;
32
34
  interceptionContext: string | null;
33
35
  isProgressiveActionRender: boolean;
@@ -56,6 +58,15 @@ type HandleProgressiveActionRequestOptions = {
56
58
  middlewareContext: AppRscMiddlewareContext;
57
59
  request: Request;
58
60
  };
61
+ type ProgressiveActionFormStateResult = {
62
+ formState: ReactFormState | null;
63
+ kind: "form-state";
64
+ } | {
65
+ actionError: unknown;
66
+ actionFailed: true;
67
+ formState: null;
68
+ kind: "form-state";
69
+ };
59
70
  type HandleServerActionRequestOptions = {
60
71
  actionId: string | null;
61
72
  cleanPathname: string;
@@ -99,10 +110,7 @@ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
99
110
  dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;
100
111
  dispatchMatchedRouteHandler: (options: DispatchMatchedRouteHandlerOptions<TRoute>) => Promise<Response>;
101
112
  ensureInstrumentation?: () => Promise<void>;
102
- handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | {
103
- formState: ReactFormState | null;
104
- kind: "form-state";
105
- } | null>;
113
+ handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | ProgressiveActionFormStateResult | null>;
106
114
  handleServerActionRequest: (options: HandleServerActionRequestOptions) => Promise<Response | null>;
107
115
  i18nConfig: NextI18nConfig | null;
108
116
  isMiddlewareProxy: boolean;
@@ -9,7 +9,6 @@ import { headersContextFromRequest } from "../shims/headers.js";
9
9
  import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
10
10
  import { createRscRedirectLocation, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
11
11
  import { getScriptNonceFromHeaderSources } from "./csp.js";
12
- import { flattenErrorCauses } from "../utils/error-cause.js";
13
12
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
14
13
  import { applyAppMiddleware } from "./app-middleware.js";
15
14
  import "./app-page-response.js";
@@ -17,6 +16,7 @@ import { buildPageCacheTags } from "./implicit-tags.js";
17
16
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
18
17
  import { pickRootParams, setRootParams } from "../shims/root-params.js";
19
18
  import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
19
+ import { flattenErrorCauses } from "../utils/error-cause.js";
20
20
  import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
21
21
  import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
22
22
  import { handleMetadataRouteRequest } from "./metadata-route-response.js";
@@ -171,6 +171,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
171
171
  if (progressiveActionResult instanceof Response) return progressiveActionResult;
172
172
  const isProgressiveActionRender = progressiveActionResult?.kind === "form-state";
173
173
  const formState = isProgressiveActionRender ? progressiveActionResult.formState : null;
174
+ const failedProgressiveActionResult = isProgressiveActionRender && "actionFailed" in progressiveActionResult ? progressiveActionResult : null;
175
+ const actionFailed = failedProgressiveActionResult !== null;
176
+ const actionError = failedProgressiveActionResult?.actionError;
174
177
  const serverActionResponse = await options.handleServerActionRequest({
175
178
  actionId,
176
179
  cleanPathname,
@@ -255,6 +258,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
255
258
  return options.dispatchMatchedPage({
256
259
  cleanPathname,
257
260
  formState,
261
+ actionError,
262
+ actionFailed,
258
263
  handlerStart,
259
264
  interceptionContext: interceptionContextHeader,
260
265
  isProgressiveActionRender,
@@ -1 +1 @@
1
- {"version":3,"file":"app-rsc-handler.js","names":[],"sources":["../../src/server/app-rsc-handler.ts"],"sourcesContent":["import type {\n NextHeader,\n NextI18nConfig,\n NextRedirect,\n NextRewrite,\n} from \"../config/next-config.js\";\nimport {\n isExternalUrl,\n matchRedirect,\n matchRewrite,\n proxyExternalRequest,\n requestContextFromRequest,\n sanitizeDestination,\n} from \"../config/config-matchers.js\";\nimport { headersContextFromRequest } from \"vinext/shims/headers\";\nimport {\n NEXT_ACTION_HEADER,\n RSC_ACTION_HEADER,\n RSC_HEADER,\n VINEXT_MW_CTX_HEADER,\n} from \"./headers.js\";\nimport { ensureFetchPatch, setCurrentFetchSoftTags } from \"vinext/shims/fetch-cache\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport {\n getRequestExecutionContext,\n type ExecutionContextLike,\n} from \"vinext/shims/request-context\";\nimport { pickRootParams, setRootParams } from \"vinext/shims/root-params\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport { flattenErrorCauses } from \"../utils/error-cause.js\";\nimport { hasBasePath } from \"../utils/base-path.js\";\nimport { applyAppMiddleware, type AppMiddlewareContext } from \"./app-middleware.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./app-page-response.js\";\nimport { handleAppPrerenderEndpoint } from \"./app-prerender-endpoints.js\";\nimport {\n createRscRedirectLocation,\n resolveInvalidRscCacheBustingRequest,\n stripRscCacheBustingSearchParam,\n stripRscSuffix,\n} from \"./app-rsc-cache-busting.js\";\nimport { finalizeAppRscResponse } from \"./app-rsc-response-finalizer.js\";\nimport { normalizeRscRequest } from \"./app-rsc-request-normalization.js\";\nimport { notFoundResponse } from \"./http-error-responses.js\";\nimport { getScriptNonceFromHeaderSources } from \"./csp.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { handleMetadataRouteRequest } from \"./metadata-route-response.js\";\nimport type { MiddlewareModule } from \"./middleware-runtime.js\";\nimport { runWithPrerenderWorkUnit } from \"./prerender-work-unit-setup.js\";\nimport { buildPostMwRequestContext } from \"./app-post-middleware-context.js\";\nimport type { AppRscRenderMode } from \"./app-rsc-render-mode.js\";\nimport {\n cloneRequestWithHeaders,\n filterInternalHeaders,\n applyConfigHeadersToResponse,\n normalizeTrailingSlash,\n resolvePublicFileRoute,\n validateImageUrl,\n} from \"./request-pipeline.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\ntype RequestContext = ReturnType<typeof requestContextFromRequest>;\ntype MetadataRoutes = Parameters<typeof handleMetadataRouteRequest>[0][\"metadataRoutes\"];\ntype MakeThenableParams = Parameters<typeof handleMetadataRouteRequest>[0][\"makeThenableParams\"];\ntype StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1][\"staticParamsMap\"];\ntype RootParamNamesMap = Parameters<\n typeof handleAppPrerenderEndpoint\n>[1][\"rootParamNamesByPattern\"];\n\ntype AppRscMiddlewareContext = AppMiddlewareContext;\n\ntype AppRscHandlerRoute = {\n isDynamic: boolean;\n page?: unknown;\n pattern: string;\n rootParamNames?: readonly string[];\n routeHandler?: unknown;\n routeSegments: readonly string[];\n};\n\ntype AppRscRouteMatch<TRoute> = {\n params: AppPageParams;\n route: TRoute;\n};\n\ntype DispatchMatchedPageOptions<TRoute> = {\n cleanPathname: string;\n formState: ReactFormState | null;\n handlerStart: number;\n interceptionContext: string | null;\n isProgressiveActionRender: boolean;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n scriptNonce?: string;\n searchParams: URLSearchParams;\n renderMode: AppRscRenderMode;\n};\n\ntype DispatchMatchedRouteHandlerOptions<TRoute> = {\n cleanPathname: string;\n middlewareContext: AppRscMiddlewareContext;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n searchParams: URLSearchParams;\n};\n\ntype HandleProgressiveActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n};\n\ntype HandleServerActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n interceptionContext: string | null;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n request: Request;\n searchParams: URLSearchParams;\n};\n\ntype RenderNotFoundOptions<TRoute> = {\n isRscRequest: boolean;\n matchedParams?: AppPageParams;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n route: TRoute | null;\n scriptNonce?: string;\n};\n\ntype RenderPagesFallbackOptions = {\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n url: URL;\n};\n\ntype NavigationContextValue = {\n params: AppPageParams;\n pathname: string;\n searchParams: URLSearchParams;\n};\n\ntype CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {\n basePath: string;\n clearRequestContext: () => void;\n configHeaders: NextHeader[];\n configRedirects: NextRedirect[];\n configRewrites: {\n afterFiles: NextRewrite[];\n beforeFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;\n dispatchMatchedRouteHandler: (\n options: DispatchMatchedRouteHandlerOptions<TRoute>,\n ) => Promise<Response>;\n ensureInstrumentation?: () => Promise<void>;\n handleProgressiveActionRequest: (\n options: HandleProgressiveActionRequestOptions,\n ) => Promise<Response | { formState: ReactFormState | null; kind: \"form-state\" } | null>;\n handleServerActionRequest: (\n options: HandleServerActionRequestOptions,\n ) => Promise<Response | null>;\n i18nConfig: NextI18nConfig | null;\n isMiddlewareProxy: boolean;\n loadPrerenderPagesRoutes?: () => Promise<unknown>;\n makeThenableParams: MakeThenableParams;\n matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;\n metadataRoutes: MetadataRoutes;\n middlewareModule: MiddlewareModule | null;\n publicFiles: ReadonlySet<string>;\n renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;\n renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;\n rootParamNamesByPattern?: RootParamNamesMap;\n setNavigationContext: (context: NavigationContextValue) => void;\n staticParamsMap: StaticParamsMap;\n trailingSlash: boolean;\n validateDevRequestOrigin?: (request: Request) => Response | null;\n};\n\nfunction hasProperty<TKey extends PropertyKey>(\n value: object,\n key: TKey,\n): value is object & Record<TKey, unknown> {\n return key in value;\n}\n\nfunction isExecutionContextLike(value: unknown): value is ExecutionContextLike {\n if (!value || typeof value !== \"object\") return false;\n return hasProperty(value, \"waitUntil\") && typeof value.waitUntil === \"function\";\n}\n\nfunction redirectDestinationWithBasePath(destination: string, basePath: string): string {\n if (!basePath || isExternalUrl(destination) || hasBasePath(destination, basePath)) {\n return destination;\n }\n return basePath + destination;\n}\n\nasync function applyRewrite(\n options: {\n clearRequestContext: () => void;\n request: Request;\n requestContext: RequestContext;\n rewrites: NextRewrite[];\n },\n cleanPathname: string,\n): Promise<Response | string | null> {\n if (!options.rewrites.length) return null;\n\n const rewritten = matchRewrite(cleanPathname, options.rewrites, options.requestContext);\n if (!rewritten) return null;\n\n if (isExternalUrl(rewritten)) {\n options.clearRequestContext();\n return proxyExternalRequest(options.request, rewritten);\n }\n\n return rewritten;\n}\n\nfunction applyConfigHeadersToMiddlewareRedirect(\n response: Response,\n options: {\n configHeaders: NextHeader[];\n pathname: string;\n requestContext: RequestContext;\n },\n): Response {\n // Non-redirect middleware responses still pass through finalization, where\n // config headers are applied once. Redirects skip finalization to avoid\n // mutating immutable redirect headers, so they need the earlier header layer here.\n if (response.status < 300 || response.status >= 400) return response;\n if (!options.configHeaders.length) return response;\n\n const headers = new Headers();\n applyConfigHeadersToResponse(headers, {\n configHeaders: options.configHeaders,\n pathname: options.pathname,\n requestContext: options.requestContext,\n });\n\n if (!headers.entries().next().done) {\n mergeMiddlewareResponseHeaders(headers, response.headers);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n return response;\n}\n\nasync function handleAppRscRequest<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n request: Request,\n preMiddlewareRequestContext: RequestContext,\n): Promise<Response> {\n const handlerStart = process.env.NODE_ENV !== \"production\" ? performance.now() : 0;\n\n if (process.env.NODE_ENV !== \"production\") {\n const originBlock = options.validateDevRequestOrigin?.(request);\n if (originBlock) return originBlock;\n }\n\n const normalized = normalizeRscRequest(request, options.basePath);\n if (normalized instanceof Response) return normalized;\n\n const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader, renderMode } =\n normalized;\n let { pathname, cleanPathname } = normalized;\n\n const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {\n isPrerenderEnabled() {\n return process.env.VINEXT_PRERENDER === \"1\";\n },\n loadPagesRoutes: options.loadPrerenderPagesRoutes,\n pathname,\n rootParamNamesByPattern: options.rootParamNamesByPattern,\n staticParamsMap: options.staticParamsMap,\n });\n if (prerenderEndpointResponse) return prerenderEndpointResponse;\n\n const trailingSlashRedirect = normalizeTrailingSlash(\n pathname,\n options.basePath,\n options.trailingSlash,\n url.search,\n );\n if (trailingSlashRedirect) return trailingSlashRedirect;\n\n const redirectPathname = stripRscSuffix(pathname);\n const redirect = matchRedirect(\n redirectPathname,\n options.configRedirects,\n preMiddlewareRequestContext,\n );\n if (redirect) {\n const destination = sanitizeDestination(\n redirectDestinationWithBasePath(redirect.destination, options.basePath),\n );\n const location =\n isRscRequest && request.headers.get(RSC_HEADER) === \"1\"\n ? await createRscRedirectLocation(destination, request)\n : destination;\n return new Response(null, {\n status: redirect.permanent ? 308 : 307,\n headers: { Location: location },\n });\n }\n\n const rscCacheBustingRedirect = await resolveInvalidRscCacheBustingRequest({\n isRscRequest,\n request,\n });\n if (rscCacheBustingRedirect) return rscCacheBustingRedirect;\n\n const middlewareContext: AppRscMiddlewareContext = {\n headers: null,\n requestHeaders: null,\n status: null,\n };\n\n if (options.middlewareModule) {\n const middlewareResult = await applyAppMiddleware({\n basePath: options.basePath,\n cleanPathname,\n context: middlewareContext,\n i18nConfig: options.i18nConfig,\n isProxy: options.isMiddlewareProxy,\n module: options.middlewareModule,\n request,\n });\n if (middlewareResult.kind === \"response\") {\n return applyConfigHeadersToMiddlewareRedirect(middlewareResult.response, {\n configHeaders: options.configHeaders,\n pathname: cleanPathname,\n requestContext: preMiddlewareRequestContext,\n });\n }\n\n cleanPathname = middlewareResult.cleanPathname;\n if (middlewareResult.search !== null) {\n url.search = middlewareResult.search;\n }\n }\n\n const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareContext.headers);\n const postMiddlewareRequestContext = buildPostMwRequestContext(request);\n\n const beforeFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.beforeFiles,\n },\n cleanPathname,\n );\n if (beforeFilesRewrite instanceof Response) return beforeFilesRewrite;\n if (beforeFilesRewrite) cleanPathname = beforeFilesRewrite;\n\n if (cleanPathname === \"/_vinext/image\") {\n const imageUrlResult = validateImageUrl(url.searchParams.get(\"url\"), request.url);\n if (imageUrlResult instanceof Response) return imageUrlResult;\n return Response.redirect(new URL(imageUrlResult, url.origin).href, 302);\n }\n\n const metadataRouteResponse = await handleMetadataRouteRequest({\n metadataRoutes: options.metadataRoutes,\n cleanPathname,\n makeThenableParams: options.makeThenableParams,\n });\n if (metadataRouteResponse) return metadataRouteResponse;\n\n const publicFileResponse = resolvePublicFileRoute({\n cleanPathname,\n middlewareContext,\n pathname,\n publicFiles: options.publicFiles,\n request,\n });\n if (publicFileResponse) {\n options.clearRequestContext();\n return publicFileResponse;\n }\n\n if (isRscRequest) {\n stripRscCacheBustingSearchParam(url);\n }\n\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params: {},\n });\n\n const actionId =\n request.headers.get(RSC_ACTION_HEADER) ?? request.headers.get(NEXT_ACTION_HEADER);\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n const progressiveActionResult = await options.handleProgressiveActionRequest({\n actionId,\n cleanPathname,\n contentType,\n middlewareContext,\n request,\n });\n if (progressiveActionResult instanceof Response) return progressiveActionResult;\n const isProgressiveActionRender = progressiveActionResult?.kind === \"form-state\";\n const formState = isProgressiveActionRender ? progressiveActionResult.formState : null;\n\n const serverActionResponse = await options.handleServerActionRequest({\n actionId,\n cleanPathname,\n contentType,\n interceptionContext: interceptionContextHeader,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n request,\n searchParams: url.searchParams,\n });\n if (serverActionResponse) return serverActionResponse;\n\n let match = options.matchRoute(cleanPathname);\n if (!match || match.route.isDynamic) {\n const afterFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.afterFiles,\n },\n cleanPathname,\n );\n if (afterFilesRewrite instanceof Response) return afterFilesRewrite;\n if (afterFilesRewrite) {\n cleanPathname = afterFilesRewrite;\n match = options.matchRoute(cleanPathname);\n }\n }\n\n if (!match) {\n const fallbackRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.fallback,\n },\n cleanPathname,\n );\n if (fallbackRewrite instanceof Response) return fallbackRewrite;\n if (fallbackRewrite) {\n cleanPathname = fallbackRewrite;\n match = options.matchRoute(cleanPathname);\n }\n }\n\n if (!match) {\n const pagesFallbackResponse = await options.renderPagesFallback?.({\n isRscRequest,\n middlewareContext,\n request,\n url,\n });\n if (pagesFallbackResponse) {\n options.clearRequestContext();\n return pagesFallbackResponse;\n }\n\n const renderedNotFoundResponse = await options.renderNotFound({\n isRscRequest,\n middlewareContext,\n request,\n route: null,\n scriptNonce,\n });\n if (renderedNotFoundResponse) return renderedNotFoundResponse;\n\n options.clearRequestContext();\n const headers = new Headers();\n mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);\n return notFoundResponse({ headers });\n }\n\n const { route, params } = match;\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params,\n });\n setRootParams(pickRootParams(params, route.rootParamNames));\n\n if (route.routeHandler) {\n setCurrentFetchSoftTags(\n buildPageCacheTags(cleanPathname, [], [...route.routeSegments], \"route\"),\n );\n return options.dispatchMatchedRouteHandler({\n cleanPathname,\n middlewareContext,\n params,\n request,\n route,\n searchParams: url.searchParams,\n });\n }\n\n return options.dispatchMatchedPage({\n cleanPathname,\n formState,\n handlerStart,\n interceptionContext: interceptionContextHeader,\n isProgressiveActionRender,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n params,\n request,\n route,\n scriptNonce,\n searchParams: url.searchParams,\n renderMode,\n });\n}\n\nexport function createAppRscHandler<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n): (request: Request, ctx: unknown) => Promise<Response> {\n return async function appRscHandler(rawRequest, ctx) {\n await options.ensureInstrumentation?.();\n\n // Strip forged internal headers at the App Router request boundary.\n // Must happen BEFORE headersContextFromRequest() and\n // requestContextFromRequest() so the captured context never contains\n // attacker-controlled internal headers. This is the correct boundary\n // for pure App Router requests; in hybrid app+pages mode the connect\n // handler already filtered headers upstream and x-vinext-mw-ctx\n // (not in INTERNAL_HEADERS) carries the forwarded middleware context.\n // srvx's NodeRequestHeaders reads from rawHeaders for iteration but falls\n // back to req.headers for .get() / .has(). In the dev server we add\n // x-vinext-mw-ctx to req.headers after the Request is built, so it is\n // visible to .get() but lost when filterInternalHeaders iterates. Read it\n // BEFORE iterating so applyForwardedMiddlewareContext can skip middleware.\n const mwCtx = rawRequest.headers.get(VINEXT_MW_CTX_HEADER);\n const filteredHeaders = filterInternalHeaders(rawRequest.headers);\n if (mwCtx !== null) {\n filteredHeaders.set(VINEXT_MW_CTX_HEADER, mwCtx);\n }\n const request = cloneRequestWithHeaders(rawRequest, filteredHeaders);\n\n const executionContext = isExecutionContextLike(ctx)\n ? ctx\n : (getRequestExecutionContext() ?? null);\n const headersContext = headersContextFromRequest(request);\n const requestContext = createRequestContext({\n headersContext,\n executionContext,\n unstableCacheRevalidation: \"background\",\n });\n\n return runWithRequestContext(requestContext, () =>\n runWithPrerenderWorkUnit(\n async () => {\n ensureFetchPatch();\n const preMiddlewareRequestContext = requestContextFromRequest(request);\n let response: Response;\n\n try {\n response = await handleAppRscRequest(options, request, preMiddlewareRequestContext);\n } catch (error) {\n if (process.env.NODE_ENV !== \"production\") {\n flattenErrorCauses(error);\n }\n throw error;\n }\n\n return finalizeAppRscResponse(response, request, {\n basePath: options.basePath,\n configHeaders: options.configHeaders,\n requestContext: preMiddlewareRequestContext,\n });\n },\n { route: () => new URL(request.url).pathname },\n ),\n );\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-rsc-handler.js","names":[],"sources":["../../src/server/app-rsc-handler.ts"],"sourcesContent":["import type {\n NextHeader,\n NextI18nConfig,\n NextRedirect,\n NextRewrite,\n} from \"../config/next-config.js\";\nimport {\n isExternalUrl,\n matchRedirect,\n matchRewrite,\n proxyExternalRequest,\n requestContextFromRequest,\n sanitizeDestination,\n} from \"../config/config-matchers.js\";\nimport { headersContextFromRequest } from \"vinext/shims/headers\";\nimport {\n NEXT_ACTION_HEADER,\n RSC_ACTION_HEADER,\n RSC_HEADER,\n VINEXT_MW_CTX_HEADER,\n} from \"./headers.js\";\nimport { ensureFetchPatch, setCurrentFetchSoftTags } from \"vinext/shims/fetch-cache\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport {\n getRequestExecutionContext,\n type ExecutionContextLike,\n} from \"vinext/shims/request-context\";\nimport { pickRootParams, setRootParams } from \"vinext/shims/root-params\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport { flattenErrorCauses } from \"../utils/error-cause.js\";\nimport { hasBasePath } from \"../utils/base-path.js\";\nimport { applyAppMiddleware, type AppMiddlewareContext } from \"./app-middleware.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./app-page-response.js\";\nimport { handleAppPrerenderEndpoint } from \"./app-prerender-endpoints.js\";\nimport {\n createRscRedirectLocation,\n resolveInvalidRscCacheBustingRequest,\n stripRscCacheBustingSearchParam,\n stripRscSuffix,\n} from \"./app-rsc-cache-busting.js\";\nimport { finalizeAppRscResponse } from \"./app-rsc-response-finalizer.js\";\nimport { normalizeRscRequest } from \"./app-rsc-request-normalization.js\";\nimport { notFoundResponse } from \"./http-error-responses.js\";\nimport { getScriptNonceFromHeaderSources } from \"./csp.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { handleMetadataRouteRequest } from \"./metadata-route-response.js\";\nimport type { MiddlewareModule } from \"./middleware-runtime.js\";\nimport { runWithPrerenderWorkUnit } from \"./prerender-work-unit-setup.js\";\nimport { buildPostMwRequestContext } from \"./app-post-middleware-context.js\";\nimport type { AppRscRenderMode } from \"./app-rsc-render-mode.js\";\nimport {\n cloneRequestWithHeaders,\n filterInternalHeaders,\n applyConfigHeadersToResponse,\n normalizeTrailingSlash,\n resolvePublicFileRoute,\n validateImageUrl,\n} from \"./request-pipeline.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\ntype RequestContext = ReturnType<typeof requestContextFromRequest>;\ntype MetadataRoutes = Parameters<typeof handleMetadataRouteRequest>[0][\"metadataRoutes\"];\ntype MakeThenableParams = Parameters<typeof handleMetadataRouteRequest>[0][\"makeThenableParams\"];\ntype StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1][\"staticParamsMap\"];\ntype RootParamNamesMap = Parameters<\n typeof handleAppPrerenderEndpoint\n>[1][\"rootParamNamesByPattern\"];\n\ntype AppRscMiddlewareContext = AppMiddlewareContext;\n\ntype AppRscHandlerRoute = {\n isDynamic: boolean;\n page?: unknown;\n pattern: string;\n rootParamNames?: readonly string[];\n routeHandler?: unknown;\n routeSegments: readonly string[];\n};\n\ntype AppRscRouteMatch<TRoute> = {\n params: AppPageParams;\n route: TRoute;\n};\n\ntype DispatchMatchedPageOptions<TRoute> = {\n cleanPathname: string;\n formState: ReactFormState | null;\n actionError?: unknown;\n actionFailed?: boolean;\n handlerStart: number;\n interceptionContext: string | null;\n isProgressiveActionRender: boolean;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n scriptNonce?: string;\n searchParams: URLSearchParams;\n renderMode: AppRscRenderMode;\n};\n\ntype DispatchMatchedRouteHandlerOptions<TRoute> = {\n cleanPathname: string;\n middlewareContext: AppRscMiddlewareContext;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n searchParams: URLSearchParams;\n};\n\ntype HandleProgressiveActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n};\n\ntype ProgressiveActionFormStateResult =\n | {\n formState: ReactFormState | null;\n kind: \"form-state\";\n }\n | {\n actionError: unknown;\n actionFailed: true;\n formState: null;\n kind: \"form-state\";\n };\n\ntype HandleServerActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n interceptionContext: string | null;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n request: Request;\n searchParams: URLSearchParams;\n};\n\ntype RenderNotFoundOptions<TRoute> = {\n isRscRequest: boolean;\n matchedParams?: AppPageParams;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n route: TRoute | null;\n scriptNonce?: string;\n};\n\ntype RenderPagesFallbackOptions = {\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n url: URL;\n};\n\ntype NavigationContextValue = {\n params: AppPageParams;\n pathname: string;\n searchParams: URLSearchParams;\n};\n\ntype CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {\n basePath: string;\n clearRequestContext: () => void;\n configHeaders: NextHeader[];\n configRedirects: NextRedirect[];\n configRewrites: {\n afterFiles: NextRewrite[];\n beforeFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;\n dispatchMatchedRouteHandler: (\n options: DispatchMatchedRouteHandlerOptions<TRoute>,\n ) => Promise<Response>;\n ensureInstrumentation?: () => Promise<void>;\n handleProgressiveActionRequest: (\n options: HandleProgressiveActionRequestOptions,\n ) => Promise<Response | ProgressiveActionFormStateResult | null>;\n handleServerActionRequest: (\n options: HandleServerActionRequestOptions,\n ) => Promise<Response | null>;\n i18nConfig: NextI18nConfig | null;\n isMiddlewareProxy: boolean;\n loadPrerenderPagesRoutes?: () => Promise<unknown>;\n makeThenableParams: MakeThenableParams;\n matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;\n metadataRoutes: MetadataRoutes;\n middlewareModule: MiddlewareModule | null;\n publicFiles: ReadonlySet<string>;\n renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;\n renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;\n rootParamNamesByPattern?: RootParamNamesMap;\n setNavigationContext: (context: NavigationContextValue) => void;\n staticParamsMap: StaticParamsMap;\n trailingSlash: boolean;\n validateDevRequestOrigin?: (request: Request) => Response | null;\n};\n\nfunction hasProperty<TKey extends PropertyKey>(\n value: object,\n key: TKey,\n): value is object & Record<TKey, unknown> {\n return key in value;\n}\n\nfunction isExecutionContextLike(value: unknown): value is ExecutionContextLike {\n if (!value || typeof value !== \"object\") return false;\n return hasProperty(value, \"waitUntil\") && typeof value.waitUntil === \"function\";\n}\n\nfunction redirectDestinationWithBasePath(destination: string, basePath: string): string {\n if (!basePath || isExternalUrl(destination) || hasBasePath(destination, basePath)) {\n return destination;\n }\n return basePath + destination;\n}\n\nasync function applyRewrite(\n options: {\n clearRequestContext: () => void;\n request: Request;\n requestContext: RequestContext;\n rewrites: NextRewrite[];\n },\n cleanPathname: string,\n): Promise<Response | string | null> {\n if (!options.rewrites.length) return null;\n\n const rewritten = matchRewrite(cleanPathname, options.rewrites, options.requestContext);\n if (!rewritten) return null;\n\n if (isExternalUrl(rewritten)) {\n options.clearRequestContext();\n return proxyExternalRequest(options.request, rewritten);\n }\n\n return rewritten;\n}\n\nfunction applyConfigHeadersToMiddlewareRedirect(\n response: Response,\n options: {\n configHeaders: NextHeader[];\n pathname: string;\n requestContext: RequestContext;\n },\n): Response {\n // Non-redirect middleware responses still pass through finalization, where\n // config headers are applied once. Redirects skip finalization to avoid\n // mutating immutable redirect headers, so they need the earlier header layer here.\n if (response.status < 300 || response.status >= 400) return response;\n if (!options.configHeaders.length) return response;\n\n const headers = new Headers();\n applyConfigHeadersToResponse(headers, {\n configHeaders: options.configHeaders,\n pathname: options.pathname,\n requestContext: options.requestContext,\n });\n\n if (!headers.entries().next().done) {\n mergeMiddlewareResponseHeaders(headers, response.headers);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n return response;\n}\n\nasync function handleAppRscRequest<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n request: Request,\n preMiddlewareRequestContext: RequestContext,\n): Promise<Response> {\n const handlerStart = process.env.NODE_ENV !== \"production\" ? performance.now() : 0;\n\n if (process.env.NODE_ENV !== \"production\") {\n const originBlock = options.validateDevRequestOrigin?.(request);\n if (originBlock) return originBlock;\n }\n\n const normalized = normalizeRscRequest(request, options.basePath);\n if (normalized instanceof Response) return normalized;\n\n const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader, renderMode } =\n normalized;\n let { pathname, cleanPathname } = normalized;\n\n const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {\n isPrerenderEnabled() {\n return process.env.VINEXT_PRERENDER === \"1\";\n },\n loadPagesRoutes: options.loadPrerenderPagesRoutes,\n pathname,\n rootParamNamesByPattern: options.rootParamNamesByPattern,\n staticParamsMap: options.staticParamsMap,\n });\n if (prerenderEndpointResponse) return prerenderEndpointResponse;\n\n const trailingSlashRedirect = normalizeTrailingSlash(\n pathname,\n options.basePath,\n options.trailingSlash,\n url.search,\n );\n if (trailingSlashRedirect) return trailingSlashRedirect;\n\n const redirectPathname = stripRscSuffix(pathname);\n const redirect = matchRedirect(\n redirectPathname,\n options.configRedirects,\n preMiddlewareRequestContext,\n );\n if (redirect) {\n const destination = sanitizeDestination(\n redirectDestinationWithBasePath(redirect.destination, options.basePath),\n );\n const location =\n isRscRequest && request.headers.get(RSC_HEADER) === \"1\"\n ? await createRscRedirectLocation(destination, request)\n : destination;\n return new Response(null, {\n status: redirect.permanent ? 308 : 307,\n headers: { Location: location },\n });\n }\n\n const rscCacheBustingRedirect = await resolveInvalidRscCacheBustingRequest({\n isRscRequest,\n request,\n });\n if (rscCacheBustingRedirect) return rscCacheBustingRedirect;\n\n const middlewareContext: AppRscMiddlewareContext = {\n headers: null,\n requestHeaders: null,\n status: null,\n };\n\n if (options.middlewareModule) {\n const middlewareResult = await applyAppMiddleware({\n basePath: options.basePath,\n cleanPathname,\n context: middlewareContext,\n i18nConfig: options.i18nConfig,\n isProxy: options.isMiddlewareProxy,\n module: options.middlewareModule,\n request,\n });\n if (middlewareResult.kind === \"response\") {\n return applyConfigHeadersToMiddlewareRedirect(middlewareResult.response, {\n configHeaders: options.configHeaders,\n pathname: cleanPathname,\n requestContext: preMiddlewareRequestContext,\n });\n }\n\n cleanPathname = middlewareResult.cleanPathname;\n if (middlewareResult.search !== null) {\n url.search = middlewareResult.search;\n }\n }\n\n const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareContext.headers);\n const postMiddlewareRequestContext = buildPostMwRequestContext(request);\n\n const beforeFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.beforeFiles,\n },\n cleanPathname,\n );\n if (beforeFilesRewrite instanceof Response) return beforeFilesRewrite;\n if (beforeFilesRewrite) cleanPathname = beforeFilesRewrite;\n\n if (cleanPathname === \"/_vinext/image\") {\n const imageUrlResult = validateImageUrl(url.searchParams.get(\"url\"), request.url);\n if (imageUrlResult instanceof Response) return imageUrlResult;\n return Response.redirect(new URL(imageUrlResult, url.origin).href, 302);\n }\n\n const metadataRouteResponse = await handleMetadataRouteRequest({\n metadataRoutes: options.metadataRoutes,\n cleanPathname,\n makeThenableParams: options.makeThenableParams,\n });\n if (metadataRouteResponse) return metadataRouteResponse;\n\n const publicFileResponse = resolvePublicFileRoute({\n cleanPathname,\n middlewareContext,\n pathname,\n publicFiles: options.publicFiles,\n request,\n });\n if (publicFileResponse) {\n options.clearRequestContext();\n return publicFileResponse;\n }\n\n if (isRscRequest) {\n stripRscCacheBustingSearchParam(url);\n }\n\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params: {},\n });\n\n const actionId =\n request.headers.get(RSC_ACTION_HEADER) ?? request.headers.get(NEXT_ACTION_HEADER);\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n const progressiveActionResult = await options.handleProgressiveActionRequest({\n actionId,\n cleanPathname,\n contentType,\n middlewareContext,\n request,\n });\n if (progressiveActionResult instanceof Response) return progressiveActionResult;\n const isProgressiveActionRender = progressiveActionResult?.kind === \"form-state\";\n const formState = isProgressiveActionRender ? progressiveActionResult.formState : null;\n const failedProgressiveActionResult =\n isProgressiveActionRender && \"actionFailed\" in progressiveActionResult\n ? progressiveActionResult\n : null;\n const actionFailed = failedProgressiveActionResult !== null;\n const actionError = failedProgressiveActionResult?.actionError;\n\n const serverActionResponse = await options.handleServerActionRequest({\n actionId,\n cleanPathname,\n contentType,\n interceptionContext: interceptionContextHeader,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n request,\n searchParams: url.searchParams,\n });\n if (serverActionResponse) return serverActionResponse;\n\n let match = options.matchRoute(cleanPathname);\n if (!match || match.route.isDynamic) {\n const afterFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.afterFiles,\n },\n cleanPathname,\n );\n if (afterFilesRewrite instanceof Response) return afterFilesRewrite;\n if (afterFilesRewrite) {\n cleanPathname = afterFilesRewrite;\n match = options.matchRoute(cleanPathname);\n }\n }\n\n if (!match) {\n const fallbackRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.fallback,\n },\n cleanPathname,\n );\n if (fallbackRewrite instanceof Response) return fallbackRewrite;\n if (fallbackRewrite) {\n cleanPathname = fallbackRewrite;\n match = options.matchRoute(cleanPathname);\n }\n }\n\n if (!match) {\n const pagesFallbackResponse = await options.renderPagesFallback?.({\n isRscRequest,\n middlewareContext,\n request,\n url,\n });\n if (pagesFallbackResponse) {\n options.clearRequestContext();\n return pagesFallbackResponse;\n }\n\n const renderedNotFoundResponse = await options.renderNotFound({\n isRscRequest,\n middlewareContext,\n request,\n route: null,\n scriptNonce,\n });\n if (renderedNotFoundResponse) return renderedNotFoundResponse;\n\n options.clearRequestContext();\n const headers = new Headers();\n mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);\n return notFoundResponse({ headers });\n }\n\n const { route, params } = match;\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params,\n });\n setRootParams(pickRootParams(params, route.rootParamNames));\n\n if (route.routeHandler) {\n setCurrentFetchSoftTags(\n buildPageCacheTags(cleanPathname, [], [...route.routeSegments], \"route\"),\n );\n return options.dispatchMatchedRouteHandler({\n cleanPathname,\n middlewareContext,\n params,\n request,\n route,\n searchParams: url.searchParams,\n });\n }\n\n return options.dispatchMatchedPage({\n cleanPathname,\n formState,\n actionError,\n actionFailed,\n handlerStart,\n interceptionContext: interceptionContextHeader,\n isProgressiveActionRender,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n params,\n request,\n route,\n scriptNonce,\n searchParams: url.searchParams,\n renderMode,\n });\n}\n\nexport function createAppRscHandler<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n): (request: Request, ctx: unknown) => Promise<Response> {\n return async function appRscHandler(rawRequest, ctx) {\n await options.ensureInstrumentation?.();\n\n // Strip forged internal headers at the App Router request boundary.\n // Must happen BEFORE headersContextFromRequest() and\n // requestContextFromRequest() so the captured context never contains\n // attacker-controlled internal headers. This is the correct boundary\n // for pure App Router requests; in hybrid app+pages mode the connect\n // handler already filtered headers upstream and x-vinext-mw-ctx\n // (not in INTERNAL_HEADERS) carries the forwarded middleware context.\n // srvx's NodeRequestHeaders reads from rawHeaders for iteration but falls\n // back to req.headers for .get() / .has(). In the dev server we add\n // x-vinext-mw-ctx to req.headers after the Request is built, so it is\n // visible to .get() but lost when filterInternalHeaders iterates. Read it\n // BEFORE iterating so applyForwardedMiddlewareContext can skip middleware.\n const mwCtx = rawRequest.headers.get(VINEXT_MW_CTX_HEADER);\n const filteredHeaders = filterInternalHeaders(rawRequest.headers);\n if (mwCtx !== null) {\n filteredHeaders.set(VINEXT_MW_CTX_HEADER, mwCtx);\n }\n const request = cloneRequestWithHeaders(rawRequest, filteredHeaders);\n\n const executionContext = isExecutionContextLike(ctx)\n ? ctx\n : (getRequestExecutionContext() ?? null);\n const headersContext = headersContextFromRequest(request);\n const requestContext = createRequestContext({\n headersContext,\n executionContext,\n unstableCacheRevalidation: \"background\",\n });\n\n return runWithRequestContext(requestContext, () =>\n runWithPrerenderWorkUnit(\n async () => {\n ensureFetchPatch();\n const preMiddlewareRequestContext = requestContextFromRequest(request);\n let response: Response;\n\n try {\n response = await handleAppRscRequest(options, request, preMiddlewareRequestContext);\n } catch (error) {\n if (process.env.NODE_ENV !== \"production\") {\n flattenErrorCauses(error);\n }\n throw error;\n }\n\n return finalizeAppRscResponse(response, request, {\n basePath: options.basePath,\n configHeaders: options.configHeaders,\n requestContext: preMiddlewareRequestContext,\n });\n },\n { route: () => new URL(request.url).pathname },\n ),\n );\n };\n}\n"],"mappings":"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"}
@@ -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,6 +1,6 @@
1
1
  import { normalizePathnameForRouteMatch } 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);
@@ -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 { normalizePathnameForRouteMatch } 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 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 // 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,+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;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