vinext 0.0.50 → 0.0.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (462) hide show
  1. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  2. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  3. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  4. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  5. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  6. package/dist/build/precompress.d.ts +13 -2
  7. package/dist/build/precompress.js +23 -13
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +4 -15
  10. package/dist/build/prerender.js +83 -53
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.d.ts +5 -4
  13. package/dist/build/report.js +196 -348
  14. package/dist/build/report.js.map +1 -1
  15. package/dist/check.js +5 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli-args.d.ts +1 -0
  18. package/dist/cli-args.js +5 -0
  19. package/dist/cli-args.js.map +1 -1
  20. package/dist/cli.js +99 -3
  21. package/dist/cli.js.map +1 -1
  22. package/dist/client/navigation-runtime.d.ts +47 -0
  23. package/dist/client/navigation-runtime.js +156 -0
  24. package/dist/client/navigation-runtime.js.map +1 -0
  25. package/dist/client/pages-router-link-navigation.d.ts +26 -0
  26. package/dist/client/pages-router-link-navigation.js +14 -0
  27. package/dist/client/pages-router-link-navigation.js.map +1 -0
  28. package/dist/client/vinext-next-data.d.ts +12 -2
  29. package/dist/client/vinext-next-data.js +50 -1
  30. package/dist/client/vinext-next-data.js.map +1 -0
  31. package/dist/client/window-next.d.ts +3 -1
  32. package/dist/client/window-next.js.map +1 -1
  33. package/dist/cloudflare/kv-cache-handler.js +2 -1
  34. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  35. package/dist/config/config-matchers.d.ts +63 -16
  36. package/dist/config/config-matchers.js +143 -8
  37. package/dist/config/config-matchers.js.map +1 -1
  38. package/dist/config/dotenv.d.ts +11 -1
  39. package/dist/config/dotenv.js.map +1 -1
  40. package/dist/config/next-config.d.ts +107 -5
  41. package/dist/config/next-config.js +233 -7
  42. package/dist/config/next-config.js.map +1 -1
  43. package/dist/config/tsconfig-paths.d.ts +13 -0
  44. package/dist/config/tsconfig-paths.js +117 -0
  45. package/dist/config/tsconfig-paths.js.map +1 -0
  46. package/dist/deploy.js +104 -41
  47. package/dist/deploy.js.map +1 -1
  48. package/dist/entries/app-browser-entry.d.ts +2 -2
  49. package/dist/entries/app-browser-entry.js +34 -3
  50. package/dist/entries/app-browser-entry.js.map +1 -1
  51. package/dist/entries/app-rsc-entry.d.ts +19 -1
  52. package/dist/entries/app-rsc-entry.js +89 -23
  53. package/dist/entries/app-rsc-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  55. package/dist/entries/app-rsc-manifest.js +57 -7
  56. package/dist/entries/app-rsc-manifest.js.map +1 -1
  57. package/dist/entries/app-ssr-entry.d.ts +3 -3
  58. package/dist/entries/app-ssr-entry.js +4 -4
  59. package/dist/entries/app-ssr-entry.js.map +1 -1
  60. package/dist/entries/pages-client-entry.js +21 -7
  61. package/dist/entries/pages-client-entry.js.map +1 -1
  62. package/dist/entries/pages-server-entry.js +77 -9
  63. package/dist/entries/pages-server-entry.js.map +1 -1
  64. package/dist/entries/runtime-entry-module.d.ts +2 -1
  65. package/dist/entries/runtime-entry-module.js +9 -3
  66. package/dist/entries/runtime-entry-module.js.map +1 -1
  67. package/dist/index.js +260 -75
  68. package/dist/index.js.map +1 -1
  69. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  70. package/dist/plugins/client-reference-dedup.js +138 -16
  71. package/dist/plugins/client-reference-dedup.js.map +1 -1
  72. package/dist/plugins/css-data-url.d.ts +7 -0
  73. package/dist/plugins/css-data-url.js +81 -0
  74. package/dist/plugins/css-data-url.js.map +1 -0
  75. package/dist/plugins/fonts.d.ts +2 -2
  76. package/dist/plugins/fonts.js +20 -9
  77. package/dist/plugins/fonts.js.map +1 -1
  78. package/dist/plugins/middleware-server-only.d.ts +54 -0
  79. package/dist/plugins/middleware-server-only.js +91 -0
  80. package/dist/plugins/middleware-server-only.js.map +1 -0
  81. package/dist/plugins/optimize-imports.js +4 -4
  82. package/dist/plugins/optimize-imports.js.map +1 -1
  83. package/dist/plugins/sass.d.ts +34 -0
  84. package/dist/plugins/sass.js +22 -0
  85. package/dist/plugins/sass.js.map +1 -0
  86. package/dist/plugins/strip-server-exports.js +5 -8
  87. package/dist/plugins/strip-server-exports.js.map +1 -1
  88. package/dist/routing/app-route-graph.d.ts +50 -2
  89. package/dist/routing/app-route-graph.js +140 -16
  90. package/dist/routing/app-route-graph.js.map +1 -1
  91. package/dist/routing/app-router.d.ts +2 -2
  92. package/dist/routing/app-router.js +2 -2
  93. package/dist/routing/app-router.js.map +1 -1
  94. package/dist/routing/route-pattern.d.ts +56 -1
  95. package/dist/routing/route-pattern.js +60 -1
  96. package/dist/routing/route-pattern.js.map +1 -1
  97. package/dist/routing/utils.d.ts +2 -1
  98. package/dist/routing/utils.js +4 -1
  99. package/dist/routing/utils.js.map +1 -1
  100. package/dist/server/api-handler.js +139 -37
  101. package/dist/server/api-handler.js.map +1 -1
  102. package/dist/server/app-browser-action-result.d.ts +27 -2
  103. package/dist/server/app-browser-action-result.js +63 -2
  104. package/dist/server/app-browser-action-result.js.map +1 -1
  105. package/dist/server/app-browser-entry.js +493 -195
  106. package/dist/server/app-browser-entry.js.map +1 -1
  107. package/dist/server/app-browser-hydration.d.ts +13 -1
  108. package/dist/server/app-browser-hydration.js +9 -1
  109. package/dist/server/app-browser-hydration.js.map +1 -1
  110. package/dist/server/app-browser-interception-context.d.ts +24 -0
  111. package/dist/server/app-browser-interception-context.js +32 -0
  112. package/dist/server/app-browser-interception-context.js.map +1 -0
  113. package/dist/server/app-browser-navigation-controller.d.ts +17 -2
  114. package/dist/server/app-browser-navigation-controller.js +33 -10
  115. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  116. package/dist/server/app-browser-popstate.d.ts +16 -0
  117. package/dist/server/app-browser-popstate.js +17 -0
  118. package/dist/server/app-browser-popstate.js.map +1 -0
  119. package/dist/server/app-browser-rsc-redirect.d.ts +29 -0
  120. package/dist/server/app-browser-rsc-redirect.js +37 -0
  121. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  122. package/dist/server/app-browser-state.d.ts +28 -7
  123. package/dist/server/app-browser-state.js +63 -27
  124. package/dist/server/app-browser-state.js.map +1 -1
  125. package/dist/server/app-browser-stream.d.ts +9 -17
  126. package/dist/server/app-browser-stream.js +18 -13
  127. package/dist/server/app-browser-stream.js.map +1 -1
  128. package/dist/server/app-browser-visible-commit.d.ts +7 -1
  129. package/dist/server/app-browser-visible-commit.js +39 -5
  130. package/dist/server/app-browser-visible-commit.js.map +1 -1
  131. package/dist/server/app-elements-wire.d.ts +43 -6
  132. package/dist/server/app-elements-wire.js +189 -7
  133. package/dist/server/app-elements-wire.js.map +1 -1
  134. package/dist/server/app-elements.d.ts +3 -2
  135. package/dist/server/app-elements.js +3 -2
  136. package/dist/server/app-elements.js.map +1 -1
  137. package/dist/server/app-fallback-renderer.d.ts +10 -1
  138. package/dist/server/app-fallback-renderer.js +41 -3
  139. package/dist/server/app-fallback-renderer.js.map +1 -1
  140. package/dist/server/app-history-state.d.ts +26 -0
  141. package/dist/server/app-history-state.js +53 -0
  142. package/dist/server/app-history-state.js.map +1 -0
  143. package/dist/server/app-middleware.d.ts +13 -0
  144. package/dist/server/app-middleware.js +3 -1
  145. package/dist/server/app-middleware.js.map +1 -1
  146. package/dist/server/app-optimistic-routing.d.ts +54 -0
  147. package/dist/server/app-optimistic-routing.js +200 -0
  148. package/dist/server/app-optimistic-routing.js.map +1 -0
  149. package/dist/server/app-page-boundary-render.d.ts +10 -1
  150. package/dist/server/app-page-boundary-render.js +13 -6
  151. package/dist/server/app-page-boundary-render.js.map +1 -1
  152. package/dist/server/app-page-boundary.js +3 -2
  153. package/dist/server/app-page-boundary.js.map +1 -1
  154. package/dist/server/app-page-cache.d.ts +26 -1
  155. package/dist/server/app-page-cache.js +86 -14
  156. package/dist/server/app-page-cache.js.map +1 -1
  157. package/dist/server/app-page-dispatch.d.ts +7 -0
  158. package/dist/server/app-page-dispatch.js +96 -12
  159. package/dist/server/app-page-dispatch.js.map +1 -1
  160. package/dist/server/app-page-element-builder.d.ts +7 -0
  161. package/dist/server/app-page-element-builder.js +34 -5
  162. package/dist/server/app-page-element-builder.js.map +1 -1
  163. package/dist/server/app-page-execution.d.ts +28 -1
  164. package/dist/server/app-page-execution.js +91 -7
  165. package/dist/server/app-page-execution.js.map +1 -1
  166. package/dist/server/app-page-head.d.ts +7 -0
  167. package/dist/server/app-page-head.js +23 -3
  168. package/dist/server/app-page-head.js.map +1 -1
  169. package/dist/server/app-page-probe.d.ts +23 -1
  170. package/dist/server/app-page-probe.js +29 -1
  171. package/dist/server/app-page-probe.js.map +1 -1
  172. package/dist/server/app-page-render-observation.d.ts +35 -0
  173. package/dist/server/app-page-render-observation.js +68 -0
  174. package/dist/server/app-page-render-observation.js.map +1 -0
  175. package/dist/server/app-page-render.d.ts +7 -1
  176. package/dist/server/app-page-render.js +81 -4
  177. package/dist/server/app-page-render.js.map +1 -1
  178. package/dist/server/app-page-request.d.ts +1 -0
  179. package/dist/server/app-page-request.js.map +1 -1
  180. package/dist/server/app-page-response.js +7 -5
  181. package/dist/server/app-page-response.js.map +1 -1
  182. package/dist/server/app-page-route-wiring.d.ts +3 -1
  183. package/dist/server/app-page-route-wiring.js +59 -24
  184. package/dist/server/app-page-route-wiring.js.map +1 -1
  185. package/dist/server/app-page-stream.d.ts +5 -0
  186. package/dist/server/app-page-stream.js +2 -0
  187. package/dist/server/app-page-stream.js.map +1 -1
  188. package/dist/server/app-prerender-static-params.d.ts +2 -1
  189. package/dist/server/app-prerender-static-params.js +44 -8
  190. package/dist/server/app-prerender-static-params.js.map +1 -1
  191. package/dist/server/app-route-handler-cache.d.ts +2 -2
  192. package/dist/server/app-route-handler-cache.js +3 -2
  193. package/dist/server/app-route-handler-cache.js.map +1 -1
  194. package/dist/server/app-route-handler-dispatch.d.ts +6 -1
  195. package/dist/server/app-route-handler-dispatch.js +1 -1
  196. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  197. package/dist/server/app-route-handler-execution.d.ts +17 -2
  198. package/dist/server/app-route-handler-execution.js.map +1 -1
  199. package/dist/server/app-route-handler-response.js +5 -4
  200. package/dist/server/app-route-handler-response.js.map +1 -1
  201. package/dist/server/app-router-entry.js +7 -15
  202. package/dist/server/app-router-entry.js.map +1 -1
  203. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  204. package/dist/server/app-rsc-cache-busting.js +36 -1
  205. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  206. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  207. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  208. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  209. package/dist/server/app-rsc-errors.d.ts +4 -1
  210. package/dist/server/app-rsc-errors.js +1 -1
  211. package/dist/server/app-rsc-errors.js.map +1 -1
  212. package/dist/server/app-rsc-handler.d.ts +21 -5
  213. package/dist/server/app-rsc-handler.js +38 -15
  214. package/dist/server/app-rsc-handler.js.map +1 -1
  215. package/dist/server/app-rsc-render-mode.d.ts +4 -3
  216. package/dist/server/app-rsc-render-mode.js +7 -1
  217. package/dist/server/app-rsc-render-mode.js.map +1 -1
  218. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  219. package/dist/server/app-rsc-request-normalization.js +4 -1
  220. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  221. package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
  222. package/dist/server/app-rsc-response-finalizer.js +10 -3
  223. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  224. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  225. package/dist/server/app-rsc-route-matching.js +47 -25
  226. package/dist/server/app-rsc-route-matching.js.map +1 -1
  227. package/dist/server/app-server-action-execution.d.ts +35 -3
  228. package/dist/server/app-server-action-execution.js +87 -33
  229. package/dist/server/app-server-action-execution.js.map +1 -1
  230. package/dist/server/app-ssr-entry.d.ts +3 -0
  231. package/dist/server/app-ssr-entry.js +83 -58
  232. package/dist/server/app-ssr-entry.js.map +1 -1
  233. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  234. package/dist/server/app-ssr-error-meta.js +50 -0
  235. package/dist/server/app-ssr-error-meta.js.map +1 -0
  236. package/dist/server/app-ssr-stream.d.ts +7 -2
  237. package/dist/server/app-ssr-stream.js +26 -15
  238. package/dist/server/app-ssr-stream.js.map +1 -1
  239. package/dist/server/artifact-compatibility.d.ts +13 -3
  240. package/dist/server/artifact-compatibility.js +12 -8
  241. package/dist/server/artifact-compatibility.js.map +1 -1
  242. package/dist/server/cache-headers.d.ts +7 -0
  243. package/dist/server/cache-headers.js +19 -0
  244. package/dist/server/cache-headers.js.map +1 -0
  245. package/dist/server/cache-proof.d.ts +170 -5
  246. package/dist/server/cache-proof.js +472 -18
  247. package/dist/server/cache-proof.js.map +1 -1
  248. package/dist/server/client-reuse-manifest.d.ts +99 -0
  249. package/dist/server/client-reuse-manifest.js +212 -0
  250. package/dist/server/client-reuse-manifest.js.map +1 -0
  251. package/dist/server/default-global-error-module.d.ts +20 -0
  252. package/dist/server/default-global-error-module.js +20 -0
  253. package/dist/server/default-global-error-module.js.map +1 -0
  254. package/dist/server/dev-lockfile.d.ts +110 -0
  255. package/dist/server/dev-lockfile.js +180 -0
  256. package/dist/server/dev-lockfile.js.map +1 -0
  257. package/dist/server/dev-server.d.ts +9 -1
  258. package/dist/server/dev-server.js +76 -19
  259. package/dist/server/dev-server.js.map +1 -1
  260. package/dist/server/edge-api-runtime.d.ts +5 -0
  261. package/dist/server/edge-api-runtime.js +8 -0
  262. package/dist/server/edge-api-runtime.js.map +1 -0
  263. package/dist/server/file-based-metadata.d.ts +13 -0
  264. package/dist/server/file-based-metadata.js +49 -2
  265. package/dist/server/file-based-metadata.js.map +1 -1
  266. package/dist/server/headers.d.ts +20 -1
  267. package/dist/server/headers.js +22 -2
  268. package/dist/server/headers.js.map +1 -1
  269. package/dist/server/html.js +1 -1
  270. package/dist/server/html.js.map +1 -1
  271. package/dist/server/http-error-responses.d.ts +26 -1
  272. package/dist/server/http-error-responses.js +32 -2
  273. package/dist/server/http-error-responses.js.map +1 -1
  274. package/dist/server/isr-cache.d.ts +8 -3
  275. package/dist/server/isr-cache.js +24 -6
  276. package/dist/server/isr-cache.js.map +1 -1
  277. package/dist/server/metadata-route-response.js +22 -5
  278. package/dist/server/metadata-route-response.js.map +1 -1
  279. package/dist/server/metadata-routes.js +27 -8
  280. package/dist/server/metadata-routes.js.map +1 -1
  281. package/dist/server/middleware-runtime.d.ts +15 -0
  282. package/dist/server/middleware-runtime.js +60 -7
  283. package/dist/server/middleware-runtime.js.map +1 -1
  284. package/dist/server/middleware.d.ts +13 -1
  285. package/dist/server/middleware.js +16 -2
  286. package/dist/server/middleware.js.map +1 -1
  287. package/dist/server/navigation-planner.d.ts +26 -6
  288. package/dist/server/navigation-planner.js +358 -24
  289. package/dist/server/navigation-planner.js.map +1 -1
  290. package/dist/server/navigation-trace.d.ts +9 -1
  291. package/dist/server/navigation-trace.js +8 -0
  292. package/dist/server/navigation-trace.js.map +1 -1
  293. package/dist/server/normalize-path.d.ts +2 -1
  294. package/dist/server/normalize-path.js +4 -1
  295. package/dist/server/normalize-path.js.map +1 -1
  296. package/dist/server/pages-api-route.d.ts +27 -1
  297. package/dist/server/pages-api-route.js +25 -3
  298. package/dist/server/pages-api-route.js.map +1 -1
  299. package/dist/server/pages-data-route.d.ts +77 -0
  300. package/dist/server/pages-data-route.js +97 -0
  301. package/dist/server/pages-data-route.js.map +1 -0
  302. package/dist/server/pages-i18n.d.ts +51 -1
  303. package/dist/server/pages-i18n.js +61 -1
  304. package/dist/server/pages-i18n.js.map +1 -1
  305. package/dist/server/pages-page-data.d.ts +32 -4
  306. package/dist/server/pages-page-data.js +52 -19
  307. package/dist/server/pages-page-data.js.map +1 -1
  308. package/dist/server/pages-page-response.d.ts +11 -1
  309. package/dist/server/pages-page-response.js +6 -4
  310. package/dist/server/pages-page-response.js.map +1 -1
  311. package/dist/server/prod-server.d.ts +26 -1
  312. package/dist/server/prod-server.js +150 -44
  313. package/dist/server/prod-server.js.map +1 -1
  314. package/dist/server/request-pipeline.d.ts +11 -2
  315. package/dist/server/request-pipeline.js +28 -11
  316. package/dist/server/request-pipeline.js.map +1 -1
  317. package/dist/server/seed-cache.d.ts +12 -31
  318. package/dist/server/seed-cache.js +22 -35
  319. package/dist/server/seed-cache.js.map +1 -1
  320. package/dist/server/server-action-not-found.d.ts +16 -3
  321. package/dist/server/server-action-not-found.js +27 -4
  322. package/dist/server/server-action-not-found.js.map +1 -1
  323. package/dist/server/server-globals.d.ts +5 -0
  324. package/dist/server/server-globals.js +37 -0
  325. package/dist/server/server-globals.js.map +1 -0
  326. package/dist/server/skip-cache-proof.d.ts +41 -0
  327. package/dist/server/skip-cache-proof.js +101 -0
  328. package/dist/server/skip-cache-proof.js.map +1 -0
  329. package/dist/server/static-file-cache.d.ts +1 -1
  330. package/dist/server/static-file-cache.js +7 -6
  331. package/dist/server/static-file-cache.js.map +1 -1
  332. package/dist/shims/cache-runtime.d.ts +19 -2
  333. package/dist/shims/cache-runtime.js +67 -11
  334. package/dist/shims/cache-runtime.js.map +1 -1
  335. package/dist/shims/cache.d.ts +5 -18
  336. package/dist/shims/cache.js +2 -0
  337. package/dist/shims/cache.js.map +1 -1
  338. package/dist/shims/client-locale.d.ts +15 -0
  339. package/dist/shims/client-locale.js +13 -0
  340. package/dist/shims/client-locale.js.map +1 -0
  341. package/dist/shims/default-global-error.d.ts +32 -0
  342. package/dist/shims/default-global-error.js +181 -0
  343. package/dist/shims/default-global-error.js.map +1 -0
  344. package/dist/shims/document.d.ts +59 -3
  345. package/dist/shims/document.js +36 -5
  346. package/dist/shims/document.js.map +1 -1
  347. package/dist/shims/error-boundary.d.ts +2 -2
  348. package/dist/shims/error-boundary.js +6 -8
  349. package/dist/shims/error-boundary.js.map +1 -1
  350. package/dist/shims/error.d.ts +18 -1
  351. package/dist/shims/error.js +56 -1
  352. package/dist/shims/error.js.map +1 -1
  353. package/dist/shims/fetch-cache.d.ts +4 -1
  354. package/dist/shims/fetch-cache.js +40 -5
  355. package/dist/shims/fetch-cache.js.map +1 -1
  356. package/dist/shims/font-google-base.d.ts +22 -8
  357. package/dist/shims/font-google-base.js +41 -71
  358. package/dist/shims/font-google-base.js.map +1 -1
  359. package/dist/shims/font-local.d.ts +3 -20
  360. package/dist/shims/font-local.js +23 -75
  361. package/dist/shims/font-local.js.map +1 -1
  362. package/dist/shims/font-utils.d.ts +51 -0
  363. package/dist/shims/font-utils.js +97 -0
  364. package/dist/shims/font-utils.js.map +1 -0
  365. package/dist/shims/form.js +13 -6
  366. package/dist/shims/form.js.map +1 -1
  367. package/dist/shims/hash-scroll.d.ts +7 -0
  368. package/dist/shims/hash-scroll.js +30 -0
  369. package/dist/shims/hash-scroll.js.map +1 -0
  370. package/dist/shims/headers.d.ts +8 -11
  371. package/dist/shims/headers.js +22 -2
  372. package/dist/shims/headers.js.map +1 -1
  373. package/dist/shims/image.d.ts +1 -0
  374. package/dist/shims/image.js +144 -78
  375. package/dist/shims/image.js.map +1 -1
  376. package/dist/shims/internal/app-router-context.d.ts +6 -6
  377. package/dist/shims/internal/app-router-context.js +17 -6
  378. package/dist/shims/internal/app-router-context.js.map +1 -1
  379. package/dist/shims/link-prefetch.d.ts +9 -1
  380. package/dist/shims/link-prefetch.js +11 -6
  381. package/dist/shims/link-prefetch.js.map +1 -1
  382. package/dist/shims/link.d.ts +33 -5
  383. package/dist/shims/link.js +205 -50
  384. package/dist/shims/link.js.map +1 -1
  385. package/dist/shims/metadata.d.ts +16 -30
  386. package/dist/shims/metadata.js +91 -32
  387. package/dist/shims/metadata.js.map +1 -1
  388. package/dist/shims/navigation.d.ts +164 -17
  389. package/dist/shims/navigation.js +355 -84
  390. package/dist/shims/navigation.js.map +1 -1
  391. package/dist/shims/navigation.react-server.d.ts +3 -2
  392. package/dist/shims/navigation.react-server.js +5 -2
  393. package/dist/shims/navigation.react-server.js.map +1 -1
  394. package/dist/shims/og.d.ts +18 -2
  395. package/dist/shims/og.js +49 -1
  396. package/dist/shims/og.js.map +1 -0
  397. package/dist/shims/pages-router-runtime.d.ts +7 -0
  398. package/dist/shims/pages-router-runtime.js +16 -0
  399. package/dist/shims/pages-router-runtime.js.map +1 -0
  400. package/dist/shims/request-state-types.d.ts +1 -1
  401. package/dist/shims/root-params.d.ts +3 -1
  402. package/dist/shims/root-params.js +11 -3
  403. package/dist/shims/root-params.js.map +1 -1
  404. package/dist/shims/router-state.d.ts +1 -0
  405. package/dist/shims/router-state.js.map +1 -1
  406. package/dist/shims/router.d.ts +40 -7
  407. package/dist/shims/router.js +355 -250
  408. package/dist/shims/router.js.map +1 -1
  409. package/dist/shims/script.js +110 -32
  410. package/dist/shims/script.js.map +1 -1
  411. package/dist/shims/server.d.ts +21 -4
  412. package/dist/shims/server.js +31 -10
  413. package/dist/shims/server.js.map +1 -1
  414. package/dist/shims/slot.d.ts +1 -0
  415. package/dist/shims/slot.js +45 -1
  416. package/dist/shims/slot.js.map +1 -1
  417. package/dist/shims/unified-request-context.d.ts +1 -1
  418. package/dist/shims/unified-request-context.js +2 -0
  419. package/dist/shims/unified-request-context.js.map +1 -1
  420. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  421. package/dist/shims/unrecognized-action-error.js +41 -0
  422. package/dist/shims/unrecognized-action-error.js.map +1 -0
  423. package/dist/shims/url-safety.d.ts +23 -1
  424. package/dist/shims/url-safety.js +29 -2
  425. package/dist/shims/url-safety.js.map +1 -1
  426. package/dist/shims/url-utils.d.ts +21 -1
  427. package/dist/shims/url-utils.js +67 -3
  428. package/dist/shims/url-utils.js.map +1 -1
  429. package/dist/typegen.d.ts +10 -0
  430. package/dist/typegen.js +242 -0
  431. package/dist/typegen.js.map +1 -0
  432. package/dist/utils/asset-prefix.d.ts +97 -0
  433. package/dist/utils/asset-prefix.js +124 -0
  434. package/dist/utils/asset-prefix.js.map +1 -0
  435. package/dist/utils/base-path.d.ts +7 -1
  436. package/dist/utils/base-path.js +10 -1
  437. package/dist/utils/base-path.js.map +1 -1
  438. package/dist/utils/cache-control-metadata.d.ts +2 -1
  439. package/dist/utils/cache-control-metadata.js +1 -3
  440. package/dist/utils/cache-control-metadata.js.map +1 -1
  441. package/dist/utils/domain-locale.d.ts +2 -1
  442. package/dist/utils/domain-locale.js +9 -1
  443. package/dist/utils/domain-locale.js.map +1 -1
  444. package/dist/utils/lazy-chunks.d.ts +1 -1
  445. package/dist/utils/lazy-chunks.js +1 -1
  446. package/dist/utils/lazy-chunks.js.map +1 -1
  447. package/dist/utils/navigation-signal.d.ts +1 -2
  448. package/dist/utils/navigation-signal.js +1 -1
  449. package/dist/utils/navigation-signal.js.map +1 -1
  450. package/dist/utils/prerender-output-paths.d.ts +15 -0
  451. package/dist/utils/prerender-output-paths.js +24 -0
  452. package/dist/utils/prerender-output-paths.js.map +1 -0
  453. package/dist/utils/query.d.ts +17 -1
  454. package/dist/utils/query.js +36 -1
  455. package/dist/utils/query.js.map +1 -1
  456. package/dist/utils/record.d.ts +5 -0
  457. package/dist/utils/record.js +8 -0
  458. package/dist/utils/record.js.map +1 -0
  459. package/dist/utils/sorted-array.d.ts +9 -0
  460. package/dist/utils/sorted-array.js +22 -0
  461. package/dist/utils/sorted-array.js.map +1 -0
  462. package/package.json +13 -5
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-cache.js","names":[],"sources":["../../src/server/app-route-handler-cache.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport type { HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport type { RouteHandlerMiddlewareContext } from \"./app-route-handler-response.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n buildRouteHandlerCachedResponse,\n} from \"./app-route-handler-response.js\";\nimport { markKnownDynamicAppRoute } from \"./app-route-handler-runtime.js\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport {\n runAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteDynamicUsageFn,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type MarkAppRouteDynamicUsageFn,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerator = (key: string, renderFn: () => Promise<void>) => void;\ntype RouteHandlerRevalidationContextRunner = (renderFn: () => Promise<void>) => Promise<void>;\n\ntype ReadAppRouteHandlerCacheOptions = {\n basePath?: string;\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n cleanPathname: string;\n clearRequestContext: () => void;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n getCollectedFetchTags: () => string[];\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n isAutoHead: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareContext: RouteHandlerMiddlewareContext;\n params: AppRouteParams;\n requestUrl: string;\n revalidateSearchParams: URLSearchParams;\n expireSeconds?: number;\n revalidateSeconds: number;\n routePattern: string;\n runInRevalidationContext: RouteHandlerRevalidationContextRunner;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n setNavigationContext: (\n context: {\n pathname: string;\n searchParams: URLSearchParams;\n params: AppRouteParams;\n } | null,\n ) => void;\n};\n\nfunction getCachedAppRouteValue(entry: ISRCacheEntry | null) {\n return entry?.value.value && entry.value.value.kind === \"APP_ROUTE\" ? entry.value.value : null;\n}\n\nexport async function readAppRouteHandlerCacheResponse(\n options: ReadAppRouteHandlerCacheOptions,\n): Promise<Response | null> {\n const routeKey = options.isrRouteKey(options.cleanPathname);\n\n try {\n const cached = await options.isrGet(routeKey);\n const cachedValue = getCachedAppRouteValue(cached);\n\n if (cachedValue && !cached?.isStale) {\n options.isrDebug?.(\"HIT (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(cachedValue, {\n cacheState: \"HIT\",\n cacheControl: cached?.value.cacheControl,\n expireSeconds: options.expireSeconds,\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n\n if (cached?.isStale && cachedValue) {\n const staleValue = cachedValue;\n const revalidateSearchParams = new URLSearchParams(options.revalidateSearchParams);\n\n options.scheduleBackgroundRegeneration(routeKey, async () => {\n await options.runInRevalidationContext(async () => {\n options.setNavigationContext({\n pathname: options.cleanPathname,\n searchParams: revalidateSearchParams,\n params: options.params,\n });\n\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n basePath: options.basePath,\n consumeDynamicUsage: options.consumeDynamicUsage,\n dynamicConfig: options.dynamicConfig,\n handlerFn: options.handlerFn,\n i18n: options.i18n,\n markDynamicUsage: options.markDynamicUsage,\n params: makeThenableParams(options.params),\n request: new Request(options.requestUrl, { method: \"GET\" }),\n routePattern: options.routePattern,\n setHeadersAccessPhase: options.setHeadersAccessPhase,\n });\n\n options.setNavigationContext(null);\n assertSupportedAppRouteHandlerResponse(response);\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n options.isrDebug?.(\"route regen skipped (dynamic usage)\", options.cleanPathname);\n return;\n }\n\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeCacheValue = await buildAppRouteCacheValue(response);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n options.revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route regen complete\", routeKey);\n });\n });\n\n options.isrDebug?.(\"STALE (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(staleValue, {\n cacheState: \"STALE\",\n cacheControl: cached.value.cacheControl,\n expireSeconds: options.expireSeconds,\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n } catch (routeCacheError) {\n console.error(\"[vinext] ISR route cache read error:\", routeCacheError);\n }\n\n return null;\n}\n"],"mappings":";;;;;AA6DA,SAAS,uBAAuB,OAA6B;CAC3D,OAAO,OAAO,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,cAAc,MAAM,MAAM,QAAQ;;AAG5F,eAAsB,iCACpB,SAC0B;CAC1B,MAAM,WAAW,QAAQ,YAAY,QAAQ,cAAc;CAE3D,IAAI;EACF,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;EAC7C,MAAM,cAAc,uBAAuB,OAAO;EAElD,IAAI,eAAe,CAAC,QAAQ,SAAS;GACnC,QAAQ,WAAW,eAAe,QAAQ,cAAc;GACxD,QAAQ,qBAAqB;GAC7B,OAAO,mCACL,gCAAgC,aAAa;IAC3C,YAAY;IACZ,cAAc,QAAQ,MAAM;IAC5B,eAAe,QAAQ;IACvB,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;EAGH,IAAI,QAAQ,WAAW,aAAa;GAClC,MAAM,aAAa;GACnB,MAAM,yBAAyB,IAAI,gBAAgB,QAAQ,uBAAuB;GAElF,QAAQ,+BAA+B,UAAU,YAAY;IAC3D,MAAM,QAAQ,yBAAyB,YAAY;KACjD,QAAQ,qBAAqB;MAC3B,UAAU,QAAQ;MAClB,cAAc;MACd,QAAQ,QAAQ;MACjB,CAAC;KAEF,MAAM,EAAE,sBAAsB,aAAa,MAAM,mBAAmB;MAClE,UAAU,QAAQ;MAClB,qBAAqB,QAAQ;MAC7B,eAAe,QAAQ;MACvB,WAAW,QAAQ;MACnB,MAAM,QAAQ;MACd,kBAAkB,QAAQ;MAC1B,QAAQ,mBAAmB,QAAQ,OAAO;MAC1C,SAAS,IAAI,QAAQ,QAAQ,YAAY,EAAE,QAAQ,OAAO,CAAC;MAC3D,cAAc,QAAQ;MACtB,uBAAuB,QAAQ;MAChC,CAAC;KAEF,QAAQ,qBAAqB,KAAK;KAClC,uCAAuC,SAAS;KAEhD,IAAI,sBAAsB;MACxB,yBAAyB,QAAQ,aAAa;MAC9C,QAAQ,WAAW,uCAAuC,QAAQ,cAAc;MAChF;;KAGF,MAAM,YAAY,QAAQ,mBACxB,QAAQ,eACR,QAAQ,uBAAuB,CAChC;KACD,MAAM,kBAAkB,MAAM,wBAAwB,SAAS;KAC/D,MAAM,QAAQ,OACZ,UACA,iBACA,QAAQ,mBACR,WACA,QAAQ,cACT;KACD,QAAQ,WAAW,wBAAwB,SAAS;MACpD;KACF;GAEF,QAAQ,WAAW,iBAAiB,QAAQ,cAAc;GAC1D,QAAQ,qBAAqB;GAC7B,OAAO,mCACL,gCAAgC,YAAY;IAC1C,YAAY;IACZ,cAAc,OAAO,MAAM;IAC3B,eAAe,QAAQ;IACvB,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;UAEI,iBAAiB;EACxB,QAAQ,MAAM,wCAAwC,gBAAgB;;CAGxE,OAAO"}
1
+ {"version":3,"file":"app-route-handler-cache.js","names":[],"sources":["../../src/server/app-route-handler-cache.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport type { HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport type { RouteHandlerMiddlewareContext } from \"./app-route-handler-response.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n buildRouteHandlerCachedResponse,\n} from \"./app-route-handler-response.js\";\nimport { markKnownDynamicAppRoute } from \"./app-route-handler-runtime.js\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport {\n runAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteDynamicUsageFn,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type MarkAppRouteDynamicUsageFn,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerator = (key: string, renderFn: () => Promise<void>) => void;\ntype RouteHandlerRevalidationContextRunner = (renderFn: () => Promise<void>) => Promise<void>;\n\ntype ReadAppRouteHandlerCacheOptions = {\n basePath?: string;\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n cleanPathname: string;\n clearRequestContext: () => void;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n getCollectedFetchTags: () => string[];\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n isAutoHead: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareContext: RouteHandlerMiddlewareContext;\n /** `null` for non-dynamic routes. See `AppRouteHandlerFunction` for details. */\n params: AppRouteParams | null;\n requestUrl: string;\n revalidateSearchParams: URLSearchParams;\n expireSeconds?: number;\n revalidateSeconds: number;\n routePattern: string;\n runInRevalidationContext: RouteHandlerRevalidationContextRunner;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n setNavigationContext: (\n context: {\n pathname: string;\n searchParams: URLSearchParams;\n params: AppRouteParams;\n } | null,\n ) => void;\n};\n\n// Navigation context expects a plain object (used for `useParams()` etc),\n// not `null`. For non-dynamic routes there are no params to expose, so we\n// pass an empty object — only the user-visible handler context surfaces\n// `null` for non-dynamic routes.\nconst EMPTY_PARAMS: AppRouteParams = Object.freeze({}) as AppRouteParams;\n\nfunction getCachedAppRouteValue(entry: ISRCacheEntry | null) {\n return entry?.value.value && entry.value.value.kind === \"APP_ROUTE\" ? entry.value.value : null;\n}\n\nexport async function readAppRouteHandlerCacheResponse(\n options: ReadAppRouteHandlerCacheOptions,\n): Promise<Response | null> {\n const routeKey = options.isrRouteKey(options.cleanPathname);\n\n try {\n const cached = await options.isrGet(routeKey);\n const cachedValue = getCachedAppRouteValue(cached);\n\n if (cachedValue && !cached?.isStale) {\n options.isrDebug?.(\"HIT (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(cachedValue, {\n cacheState: \"HIT\",\n cacheControl: cached?.value.cacheControl,\n expireSeconds: options.expireSeconds,\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n\n if (cached?.isStale && cachedValue) {\n const staleValue = cachedValue;\n const revalidateSearchParams = new URLSearchParams(options.revalidateSearchParams);\n\n options.scheduleBackgroundRegeneration(routeKey, async () => {\n await options.runInRevalidationContext(async () => {\n options.setNavigationContext({\n pathname: options.cleanPathname,\n searchParams: revalidateSearchParams,\n params: options.params ?? EMPTY_PARAMS,\n });\n\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n basePath: options.basePath,\n consumeDynamicUsage: options.consumeDynamicUsage,\n dynamicConfig: options.dynamicConfig,\n handlerFn: options.handlerFn,\n i18n: options.i18n,\n markDynamicUsage: options.markDynamicUsage,\n params: options.params === null ? null : makeThenableParams(options.params),\n request: new Request(options.requestUrl, { method: \"GET\" }),\n routePattern: options.routePattern,\n setHeadersAccessPhase: options.setHeadersAccessPhase,\n });\n\n options.setNavigationContext(null);\n assertSupportedAppRouteHandlerResponse(response);\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n options.isrDebug?.(\"route regen skipped (dynamic usage)\", options.cleanPathname);\n return;\n }\n\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeCacheValue = await buildAppRouteCacheValue(response);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n options.revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route regen complete\", routeKey);\n });\n });\n\n options.isrDebug?.(\"STALE (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(staleValue, {\n cacheState: \"STALE\",\n cacheControl: cached.value.cacheControl,\n expireSeconds: options.expireSeconds,\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n } catch (routeCacheError) {\n console.error(\"[vinext] ISR route cache read error:\", routeCacheError);\n }\n\n return null;\n}\n"],"mappings":";;;;;AAkEA,MAAM,eAA+B,OAAO,OAAO,EAAE,CAAC;AAEtD,SAAS,uBAAuB,OAA6B;CAC3D,OAAO,OAAO,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,cAAc,MAAM,MAAM,QAAQ;;AAG5F,eAAsB,iCACpB,SAC0B;CAC1B,MAAM,WAAW,QAAQ,YAAY,QAAQ,cAAc;CAE3D,IAAI;EACF,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;EAC7C,MAAM,cAAc,uBAAuB,OAAO;EAElD,IAAI,eAAe,CAAC,QAAQ,SAAS;GACnC,QAAQ,WAAW,eAAe,QAAQ,cAAc;GACxD,QAAQ,qBAAqB;GAC7B,OAAO,mCACL,gCAAgC,aAAa;IAC3C,YAAY;IACZ,cAAc,QAAQ,MAAM;IAC5B,eAAe,QAAQ;IACvB,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;EAGH,IAAI,QAAQ,WAAW,aAAa;GAClC,MAAM,aAAa;GACnB,MAAM,yBAAyB,IAAI,gBAAgB,QAAQ,uBAAuB;GAElF,QAAQ,+BAA+B,UAAU,YAAY;IAC3D,MAAM,QAAQ,yBAAyB,YAAY;KACjD,QAAQ,qBAAqB;MAC3B,UAAU,QAAQ;MAClB,cAAc;MACd,QAAQ,QAAQ,UAAU;MAC3B,CAAC;KAEF,MAAM,EAAE,sBAAsB,aAAa,MAAM,mBAAmB;MAClE,UAAU,QAAQ;MAClB,qBAAqB,QAAQ;MAC7B,eAAe,QAAQ;MACvB,WAAW,QAAQ;MACnB,MAAM,QAAQ;MACd,kBAAkB,QAAQ;MAC1B,QAAQ,QAAQ,WAAW,OAAO,OAAO,mBAAmB,QAAQ,OAAO;MAC3E,SAAS,IAAI,QAAQ,QAAQ,YAAY,EAAE,QAAQ,OAAO,CAAC;MAC3D,cAAc,QAAQ;MACtB,uBAAuB,QAAQ;MAChC,CAAC;KAEF,QAAQ,qBAAqB,KAAK;KAClC,uCAAuC,SAAS;KAEhD,IAAI,sBAAsB;MACxB,yBAAyB,QAAQ,aAAa;MAC9C,QAAQ,WAAW,uCAAuC,QAAQ,cAAc;MAChF;;KAGF,MAAM,YAAY,QAAQ,mBACxB,QAAQ,eACR,QAAQ,uBAAuB,CAChC;KACD,MAAM,kBAAkB,MAAM,wBAAwB,SAAS;KAC/D,MAAM,QAAQ,OACZ,UACA,iBACA,QAAQ,mBACR,WACA,QAAQ,cACT;KACD,QAAQ,WAAW,wBAAwB,SAAS;MACpD;KACF;GAEF,QAAQ,WAAW,iBAAiB,QAAQ,cAAc;GAC1D,QAAQ,qBAAqB;GAC7B,OAAO,mCACL,gCAAgC,YAAY;IAC1C,YAAY;IACZ,cAAc,OAAO,MAAM;IAC3B,eAAe,QAAQ;IACvB,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;UAEI,iBAAiB;EACxB,QAAQ,MAAM,wCAAwC,gBAAgB;;CAGxE,OAAO"}
@@ -31,7 +31,12 @@ type DispatchAppRouteHandlerOptions = {
31
31
  isrSet: RouteHandlerCacheSetter;
32
32
  middlewareContext: RouteHandlerMiddlewareContext;
33
33
  middlewareRequestHeaders?: Headers | null;
34
- params: AppRouteParams;
34
+ /**
35
+ * `null` for non-dynamic routes, matching Next.js semantics. The dispatch
36
+ * layer threads this through to the handler context unchanged so user code
37
+ * (`params ? await params : null`) resolves to `null`.
38
+ */
39
+ params: AppRouteParams | null;
35
40
  request: Request;
36
41
  route: AppRouteHandlerDispatchRoute;
37
42
  scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;
@@ -133,7 +133,7 @@ async function dispatchAppRouteHandler(options) {
133
133
  method,
134
134
  middlewareContext: options.middlewareContext,
135
135
  middlewareRequestHeaders: options.middlewareRequestHeaders,
136
- params: makeThenableParams(options.params),
136
+ params: options.params === null ? null : makeThenableParams(options.params),
137
137
  reportRequestError(error, request, context) {
138
138
  reportRequestError(error, request, context);
139
139
  },
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-dispatch.js","names":[],"sources":["../../src/server/app-route-handler-dispatch.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport {\n getCollectedFetchTags,\n ensureFetchPatch,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport {\n consumeDynamicUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersAccessPhase,\n} from \"vinext/shims/headers\";\nimport { setNavigationContext } from \"vinext/shims/navigation\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n getAppRouteHandlerRevalidateSeconds,\n hasAppRouteHandlerDefaultExport,\n resolveAppRouteHandlerMethod,\n shouldReadAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport { readAppRouteHandlerCacheResponse } from \"./app-route-handler-cache.js\";\nimport {\n executeAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\nimport { isKnownDynamicAppRoute, isValidHTTPMethod } from \"./app-route-handler-runtime.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { reportRequestError } from \"./instrumentation.js\";\n\ntype AppRouteHandlerDispatchRoute = {\n pattern: string;\n routeHandler: AppRouteHandlerModule;\n routeSegments: string[];\n};\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"route\";\n};\ntype RouteHandlerBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: RouteHandlerBackgroundRegenerationErrorContext,\n) => void;\n\ntype DispatchAppRouteHandlerOptions = {\n basePath?: string;\n cleanPathname: string;\n clearRequestContext: () => void;\n expireSeconds?: number;\n i18n?: NextI18nConfig | null;\n isDevelopment?: boolean;\n isProduction?: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n middlewareContext: RouteHandlerMiddlewareContext;\n middlewareRequestHeaders?: Headers | null;\n params: AppRouteParams;\n request: Request;\n route: AppRouteHandlerDispatchRoute;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n searchParams: URLSearchParams;\n};\n\nfunction isAppRouteHandlerFunction(value: unknown): value is AppRouteHandlerFunction {\n return typeof value === \"function\";\n}\n\nfunction buildRouteHandlerPageCacheTags(\n pathname: string,\n extraTags: string[],\n routeSegments: string[],\n): string[] {\n return buildPageCacheTags(pathname, extraTags, routeSegments, \"route\");\n}\n\nasync function runInRouteHandlerRevalidationContext(\n options: {\n cleanPathname: string;\n dynamicConfig?: string;\n routePattern: string;\n routeSegments: string[];\n },\n renderFn: () => Promise<void>,\n): Promise<void> {\n const headersContext = createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n await runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(\n buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments),\n );\n await renderFn();\n });\n}\n\nexport async function dispatchAppRouteHandler(\n options: DispatchAppRouteHandlerOptions,\n): Promise<Response> {\n const { route } = options;\n const handler = route.routeHandler;\n const method = options.request.method.toUpperCase();\n const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);\n const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === \"development\";\n const isProduction = options.isProduction ?? process.env.NODE_ENV === \"production\";\n\n if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) {\n console.error(\n \"[vinext] Detected default export in route handler \" +\n route.pattern +\n \". Export a named export for each HTTP method instead.\",\n );\n }\n\n // Reject non-standard HTTP methods before any auto-OPTIONS/405 logic.\n // Next.js returns 400 for invalid methods; vinext mirrors that behavior.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/app-route/module.ts#L390-L392\n if (!isValidHTTPMethod(method)) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 400 }),\n options.middlewareContext,\n );\n }\n\n const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } =\n resolveAppRouteHandlerMethod(handler, method);\n\n if (shouldAutoRespondToOptions) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 204,\n headers: { Allow: allowHeaderForOptions },\n }),\n options.middlewareContext,\n );\n }\n\n const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : undefined;\n\n if (\n revalidateSeconds !== null &&\n shouldReadAppRouteHandlerCache({\n dynamicConfig: handler.dynamic,\n handlerFn: resolvedHandlerFn,\n isAutoHead,\n isKnownDynamic: isKnownDynamicAppRoute(route.pattern),\n isProduction,\n method,\n revalidateSeconds,\n }) &&\n resolvedHandlerFn\n ) {\n const cachedRouteResponse = await readAppRouteHandlerCacheResponse({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n dynamicConfig: handler.dynamic,\n getCollectedFetchTags,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n middlewareContext: options.middlewareContext,\n params: options.params,\n requestUrl: options.request.url,\n revalidateSearchParams: options.searchParams,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n runInRevalidationContext(renderFn) {\n return runInRouteHandlerRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n dynamicConfig: handler.dynamic,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n },\n renderFn,\n );\n },\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"route\",\n });\n },\n setHeadersAccessPhase,\n setNavigationContext,\n });\n if (cachedRouteResponse) {\n return cachedRouteResponse;\n }\n }\n\n if (resolvedHandlerFn) {\n return executeAppRouteHandler({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n executionContext: getRequestExecutionContext(),\n getAndClearPendingCookies,\n getCollectedFetchTags,\n getDraftModeCookieHeader,\n handler,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isProduction,\n isrDebug: options.isrDebug,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n method,\n middlewareContext: options.middlewareContext,\n middlewareRequestHeaders: options.middlewareRequestHeaders,\n params: makeThenableParams(options.params),\n reportRequestError(error, request, context) {\n void reportRequestError(error, request, context);\n },\n request: options.request,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n setHeadersAccessPhase,\n });\n }\n\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 405,\n }),\n options.middlewareContext,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-route-handler-dispatch.js","names":[],"sources":["../../src/server/app-route-handler-dispatch.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport {\n getCollectedFetchTags,\n ensureFetchPatch,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport {\n consumeDynamicUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersAccessPhase,\n} from \"vinext/shims/headers\";\nimport { setNavigationContext } from \"vinext/shims/navigation\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n getAppRouteHandlerRevalidateSeconds,\n hasAppRouteHandlerDefaultExport,\n resolveAppRouteHandlerMethod,\n shouldReadAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport { readAppRouteHandlerCacheResponse } from \"./app-route-handler-cache.js\";\nimport {\n executeAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\nimport { isKnownDynamicAppRoute, isValidHTTPMethod } from \"./app-route-handler-runtime.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { reportRequestError } from \"./instrumentation.js\";\n\ntype AppRouteHandlerDispatchRoute = {\n pattern: string;\n routeHandler: AppRouteHandlerModule;\n routeSegments: string[];\n};\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"route\";\n};\ntype RouteHandlerBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: RouteHandlerBackgroundRegenerationErrorContext,\n) => void;\n\ntype DispatchAppRouteHandlerOptions = {\n basePath?: string;\n cleanPathname: string;\n clearRequestContext: () => void;\n expireSeconds?: number;\n i18n?: NextI18nConfig | null;\n isDevelopment?: boolean;\n isProduction?: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n middlewareContext: RouteHandlerMiddlewareContext;\n middlewareRequestHeaders?: Headers | null;\n /**\n * `null` for non-dynamic routes, matching Next.js semantics. The dispatch\n * layer threads this through to the handler context unchanged so user code\n * (`params ? await params : null`) resolves to `null`.\n */\n params: AppRouteParams | null;\n request: Request;\n route: AppRouteHandlerDispatchRoute;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n searchParams: URLSearchParams;\n};\n\nfunction isAppRouteHandlerFunction(value: unknown): value is AppRouteHandlerFunction {\n return typeof value === \"function\";\n}\n\nfunction buildRouteHandlerPageCacheTags(\n pathname: string,\n extraTags: string[],\n routeSegments: string[],\n): string[] {\n return buildPageCacheTags(pathname, extraTags, routeSegments, \"route\");\n}\n\nasync function runInRouteHandlerRevalidationContext(\n options: {\n cleanPathname: string;\n dynamicConfig?: string;\n routePattern: string;\n routeSegments: string[];\n },\n renderFn: () => Promise<void>,\n): Promise<void> {\n const headersContext = createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n await runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(\n buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments),\n );\n await renderFn();\n });\n}\n\nexport async function dispatchAppRouteHandler(\n options: DispatchAppRouteHandlerOptions,\n): Promise<Response> {\n const { route } = options;\n const handler = route.routeHandler;\n const method = options.request.method.toUpperCase();\n const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);\n const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === \"development\";\n const isProduction = options.isProduction ?? process.env.NODE_ENV === \"production\";\n\n if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) {\n console.error(\n \"[vinext] Detected default export in route handler \" +\n route.pattern +\n \". Export a named export for each HTTP method instead.\",\n );\n }\n\n // Reject non-standard HTTP methods before any auto-OPTIONS/405 logic.\n // Next.js returns 400 for invalid methods; vinext mirrors that behavior.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/app-route/module.ts#L390-L392\n if (!isValidHTTPMethod(method)) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 400 }),\n options.middlewareContext,\n );\n }\n\n const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } =\n resolveAppRouteHandlerMethod(handler, method);\n\n if (shouldAutoRespondToOptions) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 204,\n headers: { Allow: allowHeaderForOptions },\n }),\n options.middlewareContext,\n );\n }\n\n const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : undefined;\n\n if (\n revalidateSeconds !== null &&\n shouldReadAppRouteHandlerCache({\n dynamicConfig: handler.dynamic,\n handlerFn: resolvedHandlerFn,\n isAutoHead,\n isKnownDynamic: isKnownDynamicAppRoute(route.pattern),\n isProduction,\n method,\n revalidateSeconds,\n }) &&\n resolvedHandlerFn\n ) {\n const cachedRouteResponse = await readAppRouteHandlerCacheResponse({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n dynamicConfig: handler.dynamic,\n getCollectedFetchTags,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n middlewareContext: options.middlewareContext,\n params: options.params,\n requestUrl: options.request.url,\n revalidateSearchParams: options.searchParams,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n runInRevalidationContext(renderFn) {\n return runInRouteHandlerRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n dynamicConfig: handler.dynamic,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n },\n renderFn,\n );\n },\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"route\",\n });\n },\n setHeadersAccessPhase,\n setNavigationContext,\n });\n if (cachedRouteResponse) {\n return cachedRouteResponse;\n }\n }\n\n if (resolvedHandlerFn) {\n return executeAppRouteHandler({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n executionContext: getRequestExecutionContext(),\n getAndClearPendingCookies,\n getCollectedFetchTags,\n getDraftModeCookieHeader,\n handler,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isProduction,\n isrDebug: options.isrDebug,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n method,\n middlewareContext: options.middlewareContext,\n middlewareRequestHeaders: options.middlewareRequestHeaders,\n params: options.params === null ? null : makeThenableParams(options.params),\n reportRequestError(error, request, context) {\n void reportRequestError(error, request, context);\n },\n request: options.request,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n setHeadersAccessPhase,\n });\n }\n\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 405,\n }),\n options.middlewareContext,\n );\n}\n"],"mappings":"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"}
@@ -10,8 +10,19 @@ import { AppRouteHandlerModule } from "./app-route-handler-policy.js";
10
10
  type AppRouteParams = Record<string, string | string[]>;
11
11
  type AppRouteDynamicUsageFn = () => boolean;
12
12
  type MarkAppRouteDynamicUsageFn = () => void;
13
+ /**
14
+ * Route handler context.
15
+ *
16
+ * `params` is `null` for non-dynamic routes (no `[param]` segments) so that
17
+ * user code like `params ? await params : null` resolves to `null`, matching
18
+ * Next.js behavior. For dynamic routes it's a thenable that resolves to the
19
+ * matched params object.
20
+ *
21
+ * See: test/e2e/app-dir/app-routes/app-custom-routes.test.ts in Next.js for
22
+ * the authoritative assertion (`expect(meta.params).toEqual(null)`).
23
+ */
13
24
  type AppRouteHandlerFunction = (request: NextRequest, context: {
14
- params: AppRouteParams;
25
+ params: AppRouteParams | null;
15
26
  }) => Response | Promise<Response>;
16
27
  type RouteHandlerCacheSetter = (key: string, data: CachedRouteValue, revalidateSeconds: number, tags: string[], expireSeconds?: number) => Promise<void>;
17
28
  type AppRouteErrorReporter = (error: Error, request: {
@@ -32,7 +43,11 @@ type RunAppRouteHandlerOptions = {
32
43
  i18n?: NextI18nConfig | null;
33
44
  markDynamicUsage: MarkAppRouteDynamicUsageFn;
34
45
  middlewareRequestHeaders?: Headers | null;
35
- params: AppRouteParams;
46
+ /**
47
+ * `null` for non-dynamic routes. Passed through to the handler context
48
+ * unchanged — callers are expected to compute this from `route.isDynamic`.
49
+ */
50
+ params: AppRouteParams | null;
36
51
  request: Request;
37
52
  routePattern?: string;
38
53
  setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-execution.js","names":[],"sources":["../../src/server/app-route-handler-execution.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport { setHeadersContext, type HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ExecutionContextLike } from \"vinext/shims/request-context\";\nimport type { CachedRouteValue } from \"vinext/shims/cache\";\nimport type { NextRequest } from \"vinext/shims/server\";\nimport {\n createStaticGenerationHeadersContext,\n getAppRouteStaticGenerationErrorMessage,\n} from \"./app-static-generation.js\";\nimport {\n isPossibleAppRouteActionRequest,\n resolveAppRouteHandlerSpecialError,\n shouldApplyAppRouteHandlerRevalidateHeader,\n shouldWriteAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n applyRouteHandlerRevalidateHeader,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n finalizeRouteHandlerResponse,\n markRouteHandlerCacheMiss,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport {\n createTrackedAppRouteRequest,\n markKnownDynamicAppRoute,\n} from \"./app-route-handler-runtime.js\";\n\nexport type AppRouteParams = Record<string, string | string[]>;\nexport type AppRouteDynamicUsageFn = () => boolean;\nexport type MarkAppRouteDynamicUsageFn = () => void;\nexport type AppRouteHandlerFunction = (\n request: NextRequest,\n context: { params: AppRouteParams },\n) => Response | Promise<Response>;\nexport type RouteHandlerCacheSetter = (\n key: string,\n data: CachedRouteValue,\n revalidateSeconds: number,\n tags: string[],\n expireSeconds?: number,\n) => Promise<void>;\ntype AppRouteErrorReporter = (\n error: Error,\n request: { path: string; method: string; headers: Record<string, string> },\n route: { routerKind: \"App Router\"; routePath: string; routeType: \"route\" },\n) => void;\nexport type AppRouteDebugLogger = (event: string, detail: string) => void;\n\ntype RunAppRouteHandlerOptions = {\n basePath?: string;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareRequestHeaders?: Headers | null;\n params: AppRouteParams;\n request: Request;\n routePattern?: string;\n setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n};\n\ntype RunAppRouteHandlerResult = {\n dynamicUsedInHandler: boolean;\n response: Response;\n};\n\ntype ExecuteAppRouteHandlerOptions = {\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n clearRequestContext: () => void;\n cleanPathname: string;\n executionContext: ExecutionContextLike | null;\n getAndClearPendingCookies: () => string[];\n getCollectedFetchTags: () => string[];\n getDraftModeCookieHeader: () => string | null | undefined;\n handler: AppRouteHandlerModule;\n isAutoHead: boolean;\n isProduction: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n method: string;\n middlewareContext: RouteHandlerMiddlewareContext;\n reportRequestError: AppRouteErrorReporter;\n expireSeconds?: number;\n revalidateSeconds: number | null;\n routePattern: string;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n} & RunAppRouteHandlerOptions;\n\nfunction configureAppRouteStaticGenerationContext(options: RunAppRouteHandlerOptions): void {\n if (options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\") {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n }),\n );\n options.setHeadersAccessPhase?.(\"route-handler\");\n }\n}\n\nexport async function runAppRouteHandler(\n options: RunAppRouteHandlerOptions,\n): Promise<RunAppRouteHandlerResult> {\n options.consumeDynamicUsage();\n configureAppRouteStaticGenerationContext(options);\n const trackedRequest = createTrackedAppRouteRequest(options.request, {\n basePath: options.basePath,\n i18n: options.i18n,\n middlewareHeaders: options.middlewareRequestHeaders,\n onDynamicAccess() {\n options.markDynamicUsage();\n },\n requestMode:\n options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\"\n ? options.dynamicConfig\n : \"auto\",\n staticGenerationErrorMessage(expression) {\n return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);\n },\n });\n const response = await options.handlerFn(trackedRequest.request, {\n params: options.params,\n });\n\n return {\n dynamicUsedInHandler: options.consumeDynamicUsage(),\n response,\n };\n}\n\nexport async function executeAppRouteHandler(\n options: ExecuteAppRouteHandlerOptions,\n): Promise<Response> {\n const previousHeadersPhase = options.setHeadersAccessPhase(\"route-handler\");\n\n try {\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n ...options,\n dynamicConfig: options.handler.dynamic,\n });\n assertSupportedAppRouteHandlerResponse(response);\n const handlerSetCacheControl = response.headers.has(\"cache-control\");\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n }\n\n if (\n shouldApplyAppRouteHandlerRevalidateHeader({\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler revalidate seconds\");\n }\n applyRouteHandlerRevalidateHeader(response, revalidateSeconds, options.expireSeconds);\n }\n\n if (\n shouldWriteAppRouteHandlerCache({\n dynamicConfig: options.handler.dynamic,\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n isProduction: options.isProduction,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n markRouteHandlerCacheMiss(response);\n const routeClone = response.clone();\n const routeKey = options.isrRouteKey(options.cleanPathname);\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler cache revalidate seconds\");\n }\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeWritePromise = (async () => {\n try {\n const routeCacheValue = await buildAppRouteCacheValue(routeClone);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route cache written\", routeKey);\n } catch (cacheErr) {\n console.error(\"[vinext] ISR route cache write error:\", cacheErr);\n }\n })();\n options.executionContext?.waitUntil(routeWritePromise);\n }\n\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n options.clearRequestContext();\n\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(response, {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n }),\n options.middlewareContext,\n );\n } catch (error) {\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, {\n isAction: isPossibleAppRouteActionRequest(options.request),\n });\n options.clearRequestContext();\n\n if (specialError) {\n if (specialError.kind === \"redirect\") {\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(\n new Response(null, {\n status: specialError.statusCode,\n headers: { Location: specialError.location },\n }),\n {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n },\n ),\n options.middlewareContext,\n );\n }\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: specialError.statusCode }),\n options.middlewareContext,\n );\n }\n\n console.error(\"[vinext] Route handler error:\", error);\n options.reportRequestError(\n error instanceof Error ? error : new Error(String(error)),\n {\n path: options.cleanPathname,\n method: options.request.method,\n headers: Object.fromEntries(options.request.headers.entries()),\n },\n {\n routerKind: \"App Router\",\n routePath: options.routePattern,\n routeType: \"route\",\n },\n );\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 500 }),\n options.middlewareContext,\n );\n } finally {\n options.setHeadersAccessPhase(previousHeadersPhase);\n }\n}\n"],"mappings":";;;;;;AA6FA,SAAS,yCAAyC,SAA0C;CAC1F,IAAI,QAAQ,kBAAkB,kBAAkB,QAAQ,kBAAkB,SAAS;EACjF,kBACE,qCAAqC;GACnC,eAAe,QAAQ;GACvB,WAAW;GACX,cAAc,QAAQ;GACvB,CAAC,CACH;EACD,QAAQ,wBAAwB,gBAAgB;;;AAIpD,eAAsB,mBACpB,SACmC;CACnC,QAAQ,qBAAqB;CAC7B,yCAAyC,QAAQ;CACjD,MAAM,iBAAiB,6BAA6B,QAAQ,SAAS;EACnE,UAAU,QAAQ;EAClB,MAAM,QAAQ;EACd,mBAAmB,QAAQ;EAC3B,kBAAkB;GAChB,QAAQ,kBAAkB;;EAE5B,aACE,QAAQ,kBAAkB,kBAAkB,QAAQ,kBAAkB,UAClE,QAAQ,gBACR;EACN,6BAA6B,YAAY;GACvC,OAAO,wCAAwC,QAAQ,cAAc,WAAW;;EAEnF,CAAC;CACF,MAAM,WAAW,MAAM,QAAQ,UAAU,eAAe,SAAS,EAC/D,QAAQ,QAAQ,QACjB,CAAC;CAEF,OAAO;EACL,sBAAsB,QAAQ,qBAAqB;EACnD;EACD;;AAGH,eAAsB,uBACpB,SACmB;CACnB,MAAM,uBAAuB,QAAQ,sBAAsB,gBAAgB;CAE3E,IAAI;EACF,MAAM,EAAE,sBAAsB,aAAa,MAAM,mBAAmB;GAClE,GAAG;GACH,eAAe,QAAQ,QAAQ;GAChC,CAAC;EACF,uCAAuC,SAAS;EAChD,MAAM,yBAAyB,SAAS,QAAQ,IAAI,gBAAgB;EAEpE,IAAI,sBACF,yBAAyB,QAAQ,aAAa;EAGhD,IACE,2CAA2C;GACzC;GACA;GACA,YAAY,QAAQ;GACpB,QAAQ,QAAQ;GAChB,mBAAmB,QAAQ;GAC5B,CAAC,EACF;GACA,MAAM,oBAAoB,QAAQ;GAClC,IAAI,qBAAqB,MACvB,MAAM,IAAI,MAAM,4CAA4C;GAE9D,kCAAkC,UAAU,mBAAmB,QAAQ,cAAc;;EAGvF,IACE,gCAAgC;GAC9B,eAAe,QAAQ,QAAQ;GAC/B;GACA;GACA,YAAY,QAAQ;GACpB,cAAc,QAAQ;GACtB,QAAQ,QAAQ;GAChB,mBAAmB,QAAQ;GAC5B,CAAC,EACF;GACA,0BAA0B,SAAS;GACnC,MAAM,aAAa,SAAS,OAAO;GACnC,MAAM,WAAW,QAAQ,YAAY,QAAQ,cAAc;GAC3D,MAAM,oBAAoB,QAAQ;GAClC,IAAI,qBAAqB,MACvB,MAAM,IAAI,MAAM,kDAAkD;GAEpE,MAAM,YAAY,QAAQ,mBACxB,QAAQ,eACR,QAAQ,uBAAuB,CAChC;GACD,MAAM,qBAAqB,YAAY;IACrC,IAAI;KACF,MAAM,kBAAkB,MAAM,wBAAwB,WAAW;KACjE,MAAM,QAAQ,OACZ,UACA,iBACA,mBACA,WACA,QAAQ,cACT;KACD,QAAQ,WAAW,uBAAuB,SAAS;aAC5C,UAAU;KACjB,QAAQ,MAAM,yCAAyC,SAAS;;OAEhE;GACJ,QAAQ,kBAAkB,UAAU,kBAAkB;;EAGxD,MAAM,iBAAiB,QAAQ,2BAA2B;EAC1D,MAAM,cAAc,QAAQ,0BAA0B;EACtD,QAAQ,qBAAqB;EAE7B,OAAO,mCACL,6BAA6B,UAAU;GACrC;GACA;GACA,QAAQ,QAAQ;GACjB,CAAC,EACF,QAAQ,kBACT;UACM,OAAO;EACd,MAAM,iBAAiB,QAAQ,2BAA2B;EAC1D,MAAM,cAAc,QAAQ,0BAA0B;EACtD,MAAM,eAAe,mCAAmC,OAAO,QAAQ,QAAQ,KAAK,EAClF,UAAU,gCAAgC,QAAQ,QAAQ,EAC3D,CAAC;EACF,QAAQ,qBAAqB;EAE7B,IAAI,cAAc;GAChB,IAAI,aAAa,SAAS,YACxB,OAAO,mCACL,6BACE,IAAI,SAAS,MAAM;IACjB,QAAQ,aAAa;IACrB,SAAS,EAAE,UAAU,aAAa,UAAU;IAC7C,CAAC,EACF;IACE;IACA;IACA,QAAQ,QAAQ;IACjB,CACF,EACD,QAAQ,kBACT;GAGH,OAAO,mCACL,IAAI,SAAS,MAAM,EAAE,QAAQ,aAAa,YAAY,CAAC,EACvD,QAAQ,kBACT;;EAGH,QAAQ,MAAM,iCAAiC,MAAM;EACrD,QAAQ,mBACN,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,EACzD;GACE,MAAM,QAAQ;GACd,QAAQ,QAAQ,QAAQ;GACxB,SAAS,OAAO,YAAY,QAAQ,QAAQ,QAAQ,SAAS,CAAC;GAC/D,EACD;GACE,YAAY;GACZ,WAAW,QAAQ;GACnB,WAAW;GACZ,CACF;EAED,OAAO,mCACL,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,CAAC,EACnC,QAAQ,kBACT;WACO;EACR,QAAQ,sBAAsB,qBAAqB"}
1
+ {"version":3,"file":"app-route-handler-execution.js","names":[],"sources":["../../src/server/app-route-handler-execution.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport { setHeadersContext, type HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ExecutionContextLike } from \"vinext/shims/request-context\";\nimport type { CachedRouteValue } from \"vinext/shims/cache\";\nimport type { NextRequest } from \"vinext/shims/server\";\nimport {\n createStaticGenerationHeadersContext,\n getAppRouteStaticGenerationErrorMessage,\n} from \"./app-static-generation.js\";\nimport {\n isPossibleAppRouteActionRequest,\n resolveAppRouteHandlerSpecialError,\n shouldApplyAppRouteHandlerRevalidateHeader,\n shouldWriteAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n applyRouteHandlerRevalidateHeader,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n finalizeRouteHandlerResponse,\n markRouteHandlerCacheMiss,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport {\n createTrackedAppRouteRequest,\n markKnownDynamicAppRoute,\n} from \"./app-route-handler-runtime.js\";\n\nexport type AppRouteParams = Record<string, string | string[]>;\nexport type AppRouteDynamicUsageFn = () => boolean;\nexport type MarkAppRouteDynamicUsageFn = () => void;\n/**\n * Route handler context.\n *\n * `params` is `null` for non-dynamic routes (no `[param]` segments) so that\n * user code like `params ? await params : null` resolves to `null`, matching\n * Next.js behavior. For dynamic routes it's a thenable that resolves to the\n * matched params object.\n *\n * See: test/e2e/app-dir/app-routes/app-custom-routes.test.ts in Next.js for\n * the authoritative assertion (`expect(meta.params).toEqual(null)`).\n */\nexport type AppRouteHandlerFunction = (\n request: NextRequest,\n context: { params: AppRouteParams | null },\n) => Response | Promise<Response>;\nexport type RouteHandlerCacheSetter = (\n key: string,\n data: CachedRouteValue,\n revalidateSeconds: number,\n tags: string[],\n expireSeconds?: number,\n) => Promise<void>;\ntype AppRouteErrorReporter = (\n error: Error,\n request: { path: string; method: string; headers: Record<string, string> },\n route: { routerKind: \"App Router\"; routePath: string; routeType: \"route\" },\n) => void;\nexport type AppRouteDebugLogger = (event: string, detail: string) => void;\n\ntype RunAppRouteHandlerOptions = {\n basePath?: string;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareRequestHeaders?: Headers | null;\n /**\n * `null` for non-dynamic routes. Passed through to the handler context\n * unchanged — callers are expected to compute this from `route.isDynamic`.\n */\n params: AppRouteParams | null;\n request: Request;\n routePattern?: string;\n setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n};\n\ntype RunAppRouteHandlerResult = {\n dynamicUsedInHandler: boolean;\n response: Response;\n};\n\ntype ExecuteAppRouteHandlerOptions = {\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n clearRequestContext: () => void;\n cleanPathname: string;\n executionContext: ExecutionContextLike | null;\n getAndClearPendingCookies: () => string[];\n getCollectedFetchTags: () => string[];\n getDraftModeCookieHeader: () => string | null | undefined;\n handler: AppRouteHandlerModule;\n isAutoHead: boolean;\n isProduction: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n method: string;\n middlewareContext: RouteHandlerMiddlewareContext;\n reportRequestError: AppRouteErrorReporter;\n expireSeconds?: number;\n revalidateSeconds: number | null;\n routePattern: string;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n} & RunAppRouteHandlerOptions;\n\nfunction configureAppRouteStaticGenerationContext(options: RunAppRouteHandlerOptions): void {\n if (options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\") {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n }),\n );\n options.setHeadersAccessPhase?.(\"route-handler\");\n }\n}\n\nexport async function runAppRouteHandler(\n options: RunAppRouteHandlerOptions,\n): Promise<RunAppRouteHandlerResult> {\n options.consumeDynamicUsage();\n configureAppRouteStaticGenerationContext(options);\n const trackedRequest = createTrackedAppRouteRequest(options.request, {\n basePath: options.basePath,\n i18n: options.i18n,\n middlewareHeaders: options.middlewareRequestHeaders,\n onDynamicAccess() {\n options.markDynamicUsage();\n },\n requestMode:\n options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\"\n ? options.dynamicConfig\n : \"auto\",\n staticGenerationErrorMessage(expression) {\n return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);\n },\n });\n const response = await options.handlerFn(trackedRequest.request, {\n params: options.params,\n });\n\n return {\n dynamicUsedInHandler: options.consumeDynamicUsage(),\n response,\n };\n}\n\nexport async function executeAppRouteHandler(\n options: ExecuteAppRouteHandlerOptions,\n): Promise<Response> {\n const previousHeadersPhase = options.setHeadersAccessPhase(\"route-handler\");\n\n try {\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n ...options,\n dynamicConfig: options.handler.dynamic,\n });\n assertSupportedAppRouteHandlerResponse(response);\n const handlerSetCacheControl = response.headers.has(\"cache-control\");\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n }\n\n if (\n shouldApplyAppRouteHandlerRevalidateHeader({\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler revalidate seconds\");\n }\n applyRouteHandlerRevalidateHeader(response, revalidateSeconds, options.expireSeconds);\n }\n\n if (\n shouldWriteAppRouteHandlerCache({\n dynamicConfig: options.handler.dynamic,\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n isProduction: options.isProduction,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n markRouteHandlerCacheMiss(response);\n const routeClone = response.clone();\n const routeKey = options.isrRouteKey(options.cleanPathname);\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler cache revalidate seconds\");\n }\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeWritePromise = (async () => {\n try {\n const routeCacheValue = await buildAppRouteCacheValue(routeClone);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route cache written\", routeKey);\n } catch (cacheErr) {\n console.error(\"[vinext] ISR route cache write error:\", cacheErr);\n }\n })();\n options.executionContext?.waitUntil(routeWritePromise);\n }\n\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n options.clearRequestContext();\n\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(response, {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n }),\n options.middlewareContext,\n );\n } catch (error) {\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, {\n isAction: isPossibleAppRouteActionRequest(options.request),\n });\n options.clearRequestContext();\n\n if (specialError) {\n if (specialError.kind === \"redirect\") {\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(\n new Response(null, {\n status: specialError.statusCode,\n headers: { Location: specialError.location },\n }),\n {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n },\n ),\n options.middlewareContext,\n );\n }\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: specialError.statusCode }),\n options.middlewareContext,\n );\n }\n\n console.error(\"[vinext] Route handler error:\", error);\n options.reportRequestError(\n error instanceof Error ? error : new Error(String(error)),\n {\n path: options.cleanPathname,\n method: options.request.method,\n headers: Object.fromEntries(options.request.headers.entries()),\n },\n {\n routerKind: \"App Router\",\n routePath: options.routePattern,\n routeType: \"route\",\n },\n );\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 500 }),\n options.middlewareContext,\n );\n } finally {\n options.setHeadersAccessPhase(previousHeadersPhase);\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import { VINEXT_CACHE_HEADER } from "./headers.js";
1
+ import "./headers.js";
2
2
  import { processMiddlewareHeaders } from "./request-pipeline.js";
3
+ import { setCacheStateHeaders } from "./cache-headers.js";
3
4
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
4
5
  import { NEVER_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildCachedRevalidateCacheControl } from "./cache-control.js";
5
6
  //#region src/server/app-route-handler-response.ts
@@ -32,7 +33,7 @@ function buildRouteHandlerCachedResponse(cachedValue, options) {
32
33
  const headers = new Headers();
33
34
  for (const [key, value] of Object.entries(cachedValue.headers)) if (Array.isArray(value)) for (const entry of value) headers.append(key, entry);
34
35
  else headers.set(key, value);
35
- headers.set(VINEXT_CACHE_HEADER, options.cacheState);
36
+ setCacheStateHeaders(headers, options.cacheState);
36
37
  const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;
37
38
  const expireSeconds = options.cacheControl === void 0 ? void 0 : options.cacheControl.expire ?? options.expireSeconds;
38
39
  headers.set("Cache-Control", buildRouteHandlerCacheControl(options.cacheState, revalidateSeconds, expireSeconds));
@@ -45,7 +46,7 @@ function applyRouteHandlerRevalidateHeader(response, revalidateSeconds, expireSe
45
46
  response.headers.set("cache-control", buildRouteHandlerCacheControl("HIT", revalidateSeconds, expireSeconds));
46
47
  }
47
48
  function markRouteHandlerCacheMiss(response) {
48
- response.headers.set(VINEXT_CACHE_HEADER, "MISS");
49
+ setCacheStateHeaders(response.headers, "MISS");
49
50
  }
50
51
  function getSetCookieName(cookie) {
51
52
  const equalsIndex = cookie.indexOf("=");
@@ -79,7 +80,7 @@ async function buildAppRouteCacheValue(response) {
79
80
  const body = await response.arrayBuffer();
80
81
  const headers = {};
81
82
  response.headers.forEach((value, key) => {
82
- if (key === "set-cookie" || key === "X-Vinext-Cache".toLowerCase() || key === "cache-control" || key.startsWith("x-middleware-")) return;
83
+ if (key === "set-cookie" || key === "X-Vinext-Cache".toLowerCase() || key === "x-nextjs-cache".toLowerCase() || key === "cache-control" || key.startsWith("x-middleware-")) return;
83
84
  headers[key] = value;
84
85
  });
85
86
  const setCookies = response.headers.getSetCookie?.() ?? [];
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-response.js","names":[],"sources":["../../src/server/app-route-handler-response.ts"],"sourcesContent":["import type { CachedRouteValue, CacheControlMetadata } from \"vinext/shims/cache\";\nimport {\n buildCachedRevalidateCacheControl,\n NEVER_CACHE_CONTROL,\n STATIC_CACHE_CONTROL,\n} from \"./cache-control.js\";\nimport {\n MIDDLEWARE_HEADER_PREFIX,\n MIDDLEWARE_NEXT_HEADER,\n MIDDLEWARE_REWRITE_HEADER,\n VINEXT_CACHE_HEADER,\n} from \"./headers.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport { processMiddlewareHeaders } from \"./request-pipeline.js\";\n\nexport type RouteHandlerMiddlewareContext = {\n headers: Headers | null;\n status: number | null;\n};\n\ntype BuildRouteHandlerCachedResponseOptions = {\n cacheControl?: CacheControlMetadata;\n cacheState: \"HIT\" | \"STALE\";\n expireSeconds?: number;\n isHead: boolean;\n revalidateSeconds: number;\n};\n\ntype FinalizeRouteHandlerResponseOptions = {\n pendingCookies: string[];\n draftCookie?: string | null;\n isHead: boolean;\n};\n\nconst APP_ROUTE_REWRITE_ERROR =\n \"NextResponse.rewrite() was used in a app route handler, this is not currently supported. Please remove the invocation to continue.\";\nconst APP_ROUTE_NEXT_ERROR =\n \"NextResponse.next() was used in a app route handler, this is not supported. See here for more info: https://nextjs.org/docs/messages/next-response-next-in-app-route-handler\";\n\nfunction hasMiddlewareHeader(headers: Headers): boolean {\n for (const key of headers.keys()) {\n if (key.startsWith(MIDDLEWARE_HEADER_PREFIX)) return true;\n }\n return false;\n}\n\nfunction buildRouteHandlerCacheControl(\n cacheState: BuildRouteHandlerCachedResponseOptions[\"cacheState\"],\n revalidateSeconds: number,\n expireSeconds?: number,\n): string {\n if (revalidateSeconds === 0) {\n // A cached response is never produced for revalidate = 0 (the ISR write\n // path skips it), so only the HIT/STALE->fresh rewrite can arrive here\n // with a 0 value, via applyRouteHandlerRevalidateHeader. In all such\n // cases the author opted out of caching entirely.\n return NEVER_CACHE_CONTROL;\n }\n\n if (revalidateSeconds === Infinity) {\n // revalidate = false / Infinity means \"cache indefinitely\" — emit the\n // same static Cache-Control used by pages, not a dynamic SWR value.\n return STATIC_CACHE_CONTROL;\n }\n\n return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);\n}\n\nexport function applyRouteHandlerMiddlewareContext(\n response: Response,\n middlewareContext: RouteHandlerMiddlewareContext,\n): Response {\n if (!middlewareContext.headers && middlewareContext.status == null) {\n return response;\n }\n\n const responseHeaders = new Headers(response.headers);\n mergeMiddlewareResponseHeaders(responseHeaders, middlewareContext.headers);\n\n return new Response(response.body, {\n status: middlewareContext.status ?? response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n });\n}\n\nexport function assertSupportedAppRouteHandlerResponse(response: Response): void {\n // NextResponse.next() and rewrite() are middleware control-flow signals.\n // Once an App Route handler has returned, Next.js rejects those responses.\n if (response.headers.has(MIDDLEWARE_REWRITE_HEADER)) {\n throw new Error(APP_ROUTE_REWRITE_ERROR);\n }\n\n if (response.headers.get(MIDDLEWARE_NEXT_HEADER) === \"1\") {\n throw new Error(APP_ROUTE_NEXT_ERROR);\n }\n}\n\nexport function buildRouteHandlerCachedResponse(\n cachedValue: CachedRouteValue,\n options: BuildRouteHandlerCachedResponseOptions,\n): Response {\n const headers = new Headers();\n for (const [key, value] of Object.entries(cachedValue.headers)) {\n if (Array.isArray(value)) {\n for (const entry of value) {\n headers.append(key, entry);\n }\n } else {\n headers.set(key, value);\n }\n }\n headers.set(VINEXT_CACHE_HEADER, options.cacheState);\n const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;\n const expireSeconds =\n options.cacheControl === undefined\n ? undefined\n : (options.cacheControl.expire ?? options.expireSeconds);\n headers.set(\n \"Cache-Control\",\n buildRouteHandlerCacheControl(options.cacheState, revalidateSeconds, expireSeconds),\n );\n\n return new Response(options.isHead ? null : cachedValue.body, {\n status: cachedValue.status,\n headers,\n });\n}\n\nexport function applyRouteHandlerRevalidateHeader(\n response: Response,\n revalidateSeconds: number,\n expireSeconds?: number,\n): void {\n response.headers.set(\n \"cache-control\",\n buildRouteHandlerCacheControl(\"HIT\", revalidateSeconds, expireSeconds),\n );\n}\n\nexport function markRouteHandlerCacheMiss(response: Response): void {\n response.headers.set(VINEXT_CACHE_HEADER, \"MISS\");\n}\n\nfunction getSetCookieName(cookie: string): string | null {\n const equalsIndex = cookie.indexOf(\"=\");\n if (equalsIndex <= 0) {\n return null;\n }\n return cookie.slice(0, equalsIndex);\n}\n\nfunction applyMutableCookieFallbacks(headers: Headers, pendingCookies: string[]): void {\n if (pendingCookies.length === 0) {\n return;\n }\n\n const returnedCookies = headers.getSetCookie();\n const returnedCookieNames = new Set<string>();\n for (const cookie of returnedCookies) {\n const name = getSetCookieName(cookie);\n if (name) {\n returnedCookieNames.add(name);\n }\n }\n\n const fallbackCookies = new Map<string, string>();\n const unkeyedFallbackCookies: string[] = [];\n for (const cookie of pendingCookies) {\n const name = getSetCookieName(cookie);\n if (!name) {\n unkeyedFallbackCookies.push(cookie);\n continue;\n }\n\n if (!returnedCookieNames.has(name)) {\n fallbackCookies.set(name, cookie);\n }\n }\n\n headers.delete(\"Set-Cookie\");\n for (const cookie of unkeyedFallbackCookies) {\n headers.append(\"Set-Cookie\", cookie);\n }\n for (const cookie of fallbackCookies.values()) {\n headers.append(\"Set-Cookie\", cookie);\n }\n for (const cookie of returnedCookies) {\n headers.append(\"Set-Cookie\", cookie);\n }\n}\n\nexport async function buildAppRouteCacheValue(response: Response): Promise<CachedRouteValue> {\n const body = await response.arrayBuffer();\n const headers: CachedRouteValue[\"headers\"] = {};\n\n response.headers.forEach((value, key) => {\n if (\n key === \"set-cookie\" ||\n key === VINEXT_CACHE_HEADER.toLowerCase() ||\n key === \"cache-control\" ||\n key.startsWith(MIDDLEWARE_HEADER_PREFIX)\n ) {\n return;\n }\n headers[key] = value;\n });\n const setCookies = response.headers.getSetCookie?.() ?? [];\n if (setCookies.length > 0) {\n headers[\"set-cookie\"] = setCookies;\n }\n\n return {\n kind: \"APP_ROUTE\",\n body,\n status: response.status,\n headers,\n };\n}\n\nexport function finalizeRouteHandlerResponse(\n response: Response,\n options: FinalizeRouteHandlerResponseOptions,\n): Response {\n const { pendingCookies, draftCookie, isHead } = options;\n if (\n pendingCookies.length === 0 &&\n !draftCookie &&\n !isHead &&\n !hasMiddlewareHeader(response.headers)\n ) {\n return response;\n }\n\n const headers = new Headers(response.headers);\n processMiddlewareHeaders(headers);\n applyMutableCookieFallbacks(headers, pendingCookies);\n if (draftCookie) {\n headers.append(\"Set-Cookie\", draftCookie);\n }\n\n return new Response(isHead ? null : response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-route-handler-response.js","names":[],"sources":["../../src/server/app-route-handler-response.ts"],"sourcesContent":["import type { CachedRouteValue, CacheControlMetadata } from \"vinext/shims/cache\";\nimport {\n buildCachedRevalidateCacheControl,\n NEVER_CACHE_CONTROL,\n STATIC_CACHE_CONTROL,\n} from \"./cache-control.js\";\nimport {\n MIDDLEWARE_HEADER_PREFIX,\n MIDDLEWARE_NEXT_HEADER,\n MIDDLEWARE_REWRITE_HEADER,\n NEXTJS_CACHE_HEADER,\n VINEXT_CACHE_HEADER,\n} from \"./headers.js\";\nimport { setCacheStateHeaders } from \"./cache-headers.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport { processMiddlewareHeaders } from \"./request-pipeline.js\";\n\nexport type RouteHandlerMiddlewareContext = {\n headers: Headers | null;\n status: number | null;\n};\n\ntype BuildRouteHandlerCachedResponseOptions = {\n cacheControl?: CacheControlMetadata;\n cacheState: \"HIT\" | \"STALE\";\n expireSeconds?: number;\n isHead: boolean;\n revalidateSeconds: number;\n};\n\ntype FinalizeRouteHandlerResponseOptions = {\n pendingCookies: string[];\n draftCookie?: string | null;\n isHead: boolean;\n};\n\nconst APP_ROUTE_REWRITE_ERROR =\n \"NextResponse.rewrite() was used in a app route handler, this is not currently supported. Please remove the invocation to continue.\";\nconst APP_ROUTE_NEXT_ERROR =\n \"NextResponse.next() was used in a app route handler, this is not supported. See here for more info: https://nextjs.org/docs/messages/next-response-next-in-app-route-handler\";\n\nfunction hasMiddlewareHeader(headers: Headers): boolean {\n for (const key of headers.keys()) {\n if (key.startsWith(MIDDLEWARE_HEADER_PREFIX)) return true;\n }\n return false;\n}\n\nfunction buildRouteHandlerCacheControl(\n cacheState: BuildRouteHandlerCachedResponseOptions[\"cacheState\"],\n revalidateSeconds: number,\n expireSeconds?: number,\n): string {\n if (revalidateSeconds === 0) {\n // A cached response is never produced for revalidate = 0 (the ISR write\n // path skips it), so only the HIT/STALE->fresh rewrite can arrive here\n // with a 0 value, via applyRouteHandlerRevalidateHeader. In all such\n // cases the author opted out of caching entirely.\n return NEVER_CACHE_CONTROL;\n }\n\n if (revalidateSeconds === Infinity) {\n // revalidate = false / Infinity means \"cache indefinitely\" — emit the\n // same static Cache-Control used by pages, not a dynamic SWR value.\n return STATIC_CACHE_CONTROL;\n }\n\n return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);\n}\n\nexport function applyRouteHandlerMiddlewareContext(\n response: Response,\n middlewareContext: RouteHandlerMiddlewareContext,\n): Response {\n if (!middlewareContext.headers && middlewareContext.status == null) {\n return response;\n }\n\n const responseHeaders = new Headers(response.headers);\n mergeMiddlewareResponseHeaders(responseHeaders, middlewareContext.headers);\n\n return new Response(response.body, {\n status: middlewareContext.status ?? response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n });\n}\n\nexport function assertSupportedAppRouteHandlerResponse(response: Response): void {\n // NextResponse.next() and rewrite() are middleware control-flow signals.\n // Once an App Route handler has returned, Next.js rejects those responses.\n if (response.headers.has(MIDDLEWARE_REWRITE_HEADER)) {\n throw new Error(APP_ROUTE_REWRITE_ERROR);\n }\n\n if (response.headers.get(MIDDLEWARE_NEXT_HEADER) === \"1\") {\n throw new Error(APP_ROUTE_NEXT_ERROR);\n }\n}\n\nexport function buildRouteHandlerCachedResponse(\n cachedValue: CachedRouteValue,\n options: BuildRouteHandlerCachedResponseOptions,\n): Response {\n const headers = new Headers();\n for (const [key, value] of Object.entries(cachedValue.headers)) {\n if (Array.isArray(value)) {\n for (const entry of value) {\n headers.append(key, entry);\n }\n } else {\n headers.set(key, value);\n }\n }\n setCacheStateHeaders(headers, options.cacheState);\n const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;\n const expireSeconds =\n options.cacheControl === undefined\n ? undefined\n : (options.cacheControl.expire ?? options.expireSeconds);\n headers.set(\n \"Cache-Control\",\n buildRouteHandlerCacheControl(options.cacheState, revalidateSeconds, expireSeconds),\n );\n\n return new Response(options.isHead ? null : cachedValue.body, {\n status: cachedValue.status,\n headers,\n });\n}\n\nexport function applyRouteHandlerRevalidateHeader(\n response: Response,\n revalidateSeconds: number,\n expireSeconds?: number,\n): void {\n response.headers.set(\n \"cache-control\",\n buildRouteHandlerCacheControl(\"HIT\", revalidateSeconds, expireSeconds),\n );\n}\n\nexport function markRouteHandlerCacheMiss(response: Response): void {\n setCacheStateHeaders(response.headers, \"MISS\");\n}\n\nfunction getSetCookieName(cookie: string): string | null {\n const equalsIndex = cookie.indexOf(\"=\");\n if (equalsIndex <= 0) {\n return null;\n }\n return cookie.slice(0, equalsIndex);\n}\n\nfunction applyMutableCookieFallbacks(headers: Headers, pendingCookies: string[]): void {\n if (pendingCookies.length === 0) {\n return;\n }\n\n const returnedCookies = headers.getSetCookie();\n const returnedCookieNames = new Set<string>();\n for (const cookie of returnedCookies) {\n const name = getSetCookieName(cookie);\n if (name) {\n returnedCookieNames.add(name);\n }\n }\n\n const fallbackCookies = new Map<string, string>();\n const unkeyedFallbackCookies: string[] = [];\n for (const cookie of pendingCookies) {\n const name = getSetCookieName(cookie);\n if (!name) {\n unkeyedFallbackCookies.push(cookie);\n continue;\n }\n\n if (!returnedCookieNames.has(name)) {\n fallbackCookies.set(name, cookie);\n }\n }\n\n headers.delete(\"Set-Cookie\");\n for (const cookie of unkeyedFallbackCookies) {\n headers.append(\"Set-Cookie\", cookie);\n }\n for (const cookie of fallbackCookies.values()) {\n headers.append(\"Set-Cookie\", cookie);\n }\n for (const cookie of returnedCookies) {\n headers.append(\"Set-Cookie\", cookie);\n }\n}\n\nexport async function buildAppRouteCacheValue(response: Response): Promise<CachedRouteValue> {\n const body = await response.arrayBuffer();\n const headers: CachedRouteValue[\"headers\"] = {};\n\n response.headers.forEach((value, key) => {\n if (\n key === \"set-cookie\" ||\n key === VINEXT_CACHE_HEADER.toLowerCase() ||\n key === NEXTJS_CACHE_HEADER.toLowerCase() ||\n key === \"cache-control\" ||\n key.startsWith(MIDDLEWARE_HEADER_PREFIX)\n ) {\n return;\n }\n headers[key] = value;\n });\n const setCookies = response.headers.getSetCookie?.() ?? [];\n if (setCookies.length > 0) {\n headers[\"set-cookie\"] = setCookies;\n }\n\n return {\n kind: \"APP_ROUTE\",\n body,\n status: response.status,\n headers,\n };\n}\n\nexport function finalizeRouteHandlerResponse(\n response: Response,\n options: FinalizeRouteHandlerResponseOptions,\n): Response {\n const { pendingCookies, draftCookie, isHead } = options;\n if (\n pendingCookies.length === 0 &&\n !draftCookie &&\n !isHead &&\n !hasMiddlewareHeader(response.headers)\n ) {\n return response;\n }\n\n const headers = new Headers(response.headers);\n processMiddlewareHeaders(headers);\n applyMutableCookieFallbacks(headers, pendingCookies);\n if (draftCookie) {\n headers.append(\"Set-Cookie\", draftCookie);\n }\n\n return new Response(isHead ? null : response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n"],"mappings":"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"}
@@ -1,22 +1,13 @@
1
+ import "./server-globals.js";
1
2
  import { runWithExecutionContext } from "../shims/request-context.js";
2
- import { badRequestResponse, notFoundResponse } from "./http-error-responses.js";
3
+ import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
3
4
  import { cloneRequestWithHeaders, filterInternalHeaders, isOpenRedirectShaped } from "./request-pipeline.js";
5
+ import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
4
6
  import { resolveStaticAssetSignal } from "./worker-utils.js";
5
- import rscHandler from "virtual:vinext-rsc-entry";
7
+ import rscHandler, { __assetPrefix, __basePath } from "virtual:vinext-rsc-entry";
6
8
  //#region src/server/app-router-entry.ts
7
- /**
8
- * Default Cloudflare Worker entry point for vinext App Router.
9
- *
10
- * Use this directly in wrangler.jsonc:
11
- * "main": "vinext/server/app-router-entry"
12
- *
13
- * Or import and delegate to it from a custom worker:
14
- * import handler from "vinext/server/app-router-entry";
15
- * return handler.fetch(request, env, ctx);
16
- *
17
- * This file runs in the RSC environment. Configure the Cloudflare plugin with:
18
- * cloudflare({ viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] } })
19
- */
9
+ const __workerBasePath = typeof __basePath === "string" ? __basePath : "";
10
+ const __workerAssetPathPrefix = assetPrefixPathname(typeof __assetPrefix === "string" ? __assetPrefix : "");
20
11
  var app_router_entry_default = { async fetch(request, env, ctx) {
21
12
  return handleRequest(request, env, ctx);
22
13
  } };
@@ -28,6 +19,7 @@ async function handleRequest(request, env, ctx) {
28
19
  } catch {
29
20
  return badRequestResponse();
30
21
  }
22
+ if (isNextStaticPath(url.pathname, __workerBasePath, __workerAssetPathPrefix)) return notFoundStaticAssetResponse();
31
23
  {
32
24
  const filteredHeaders = filterInternalHeaders(request.headers);
33
25
  request = cloneRequestWithHeaders(request, filteredHeaders);
@@ -1 +1 @@
1
- {"version":3,"file":"app-router-entry.js","names":[],"sources":["../../src/server/app-router-entry.ts"],"sourcesContent":["/**\n * Default Cloudflare Worker entry point for vinext App Router.\n *\n * Use this directly in wrangler.jsonc:\n * \"main\": \"vinext/server/app-router-entry\"\n *\n * Or import and delegate to it from a custom worker:\n * import handler from \"vinext/server/app-router-entry\";\n * return handler.fetch(request, env, ctx);\n *\n * This file runs in the RSC environment. Configure the Cloudflare plugin with:\n * cloudflare({ viteEnvironment: { name: \"rsc\", childEnvironments: [\"ssr\"] } })\n */\n\n// @ts-expect-error virtual module resolved by vinext\nimport rscHandler from \"virtual:vinext-rsc-entry\";\nimport { runWithExecutionContext, type ExecutionContextLike } from \"vinext/shims/request-context\";\nimport { resolveStaticAssetSignal } from \"./worker-utils.js\";\nimport {\n cloneRequestWithHeaders,\n filterInternalHeaders,\n isOpenRedirectShaped,\n} from \"./request-pipeline.js\";\nimport { badRequestResponse, notFoundResponse } from \"./http-error-responses.js\";\n\ntype WorkerAssetEnv = {\n ASSETS?: {\n fetch(request: Request): Promise<Response> | Response;\n };\n};\n\nexport default {\n async fetch(\n request: Request,\n env?: WorkerAssetEnv,\n ctx?: ExecutionContextLike,\n ): Promise<Response> {\n return handleRequest(request, env, ctx);\n },\n};\n\nasync function handleRequest(\n request: Request,\n env: WorkerAssetEnv | undefined,\n ctx: ExecutionContextLike | undefined,\n): Promise<Response> {\n const url = new URL(request.url);\n\n // Block protocol-relative URL open redirects (//evil.com/, /\\evil.com/,\n // /%5Cevil.com/, /%2F/evil.com/). Check BEFORE decode so both literal and\n // percent-encoded variants are caught — encoded forms survive segment-wise\n // decoding and would otherwise reach trailing-slash redirect emitters.\n if (isOpenRedirectShaped(url.pathname)) {\n return notFoundResponse();\n }\n\n // Validate that percent-encoding is well-formed. The RSC handler performs\n // the actual decode + normalize; we only check here to return a clean 400\n // instead of letting a malformed sequence crash downstream.\n try {\n decodeURIComponent(url.pathname);\n } catch {\n // Malformed percent-encoding (e.g. /%E0%A4%A) — return 400 instead of throwing.\n return badRequestResponse();\n }\n\n // Strip internal headers from inbound requests before any handler or\n // middleware sees them. Must happen before the RSC handler runs.\n // Builds a new Headers — Request.headers is immutable in Workers.\n {\n const filteredHeaders = filterInternalHeaders(request.headers);\n request = cloneRequestWithHeaders(request, filteredHeaders);\n }\n\n // Do NOT decode/normalize the pathname here. The RSC handler\n // (virtual:vinext-rsc-entry) is the single point of decoding — it calls\n // decodeURIComponent + normalizePath on the incoming URL. Decoding here\n // AND in the handler would double-decode, causing inconsistent path\n // matching between middleware and routing.\n\n // Delegate to RSC handler (which decodes + normalizes the pathname itself),\n // wrapping in the ExecutionContext ALS scope so downstream code can reach\n // ctx.waitUntil() without having ctx threaded through every call site.\n const handleFn = () => rscHandler(request, ctx);\n const result = await (ctx ? runWithExecutionContext(ctx, handleFn) : handleFn());\n\n if (result instanceof Response) {\n if (env?.ASSETS) {\n const assetFetcher = env.ASSETS;\n const assetResponse = await resolveStaticAssetSignal(result, {\n fetchAsset: (path) =>\n Promise.resolve(assetFetcher.fetch(new Request(new URL(path, request.url)))),\n });\n if (assetResponse) return assetResponse;\n }\n return result;\n }\n\n if (result === null || result === undefined) {\n return notFoundResponse();\n }\n\n return new Response(String(result), { status: 200 });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA+BA,IAAA,2BAAe,EACb,MAAM,MACJ,SACA,KACA,KACmB;CACnB,OAAO,cAAc,SAAS,KAAK,IAAI;GAE1C;AAED,eAAe,cACb,SACA,KACA,KACmB;CACnB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAMhC,IAAI,qBAAqB,IAAI,SAAS,EACpC,OAAO,kBAAkB;CAM3B,IAAI;EACF,mBAAmB,IAAI,SAAS;SAC1B;EAEN,OAAO,oBAAoB;;CAM7B;EACE,MAAM,kBAAkB,sBAAsB,QAAQ,QAAQ;EAC9D,UAAU,wBAAwB,SAAS,gBAAgB;;CAY7D,MAAM,iBAAiB,WAAW,SAAS,IAAI;CAC/C,MAAM,SAAS,OAAO,MAAM,wBAAwB,KAAK,SAAS,GAAG,UAAU;CAE/E,IAAI,kBAAkB,UAAU;EAC9B,IAAI,KAAK,QAAQ;GACf,MAAM,eAAe,IAAI;GACzB,MAAM,gBAAgB,MAAM,yBAAyB,QAAQ,EAC3D,aAAa,SACX,QAAQ,QAAQ,aAAa,MAAM,IAAI,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI,CAAC,CAAC,CAAC,EAC/E,CAAC;GACF,IAAI,eAAe,OAAO;;EAE5B,OAAO;;CAGT,IAAI,WAAW,QAAQ,WAAW,KAAA,GAChC,OAAO,kBAAkB;CAG3B,OAAO,IAAI,SAAS,OAAO,OAAO,EAAE,EAAE,QAAQ,KAAK,CAAC"}
1
+ {"version":3,"file":"app-router-entry.js","names":["__rscBasePath","__rscAssetPrefix"],"sources":["../../src/server/app-router-entry.ts"],"sourcesContent":["/**\n * Default Cloudflare Worker entry point for vinext App Router.\n *\n * Use this directly in wrangler.jsonc:\n * \"main\": \"vinext/server/app-router-entry\"\n *\n * Or import and delegate to it from a custom worker:\n * import handler from \"vinext/server/app-router-entry\";\n * return handler.fetch(request, env, ctx);\n *\n * This file runs in the RSC environment. Configure the Cloudflare plugin with:\n * cloudflare({ viteEnvironment: { name: \"rsc\", childEnvironments: [\"ssr\"] } })\n */\n\nimport \"./server-globals.js\";\n// Virtual module generated by vinext at build time. The default export is\n// the request handler; `__assetPrefix` and `__basePath` are named exports\n// inlined from next.config (both as string literals) so this worker can\n// recognise asset-shaped requests without invoking the handler. Types\n// live in `virtual-vinext-rsc-entry.d.ts`; the generator is in\n// `entries/app-rsc-entry.ts`.\nimport rscHandler, {\n __assetPrefix as __rscAssetPrefix,\n __basePath as __rscBasePath,\n} from \"virtual:vinext-rsc-entry\";\nimport { runWithExecutionContext, type ExecutionContextLike } from \"vinext/shims/request-context\";\nimport { resolveStaticAssetSignal } from \"./worker-utils.js\";\nimport {\n cloneRequestWithHeaders,\n filterInternalHeaders,\n isOpenRedirectShaped,\n} from \"./request-pipeline.js\";\nimport {\n badRequestResponse,\n notFoundResponse,\n notFoundStaticAssetResponse,\n} from \"./http-error-responses.js\";\nimport { assetPrefixPathname, isNextStaticPath } from \"../utils/asset-prefix.js\";\n\n// Precompute the path components used for `_next/static/*` 404 short-circuit\n// detection. Both `__basePath` and `__assetPrefix` are inlined as\n// compile-time constants in the generated RSC entry — see entries/app-rsc-entry.ts.\nconst __workerBasePath: string = typeof __rscBasePath === \"string\" ? __rscBasePath : \"\";\nconst __workerAssetPathPrefix: string = assetPrefixPathname(\n typeof __rscAssetPrefix === \"string\" ? __rscAssetPrefix : \"\",\n);\n\ntype WorkerAssetEnv = {\n ASSETS?: {\n fetch(request: Request): Promise<Response> | Response;\n };\n};\n\nexport default {\n async fetch(\n request: Request,\n env?: WorkerAssetEnv,\n ctx?: ExecutionContextLike,\n ): Promise<Response> {\n return handleRequest(request, env, ctx);\n },\n};\n\nasync function handleRequest(\n request: Request,\n env: WorkerAssetEnv | undefined,\n ctx: ExecutionContextLike | undefined,\n): Promise<Response> {\n const url = new URL(request.url);\n\n // Block protocol-relative URL open redirects (//evil.com/, /\\evil.com/,\n // /%5Cevil.com/, /%2F/evil.com/). Check BEFORE decode so both literal and\n // percent-encoded variants are caught — encoded forms survive segment-wise\n // decoding and would otherwise reach trailing-slash redirect emitters.\n if (isOpenRedirectShaped(url.pathname)) {\n return notFoundResponse();\n }\n\n // Validate that percent-encoding is well-formed. The RSC handler performs\n // the actual decode + normalize; we only check here to return a clean 400\n // instead of letting a malformed sequence crash downstream.\n try {\n decodeURIComponent(url.pathname);\n } catch {\n // Malformed percent-encoding (e.g. /%E0%A4%A) — return 400 instead of throwing.\n return badRequestResponse();\n }\n\n // Invalid `_next/static/*` paths short-circuit with a plain-text 404\n // instead of falling through to the RSC handler (which would render the\n // full HTML 404 page). Valid assets are served by Cloudflare's ASSETS\n // binding BEFORE the worker is invoked; only misses reach this code.\n // Matches Next.js: packages/next/src/server/lib/router-server.ts.\n if (isNextStaticPath(url.pathname, __workerBasePath, __workerAssetPathPrefix)) {\n return notFoundStaticAssetResponse();\n }\n\n // Strip internal headers from inbound requests before any handler or\n // middleware sees them. Must happen before the RSC handler runs.\n // Builds a new Headers — Request.headers is immutable in Workers.\n {\n const filteredHeaders = filterInternalHeaders(request.headers);\n request = cloneRequestWithHeaders(request, filteredHeaders);\n }\n\n // Do NOT decode/normalize the pathname here. The RSC handler\n // (virtual:vinext-rsc-entry) is the single point of decoding — it calls\n // decodeURIComponent + normalizePath on the incoming URL. Decoding here\n // AND in the handler would double-decode, causing inconsistent path\n // matching between middleware and routing.\n\n // Delegate to RSC handler (which decodes + normalizes the pathname itself),\n // wrapping in the ExecutionContext ALS scope so downstream code can reach\n // ctx.waitUntil() without having ctx threaded through every call site.\n const handleFn = () => rscHandler(request, ctx);\n const result = await (ctx ? runWithExecutionContext(ctx, handleFn) : handleFn());\n\n if (result instanceof Response) {\n if (env?.ASSETS) {\n const assetFetcher = env.ASSETS;\n const assetResponse = await resolveStaticAssetSignal(result, {\n fetchAsset: (path) =>\n Promise.resolve(assetFetcher.fetch(new Request(new URL(path, request.url)))),\n });\n if (assetResponse) return assetResponse;\n }\n return result;\n }\n\n if (result === null || result === undefined) {\n return notFoundResponse();\n }\n\n return new Response(String(result), { status: 200 });\n}\n"],"mappings":";;;;;;;;AA0CA,MAAM,mBAA2B,OAAOA,eAAkB,WAAWA,aAAgB;AACrF,MAAM,0BAAkC,oBACtC,OAAOC,kBAAqB,WAAWA,gBAAmB,GAC3D;AAQD,IAAA,2BAAe,EACb,MAAM,MACJ,SACA,KACA,KACmB;CACnB,OAAO,cAAc,SAAS,KAAK,IAAI;GAE1C;AAED,eAAe,cACb,SACA,KACA,KACmB;CACnB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAMhC,IAAI,qBAAqB,IAAI,SAAS,EACpC,OAAO,kBAAkB;CAM3B,IAAI;EACF,mBAAmB,IAAI,SAAS;SAC1B;EAEN,OAAO,oBAAoB;;CAQ7B,IAAI,iBAAiB,IAAI,UAAU,kBAAkB,wBAAwB,EAC3E,OAAO,6BAA6B;CAMtC;EACE,MAAM,kBAAkB,sBAAsB,QAAQ,QAAQ;EAC9D,UAAU,wBAAwB,SAAS,gBAAgB;;CAY7D,MAAM,iBAAiB,WAAW,SAAS,IAAI;CAC/C,MAAM,SAAS,OAAO,MAAM,wBAAwB,KAAK,SAAS,GAAG,UAAU;CAE/E,IAAI,kBAAkB,UAAU;EAC9B,IAAI,KAAK,QAAQ;GACf,MAAM,eAAe,IAAI;GACzB,MAAM,gBAAgB,MAAM,yBAAyB,QAAQ,EAC3D,aAAa,SACX,QAAQ,QAAQ,aAAa,MAAM,IAAI,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI,CAAC,CAAC,CAAC,EAC/E,CAAC;GACF,IAAI,eAAe,OAAO;;EAE5B,OAAO;;CAGT,IAAI,WAAW,QAAQ,WAAW,KAAA,GAChC,OAAO,kBAAkB;CAG3B,OAAO,IAAI,SAAS,OAAO,OAAO,EAAE,EAAE,QAAQ,KAAK,CAAC"}
@@ -9,6 +9,7 @@ import { AppRscRenderMode } from "./app-rsc-render-mode.js";
9
9
  * repeated canonicalization redirects.
10
10
  */
11
11
  declare const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = "_rsc";
12
+ declare const VINEXT_RSC_COMPATIBILITY_ID_HEADER = "X-Vinext-RSC-Compatibility-Id";
12
13
  declare const VINEXT_RSC_CONTENT_TYPE = "text/x-component";
13
14
  declare const VINEXT_RSC_VARY_HEADER: string;
14
15
  type CreateRscRequestHeadersOptions = {
@@ -20,6 +21,23 @@ type ResolveInvalidRscCacheBustingRequestOptions = {
20
21
  isRscRequest: boolean;
21
22
  request: Request;
22
23
  };
24
+ declare function getVinextRscCompatibilityId(): string | null;
25
+ declare function applyRscCompatibilityIdHeader(headers: Headers, compatibilityId?: string | null | undefined): void;
26
+ declare function isRscCompatibilityIdCompatible(responseCompatibilityId: string | null | undefined, clientCompatibilityId?: string | null | undefined): boolean;
27
+ type RscCompatibilityNavigationDecision = {
28
+ kind: "compatible";
29
+ } | {
30
+ hardNavigationTarget: string;
31
+ kind: "hard-navigate";
32
+ };
33
+ declare function resolveHardNavigationTargetFromRscResponse(responseUrl: string | null | undefined, currentHref: string, origin: string): string;
34
+ declare function resolveRscCompatibilityNavigationDecision(options: {
35
+ clientCompatibilityId?: string | null;
36
+ currentHref: string;
37
+ origin: string;
38
+ responseCompatibilityId: string | null | undefined;
39
+ responseUrl?: string | null;
40
+ }): RscCompatibilityNavigationDecision;
23
41
  declare function computeRscCacheBustingSearchParam(headers: Headers): Promise<string>;
24
42
  declare function setRscCacheBustingSearchParam(url: URL, hash: string): void;
25
43
  declare function stripRscCacheBustingSearchParam(url: URL): void;
@@ -33,5 +51,5 @@ declare function createRscRequestUrl(href: string, headers: Headers): Promise<st
33
51
  declare function createRscRedirectLocation(location: string, request: Request): Promise<string>;
34
52
  declare function resolveInvalidRscCacheBustingRequest(options: ResolveInvalidRscCacheBustingRequestOptions): Promise<Response | null>;
35
53
  //#endregion
36
- export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, resolveInvalidRscCacheBustingRequest, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
54
+ export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
37
55
  //# sourceMappingURL=app-rsc-cache-busting.d.ts.map
@@ -9,6 +9,7 @@ import { parseAppRscRenderMode } from "./app-rsc-render-mode.js";
9
9
  * repeated canonicalization redirects.
10
10
  */
11
11
  const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = "_rsc";
12
+ const VINEXT_RSC_COMPATIBILITY_ID_HEADER = "X-Vinext-RSC-Compatibility-Id";
12
13
  const VINEXT_RSC_CONTENT_TYPE = "text/x-component";
13
14
  const VINEXT_RSC_VARY_HEADER = [
14
15
  "RSC",
@@ -31,6 +32,40 @@ function encodeBase64Url(bytes) {
31
32
  function normalizeHeaderValue(value) {
32
33
  return value ?? "0";
33
34
  }
35
+ function normalizeCompatibilityId(value) {
36
+ return value && value.length > 0 ? value : null;
37
+ }
38
+ function getVinextRscCompatibilityId() {
39
+ return normalizeCompatibilityId(process.env.__VINEXT_RSC_COMPATIBILITY_ID);
40
+ }
41
+ function applyRscCompatibilityIdHeader(headers, compatibilityId = getVinextRscCompatibilityId()) {
42
+ const normalized = normalizeCompatibilityId(compatibilityId);
43
+ if (normalized) headers.set(VINEXT_RSC_COMPATIBILITY_ID_HEADER, normalized);
44
+ else headers.delete(VINEXT_RSC_COMPATIBILITY_ID_HEADER);
45
+ }
46
+ function isRscCompatibilityIdCompatible(responseCompatibilityId, clientCompatibilityId = getVinextRscCompatibilityId()) {
47
+ const normalizedResponseCompatibilityId = normalizeCompatibilityId(responseCompatibilityId);
48
+ const normalizedClientCompatibilityId = normalizeCompatibilityId(clientCompatibilityId);
49
+ return normalizedClientCompatibilityId === null || normalizedResponseCompatibilityId !== null && normalizedResponseCompatibilityId === normalizedClientCompatibilityId;
50
+ }
51
+ function resolveHardNavigationTargetFromRscResponse(responseUrl, currentHref, origin) {
52
+ if (!responseUrl) return currentHref;
53
+ const parsed = new URL(responseUrl, origin);
54
+ stripRscCacheBustingSearchParam(parsed);
55
+ const origUrl = new URL(currentHref, origin);
56
+ let pathname = stripRscSuffix(parsed.pathname);
57
+ if (origUrl.pathname.length > 1 && origUrl.pathname.endsWith("/") && !pathname.endsWith("/")) pathname += "/";
58
+ let hardNavigationTarget = pathname + parsed.search;
59
+ if (origUrl.hash) hardNavigationTarget += origUrl.hash;
60
+ return hardNavigationTarget;
61
+ }
62
+ function resolveRscCompatibilityNavigationDecision(options) {
63
+ if (isRscCompatibilityIdCompatible(options.responseCompatibilityId, options.clientCompatibilityId)) return { kind: "compatible" };
64
+ return {
65
+ hardNavigationTarget: resolveHardNavigationTargetFromRscResponse(options.responseUrl, options.currentHref, options.origin),
66
+ kind: "hard-navigate"
67
+ };
68
+ }
34
69
  function normalizeRenderModeHeaderValue(value) {
35
70
  const renderMode = parseAppRscRenderMode(value);
36
71
  return renderMode === "navigation" ? null : renderMode;
@@ -153,6 +188,6 @@ async function resolveInvalidRscCacheBustingRequest(options) {
153
188
  });
154
189
  }
155
190
  //#endregion
156
- export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, resolveInvalidRscCacheBustingRequest, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
191
+ export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
157
192
 
158
193
  //# sourceMappingURL=app-rsc-cache-busting.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-rsc-cache-busting.js","names":[],"sources":["../../src/server/app-rsc-cache-busting.ts"],"sourcesContent":["import { fnv1a64 } from \"../utils/hash.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n parseAppRscRenderMode,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.js\";\nimport {\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_URL_HEADER,\n RSC_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n VINEXT_RSC_RENDER_MODE_HEADER,\n} from \"./headers.js\";\n\n/**\n * RSC cache-busting hashes cover the headers that make a `.rsc` payload vary.\n * Client-side variant headers must survive transit through CDNs and reverse\n * proxies; stripping them changes the server hash and turns stale URLs into\n * repeated canonicalization redirects.\n */\nexport const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = \"_rsc\";\nexport const VINEXT_RSC_CONTENT_TYPE = \"text/x-component\";\n\n// Re-export so existing consumers that import from this module keep working.\nexport { VINEXT_RSC_RENDER_MODE_HEADER } from \"./headers.js\";\n\nexport const VINEXT_RSC_VARY_HEADER = [\n RSC_HEADER,\n \"Accept\",\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_URL_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n VINEXT_RSC_RENDER_MODE_HEADER,\n].join(\", \");\n\nconst CACHE_BUSTING_DIGEST_BYTES = 12;\nconst textEncoder = new TextEncoder();\n\ntype CreateRscRequestHeadersOptions = {\n interceptionContext?: string | null;\n mountedSlotsHeader?: string | null;\n renderMode?: AppRscRenderMode;\n};\n\ntype ResolveInvalidRscCacheBustingRequestOptions = {\n isRscRequest: boolean;\n request: Request;\n};\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/, \"\");\n}\n\nfunction normalizeHeaderValue(value: string | null): string {\n return value ?? \"0\";\n}\n\nfunction normalizeRenderModeHeaderValue(value: string | null): string | null {\n const renderMode = parseAppRscRenderMode(value);\n return renderMode === APP_RSC_RENDER_MODE_NAVIGATION ? null : renderMode;\n}\n\ntype CreateCacheBustingInputOptions = {\n includeRenderModeHeader?: boolean;\n};\n\nfunction createCacheBustingInput(\n headers: Headers,\n options: CreateCacheBustingInputOptions = {},\n): string | null {\n // The order of these values determines the hash. Changing it is a breaking\n // cache-key change and requires accepting the previous hash during rollout.\n const values = [\n headers.get(NEXT_ROUTER_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_STATE_TREE_HEADER),\n headers.get(NEXT_URL_HEADER),\n headers.get(VINEXT_INTERCEPTION_CONTEXT_HEADER),\n headers.get(VINEXT_MOUNTED_SLOTS_HEADER),\n ...(options.includeRenderModeHeader === false\n ? []\n : [normalizeRenderModeHeaderValue(headers.get(VINEXT_RSC_RENDER_MODE_HEADER))]),\n ];\n\n if (values.every((value) => value === null)) {\n return null;\n }\n\n return values.map(normalizeHeaderValue).join(\",\");\n}\n\nasync function sha256CacheBustingHash(input: string): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", textEncoder.encode(input));\n return encodeBase64Url(new Uint8Array(digest).subarray(0, CACHE_BUSTING_DIGEST_BYTES));\n}\n\nfunction computeLegacyRscCacheBustingSearchParam(headers: Headers): string {\n const input = createCacheBustingInput(headers);\n return input === null ? \"\" : fnv1a64(input);\n}\n\nasync function computePreviousRscCacheBustingSearchParam(headers: Headers): Promise<string | null> {\n const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });\n if (input === null) {\n return null;\n }\n\n return sha256CacheBustingHash(input);\n}\n\nfunction computePreviousLegacyRscCacheBustingSearchParam(headers: Headers): string | null {\n const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });\n return input === null ? null : fnv1a64(input);\n}\n\nfunction getSearchPairsWithoutRscCacheBusting(url: URL): string[] {\n const rawQuery = url.search.startsWith(\"?\") ? url.search.slice(1) : url.search;\n return rawQuery\n .split(\"&\")\n .filter((pair) => pair.length > 0 && !isRscCacheBustingSearchPair(pair));\n}\n\nfunction isRscCacheBustingSearchPair(pair: string): boolean {\n const separatorIndex = pair.indexOf(\"=\");\n const rawKey = separatorIndex === -1 ? pair : pair.slice(0, separatorIndex);\n\n try {\n return (\n decodeURIComponent(rawKey.replaceAll(\"+\", \" \")) === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM\n );\n } catch {\n return rawKey === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM;\n }\n}\n\nexport async function computeRscCacheBustingSearchParam(headers: Headers): Promise<string> {\n const input = createCacheBustingInput(headers);\n if (input === null) {\n return \"\";\n }\n\n return sha256CacheBustingHash(input);\n}\n\nexport function setRscCacheBustingSearchParam(url: URL, hash: string): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n\n pairs.push(\n hash.length > 0\n ? `${VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM}=${hash}`\n : VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM,\n );\n url.search = `?${pairs.join(\"&\")}`;\n}\n\nexport function stripRscCacheBustingSearchParam(url: URL): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n url.search = pairs.length > 0 ? `?${pairs.join(\"&\")}` : \"\";\n}\n\n/**\n * Remove a trailing `.rsc` suffix from a pathname. Returns the pathname\n * unchanged when the suffix is absent.\n */\nexport function stripRscSuffix(pathname: string): string {\n return pathname.endsWith(\".rsc\") ? pathname.slice(0, -4) : pathname;\n}\n\nexport function createRscRequestHeaders(options: CreateRscRequestHeadersOptions = {}): Headers {\n const headers = new Headers({\n Accept: VINEXT_RSC_CONTENT_TYPE,\n [RSC_HEADER]: \"1\",\n });\n\n if (options.interceptionContext !== undefined && options.interceptionContext !== null) {\n headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);\n }\n\n if (options.mountedSlotsHeader !== undefined && options.mountedSlotsHeader !== null) {\n headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);\n }\n\n const renderMode = options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION;\n if (renderMode !== APP_RSC_RENDER_MODE_NAVIGATION) {\n headers.set(VINEXT_RSC_RENDER_MODE_HEADER, renderMode);\n }\n\n return headers;\n}\n\nfunction toRscRequestPath(href: string): string {\n const hashIndex = href.indexOf(\"#\");\n const beforeHash = hashIndex === -1 ? href : href.slice(0, hashIndex);\n const queryIndex = beforeHash.indexOf(\"?\");\n const pathname = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);\n const query = queryIndex === -1 ? \"\" : beforeHash.slice(queryIndex);\n const normalizedPath =\n pathname.length > 1 && pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n return `${normalizedPath}.rsc${query}`;\n}\n\nexport async function createRscRequestUrl(href: string, headers: Headers): Promise<string> {\n const url = new URL(toRscRequestPath(href), \"http://vinext.local\");\n const hash = await computeRscCacheBustingSearchParam(headers);\n setRscCacheBustingSearchParam(url, hash);\n return `${url.pathname}${url.search}`;\n}\n\nexport async function createRscRedirectLocation(\n location: string,\n request: Request,\n): Promise<string> {\n const requestUrl = new URL(request.url);\n const destinationUrl = new URL(location, requestUrl);\n\n if (destinationUrl.origin !== requestUrl.origin) {\n return destinationUrl.toString();\n }\n\n const rscPath = await createRscRequestUrl(\n `${destinationUrl.pathname}${destinationUrl.search}`,\n request.headers,\n );\n return `${destinationUrl.origin}${rscPath}`;\n}\n\nexport async function resolveInvalidRscCacheBustingRequest(\n options: ResolveInvalidRscCacheBustingRequestOptions,\n): Promise<Response | null> {\n if (\n !options.isRscRequest ||\n (options.request.method !== \"GET\" && options.request.method !== \"HEAD\")\n ) {\n return null;\n }\n\n const url = new URL(options.request.url);\n const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);\n const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);\n\n if (actualHash === null && expectedHash === \"\") {\n return null;\n }\n\n const acceptedHashes = new Set<string>([expectedHash]);\n if (actualHash !== null && actualHash !== expectedHash) {\n acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));\n if (\n normalizeRenderModeHeaderValue(options.request.headers.get(VINEXT_RSC_RENDER_MODE_HEADER)) ===\n null\n ) {\n const previousHash = await computePreviousRscCacheBustingSearchParam(options.request.headers);\n const previousLegacyHash = computePreviousLegacyRscCacheBustingSearchParam(\n options.request.headers,\n );\n if (previousHash !== null) acceptedHashes.add(previousHash);\n if (previousLegacyHash !== null) acceptedHashes.add(previousLegacyHash);\n }\n }\n\n if (actualHash !== null && acceptedHashes.has(actualHash)) {\n return null;\n }\n\n setRscCacheBustingSearchParam(url, expectedHash);\n return new Response(null, {\n status: 307,\n headers: {\n Location: `${url.pathname}${url.search}`,\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-rsc-cache-busting.js","names":[],"sources":["../../src/server/app-rsc-cache-busting.ts"],"sourcesContent":["import { fnv1a64 } from \"../utils/hash.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n parseAppRscRenderMode,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.js\";\nimport {\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_URL_HEADER,\n RSC_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n VINEXT_RSC_RENDER_MODE_HEADER,\n} from \"./headers.js\";\n\n/**\n * RSC cache-busting hashes cover the headers that make a `.rsc` payload vary.\n * Client-side variant headers must survive transit through CDNs and reverse\n * proxies; stripping them changes the server hash and turns stale URLs into\n * repeated canonicalization redirects.\n */\nexport const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = \"_rsc\";\nexport const VINEXT_RSC_COMPATIBILITY_ID_HEADER = \"X-Vinext-RSC-Compatibility-Id\";\nexport const VINEXT_RSC_CONTENT_TYPE = \"text/x-component\";\n\n// Re-export so existing consumers that import from this module keep working.\nexport { VINEXT_RSC_RENDER_MODE_HEADER } from \"./headers.js\";\n\nexport const VINEXT_RSC_VARY_HEADER = [\n RSC_HEADER,\n \"Accept\",\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_URL_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n VINEXT_RSC_RENDER_MODE_HEADER,\n].join(\", \");\n\nconst CACHE_BUSTING_DIGEST_BYTES = 12;\nconst textEncoder = new TextEncoder();\n\ntype CreateRscRequestHeadersOptions = {\n interceptionContext?: string | null;\n mountedSlotsHeader?: string | null;\n renderMode?: AppRscRenderMode;\n};\n\ntype ResolveInvalidRscCacheBustingRequestOptions = {\n isRscRequest: boolean;\n request: Request;\n};\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/, \"\");\n}\n\nfunction normalizeHeaderValue(value: string | null): string {\n return value ?? \"0\";\n}\n\nfunction normalizeCompatibilityId(value: string | null | undefined): string | null {\n return value && value.length > 0 ? value : null;\n}\n\nexport function getVinextRscCompatibilityId(): string | null {\n return normalizeCompatibilityId(process.env.__VINEXT_RSC_COMPATIBILITY_ID);\n}\n\nexport function applyRscCompatibilityIdHeader(\n headers: Headers,\n compatibilityId: string | null | undefined = getVinextRscCompatibilityId(),\n): void {\n const normalized = normalizeCompatibilityId(compatibilityId);\n if (normalized) {\n headers.set(VINEXT_RSC_COMPATIBILITY_ID_HEADER, normalized);\n } else {\n headers.delete(VINEXT_RSC_COMPATIBILITY_ID_HEADER);\n }\n}\n\nexport function isRscCompatibilityIdCompatible(\n responseCompatibilityId: string | null | undefined,\n clientCompatibilityId: string | null | undefined = getVinextRscCompatibilityId(),\n): boolean {\n const normalizedResponseCompatibilityId = normalizeCompatibilityId(responseCompatibilityId);\n const normalizedClientCompatibilityId = normalizeCompatibilityId(clientCompatibilityId);\n return (\n normalizedClientCompatibilityId === null ||\n (normalizedResponseCompatibilityId !== null &&\n normalizedResponseCompatibilityId === normalizedClientCompatibilityId)\n );\n}\n\ntype RscCompatibilityNavigationDecision =\n | { kind: \"compatible\" }\n | { hardNavigationTarget: string; kind: \"hard-navigate\" };\n\nexport function resolveHardNavigationTargetFromRscResponse(\n responseUrl: string | null | undefined,\n currentHref: string,\n origin: string,\n): string {\n if (!responseUrl) {\n return currentHref;\n }\n\n const parsed = new URL(responseUrl, origin);\n stripRscCacheBustingSearchParam(parsed);\n const origUrl = new URL(currentHref, origin);\n let pathname = stripRscSuffix(parsed.pathname);\n if (origUrl.pathname.length > 1 && origUrl.pathname.endsWith(\"/\") && !pathname.endsWith(\"/\")) {\n pathname += \"/\";\n }\n\n let hardNavigationTarget = pathname + parsed.search;\n if (origUrl.hash) hardNavigationTarget += origUrl.hash;\n return hardNavigationTarget;\n}\n\nexport function resolveRscCompatibilityNavigationDecision(options: {\n clientCompatibilityId?: string | null;\n currentHref: string;\n origin: string;\n responseCompatibilityId: string | null | undefined;\n responseUrl?: string | null;\n}): RscCompatibilityNavigationDecision {\n if (\n isRscCompatibilityIdCompatible(options.responseCompatibilityId, options.clientCompatibilityId)\n ) {\n return { kind: \"compatible\" };\n }\n\n return {\n hardNavigationTarget: resolveHardNavigationTargetFromRscResponse(\n options.responseUrl,\n options.currentHref,\n options.origin,\n ),\n kind: \"hard-navigate\",\n };\n}\n\nfunction normalizeRenderModeHeaderValue(value: string | null): string | null {\n const renderMode = parseAppRscRenderMode(value);\n return renderMode === APP_RSC_RENDER_MODE_NAVIGATION ? null : renderMode;\n}\n\ntype CreateCacheBustingInputOptions = {\n includeRenderModeHeader?: boolean;\n};\n\nfunction createCacheBustingInput(\n headers: Headers,\n options: CreateCacheBustingInputOptions = {},\n): string | null {\n // The order of these values determines the hash. Changing it is a breaking\n // cache-key change and requires accepting the previous hash during rollout.\n const values = [\n headers.get(NEXT_ROUTER_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_STATE_TREE_HEADER),\n headers.get(NEXT_URL_HEADER),\n headers.get(VINEXT_INTERCEPTION_CONTEXT_HEADER),\n headers.get(VINEXT_MOUNTED_SLOTS_HEADER),\n ...(options.includeRenderModeHeader === false\n ? []\n : [normalizeRenderModeHeaderValue(headers.get(VINEXT_RSC_RENDER_MODE_HEADER))]),\n ];\n\n if (values.every((value) => value === null)) {\n return null;\n }\n\n return values.map(normalizeHeaderValue).join(\",\");\n}\n\nasync function sha256CacheBustingHash(input: string): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", textEncoder.encode(input));\n return encodeBase64Url(new Uint8Array(digest).subarray(0, CACHE_BUSTING_DIGEST_BYTES));\n}\n\nfunction computeLegacyRscCacheBustingSearchParam(headers: Headers): string {\n const input = createCacheBustingInput(headers);\n return input === null ? \"\" : fnv1a64(input);\n}\n\nasync function computePreviousRscCacheBustingSearchParam(headers: Headers): Promise<string | null> {\n const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });\n if (input === null) {\n return null;\n }\n\n return sha256CacheBustingHash(input);\n}\n\nfunction computePreviousLegacyRscCacheBustingSearchParam(headers: Headers): string | null {\n const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });\n return input === null ? null : fnv1a64(input);\n}\n\nfunction getSearchPairsWithoutRscCacheBusting(url: URL): string[] {\n const rawQuery = url.search.startsWith(\"?\") ? url.search.slice(1) : url.search;\n return rawQuery\n .split(\"&\")\n .filter((pair) => pair.length > 0 && !isRscCacheBustingSearchPair(pair));\n}\n\nfunction isRscCacheBustingSearchPair(pair: string): boolean {\n const separatorIndex = pair.indexOf(\"=\");\n const rawKey = separatorIndex === -1 ? pair : pair.slice(0, separatorIndex);\n\n try {\n return (\n decodeURIComponent(rawKey.replaceAll(\"+\", \" \")) === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM\n );\n } catch {\n return rawKey === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM;\n }\n}\n\nexport async function computeRscCacheBustingSearchParam(headers: Headers): Promise<string> {\n const input = createCacheBustingInput(headers);\n if (input === null) {\n return \"\";\n }\n\n return sha256CacheBustingHash(input);\n}\n\nexport function setRscCacheBustingSearchParam(url: URL, hash: string): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n\n pairs.push(\n hash.length > 0\n ? `${VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM}=${hash}`\n : VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM,\n );\n url.search = `?${pairs.join(\"&\")}`;\n}\n\nexport function stripRscCacheBustingSearchParam(url: URL): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n url.search = pairs.length > 0 ? `?${pairs.join(\"&\")}` : \"\";\n}\n\n/**\n * Remove a trailing `.rsc` suffix from a pathname. Returns the pathname\n * unchanged when the suffix is absent.\n */\nexport function stripRscSuffix(pathname: string): string {\n return pathname.endsWith(\".rsc\") ? pathname.slice(0, -4) : pathname;\n}\n\nexport function createRscRequestHeaders(options: CreateRscRequestHeadersOptions = {}): Headers {\n const headers = new Headers({\n Accept: VINEXT_RSC_CONTENT_TYPE,\n [RSC_HEADER]: \"1\",\n });\n\n if (options.interceptionContext !== undefined && options.interceptionContext !== null) {\n headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);\n }\n\n if (options.mountedSlotsHeader !== undefined && options.mountedSlotsHeader !== null) {\n headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);\n }\n\n const renderMode = options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION;\n if (renderMode !== APP_RSC_RENDER_MODE_NAVIGATION) {\n headers.set(VINEXT_RSC_RENDER_MODE_HEADER, renderMode);\n }\n\n return headers;\n}\n\nfunction toRscRequestPath(href: string): string {\n const hashIndex = href.indexOf(\"#\");\n const beforeHash = hashIndex === -1 ? href : href.slice(0, hashIndex);\n const queryIndex = beforeHash.indexOf(\"?\");\n const pathname = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);\n const query = queryIndex === -1 ? \"\" : beforeHash.slice(queryIndex);\n const normalizedPath =\n pathname.length > 1 && pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n return `${normalizedPath}.rsc${query}`;\n}\n\nexport async function createRscRequestUrl(href: string, headers: Headers): Promise<string> {\n const url = new URL(toRscRequestPath(href), \"http://vinext.local\");\n const hash = await computeRscCacheBustingSearchParam(headers);\n setRscCacheBustingSearchParam(url, hash);\n return `${url.pathname}${url.search}`;\n}\n\nexport async function createRscRedirectLocation(\n location: string,\n request: Request,\n): Promise<string> {\n const requestUrl = new URL(request.url);\n const destinationUrl = new URL(location, requestUrl);\n\n if (destinationUrl.origin !== requestUrl.origin) {\n return destinationUrl.toString();\n }\n\n const rscPath = await createRscRequestUrl(\n `${destinationUrl.pathname}${destinationUrl.search}`,\n request.headers,\n );\n return `${destinationUrl.origin}${rscPath}`;\n}\n\nexport async function resolveInvalidRscCacheBustingRequest(\n options: ResolveInvalidRscCacheBustingRequestOptions,\n): Promise<Response | null> {\n if (\n !options.isRscRequest ||\n (options.request.method !== \"GET\" && options.request.method !== \"HEAD\")\n ) {\n return null;\n }\n\n const url = new URL(options.request.url);\n const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);\n const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);\n\n if (actualHash === null && expectedHash === \"\") {\n return null;\n }\n\n const acceptedHashes = new Set<string>([expectedHash]);\n if (actualHash !== null && actualHash !== expectedHash) {\n acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));\n if (\n normalizeRenderModeHeaderValue(options.request.headers.get(VINEXT_RSC_RENDER_MODE_HEADER)) ===\n null\n ) {\n const previousHash = await computePreviousRscCacheBustingSearchParam(options.request.headers);\n const previousLegacyHash = computePreviousLegacyRscCacheBustingSearchParam(\n options.request.headers,\n );\n if (previousHash !== null) acceptedHashes.add(previousHash);\n if (previousLegacyHash !== null) acceptedHashes.add(previousLegacyHash);\n }\n }\n\n if (actualHash !== null && acceptedHashes.has(actualHash)) {\n return null;\n }\n\n setRscCacheBustingSearchParam(url, expectedHash);\n return new Response(null, {\n status: 307,\n headers: {\n Location: `${url.pathname}${url.search}`,\n },\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ //#region src/server/app-rsc-embedded-chunks.d.ts
2
+ declare const RSC_EMBEDDED_BINARY_CHUNK = 3;
3
+ type RscEmbeddedChunk = string | [typeof RSC_EMBEDDED_BINARY_CHUNK, string];
4
+ declare function bytesToBase64(bytes: Uint8Array): string;
5
+ declare function decodeRscEmbeddedChunk(chunk: RscEmbeddedChunk): Uint8Array;
6
+ declare function concatUint8Arrays(chunks: readonly Uint8Array[]): Uint8Array<ArrayBuffer>;
7
+ //#endregion
8
+ export { RSC_EMBEDDED_BINARY_CHUNK, RscEmbeddedChunk, bytesToBase64, concatUint8Arrays, decodeRscEmbeddedChunk };
9
+ //# sourceMappingURL=app-rsc-embedded-chunks.d.ts.map
@@ -0,0 +1,34 @@
1
+ //#region src/server/app-rsc-embedded-chunks.ts
2
+ const RSC_EMBEDDED_BINARY_CHUNK = 3;
3
+ const BASE64_CHUNK_SIZE = 32768;
4
+ const textEncoder = new TextEncoder();
5
+ function bytesToBase64(bytes) {
6
+ let binary = "";
7
+ for (let offset = 0; offset < bytes.byteLength; offset += BASE64_CHUNK_SIZE) binary += String.fromCharCode(...bytes.subarray(offset, offset + BASE64_CHUNK_SIZE));
8
+ return btoa(binary);
9
+ }
10
+ function base64ToBytes(base64) {
11
+ const binary = atob(base64);
12
+ const bytes = new Uint8Array(binary.length);
13
+ for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
14
+ return bytes;
15
+ }
16
+ function decodeRscEmbeddedChunk(chunk) {
17
+ if (typeof chunk === "string") return textEncoder.encode(chunk);
18
+ return base64ToBytes(chunk[1]);
19
+ }
20
+ function concatUint8Arrays(chunks) {
21
+ let totalLength = 0;
22
+ for (const chunk of chunks) totalLength += chunk.byteLength;
23
+ const result = new Uint8Array(totalLength);
24
+ let offset = 0;
25
+ for (const chunk of chunks) {
26
+ result.set(chunk, offset);
27
+ offset += chunk.byteLength;
28
+ }
29
+ return result;
30
+ }
31
+ //#endregion
32
+ export { RSC_EMBEDDED_BINARY_CHUNK, bytesToBase64, concatUint8Arrays, decodeRscEmbeddedChunk };
33
+
34
+ //# sourceMappingURL=app-rsc-embedded-chunks.js.map