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":"file-based-metadata.js","names":[],"sources":["../../src/server/file-based-metadata.ts"],"sourcesContent":["import type { Metadata } from \"vinext/shims/metadata\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { fillRoutePatternSegments, routePattern } from \"../routing/route-pattern.js\";\nimport {\n getMetadataImageRouteKind,\n getMetadataRouteKind,\n isValidMetadataImageId,\n type MetadataFileRoute,\n type MetadataRouteHeadData,\n} from \"./metadata-routes.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\n\ntype IconEntry = {\n url: string | URL;\n sizes?: string;\n type?: string;\n media?: string;\n};\n\ntype AppleIconEntry = {\n url: string | URL;\n sizes?: string;\n type?: string;\n};\n\ntype SocialImageEntry = {\n url: string | URL;\n width?: number;\n height?: number;\n alt?: string;\n type?: string;\n};\n\ntype DynamicImageSize = {\n width?: number;\n height?: number;\n};\n\ntype DynamicImageMetadataSource = {\n id?: string | number;\n alt?: string;\n contentType?: string;\n size?: DynamicImageSize;\n};\n\ntype FileBasedMetadataSource = {\n routeSegments: readonly string[];\n metadata: Metadata | null;\n};\n\ntype FileBasedMetadataOptions = {\n routeSegments?: readonly string[] | null;\n metadataSources?: readonly FileBasedMetadataSource[] | null;\n};\n\ntype IconMap = {\n icon?: string | URL | IconEntry | IconEntry[];\n shortcut?: string | URL | Array<string | URL>;\n apple?: string | URL | AppleIconEntry | AppleIconEntry[];\n other?: Array<{ rel: string; url: string | URL; sizes?: string; type?: string }>;\n};\n\nfunction routeApplies(routePath: string, routePrefix: string): boolean {\n if (!routePrefix) {\n return true;\n }\n return routePath === routePrefix || routePath.startsWith(`${routePrefix}/`);\n}\n\nfunction routeScore(routePrefix: string): number {\n return routePrefix.split(\"/\").filter(Boolean).length;\n}\n\nfunction routeSegmentsApply(\n routeSegments: readonly string[],\n routePrefixSegments: readonly string[],\n): boolean {\n if (routePrefixSegments.length > routeSegments.length) {\n return false;\n }\n\n for (let index = 0; index < routePrefixSegments.length; index++) {\n if (routeSegments[index] !== routePrefixSegments[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction removeParallelRouteSegments(routeSegments: readonly string[]): string[] {\n return routeSegments.filter((segment) => !segment.startsWith(\"@\"));\n}\n\nfunction routeSegmentsApplyWithParallelSlots(\n routeSegments: readonly string[],\n routePrefixSegments: readonly string[],\n): boolean {\n if (routeSegmentsApply(routeSegments, routePrefixSegments)) {\n return true;\n }\n\n const visiblePrefixSegments = removeParallelRouteSegments(routePrefixSegments);\n return (\n visiblePrefixSegments.length !== routePrefixSegments.length &&\n routeSegmentsApply(routeSegments, visiblePrefixSegments)\n );\n}\n\nfunction routeSpecificity(route: MetadataFileRoute): number {\n return route.routeSegments?.length ?? routeScore(route.routePrefix);\n}\n\nfunction selectDeepestRoutes(\n metadataRoutes: readonly MetadataFileRoute[] | null | undefined,\n kind: MetadataRouteHeadData[\"kind\"],\n routePath: string,\n params: AppPageParams,\n routeSegments: readonly string[] | null | undefined,\n): MetadataFileRoute[] {\n if (!metadataRoutes || metadataRoutes.length === 0) {\n return [];\n }\n\n let selectedScore = -1;\n const selectedRoutes: MetadataFileRoute[] = [];\n\n for (const route of metadataRoutes) {\n const routeKind = route.headData?.kind ?? getMetadataRouteKind(route);\n\n if (routeKind !== kind) {\n continue;\n }\n\n if (routeSegments && route.routeSegments) {\n // Raw app-tree segments are authoritative when present. Falling back to\n // visible URL prefixes here would reintroduce route-group collisions.\n if (!routeSegmentsApplyWithParallelSlots(routeSegments, route.routeSegments)) {\n continue;\n }\n const currentScore = routeSpecificity(route);\n if (currentScore > selectedScore) {\n selectedScore = currentScore;\n selectedRoutes.length = 0;\n selectedRoutes.push(route);\n continue;\n }\n\n if (currentScore === selectedScore) {\n selectedRoutes.push(route);\n }\n continue;\n }\n\n const routePrefix = route.routePrefix;\n const resolvedRoutePrefix = fillRoutePatternSegments(routePrefix, params);\n const normalizedRoutePrefix = routePattern(routePrefix);\n if (\n !routeApplies(routePath, routePrefix) &&\n !routeApplies(routePath, normalizedRoutePrefix) &&\n (!resolvedRoutePrefix || !routeApplies(routePath, resolvedRoutePrefix))\n ) {\n continue;\n }\n\n const currentScore = routeSpecificity(route);\n if (currentScore > selectedScore) {\n selectedScore = currentScore;\n selectedRoutes.length = 0;\n selectedRoutes.push(route);\n continue;\n }\n\n if (currentScore === selectedScore) {\n selectedRoutes.push(route);\n }\n }\n\n return selectedRoutes;\n}\n\nfunction isStringOrUrl(value: unknown): value is string | URL {\n return typeof value === \"string\" || (typeof value === \"object\" && value instanceof URL);\n}\n\nfunction normalizeIconDescriptor(value: unknown): IconEntry | null {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return null;\n }\n\n const urlValue = Reflect.get(value, \"url\");\n if (!isStringOrUrl(urlValue)) {\n return null;\n }\n\n const entry: IconEntry = { url: urlValue };\n\n const sizesValue = Reflect.get(value, \"sizes\");\n if (typeof sizesValue === \"string\") {\n entry.sizes = sizesValue;\n }\n\n const typeValue = Reflect.get(value, \"type\");\n if (typeof typeValue === \"string\") {\n entry.type = typeValue;\n }\n\n const mediaValue = Reflect.get(value, \"media\");\n if (typeof mediaValue === \"string\") {\n entry.media = mediaValue;\n }\n\n return entry;\n}\n\nfunction normalizeIconValue(value: unknown): IconEntry | null {\n if (isStringOrUrl(value)) {\n return { url: value };\n }\n\n return normalizeIconDescriptor(value);\n}\n\nfunction normalizeIconValueList(values: readonly unknown[]): IconEntry[] {\n const normalizedEntries: IconEntry[] = [];\n for (const value of values) {\n const normalizedValue = normalizeIconValue(value);\n if (normalizedValue) {\n normalizedEntries.push(normalizedValue);\n }\n }\n return normalizedEntries;\n}\n\nfunction normalizeIconEntries(icon: NonNullable<Metadata[\"icons\"]>): IconEntry[] {\n const normalizedTopLevelValue = normalizeIconValue(icon);\n if (normalizedTopLevelValue) {\n return [normalizedTopLevelValue];\n }\n\n if (Array.isArray(icon)) {\n return normalizeIconValueList(icon);\n }\n\n if (!isIconMap(icon)) {\n return [];\n }\n\n const iconValue = icon.icon;\n if (!iconValue) {\n return [];\n }\n\n if (Array.isArray(iconValue)) {\n return normalizeIconValueList(iconValue);\n }\n\n const normalizedValue = normalizeIconValue(iconValue);\n return normalizedValue ? [normalizedValue] : [];\n}\n\nfunction isIconMap(value: Metadata[\"icons\"]): value is IconMap {\n if (!value || typeof value !== \"object\" || value instanceof URL || Array.isArray(value)) {\n return false;\n }\n return normalizeIconValue(value) === null;\n}\n\nfunction cloneIconMap(value: Metadata[\"icons\"]): IconMap {\n if (!value) {\n return {};\n }\n\n if (isIconMap(value)) {\n return { ...value };\n }\n\n const iconEntries = normalizeIconEntries(value);\n return iconEntries.length > 0 ? { icon: iconEntries } : {};\n}\n\nfunction buildIconEntry(headData: MetadataRouteHeadData): IconEntry | null {\n if (headData.kind !== \"favicon\" && headData.kind !== \"icon\") {\n return null;\n }\n\n const iconEntry: IconEntry = {\n url: headData.href,\n };\n if (headData.sizes) {\n iconEntry.sizes = headData.sizes;\n }\n if (headData.type) {\n iconEntry.type = headData.type;\n }\n return iconEntry;\n}\n\nfunction buildAppleEntry(headData: MetadataRouteHeadData): AppleIconEntry | null {\n if (headData.kind !== \"apple\") {\n return null;\n }\n\n const appleEntry: AppleIconEntry = {\n url: headData.href,\n };\n if (headData.sizes) {\n appleEntry.sizes = headData.sizes;\n }\n if (headData.type) {\n appleEntry.type = headData.type;\n }\n return appleEntry;\n}\n\nfunction normalizeAppleEntry(value: string | URL | AppleIconEntry): AppleIconEntry {\n if (isStringOrUrl(value)) {\n return { url: value };\n }\n return { ...value };\n}\n\nfunction buildSocialEntry(headData: MetadataRouteHeadData): SocialImageEntry | null {\n if (headData.kind !== \"openGraph\" && headData.kind !== \"twitter\") {\n return null;\n }\n\n const socialEntry: SocialImageEntry = {\n url: headData.href,\n };\n if (headData.width !== undefined) {\n socialEntry.width = headData.width;\n }\n if (headData.height !== undefined) {\n socialEntry.height = headData.height;\n }\n if (headData.alt) {\n socialEntry.alt = headData.alt;\n }\n if (headData.type) {\n socialEntry.type = headData.type;\n }\n return socialEntry;\n}\n\nfunction normalizeMetadataImageId(route: MetadataFileRoute, id: string | number): string | null {\n const normalizedId = String(id);\n if (!isValidMetadataImageId(normalizedId)) {\n console.warn(\n `[vinext] Skipping metadata route ${route.servedUrl} image id \"${normalizedId}\" because metadata image ids must match /^[a-zA-Z0-9-_.]+$/.`,\n );\n return null;\n }\n return normalizedId;\n}\n\nfunction withContentHash(href: string, contentHash?: string): string {\n if (!contentHash) {\n return href;\n }\n return `${href}?${contentHash}`;\n}\n\nfunction hasOwnProperty(source: object | null | undefined, key: string): boolean {\n return Boolean(source && Object.prototype.hasOwnProperty.call(source, key));\n}\n\nfunction hasOpenGraphImages(metadata: Metadata | null | undefined): boolean {\n return hasOwnProperty(metadata?.openGraph, \"images\");\n}\n\nfunction hasTwitterImages(metadata: Metadata | null | undefined): boolean {\n return hasOwnProperty(metadata?.twitter, \"images\");\n}\n\nfunction hasIcons(metadata: Metadata | null | undefined): boolean {\n return Boolean(metadata?.icons);\n}\n\nfunction getMetadataSourceForRoute(\n route: MetadataFileRoute,\n options: FileBasedMetadataOptions | undefined,\n fallbackMetadata: Metadata | null,\n): Metadata | null {\n if (!options?.metadataSources) {\n return fallbackMetadata;\n }\n\n if (!route.routeSegments) {\n return null;\n }\n\n for (let index = options.metadataSources.length - 1; index >= 0; index--) {\n const source = options.metadataSources[index];\n if (routeSegmentsApplyWithParallelSlots(source.routeSegments, route.routeSegments)) {\n return source.metadata;\n }\n }\n\n return null;\n}\n\nfunction socialRouteHasExplicitImagesAtSource(\n route: MetadataFileRoute,\n kind: \"openGraph\" | \"twitter\",\n options: FileBasedMetadataOptions | undefined,\n fallbackMetadata: Metadata | null,\n): boolean {\n const sourceMetadata = getMetadataSourceForRoute(route, options, fallbackMetadata);\n return kind === \"openGraph\"\n ? hasOpenGraphImages(sourceMetadata)\n : hasTwitterImages(sourceMetadata);\n}\n\nfunction iconRouteHasExplicitIconsAtSource(\n route: MetadataFileRoute,\n options: FileBasedMetadataOptions | undefined,\n fallbackMetadata: Metadata | null,\n): boolean {\n // Next suppresses file icon routes when any resolved icons metadata exists.\n // Social image routes stay segment-scoped instead of using this merged fallback.\n return hasIcons(fallbackMetadata) || hasIcons(getMetadataSourceForRoute(route, options, null));\n}\n\nfunction readStringProperty(source: object, key: string): string | undefined {\n const value = Reflect.get(source, key);\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction readNumberProperty(source: object, key: string): number | undefined {\n const value = Reflect.get(source, key);\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction readStringOrNumberProperty(source: object, key: string): string | number | undefined {\n const value = Reflect.get(source, key);\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return undefined;\n}\n\nfunction readSizeProperty(source: object): DynamicImageSize | undefined {\n const sizeValue = Reflect.get(source, \"size\");\n if (typeof sizeValue !== \"object\" || sizeValue === null) {\n return undefined;\n }\n\n const width = readNumberProperty(sizeValue, \"width\");\n const height = readNumberProperty(sizeValue, \"height\");\n if (width === undefined && height === undefined) {\n return undefined;\n }\n\n return { width, height };\n}\n\nfunction readDynamicImageMetadataSource(source: object): DynamicImageMetadataSource {\n return {\n id: readStringOrNumberProperty(source, \"id\"),\n alt: readStringProperty(source, \"alt\"),\n contentType: readStringProperty(source, \"contentType\"),\n size: readSizeProperty(source),\n };\n}\n\nasync function resolveDynamicImageMetadataSources(\n route: MetadataFileRoute,\n params: AppPageParams,\n): Promise<DynamicImageMetadataSource[]> {\n if (!route.module || typeof route.module !== \"object\") {\n return [];\n }\n\n const generateImageMetadata = Reflect.get(route.module, \"generateImageMetadata\");\n if (typeof generateImageMetadata !== \"function\") {\n return [readDynamicImageMetadataSource(route.module)];\n }\n\n const result = await generateImageMetadata({ params: makeThenableParams(params) });\n if (!Array.isArray(result)) {\n return [];\n }\n\n const sources: DynamicImageMetadataSource[] = [];\n for (const entry of result) {\n if (typeof entry === \"object\" && entry !== null) {\n const source = readDynamicImageMetadataSource(entry);\n if (source.id === undefined) {\n console.warn(\n `[vinext] Skipping metadata route ${route.servedUrl} image metadata entry because generateImageMetadata entries must include an id.`,\n );\n continue;\n }\n sources.push(source);\n }\n }\n return sources;\n}\n\nasync function resolveRouteHeadData(\n route: MetadataFileRoute,\n params: AppPageParams,\n): Promise<MetadataRouteHeadData[]> {\n if (!route.isDynamic || !route.module || typeof route.module !== \"object\") {\n return route.headData ? [route.headData] : [];\n }\n\n const routeKind = getMetadataImageRouteKind(route);\n if (!routeKind) {\n return route.headData ? [route.headData] : [];\n }\n\n // servedUrl must stay query-free here; content hashes are appended after dynamic segment filling.\n const resolvedUrl = fillRoutePatternSegments(route.servedUrl, params);\n if (!resolvedUrl) {\n console.warn(\n `[vinext] Skipping metadata route ${route.servedUrl} because params did not fill all dynamic segments.`,\n );\n return [];\n }\n const metadataSources = await resolveDynamicImageMetadataSources(route, params);\n const resolvedHeadData: MetadataRouteHeadData[] = [];\n\n for (const metadataSource of metadataSources) {\n let hrefBase = resolvedUrl;\n if (metadataSource.id !== undefined) {\n const normalizedId = normalizeMetadataImageId(route, metadataSource.id);\n if (!normalizedId) {\n continue;\n }\n hrefBase = `${resolvedUrl}/${normalizedId}`;\n }\n const href = withContentHash(hrefBase, route.contentHash);\n const contentType = metadataSource.contentType ?? route.contentType;\n const size = metadataSource.size;\n\n if (routeKind === \"icon\" || routeKind === \"apple\") {\n let sizes: string | undefined;\n if (size?.width !== undefined && size.height !== undefined) {\n sizes = `${size.width}x${size.height}`;\n }\n\n resolvedHeadData.push({\n kind: routeKind,\n href,\n sizes,\n type: contentType,\n });\n continue;\n }\n\n resolvedHeadData.push({\n kind: routeKind,\n href,\n alt: metadataSource.alt,\n height: size?.height,\n type: contentType,\n width: size?.width,\n });\n }\n\n return resolvedHeadData;\n}\n\nasync function resolveHeadDataList(\n routes: MetadataFileRoute[],\n params: AppPageParams,\n): Promise<MetadataRouteHeadData[]> {\n const headDataList = await Promise.all(\n routes.map((route) => resolveRouteHeadData(route, params)),\n );\n return headDataList.flat();\n}\n\nexport async function applyFileBasedMetadata(\n metadata: Metadata | null,\n routePath: string,\n params: AppPageParams,\n metadataRoutes: readonly MetadataFileRoute[] | null | undefined,\n options?: FileBasedMetadataOptions,\n): Promise<Metadata | null> {\n if (!metadataRoutes || metadataRoutes.length === 0) {\n return metadata;\n }\n\n const routeSegments = options?.routeSegments ?? null;\n const faviconRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"favicon\",\n routePath,\n params,\n routeSegments,\n );\n const iconRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"icon\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !iconRouteHasExplicitIconsAtSource(route, options, metadata));\n const appleRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"apple\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !iconRouteHasExplicitIconsAtSource(route, options, metadata));\n const openGraphRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"openGraph\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !socialRouteHasExplicitImagesAtSource(route, \"openGraph\", options, metadata));\n const twitterRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"twitter\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !socialRouteHasExplicitImagesAtSource(route, \"twitter\", options, metadata));\n const manifestRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"manifest\",\n routePath,\n params,\n routeSegments,\n );\n\n const [\n faviconHeadData,\n iconHeadData,\n appleHeadData,\n openGraphHeadData,\n twitterHeadData,\n manifestHeadData,\n ] = await Promise.all([\n resolveHeadDataList(faviconRoutes, params),\n resolveHeadDataList(iconRoutes, params),\n resolveHeadDataList(appleRoutes, params),\n resolveHeadDataList(openGraphRoutes, params),\n resolveHeadDataList(twitterRoutes, params),\n resolveHeadDataList(manifestRoutes, params),\n ]);\n\n if (\n !metadata &&\n faviconHeadData.length === 0 &&\n iconHeadData.length === 0 &&\n appleHeadData.length === 0 &&\n openGraphHeadData.length === 0 &&\n twitterHeadData.length === 0 &&\n manifestHeadData.length === 0\n ) {\n return null;\n }\n\n const nextMetadata: Metadata = metadata ? { ...metadata } : {};\n\n const faviconEntries: IconEntry[] = [];\n for (const headData of faviconHeadData) {\n const iconEntry = buildIconEntry(headData);\n if (iconEntry) {\n faviconEntries.push(iconEntry);\n }\n }\n if (faviconEntries.length > 0) {\n const nextIcons = cloneIconMap(nextMetadata.icons);\n const normalizedIcons = normalizeIconEntries(nextIcons);\n nextIcons.icon = [...faviconEntries, ...normalizedIcons];\n nextMetadata.icons = nextIcons;\n }\n\n {\n const nextIcons = cloneIconMap(nextMetadata.icons);\n\n const iconEntries: IconEntry[] = [];\n for (const headData of iconHeadData) {\n const iconEntry = buildIconEntry(headData);\n if (iconEntry) {\n iconEntries.push(iconEntry);\n }\n }\n if (iconEntries.length > 0) {\n const normalizedIcons = normalizeIconEntries(nextIcons);\n nextIcons.icon = [...iconEntries, ...normalizedIcons];\n }\n\n const appleEntries: AppleIconEntry[] = [];\n for (const headData of appleHeadData) {\n const appleEntry = buildAppleEntry(headData);\n if (appleEntry) {\n appleEntries.push(appleEntry);\n }\n }\n if (appleEntries.length > 0) {\n const existingApple = nextIcons.apple;\n const normalizedAppleEntries: AppleIconEntry[] = [];\n if (Array.isArray(existingApple)) {\n for (const entry of existingApple) {\n normalizedAppleEntries.push(normalizeAppleEntry(entry));\n }\n } else if (existingApple) {\n normalizedAppleEntries.push(normalizeAppleEntry(existingApple));\n }\n nextIcons.apple = [...appleEntries, ...normalizedAppleEntries];\n }\n\n if (iconEntries.length > 0 || appleEntries.length > 0) {\n nextMetadata.icons = nextIcons;\n }\n }\n\n if (openGraphHeadData.length > 0) {\n const socialEntries: SocialImageEntry[] = [];\n for (const headData of openGraphHeadData) {\n const socialEntry = buildSocialEntry(headData);\n if (socialEntry) {\n socialEntries.push(socialEntry);\n }\n }\n if (socialEntries.length > 0) {\n const nextOpenGraph: NonNullable<Metadata[\"openGraph\"]> = nextMetadata.openGraph\n ? { ...nextMetadata.openGraph }\n : {};\n nextOpenGraph.images = socialEntries;\n nextMetadata.openGraph = nextOpenGraph;\n }\n }\n\n if (twitterHeadData.length > 0) {\n const socialEntries: SocialImageEntry[] = [];\n for (const headData of twitterHeadData) {\n const socialEntry = buildSocialEntry(headData);\n if (socialEntry) {\n socialEntries.push(socialEntry);\n }\n }\n if (socialEntries.length > 0) {\n const nextTwitter: NonNullable<Metadata[\"twitter\"]> = nextMetadata.twitter\n ? { ...nextMetadata.twitter }\n : {};\n nextTwitter.images = socialEntries;\n nextMetadata.twitter = nextTwitter;\n }\n }\n\n if (manifestHeadData.length > 0 && manifestHeadData[0].kind === \"manifest\") {\n nextMetadata.manifest = manifestHeadData[0].href;\n }\n\n return nextMetadata;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"file-based-metadata.js","names":[],"sources":["../../src/server/file-based-metadata.ts"],"sourcesContent":["import type { Metadata } from \"vinext/shims/metadata\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { fillRoutePatternSegments, routePattern } from \"../routing/route-pattern.js\";\nimport { addBasePathToPathname, hasBasePath } from \"../utils/base-path.js\";\nimport {\n getMetadataImageRouteKind,\n getMetadataRouteKind,\n isValidMetadataImageId,\n type MetadataFileRoute,\n type MetadataRouteHeadData,\n} from \"./metadata-routes.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\n\ntype IconEntry = {\n url: string | URL;\n sizes?: string;\n type?: string;\n media?: string;\n};\n\ntype AppleIconEntry = {\n url: string | URL;\n sizes?: string;\n type?: string;\n};\n\ntype SocialImageEntry = {\n url: string | URL;\n width?: number;\n height?: number;\n alt?: string;\n type?: string;\n metadataRoute?: true;\n};\n\ntype DynamicImageSize = {\n width?: number;\n height?: number;\n};\n\ntype DynamicImageMetadataSource = {\n id?: string | number;\n alt?: string;\n contentType?: string;\n size?: DynamicImageSize;\n};\n\ntype FileBasedMetadataSource = {\n routeSegments: readonly string[];\n metadata: Metadata | null;\n};\n\ntype FileBasedMetadataOptions = {\n routeSegments?: readonly string[] | null;\n metadataSources?: readonly FileBasedMetadataSource[] | null;\n /**\n * The configured next.config `basePath`, prefixed to all file-based\n * metadata URLs emitted in the page <head> (icons, opengraph-image,\n * twitter-image, manifest, apple-icon, favicon).\n *\n * Mirrors Next.js, which bakes basePath into static metadata route URLs\n * during webpack build and threads it through the dynamic image loader's\n * `pathnamePrefix = normalizePathSep(path.join(basePath, segment))`.\n *\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/next-metadata-image-loader.ts#L63\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/loaders/metadata/discover.ts#L88\n */\n basePath?: string;\n};\n\ntype IconMap = {\n icon?: string | URL | IconEntry | IconEntry[];\n shortcut?: string | URL | Array<string | URL>;\n apple?: string | URL | AppleIconEntry | AppleIconEntry[];\n other?: Array<{ rel: string; url: string | URL; sizes?: string; type?: string }>;\n};\n\nfunction routeApplies(routePath: string, routePrefix: string): boolean {\n if (!routePrefix) {\n return true;\n }\n return routePath === routePrefix || routePath.startsWith(`${routePrefix}/`);\n}\n\nfunction routeScore(routePrefix: string): number {\n return routePrefix.split(\"/\").filter(Boolean).length;\n}\n\nfunction routeSegmentsApply(\n routeSegments: readonly string[],\n routePrefixSegments: readonly string[],\n): boolean {\n if (routePrefixSegments.length > routeSegments.length) {\n return false;\n }\n\n for (let index = 0; index < routePrefixSegments.length; index++) {\n if (routeSegments[index] !== routePrefixSegments[index]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction removeParallelRouteSegments(routeSegments: readonly string[]): string[] {\n return routeSegments.filter((segment) => !segment.startsWith(\"@\"));\n}\n\nfunction routeSegmentsApplyWithParallelSlots(\n routeSegments: readonly string[],\n routePrefixSegments: readonly string[],\n): boolean {\n if (routeSegmentsApply(routeSegments, routePrefixSegments)) {\n return true;\n }\n\n const visiblePrefixSegments = removeParallelRouteSegments(routePrefixSegments);\n return (\n visiblePrefixSegments.length !== routePrefixSegments.length &&\n routeSegmentsApply(routeSegments, visiblePrefixSegments)\n );\n}\n\nfunction routeSpecificity(route: MetadataFileRoute): number {\n return route.routeSegments?.length ?? routeScore(route.routePrefix);\n}\n\nfunction selectDeepestRoutes(\n metadataRoutes: readonly MetadataFileRoute[] | null | undefined,\n kind: MetadataRouteHeadData[\"kind\"],\n routePath: string,\n params: AppPageParams,\n routeSegments: readonly string[] | null | undefined,\n): MetadataFileRoute[] {\n if (!metadataRoutes || metadataRoutes.length === 0) {\n return [];\n }\n\n let selectedScore = -1;\n const selectedRoutes: MetadataFileRoute[] = [];\n\n for (const route of metadataRoutes) {\n const routeKind = route.headData?.kind ?? getMetadataRouteKind(route);\n\n if (routeKind !== kind) {\n continue;\n }\n\n if (routeSegments && route.routeSegments) {\n // Raw app-tree segments are authoritative when present. Falling back to\n // visible URL prefixes here would reintroduce route-group collisions.\n if (!routeSegmentsApplyWithParallelSlots(routeSegments, route.routeSegments)) {\n continue;\n }\n const currentScore = routeSpecificity(route);\n if (currentScore > selectedScore) {\n selectedScore = currentScore;\n selectedRoutes.length = 0;\n selectedRoutes.push(route);\n continue;\n }\n\n if (currentScore === selectedScore) {\n selectedRoutes.push(route);\n }\n continue;\n }\n\n const routePrefix = route.routePrefix;\n const resolvedRoutePrefix = fillRoutePatternSegments(routePrefix, params);\n const normalizedRoutePrefix = routePattern(routePrefix);\n if (\n !routeApplies(routePath, routePrefix) &&\n !routeApplies(routePath, normalizedRoutePrefix) &&\n (!resolvedRoutePrefix || !routeApplies(routePath, resolvedRoutePrefix))\n ) {\n continue;\n }\n\n const currentScore = routeSpecificity(route);\n if (currentScore > selectedScore) {\n selectedScore = currentScore;\n selectedRoutes.length = 0;\n selectedRoutes.push(route);\n continue;\n }\n\n if (currentScore === selectedScore) {\n selectedRoutes.push(route);\n }\n }\n\n return selectedRoutes;\n}\n\nfunction isStringOrUrl(value: unknown): value is string | URL {\n return typeof value === \"string\" || (typeof value === \"object\" && value instanceof URL);\n}\n\nfunction normalizeIconDescriptor(value: unknown): IconEntry | null {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return null;\n }\n\n const urlValue = Reflect.get(value, \"url\");\n if (!isStringOrUrl(urlValue)) {\n return null;\n }\n\n const entry: IconEntry = { url: urlValue };\n\n const sizesValue = Reflect.get(value, \"sizes\");\n if (typeof sizesValue === \"string\") {\n entry.sizes = sizesValue;\n }\n\n const typeValue = Reflect.get(value, \"type\");\n if (typeof typeValue === \"string\") {\n entry.type = typeValue;\n }\n\n const mediaValue = Reflect.get(value, \"media\");\n if (typeof mediaValue === \"string\") {\n entry.media = mediaValue;\n }\n\n return entry;\n}\n\nfunction normalizeIconValue(value: unknown): IconEntry | null {\n if (isStringOrUrl(value)) {\n return { url: value };\n }\n\n return normalizeIconDescriptor(value);\n}\n\nfunction normalizeIconValueList(values: readonly unknown[]): IconEntry[] {\n const normalizedEntries: IconEntry[] = [];\n for (const value of values) {\n const normalizedValue = normalizeIconValue(value);\n if (normalizedValue) {\n normalizedEntries.push(normalizedValue);\n }\n }\n return normalizedEntries;\n}\n\nfunction normalizeIconEntries(icon: NonNullable<Metadata[\"icons\"]>): IconEntry[] {\n const normalizedTopLevelValue = normalizeIconValue(icon);\n if (normalizedTopLevelValue) {\n return [normalizedTopLevelValue];\n }\n\n if (Array.isArray(icon)) {\n return normalizeIconValueList(icon);\n }\n\n if (!isIconMap(icon)) {\n return [];\n }\n\n const iconValue = icon.icon;\n if (!iconValue) {\n return [];\n }\n\n if (Array.isArray(iconValue)) {\n return normalizeIconValueList(iconValue);\n }\n\n const normalizedValue = normalizeIconValue(iconValue);\n return normalizedValue ? [normalizedValue] : [];\n}\n\nfunction isIconMap(value: Metadata[\"icons\"]): value is IconMap {\n if (!value || typeof value !== \"object\" || value instanceof URL || Array.isArray(value)) {\n return false;\n }\n return normalizeIconValue(value) === null;\n}\n\nfunction cloneIconMap(value: Metadata[\"icons\"]): IconMap {\n if (!value) {\n return {};\n }\n\n if (isIconMap(value)) {\n return { ...value };\n }\n\n const iconEntries = normalizeIconEntries(value);\n return iconEntries.length > 0 ? { icon: iconEntries } : {};\n}\n\nfunction buildIconEntry(headData: MetadataRouteHeadData): IconEntry | null {\n if (headData.kind !== \"favicon\" && headData.kind !== \"icon\") {\n return null;\n }\n\n const iconEntry: IconEntry = {\n url: headData.href,\n };\n if (headData.sizes) {\n iconEntry.sizes = headData.sizes;\n }\n if (headData.type) {\n iconEntry.type = headData.type;\n }\n return iconEntry;\n}\n\nfunction buildAppleEntry(headData: MetadataRouteHeadData): AppleIconEntry | null {\n if (headData.kind !== \"apple\") {\n return null;\n }\n\n const appleEntry: AppleIconEntry = {\n url: headData.href,\n };\n if (headData.sizes) {\n appleEntry.sizes = headData.sizes;\n }\n if (headData.type) {\n appleEntry.type = headData.type;\n }\n return appleEntry;\n}\n\nfunction normalizeAppleEntry(value: string | URL | AppleIconEntry): AppleIconEntry {\n if (isStringOrUrl(value)) {\n return { url: value };\n }\n return { ...value };\n}\n\nfunction markMetadataRouteSocialImage(entry: SocialImageEntry): SocialImageEntry {\n Object.defineProperty(entry, \"metadataRoute\", {\n configurable: true,\n enumerable: false,\n value: true,\n });\n return entry;\n}\n\nfunction buildSocialEntry(headData: MetadataRouteHeadData): SocialImageEntry | null {\n if (headData.kind !== \"openGraph\" && headData.kind !== \"twitter\") {\n return null;\n }\n\n const socialEntry: SocialImageEntry = {\n url: headData.href,\n };\n if (headData.width !== undefined) {\n socialEntry.width = headData.width;\n }\n if (headData.height !== undefined) {\n socialEntry.height = headData.height;\n }\n if (headData.alt) {\n socialEntry.alt = headData.alt;\n }\n if (headData.type) {\n socialEntry.type = headData.type;\n }\n return markMetadataRouteSocialImage(socialEntry);\n}\n\nfunction normalizeMetadataImageId(route: MetadataFileRoute, id: string | number): string | null {\n const normalizedId = String(id);\n if (!isValidMetadataImageId(normalizedId)) {\n console.warn(\n `[vinext] Skipping metadata route ${route.servedUrl} image id \"${normalizedId}\" because metadata image ids must match /^[a-zA-Z0-9-_.]+$/.`,\n );\n return null;\n }\n return normalizedId;\n}\n\nfunction withContentHash(href: string, contentHash?: string): string {\n if (!contentHash) {\n return href;\n }\n return `${href}?${contentHash}`;\n}\n\nfunction hasOwnProperty(source: object | null | undefined, key: string): boolean {\n return Boolean(source && Object.prototype.hasOwnProperty.call(source, key));\n}\n\nfunction hasOpenGraphImages(metadata: Metadata | null | undefined): boolean {\n return hasOwnProperty(metadata?.openGraph, \"images\");\n}\n\nfunction hasTwitterImages(metadata: Metadata | null | undefined): boolean {\n return hasOwnProperty(metadata?.twitter, \"images\");\n}\n\nfunction hasIcons(metadata: Metadata | null | undefined): boolean {\n return Boolean(metadata?.icons);\n}\n\nfunction getMetadataSourceForRoute(\n route: MetadataFileRoute,\n options: FileBasedMetadataOptions | undefined,\n fallbackMetadata: Metadata | null,\n): Metadata | null {\n if (!options?.metadataSources) {\n return fallbackMetadata;\n }\n\n if (!route.routeSegments) {\n return null;\n }\n\n for (let index = options.metadataSources.length - 1; index >= 0; index--) {\n const source = options.metadataSources[index];\n if (routeSegmentsApplyWithParallelSlots(source.routeSegments, route.routeSegments)) {\n return source.metadata;\n }\n }\n\n return null;\n}\n\nfunction socialRouteHasExplicitImagesAtSource(\n route: MetadataFileRoute,\n kind: \"openGraph\" | \"twitter\",\n options: FileBasedMetadataOptions | undefined,\n fallbackMetadata: Metadata | null,\n): boolean {\n const sourceMetadata = getMetadataSourceForRoute(route, options, fallbackMetadata);\n return kind === \"openGraph\"\n ? hasOpenGraphImages(sourceMetadata)\n : hasTwitterImages(sourceMetadata);\n}\n\nfunction iconRouteHasExplicitIconsAtSource(\n route: MetadataFileRoute,\n options: FileBasedMetadataOptions | undefined,\n fallbackMetadata: Metadata | null,\n): boolean {\n // Next suppresses file icon routes when any resolved icons metadata exists.\n // Social image routes stay segment-scoped instead of using this merged fallback.\n return hasIcons(fallbackMetadata) || hasIcons(getMetadataSourceForRoute(route, options, null));\n}\n\nfunction readStringProperty(source: object, key: string): string | undefined {\n const value = Reflect.get(source, key);\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction readNumberProperty(source: object, key: string): number | undefined {\n const value = Reflect.get(source, key);\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction readStringOrNumberProperty(source: object, key: string): string | number | undefined {\n const value = Reflect.get(source, key);\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return undefined;\n}\n\nfunction readSizeProperty(source: object): DynamicImageSize | undefined {\n const sizeValue = Reflect.get(source, \"size\");\n if (typeof sizeValue !== \"object\" || sizeValue === null) {\n return undefined;\n }\n\n const width = readNumberProperty(sizeValue, \"width\");\n const height = readNumberProperty(sizeValue, \"height\");\n if (width === undefined && height === undefined) {\n return undefined;\n }\n\n return { width, height };\n}\n\nfunction readDynamicImageMetadataSource(source: object): DynamicImageMetadataSource {\n return {\n id: readStringOrNumberProperty(source, \"id\"),\n alt: readStringProperty(source, \"alt\"),\n contentType: readStringProperty(source, \"contentType\"),\n size: readSizeProperty(source),\n };\n}\n\nasync function resolveDynamicImageMetadataSources(\n route: MetadataFileRoute,\n params: AppPageParams,\n): Promise<DynamicImageMetadataSource[]> {\n if (!route.module || typeof route.module !== \"object\") {\n return [];\n }\n\n const generateImageMetadata = Reflect.get(route.module, \"generateImageMetadata\");\n if (typeof generateImageMetadata !== \"function\") {\n return [readDynamicImageMetadataSource(route.module)];\n }\n\n const result = await generateImageMetadata({ params: makeThenableParams(params) });\n if (!Array.isArray(result)) {\n return [];\n }\n\n const sources: DynamicImageMetadataSource[] = [];\n for (const entry of result) {\n if (typeof entry === \"object\" && entry !== null) {\n const source = readDynamicImageMetadataSource(entry);\n if (source.id === undefined) {\n console.warn(\n `[vinext] Skipping metadata route ${route.servedUrl} image metadata entry because generateImageMetadata entries must include an id.`,\n );\n continue;\n }\n sources.push(source);\n }\n }\n return sources;\n}\n\nasync function resolveRouteHeadData(\n route: MetadataFileRoute,\n params: AppPageParams,\n): Promise<MetadataRouteHeadData[]> {\n if (!route.isDynamic || !route.module || typeof route.module !== \"object\") {\n return route.headData ? [route.headData] : [];\n }\n\n const routeKind = getMetadataImageRouteKind(route);\n if (!routeKind) {\n return route.headData ? [route.headData] : [];\n }\n\n // servedUrl must stay query-free here; content hashes are appended after dynamic segment filling.\n const resolvedUrl = fillRoutePatternSegments(route.servedUrl, params);\n if (!resolvedUrl) {\n console.warn(\n `[vinext] Skipping metadata route ${route.servedUrl} because params did not fill all dynamic segments.`,\n );\n return [];\n }\n const metadataSources = await resolveDynamicImageMetadataSources(route, params);\n const resolvedHeadData: MetadataRouteHeadData[] = [];\n\n for (const metadataSource of metadataSources) {\n let hrefBase = resolvedUrl;\n if (metadataSource.id !== undefined) {\n const normalizedId = normalizeMetadataImageId(route, metadataSource.id);\n if (!normalizedId) {\n continue;\n }\n hrefBase = `${resolvedUrl}/${normalizedId}`;\n }\n const href = withContentHash(hrefBase, route.contentHash);\n const contentType = metadataSource.contentType ?? route.contentType;\n const size = metadataSource.size;\n\n if (routeKind === \"icon\" || routeKind === \"apple\") {\n let sizes: string | undefined;\n if (size?.width !== undefined && size.height !== undefined) {\n sizes = `${size.width}x${size.height}`;\n }\n\n resolvedHeadData.push({\n kind: routeKind,\n href,\n sizes,\n type: contentType,\n });\n continue;\n }\n\n resolvedHeadData.push({\n kind: routeKind,\n href,\n alt: metadataSource.alt,\n height: size?.height,\n type: contentType,\n width: size?.width,\n });\n }\n\n return resolvedHeadData;\n}\n\nasync function resolveHeadDataList(\n routes: MetadataFileRoute[],\n params: AppPageParams,\n): Promise<MetadataRouteHeadData[]> {\n const headDataList = await Promise.all(\n routes.map((route) => resolveRouteHeadData(route, params)),\n );\n return headDataList.flat();\n}\n\n/**\n * Prepend the configured basePath to a file-based metadata href.\n *\n * Hrefs at this point are framework-built strings of the form\n * \"/<route>/<file>[?<contentHash>]\"\n * The basePath must go before the path portion only; the query (cache-busting\n * content hash) must be preserved verbatim. External URLs (http://, https://,\n * //, data:, blob:) are left untouched — those are user-controlled and the\n * framework has no business prefixing them.\n *\n * Idempotent: when the path already starts with `basePath` (or equals it),\n * the path is returned unchanged so consumers may safely apply the prefix\n * at any layer without risking `/base/base/icon.png`.\n */\nfunction prefixMetadataHrefWithBasePath(href: string, basePath: string): string {\n if (!basePath) return href;\n // External / scheme-relative / data URLs: not a framework-owned route.\n if (/^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith(\"//\")) {\n return href;\n }\n // Must start with \"/\" to be a framework-owned pathname. Defensive guard —\n // resolveRouteHeadData / metadata-route-build-data always emit absolute paths.\n if (!href.startsWith(\"/\")) return href;\n\n // Split off the optional query so addBasePathToPathname only sees the path.\n const queryIndex = href.indexOf(\"?\");\n const pathname = queryIndex === -1 ? href : href.slice(0, queryIndex);\n const search = queryIndex === -1 ? \"\" : href.slice(queryIndex);\n\n if (hasBasePath(pathname, basePath)) return href;\n return `${addBasePathToPathname(pathname, basePath)}${search}`;\n}\n\nfunction applyBasePathToHeadDataList(\n headDataList: MetadataRouteHeadData[],\n basePath: string,\n): MetadataRouteHeadData[] {\n if (!basePath) return headDataList;\n return headDataList.map((entry) => ({\n ...entry,\n href: prefixMetadataHrefWithBasePath(entry.href, basePath),\n }));\n}\n\nexport async function applyFileBasedMetadata(\n metadata: Metadata | null,\n routePath: string,\n params: AppPageParams,\n metadataRoutes: readonly MetadataFileRoute[] | null | undefined,\n options?: FileBasedMetadataOptions,\n): Promise<Metadata | null> {\n if (!metadataRoutes || metadataRoutes.length === 0) {\n return metadata;\n }\n\n const routeSegments = options?.routeSegments ?? null;\n const faviconRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"favicon\",\n routePath,\n params,\n routeSegments,\n );\n const iconRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"icon\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !iconRouteHasExplicitIconsAtSource(route, options, metadata));\n const appleRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"apple\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !iconRouteHasExplicitIconsAtSource(route, options, metadata));\n const openGraphRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"openGraph\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !socialRouteHasExplicitImagesAtSource(route, \"openGraph\", options, metadata));\n const twitterRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"twitter\",\n routePath,\n params,\n routeSegments,\n ).filter((route) => !socialRouteHasExplicitImagesAtSource(route, \"twitter\", options, metadata));\n const manifestRoutes = selectDeepestRoutes(\n metadataRoutes,\n \"manifest\",\n routePath,\n params,\n routeSegments,\n );\n\n const basePath = options?.basePath ?? \"\";\n\n const [\n rawFaviconHeadData,\n rawIconHeadData,\n rawAppleHeadData,\n rawOpenGraphHeadData,\n rawTwitterHeadData,\n rawManifestHeadData,\n ] = await Promise.all([\n resolveHeadDataList(faviconRoutes, params),\n resolveHeadDataList(iconRoutes, params),\n resolveHeadDataList(appleRoutes, params),\n resolveHeadDataList(openGraphRoutes, params),\n resolveHeadDataList(twitterRoutes, params),\n resolveHeadDataList(manifestRoutes, params),\n ]);\n\n // Prefix every file-based metadata href with the configured basePath.\n // Matches Next.js, which bakes basePath into both static and dynamic\n // metadata route URLs at build time. Doing it here keeps the metadata route\n // request matching (which operates on basePath-stripped pathnames) and the\n // <head> URL emission (which must include basePath) symmetric.\n const faviconHeadData = applyBasePathToHeadDataList(rawFaviconHeadData, basePath);\n const iconHeadData = applyBasePathToHeadDataList(rawIconHeadData, basePath);\n const appleHeadData = applyBasePathToHeadDataList(rawAppleHeadData, basePath);\n const openGraphHeadData = applyBasePathToHeadDataList(rawOpenGraphHeadData, basePath);\n const twitterHeadData = applyBasePathToHeadDataList(rawTwitterHeadData, basePath);\n const manifestHeadData = applyBasePathToHeadDataList(rawManifestHeadData, basePath);\n\n if (\n !metadata &&\n faviconHeadData.length === 0 &&\n iconHeadData.length === 0 &&\n appleHeadData.length === 0 &&\n openGraphHeadData.length === 0 &&\n twitterHeadData.length === 0 &&\n manifestHeadData.length === 0\n ) {\n return null;\n }\n\n const nextMetadata: Metadata = metadata ? { ...metadata } : {};\n\n const faviconEntries: IconEntry[] = [];\n for (const headData of faviconHeadData) {\n const iconEntry = buildIconEntry(headData);\n if (iconEntry) {\n faviconEntries.push(iconEntry);\n }\n }\n if (faviconEntries.length > 0) {\n const nextIcons = cloneIconMap(nextMetadata.icons);\n const normalizedIcons = normalizeIconEntries(nextIcons);\n nextIcons.icon = [...faviconEntries, ...normalizedIcons];\n nextMetadata.icons = nextIcons;\n }\n\n {\n const nextIcons = cloneIconMap(nextMetadata.icons);\n\n const iconEntries: IconEntry[] = [];\n for (const headData of iconHeadData) {\n const iconEntry = buildIconEntry(headData);\n if (iconEntry) {\n iconEntries.push(iconEntry);\n }\n }\n if (iconEntries.length > 0) {\n const normalizedIcons = normalizeIconEntries(nextIcons);\n nextIcons.icon = [...iconEntries, ...normalizedIcons];\n }\n\n const appleEntries: AppleIconEntry[] = [];\n for (const headData of appleHeadData) {\n const appleEntry = buildAppleEntry(headData);\n if (appleEntry) {\n appleEntries.push(appleEntry);\n }\n }\n if (appleEntries.length > 0) {\n const existingApple = nextIcons.apple;\n const normalizedAppleEntries: AppleIconEntry[] = [];\n if (Array.isArray(existingApple)) {\n for (const entry of existingApple) {\n normalizedAppleEntries.push(normalizeAppleEntry(entry));\n }\n } else if (existingApple) {\n normalizedAppleEntries.push(normalizeAppleEntry(existingApple));\n }\n nextIcons.apple = [...appleEntries, ...normalizedAppleEntries];\n }\n\n if (iconEntries.length > 0 || appleEntries.length > 0) {\n nextMetadata.icons = nextIcons;\n }\n }\n\n if (openGraphHeadData.length > 0) {\n const socialEntries: SocialImageEntry[] = [];\n for (const headData of openGraphHeadData) {\n const socialEntry = buildSocialEntry(headData);\n if (socialEntry) {\n socialEntries.push(socialEntry);\n }\n }\n if (socialEntries.length > 0) {\n const nextOpenGraph: NonNullable<Metadata[\"openGraph\"]> = nextMetadata.openGraph\n ? { ...nextMetadata.openGraph }\n : {};\n nextOpenGraph.images = socialEntries;\n nextMetadata.openGraph = nextOpenGraph;\n }\n }\n\n if (twitterHeadData.length > 0) {\n const socialEntries: SocialImageEntry[] = [];\n for (const headData of twitterHeadData) {\n const socialEntry = buildSocialEntry(headData);\n if (socialEntry) {\n socialEntries.push(socialEntry);\n }\n }\n if (socialEntries.length > 0) {\n const nextTwitter: NonNullable<Metadata[\"twitter\"]> = nextMetadata.twitter\n ? { ...nextMetadata.twitter }\n : {};\n nextTwitter.images = socialEntries;\n nextMetadata.twitter = nextTwitter;\n }\n }\n\n if (manifestHeadData.length > 0 && manifestHeadData[0].kind === \"manifest\") {\n nextMetadata.manifest = manifestHeadData[0].href;\n }\n\n return nextMetadata;\n}\n"],"mappings":"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"}
@@ -11,6 +11,8 @@
11
11
  */
12
12
  /** ISR / page cache state indicator: "HIT" | "MISS" | "STALE" | "STATIC". */
13
13
  declare const VINEXT_CACHE_HEADER = "X-Vinext-Cache";
14
+ /** Next.js public ISR / page cache state indicator. */
15
+ declare const NEXTJS_CACHE_HEADER = "x-nextjs-cache";
14
16
  /** Static file signal — value is URL-encoded pathname. */
15
17
  declare const VINEXT_STATIC_FILE_HEADER = "x-vinext-static-file";
16
18
  /** Serialized middleware context (JSON) forwarded from dev server to RSC entry. */
@@ -31,6 +33,21 @@ declare const VINEXT_MOUNTED_SLOTS_HEADER = "X-Vinext-Mounted-Slots";
31
33
  declare const VINEXT_INTERCEPTION_CONTEXT_HEADER = "X-Vinext-Interception-Context";
32
34
  /** RSC render mode (e.g. "navigation", "prefetch"). */
33
35
  declare const VINEXT_RSC_RENDER_MODE_HEADER = "X-Vinext-Rsc-Render-Mode";
36
+ /** Disabled-by-default client hint describing already-held App Router payload entries. */
37
+ declare const VINEXT_CLIENT_REUSE_MANIFEST_HEADER = "X-Vinext-Client-Reuse-Manifest";
38
+ /**
39
+ * Side-channel signal that an RSC response (HTTP 200) encodes a `redirect()`
40
+ * thrown during render. The header value is the redirect target (path-only
41
+ * for same-origin, absolute for cross-origin). The flight body still carries
42
+ * the canonical `NEXT_REDIRECT;...` digest so Next.js's own tests can read it
43
+ * via response.body; this header is purely for vinext's own client
44
+ * (`navigateRsc` in app-browser-entry.ts) to follow the redirect inside the
45
+ * same navigation transaction — keeping `useTransition`'s pending state
46
+ * continuous across the hop. Pre-1347 vinext relied on `fetch`'s auto-follow
47
+ * of a 307 for that, but the new 200 + flight format leaves it without a
48
+ * cheap way to detect the redirect ahead of stream decode.
49
+ */
50
+ declare const VINEXT_RSC_REDIRECT_HEADER = "X-Vinext-Rsc-Redirect";
34
51
  /** Standard RSC header — value "1" indicates an RSC payload request. */
35
52
  declare const RSC_HEADER = "RSC";
36
53
  /** Server Action invocation header (vinext/vite-rsc protocol). */
@@ -39,6 +56,8 @@ declare const RSC_ACTION_HEADER = "x-rsc-action";
39
56
  declare const NEXT_ACTION_HEADER = "next-action";
40
57
  /** Next.js action-not-found indicator (value "1"). */
41
58
  declare const NEXTJS_ACTION_NOT_FOUND_HEADER = "x-nextjs-action-not-found";
59
+ /** Forwarded action marker — set when a request has already been forwarded between workers. */
60
+ declare const ACTION_FORWARDED_HEADER = "x-action-forwarded";
42
61
  /** Indicates revalidation occurred — value is JSON kind (1 = path/tag, 2 = dynamic-only). */
43
62
  declare const ACTION_REVALIDATED_HEADER = "x-action-revalidated";
44
63
  /** Redirect URL from a Server Action. */
@@ -75,5 +94,5 @@ declare const FLIGHT_HEADERS: readonly string[];
75
94
  */
76
95
  declare const INTERNAL_HEADERS: string[];
77
96
  //#endregion
78
- export { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
97
+ export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
79
98
  //# sourceMappingURL=headers.d.ts.map
@@ -11,6 +11,8 @@
11
11
  */
12
12
  /** ISR / page cache state indicator: "HIT" | "MISS" | "STALE" | "STATIC". */
13
13
  const VINEXT_CACHE_HEADER = "X-Vinext-Cache";
14
+ /** Next.js public ISR / page cache state indicator. */
15
+ const NEXTJS_CACHE_HEADER = "x-nextjs-cache";
14
16
  /** Static file signal — value is URL-encoded pathname. */
15
17
  const VINEXT_STATIC_FILE_HEADER = "x-vinext-static-file";
16
18
  /** Serialized middleware context (JSON) forwarded from dev server to RSC entry. */
@@ -31,6 +33,21 @@ const VINEXT_MOUNTED_SLOTS_HEADER = "X-Vinext-Mounted-Slots";
31
33
  const VINEXT_INTERCEPTION_CONTEXT_HEADER = "X-Vinext-Interception-Context";
32
34
  /** RSC render mode (e.g. "navigation", "prefetch"). */
33
35
  const VINEXT_RSC_RENDER_MODE_HEADER = "X-Vinext-Rsc-Render-Mode";
36
+ /** Disabled-by-default client hint describing already-held App Router payload entries. */
37
+ const VINEXT_CLIENT_REUSE_MANIFEST_HEADER = "X-Vinext-Client-Reuse-Manifest";
38
+ /**
39
+ * Side-channel signal that an RSC response (HTTP 200) encodes a `redirect()`
40
+ * thrown during render. The header value is the redirect target (path-only
41
+ * for same-origin, absolute for cross-origin). The flight body still carries
42
+ * the canonical `NEXT_REDIRECT;...` digest so Next.js's own tests can read it
43
+ * via response.body; this header is purely for vinext's own client
44
+ * (`navigateRsc` in app-browser-entry.ts) to follow the redirect inside the
45
+ * same navigation transaction — keeping `useTransition`'s pending state
46
+ * continuous across the hop. Pre-1347 vinext relied on `fetch`'s auto-follow
47
+ * of a 307 for that, but the new 200 + flight format leaves it without a
48
+ * cheap way to detect the redirect ahead of stream decode.
49
+ */
50
+ const VINEXT_RSC_REDIRECT_HEADER = "X-Vinext-Rsc-Redirect";
34
51
  /** Standard RSC header — value "1" indicates an RSC payload request. */
35
52
  const RSC_HEADER = "RSC";
36
53
  /** Server Action invocation header (vinext/vite-rsc protocol). */
@@ -39,6 +56,8 @@ const RSC_ACTION_HEADER = "x-rsc-action";
39
56
  const NEXT_ACTION_HEADER = "next-action";
40
57
  /** Next.js action-not-found indicator (value "1"). */
41
58
  const NEXTJS_ACTION_NOT_FOUND_HEADER = "x-nextjs-action-not-found";
59
+ /** Forwarded action marker — set when a request has already been forwarded between workers. */
60
+ const ACTION_FORWARDED_HEADER = "x-action-forwarded";
42
61
  /** Indicates revalidation occurred — value is JSON kind (1 = path/tag, 2 = dynamic-only). */
43
62
  const ACTION_REVALIDATED_HEADER = "x-action-revalidated";
44
63
  /** Redirect URL from a Server Action. */
@@ -93,9 +112,10 @@ const INTERNAL_HEADERS = [
93
112
  "x-now-route-matches",
94
113
  "x-matched-path",
95
114
  "x-nextjs-data",
96
- "x-next-resume-state-length"
115
+ "x-next-resume-state-length",
116
+ ACTION_FORWARDED_HEADER
97
117
  ];
98
118
  //#endregion
99
- export { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
119
+ export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
100
120
 
101
121
  //# sourceMappingURL=headers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"headers.js","names":[],"sources":["../../src/server/headers.ts"],"sourcesContent":["/**\n * Internal HTTP header name constants used throughout vinext.\n *\n * Centralizes all custom header names so they are defined once and referenced\n * everywhere via imports. Keeping them in one module prevents typos, makes\n * rename-refactors trivial, and lets grep find every consumer instantly.\n *\n * Standard HTTP headers (Content-Type, Cache-Control, etc.) are intentionally\n * omitted — only vinext-internal and Next.js-protocol headers belong here.\n */\n\n// ---------------------------------------------------------------------------\n// Vinext-proprietary headers (`x-vinext-*` / `X-Vinext-*`)\n// ---------------------------------------------------------------------------\n\n/** ISR / page cache state indicator: \"HIT\" | \"MISS\" | \"STALE\" | \"STATIC\". */\nexport const VINEXT_CACHE_HEADER = \"X-Vinext-Cache\";\n\n/** Static file signal — value is URL-encoded pathname. */\nexport const VINEXT_STATIC_FILE_HEADER = \"x-vinext-static-file\";\n\n/** Serialized middleware context (JSON) forwarded from dev server to RSC entry. */\nexport const VINEXT_MW_CTX_HEADER = \"x-vinext-mw-ctx\";\n\n/** Timing metrics: `handlerStart,compileMs,renderMs`. */\nexport const VINEXT_TIMING_HEADER = \"x-vinext-timing\";\n\n/** Build-time prerender authentication secret. */\nexport const VINEXT_PRERENDER_SECRET_HEADER = \"x-vinext-prerender-secret\";\n\n/** TPR (Tailored Per-Request) revalidation interval in seconds. */\nexport const VINEXT_REVALIDATE_HEADER = \"x-vinext-revalidate\";\n\n/** Marker on cached ISR entries indicating RSC payload (value \"1\"). */\nexport const VINEXT_RSC_MARKER_HEADER = \"x-vinext-rsc\";\n\n/** URL-encoded JSON route params carried on RSC responses. */\nexport const VINEXT_PARAMS_HEADER = \"X-Vinext-Params\";\n\n/** Deduplicated, sorted list of mounted layout slots for cache keying. */\nexport const VINEXT_MOUNTED_SLOTS_HEADER = \"X-Vinext-Mounted-Slots\";\n\n/** Route interception context for parallel/intercepting routes. */\nexport const VINEXT_INTERCEPTION_CONTEXT_HEADER = \"X-Vinext-Interception-Context\";\n\n/** RSC render mode (e.g. \"navigation\", \"prefetch\"). */\nexport const VINEXT_RSC_RENDER_MODE_HEADER = \"X-Vinext-Rsc-Render-Mode\";\n\n// ---------------------------------------------------------------------------\n// RSC protocol headers\n// ---------------------------------------------------------------------------\n\n/** Standard RSC header — value \"1\" indicates an RSC payload request. */\nexport const RSC_HEADER = \"RSC\";\n\n/** Server Action invocation header (vinext/vite-rsc protocol). */\nexport const RSC_ACTION_HEADER = \"x-rsc-action\";\n\n// ---------------------------------------------------------------------------\n// Next.js compatibility headers\n// ---------------------------------------------------------------------------\n\n/** Next.js Server Action invocation header (fallback for x-rsc-action). */\nexport const NEXT_ACTION_HEADER = \"next-action\";\n\n/** Next.js action-not-found indicator (value \"1\"). */\nexport const NEXTJS_ACTION_NOT_FOUND_HEADER = \"x-nextjs-action-not-found\";\n\n// ---------------------------------------------------------------------------\n// Server Action response headers (`x-action-*`)\n// ---------------------------------------------------------------------------\n\n/** Indicates revalidation occurred — value is JSON kind (1 = path/tag, 2 = dynamic-only). */\nexport const ACTION_REVALIDATED_HEADER = \"x-action-revalidated\";\n\n/** Redirect URL from a Server Action. */\nexport const ACTION_REDIRECT_HEADER = \"x-action-redirect\";\n\n/** Redirect type from a Server Action (\"push\" | \"replace\"). */\nexport const ACTION_REDIRECT_TYPE_HEADER = \"x-action-redirect-type\";\n\n/** HTTP status for a Server Action redirect (e.g. \"308\"). */\nexport const ACTION_REDIRECT_STATUS_HEADER = \"x-action-redirect-status\";\n\n// ---------------------------------------------------------------------------\n// Middleware protocol headers (`x-middleware-*`)\n// ---------------------------------------------------------------------------\n\n/** Prefix for forwarded request headers (e.g. `x-middleware-request-cookie`). */\nexport const MIDDLEWARE_REQUEST_HEADER_PREFIX = \"x-middleware-request-\";\n\n/** Comma-separated list of header names that middleware wants to override. */\nexport const MIDDLEWARE_OVERRIDE_HEADERS = \"x-middleware-override-headers\";\n\n/** Carries cookies set by middleware for same-render reads. */\nexport const MIDDLEWARE_SET_COOKIE_HEADER = \"x-middleware-set-cookie\";\n\n/** Signal from `NextResponse.next()` — value \"1\" means \"continue to next handler\". */\nexport const MIDDLEWARE_NEXT_HEADER = \"x-middleware-next\";\n\n/** Rewrite destination URL set by `NextResponse.rewrite()`. */\nexport const MIDDLEWARE_REWRITE_HEADER = \"x-middleware-rewrite\";\n\n/** Redirect URL set by middleware. */\nconst MIDDLEWARE_REDIRECT_HEADER = \"x-middleware-redirect\";\n\n/** Skip-middleware signal. */\nconst MIDDLEWARE_SKIP_HEADER = \"x-middleware-skip\";\n\n/** Generic prefix for all middleware internal headers. */\nexport const MIDDLEWARE_HEADER_PREFIX = \"x-middleware-\";\n\n// ---------------------------------------------------------------------------\n// Next.js / RSC flight headers (forwarded through middleware)\n// ---------------------------------------------------------------------------\n\nexport const NEXT_ROUTER_STATE_TREE_HEADER = \"Next-Router-State-Tree\";\nexport const NEXT_ROUTER_PREFETCH_HEADER = \"Next-Router-Prefetch\";\nexport const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = \"Next-Router-Segment-Prefetch\";\nexport const NEXT_URL_HEADER = \"Next-Url\";\n\n/** Lowercase flight header variants used in middleware forwarding. */\nexport const FLIGHT_HEADERS: readonly string[] = [\n \"rsc\",\n \"next-router-state-tree\",\n \"next-router-prefetch\",\n \"next-hmr-refresh\",\n \"next-router-segment-prefetch\",\n];\n\n// ---------------------------------------------------------------------------\n// Vercel / Now.sh legacy internal headers (stripped from inbound requests)\n// ---------------------------------------------------------------------------\n\nconst NOW_ROUTE_MATCHES_HEADER = \"x-now-route-matches\";\nconst MATCHED_PATH_HEADER = \"x-matched-path\";\nconst NEXTJS_DATA_HEADER = \"x-nextjs-data\";\nconst NEXT_RESUME_STATE_LENGTH_HEADER = \"x-next-resume-state-length\";\n\n// ---------------------------------------------------------------------------\n// Internal headers blocklist — stripped from inbound requests for security\n// ---------------------------------------------------------------------------\n\n/**\n * Headers that must be stripped from external requests before any handler\n * processes them. An attacker could forge these to influence routing or\n * impersonate internal data fetches.\n *\n * Ported from Next.js `INTERNAL_HEADERS`:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/server-ipc/utils.ts\n */\nexport const INTERNAL_HEADERS = [\n MIDDLEWARE_REWRITE_HEADER,\n MIDDLEWARE_REDIRECT_HEADER,\n MIDDLEWARE_SET_COOKIE_HEADER,\n MIDDLEWARE_SKIP_HEADER,\n MIDDLEWARE_OVERRIDE_HEADERS,\n MIDDLEWARE_NEXT_HEADER,\n NOW_ROUTE_MATCHES_HEADER,\n MATCHED_PATH_HEADER,\n NEXTJS_DATA_HEADER,\n NEXT_RESUME_STATE_LENGTH_HEADER,\n];\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAa,sBAAsB;;AAGnC,MAAa,4BAA4B;;AAGzC,MAAa,uBAAuB;;AAGpC,MAAa,uBAAuB;;AAGpC,MAAa,iCAAiC;;AAG9C,MAAa,2BAA2B;;AAGxC,MAAa,2BAA2B;;AAGxC,MAAa,uBAAuB;;AAGpC,MAAa,8BAA8B;;AAG3C,MAAa,qCAAqC;;AAGlD,MAAa,gCAAgC;;AAO7C,MAAa,aAAa;;AAG1B,MAAa,oBAAoB;;AAOjC,MAAa,qBAAqB;;AAGlC,MAAa,iCAAiC;;AAO9C,MAAa,4BAA4B;;AAGzC,MAAa,yBAAyB;;AAGtC,MAAa,8BAA8B;;AAG3C,MAAa,gCAAgC;;AAO7C,MAAa,mCAAmC;;AAGhD,MAAa,8BAA8B;;AAG3C,MAAa,+BAA+B;;AAG5C,MAAa,yBAAyB;;AAGtC,MAAa,4BAA4B;;AAGzC,MAAM,6BAA6B;;AAGnC,MAAM,yBAAyB;;AAG/B,MAAa,2BAA2B;AAMxC,MAAa,gCAAgC;AAC7C,MAAa,8BAA8B;AAC3C,MAAa,sCAAsC;AACnD,MAAa,kBAAkB;;AAG/B,MAAa,iBAAoC;CAC/C;CACA;CACA;CACA;CACA;CACD;;;;;;;;;AAuBD,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"headers.js","names":[],"sources":["../../src/server/headers.ts"],"sourcesContent":["/**\n * Internal HTTP header name constants used throughout vinext.\n *\n * Centralizes all custom header names so they are defined once and referenced\n * everywhere via imports. Keeping them in one module prevents typos, makes\n * rename-refactors trivial, and lets grep find every consumer instantly.\n *\n * Standard HTTP headers (Content-Type, Cache-Control, etc.) are intentionally\n * omitted — only vinext-internal and Next.js-protocol headers belong here.\n */\n\n// ---------------------------------------------------------------------------\n// Vinext-proprietary headers (`x-vinext-*` / `X-Vinext-*`)\n// ---------------------------------------------------------------------------\n\n/** ISR / page cache state indicator: \"HIT\" | \"MISS\" | \"STALE\" | \"STATIC\". */\nexport const VINEXT_CACHE_HEADER = \"X-Vinext-Cache\";\n\n/** Next.js public ISR / page cache state indicator. */\nexport const NEXTJS_CACHE_HEADER = \"x-nextjs-cache\";\n\n/** Static file signal — value is URL-encoded pathname. */\nexport const VINEXT_STATIC_FILE_HEADER = \"x-vinext-static-file\";\n\n/** Serialized middleware context (JSON) forwarded from dev server to RSC entry. */\nexport const VINEXT_MW_CTX_HEADER = \"x-vinext-mw-ctx\";\n\n/** Timing metrics: `handlerStart,compileMs,renderMs`. */\nexport const VINEXT_TIMING_HEADER = \"x-vinext-timing\";\n\n/** Build-time prerender authentication secret. */\nexport const VINEXT_PRERENDER_SECRET_HEADER = \"x-vinext-prerender-secret\";\n\n/** TPR (Tailored Per-Request) revalidation interval in seconds. */\nexport const VINEXT_REVALIDATE_HEADER = \"x-vinext-revalidate\";\n\n/** Marker on cached ISR entries indicating RSC payload (value \"1\"). */\nexport const VINEXT_RSC_MARKER_HEADER = \"x-vinext-rsc\";\n\n/** URL-encoded JSON route params carried on RSC responses. */\nexport const VINEXT_PARAMS_HEADER = \"X-Vinext-Params\";\n\n/** Deduplicated, sorted list of mounted layout slots for cache keying. */\nexport const VINEXT_MOUNTED_SLOTS_HEADER = \"X-Vinext-Mounted-Slots\";\n\n/** Route interception context for parallel/intercepting routes. */\nexport const VINEXT_INTERCEPTION_CONTEXT_HEADER = \"X-Vinext-Interception-Context\";\n\n/** RSC render mode (e.g. \"navigation\", \"prefetch\"). */\nexport const VINEXT_RSC_RENDER_MODE_HEADER = \"X-Vinext-Rsc-Render-Mode\";\n\n/** Disabled-by-default client hint describing already-held App Router payload entries. */\nexport const VINEXT_CLIENT_REUSE_MANIFEST_HEADER = \"X-Vinext-Client-Reuse-Manifest\";\n\n/**\n * Side-channel signal that an RSC response (HTTP 200) encodes a `redirect()`\n * thrown during render. The header value is the redirect target (path-only\n * for same-origin, absolute for cross-origin). The flight body still carries\n * the canonical `NEXT_REDIRECT;...` digest so Next.js's own tests can read it\n * via response.body; this header is purely for vinext's own client\n * (`navigateRsc` in app-browser-entry.ts) to follow the redirect inside the\n * same navigation transaction — keeping `useTransition`'s pending state\n * continuous across the hop. Pre-1347 vinext relied on `fetch`'s auto-follow\n * of a 307 for that, but the new 200 + flight format leaves it without a\n * cheap way to detect the redirect ahead of stream decode.\n */\nexport const VINEXT_RSC_REDIRECT_HEADER = \"X-Vinext-Rsc-Redirect\";\n\n// ---------------------------------------------------------------------------\n// RSC protocol headers\n// ---------------------------------------------------------------------------\n\n/** Standard RSC header — value \"1\" indicates an RSC payload request. */\nexport const RSC_HEADER = \"RSC\";\n\n/** Server Action invocation header (vinext/vite-rsc protocol). */\nexport const RSC_ACTION_HEADER = \"x-rsc-action\";\n\n// ---------------------------------------------------------------------------\n// Next.js compatibility headers\n// ---------------------------------------------------------------------------\n\n/** Next.js Server Action invocation header (fallback for x-rsc-action). */\nexport const NEXT_ACTION_HEADER = \"next-action\";\n\n/** Next.js action-not-found indicator (value \"1\"). */\nexport const NEXTJS_ACTION_NOT_FOUND_HEADER = \"x-nextjs-action-not-found\";\n\n/** Forwarded action marker — set when a request has already been forwarded between workers. */\nexport const ACTION_FORWARDED_HEADER = \"x-action-forwarded\";\n\n// ---------------------------------------------------------------------------\n// Server Action response headers (`x-action-*`)\n// ---------------------------------------------------------------------------\n\n/** Indicates revalidation occurred — value is JSON kind (1 = path/tag, 2 = dynamic-only). */\nexport const ACTION_REVALIDATED_HEADER = \"x-action-revalidated\";\n\n/** Redirect URL from a Server Action. */\nexport const ACTION_REDIRECT_HEADER = \"x-action-redirect\";\n\n/** Redirect type from a Server Action (\"push\" | \"replace\"). */\nexport const ACTION_REDIRECT_TYPE_HEADER = \"x-action-redirect-type\";\n\n/** HTTP status for a Server Action redirect (e.g. \"308\"). */\nexport const ACTION_REDIRECT_STATUS_HEADER = \"x-action-redirect-status\";\n\n// ---------------------------------------------------------------------------\n// Middleware protocol headers (`x-middleware-*`)\n// ---------------------------------------------------------------------------\n\n/** Prefix for forwarded request headers (e.g. `x-middleware-request-cookie`). */\nexport const MIDDLEWARE_REQUEST_HEADER_PREFIX = \"x-middleware-request-\";\n\n/** Comma-separated list of header names that middleware wants to override. */\nexport const MIDDLEWARE_OVERRIDE_HEADERS = \"x-middleware-override-headers\";\n\n/** Carries cookies set by middleware for same-render reads. */\nexport const MIDDLEWARE_SET_COOKIE_HEADER = \"x-middleware-set-cookie\";\n\n/** Signal from `NextResponse.next()` — value \"1\" means \"continue to next handler\". */\nexport const MIDDLEWARE_NEXT_HEADER = \"x-middleware-next\";\n\n/** Rewrite destination URL set by `NextResponse.rewrite()`. */\nexport const MIDDLEWARE_REWRITE_HEADER = \"x-middleware-rewrite\";\n\n/** Redirect URL set by middleware. */\nconst MIDDLEWARE_REDIRECT_HEADER = \"x-middleware-redirect\";\n\n/** Skip-middleware signal. */\nconst MIDDLEWARE_SKIP_HEADER = \"x-middleware-skip\";\n\n/** Generic prefix for all middleware internal headers. */\nexport const MIDDLEWARE_HEADER_PREFIX = \"x-middleware-\";\n\n// ---------------------------------------------------------------------------\n// Next.js / RSC flight headers (forwarded through middleware)\n// ---------------------------------------------------------------------------\n\nexport const NEXT_ROUTER_STATE_TREE_HEADER = \"Next-Router-State-Tree\";\nexport const NEXT_ROUTER_PREFETCH_HEADER = \"Next-Router-Prefetch\";\nexport const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = \"Next-Router-Segment-Prefetch\";\nexport const NEXT_URL_HEADER = \"Next-Url\";\n\n/** Lowercase flight header variants used in middleware forwarding. */\nexport const FLIGHT_HEADERS: readonly string[] = [\n \"rsc\",\n \"next-router-state-tree\",\n \"next-router-prefetch\",\n \"next-hmr-refresh\",\n \"next-router-segment-prefetch\",\n];\n\n// ---------------------------------------------------------------------------\n// Vercel / Now.sh legacy internal headers (stripped from inbound requests)\n// ---------------------------------------------------------------------------\n\nconst NOW_ROUTE_MATCHES_HEADER = \"x-now-route-matches\";\nconst MATCHED_PATH_HEADER = \"x-matched-path\";\nconst NEXTJS_DATA_HEADER = \"x-nextjs-data\";\nconst NEXT_RESUME_STATE_LENGTH_HEADER = \"x-next-resume-state-length\";\n\n// ---------------------------------------------------------------------------\n// Internal headers blocklist — stripped from inbound requests for security\n// ---------------------------------------------------------------------------\n\n/**\n * Headers that must be stripped from external requests before any handler\n * processes them. An attacker could forge these to influence routing or\n * impersonate internal data fetches.\n *\n * Ported from Next.js `INTERNAL_HEADERS`:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/server-ipc/utils.ts\n */\nexport const INTERNAL_HEADERS = [\n MIDDLEWARE_REWRITE_HEADER,\n MIDDLEWARE_REDIRECT_HEADER,\n MIDDLEWARE_SET_COOKIE_HEADER,\n MIDDLEWARE_SKIP_HEADER,\n MIDDLEWARE_OVERRIDE_HEADERS,\n MIDDLEWARE_NEXT_HEADER,\n NOW_ROUTE_MATCHES_HEADER,\n MATCHED_PATH_HEADER,\n NEXTJS_DATA_HEADER,\n NEXT_RESUME_STATE_LENGTH_HEADER,\n ACTION_FORWARDED_HEADER,\n];\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAa,sBAAsB;;AAGnC,MAAa,sBAAsB;;AAGnC,MAAa,4BAA4B;;AAGzC,MAAa,uBAAuB;;AAGpC,MAAa,uBAAuB;;AAGpC,MAAa,iCAAiC;;AAG9C,MAAa,2BAA2B;;AAGxC,MAAa,2BAA2B;;AAGxC,MAAa,uBAAuB;;AAGpC,MAAa,8BAA8B;;AAG3C,MAAa,qCAAqC;;AAGlD,MAAa,gCAAgC;;AAG7C,MAAa,sCAAsC;;;;;;;;;;;;;AAcnD,MAAa,6BAA6B;;AAO1C,MAAa,aAAa;;AAG1B,MAAa,oBAAoB;;AAOjC,MAAa,qBAAqB;;AAGlC,MAAa,iCAAiC;;AAG9C,MAAa,0BAA0B;;AAOvC,MAAa,4BAA4B;;AAGzC,MAAa,yBAAyB;;AAGtC,MAAa,8BAA8B;;AAG3C,MAAa,gCAAgC;;AAO7C,MAAa,mCAAmC;;AAGhD,MAAa,8BAA8B;;AAG3C,MAAa,+BAA+B;;AAG5C,MAAa,yBAAyB;;AAGtC,MAAa,4BAA4B;;AAGzC,MAAM,6BAA6B;;AAGnC,MAAM,yBAAyB;;AAG/B,MAAa,2BAA2B;AAMxC,MAAa,gCAAgC;AAC7C,MAAa,8BAA8B;AAC3C,MAAa,sCAAsC;AACnD,MAAa,kBAAkB;;AAG/B,MAAa,iBAAoC;CAC/C;CACA;CACA;CACA;CACA;CACD;;;;;;;;;AAuBD,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
@@ -23,7 +23,7 @@ function safeJsonStringify(data) {
23
23
  return JSON.stringify(data).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
24
24
  }
25
25
  function escapeHtmlAttr(value) {
26
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
26
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
27
27
  }
28
28
  function createNonceAttribute(nonce) {
29
29
  if (!nonce) return "";
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","names":[],"sources":["../../src/server/html.ts"],"sourcesContent":["/**\n * HTML-safe JSON serialization for embedding data in <script> tags.\n *\n * JSON.stringify does NOT escape characters that are meaningful to the\n * HTML parser. If a JSON string value contains \"</script>\", the browser\n * closes the script tag early — anything after it executes as HTML.\n * This is a well-known stored XSS vector in SSR frameworks.\n *\n * Next.js mitigates this with htmlEscapeJsonString(). We do the same.\n *\n * Characters escaped:\n * < → \\u003c (prevents </script> and <!-- breakout)\n * > → \\u003e (prevents --> and other HTML close sequences)\n * & → \\u0026 (prevents &lt; entity interpretation in XHTML)\n * \\u2028 → \\\\u2028 (line separator — invalid in JS string literals pre-ES2019)\n * \\u2029 → \\\\u2029 (paragraph separator — same)\n *\n * The result is valid JSON that is also safe to embed in any HTML context\n * without additional escaping.\n */\nexport function safeJsonStringify(data: unknown): string {\n return JSON.stringify(data)\n .replace(/</g, \"\\\\u003c\")\n .replace(/>/g, \"\\\\u003e\")\n .replace(/&/g, \"\\\\u0026\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\nexport function escapeHtmlAttr(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nexport function createNonceAttribute(nonce?: string): string {\n if (!nonce) {\n return \"\";\n }\n\n return ` nonce=\"${escapeHtmlAttr(nonce)}\"`;\n}\n\nexport function createInlineScriptTag(content: string, nonce?: string): string {\n return `<script${createNonceAttribute(nonce)}>${content}</script>`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,KAAK,UAAU,KAAK,CACxB,QAAQ,MAAM,UAAU,CACxB,QAAQ,MAAM,UAAU,CACxB,QAAQ,MAAM,UAAU,CACxB,QAAQ,WAAW,UAAU,CAC7B,QAAQ,WAAW,UAAU;;AAGlC,SAAgB,eAAe,OAAuB;CACpD,OAAO,MAAM,QAAQ,MAAM,QAAQ,CAAC,QAAQ,MAAM,SAAS;;AAG7D,SAAgB,qBAAqB,OAAwB;CAC3D,IAAI,CAAC,OACH,OAAO;CAGT,OAAO,WAAW,eAAe,MAAM,CAAC;;AAG1C,SAAgB,sBAAsB,SAAiB,OAAwB;CAC7E,OAAO,UAAU,qBAAqB,MAAM,CAAC,GAAG,QAAQ"}
1
+ {"version":3,"file":"html.js","names":[],"sources":["../../src/server/html.ts"],"sourcesContent":["/**\n * HTML-safe JSON serialization for embedding data in <script> tags.\n *\n * JSON.stringify does NOT escape characters that are meaningful to the\n * HTML parser. If a JSON string value contains \"</script>\", the browser\n * closes the script tag early — anything after it executes as HTML.\n * This is a well-known stored XSS vector in SSR frameworks.\n *\n * Next.js mitigates this with htmlEscapeJsonString(). We do the same.\n *\n * Characters escaped:\n * < → \\u003c (prevents </script> and <!-- breakout)\n * > → \\u003e (prevents --> and other HTML close sequences)\n * & → \\u0026 (prevents &lt; entity interpretation in XHTML)\n * \\u2028 → \\\\u2028 (line separator — invalid in JS string literals pre-ES2019)\n * \\u2029 → \\\\u2029 (paragraph separator — same)\n *\n * The result is valid JSON that is also safe to embed in any HTML context\n * without additional escaping.\n */\nexport function safeJsonStringify(data: unknown): string {\n return JSON.stringify(data)\n .replace(/</g, \"\\\\u003c\")\n .replace(/>/g, \"\\\\u003e\")\n .replace(/&/g, \"\\\\u0026\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\nexport function escapeHtmlAttr(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\nexport function createNonceAttribute(nonce?: string): string {\n if (!nonce) {\n return \"\";\n }\n\n return ` nonce=\"${escapeHtmlAttr(nonce)}\"`;\n}\n\nexport function createInlineScriptTag(content: string, nonce?: string): string {\n return `<script${createNonceAttribute(nonce)}>${content}</script>`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,KAAK,UAAU,KAAK,CACxB,QAAQ,MAAM,UAAU,CACxB,QAAQ,MAAM,UAAU,CACxB,QAAQ,MAAM,UAAU,CACxB,QAAQ,WAAW,UAAU,CAC7B,QAAQ,WAAW,UAAU;;AAGlC,SAAgB,eAAe,OAAuB;CACpD,OAAO,MACJ,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,SAAS,CACvB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO;;AAG1B,SAAgB,qBAAqB,OAAwB;CAC3D,IAAI,CAAC,OACH,OAAO;CAGT,OAAO,WAAW,eAAe,MAAM,CAAC;;AAG1C,SAAgB,sBAAsB,SAAiB,OAAwB;CAC7E,OAAO,UAAU,qBAAqB,MAAM,CAAC,GAAG,QAAQ"}
@@ -35,11 +35,36 @@ declare function forbiddenResponse(): Response;
35
35
  /**
36
36
  * Build a 404 Not Found plain-text response.
37
37
  *
38
+ * The body matches Next.js's plain-text 404 response exactly. Next.js writes
39
+ * `res.end('This page could not be found')` (no trailing period) for the
40
+ * fallback 404 path; see in `.nextjs-ref`:
41
+ * - packages/next/src/server/route-modules/pages/pages-handler.ts L121, L535
42
+ * - packages/next/src/build/templates/app-route.ts L170, L349
43
+ * - packages/next/src/build/templates/app-page.ts L701, L1043
44
+ * (The React-rendered not-found component in `packages/next/src/client/components/builtin/not-found.tsx`
45
+ * uses the same text with a trailing period — that variant is rendered as HTML,
46
+ * not returned as the plain-text body.)
47
+ *
38
48
  * The `headers` option lets call sites merge middleware response headers into
39
49
  * the 404, matching the pattern used by `app-rsc-handler` after a route match
40
50
  * fails but middleware has already contributed headers.
41
51
  */
42
52
  declare function notFoundResponse(init?: ErrorResponseInit): Response;
53
+ /**
54
+ * Build a 404 plain-text response for invalid `_next/static/*` paths.
55
+ *
56
+ * Next.js short-circuits invalid `_next/static/*` requests with a plain-text
57
+ * `"Not Found"` body (NOT the rendered HTML 404 page) — saves bandwidth on
58
+ * what is almost certainly a misbehaving client requesting a stale chunk.
59
+ *
60
+ * Body and content-type match Next.js exactly:
61
+ * res.statusCode = 404
62
+ * res.setHeader('Content-Type', 'text/plain; charset=utf-8')
63
+ * res.end('Not Found')
64
+ *
65
+ * @see packages/next/src/server/lib/router-server.ts in `.nextjs-ref`
66
+ */
67
+ declare function notFoundStaticAssetResponse(): Response;
43
68
  /**
44
69
  * Build a 405 Method Not Allowed plain-text response with the `Allow` header set.
45
70
  *
@@ -63,5 +88,5 @@ declare function payloadTooLargeResponse(): Response;
63
88
  */
64
89
  declare function internalServerErrorResponse(message?: string, init?: ErrorResponseInit): Response;
65
90
  //#endregion
66
- export { badRequestResponse, forbiddenResponse, internalServerErrorResponse, methodNotAllowedResponse, notFoundResponse, payloadTooLargeResponse };
91
+ export { badRequestResponse, forbiddenResponse, internalServerErrorResponse, methodNotAllowedResponse, notFoundResponse, notFoundStaticAssetResponse, payloadTooLargeResponse };
67
92
  //# sourceMappingURL=http-error-responses.d.ts.map
@@ -25,17 +25,47 @@ function forbiddenResponse() {
25
25
  /**
26
26
  * Build a 404 Not Found plain-text response.
27
27
  *
28
+ * The body matches Next.js's plain-text 404 response exactly. Next.js writes
29
+ * `res.end('This page could not be found')` (no trailing period) for the
30
+ * fallback 404 path; see in `.nextjs-ref`:
31
+ * - packages/next/src/server/route-modules/pages/pages-handler.ts L121, L535
32
+ * - packages/next/src/build/templates/app-route.ts L170, L349
33
+ * - packages/next/src/build/templates/app-page.ts L701, L1043
34
+ * (The React-rendered not-found component in `packages/next/src/client/components/builtin/not-found.tsx`
35
+ * uses the same text with a trailing period — that variant is rendered as HTML,
36
+ * not returned as the plain-text body.)
37
+ *
28
38
  * The `headers` option lets call sites merge middleware response headers into
29
39
  * the 404, matching the pattern used by `app-rsc-handler` after a route match
30
40
  * fails but middleware has already contributed headers.
31
41
  */
32
42
  function notFoundResponse(init) {
33
- return new Response("Not Found", {
43
+ return new Response("This page could not be found", {
34
44
  status: 404,
35
45
  headers: init?.headers
36
46
  });
37
47
  }
38
48
  /**
49
+ * Build a 404 plain-text response for invalid `_next/static/*` paths.
50
+ *
51
+ * Next.js short-circuits invalid `_next/static/*` requests with a plain-text
52
+ * `"Not Found"` body (NOT the rendered HTML 404 page) — saves bandwidth on
53
+ * what is almost certainly a misbehaving client requesting a stale chunk.
54
+ *
55
+ * Body and content-type match Next.js exactly:
56
+ * res.statusCode = 404
57
+ * res.setHeader('Content-Type', 'text/plain; charset=utf-8')
58
+ * res.end('Not Found')
59
+ *
60
+ * @see packages/next/src/server/lib/router-server.ts in `.nextjs-ref`
61
+ */
62
+ function notFoundStaticAssetResponse() {
63
+ return new Response("Not Found", {
64
+ status: 404,
65
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
66
+ });
67
+ }
68
+ /**
39
69
  * Build a 405 Method Not Allowed plain-text response with the `Allow` header set.
40
70
  *
41
71
  * `allowedMethods` is rendered as the comma-separated `Allow` header value.
@@ -72,6 +102,6 @@ function internalServerErrorResponse(message, init) {
72
102
  });
73
103
  }
74
104
  //#endregion
75
- export { badRequestResponse, forbiddenResponse, internalServerErrorResponse, methodNotAllowedResponse, notFoundResponse, payloadTooLargeResponse };
105
+ export { badRequestResponse, forbiddenResponse, internalServerErrorResponse, methodNotAllowedResponse, notFoundResponse, notFoundStaticAssetResponse, payloadTooLargeResponse };
76
106
 
77
107
  //# sourceMappingURL=http-error-responses.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-error-responses.js","names":[],"sources":["../../src/server/http-error-responses.ts"],"sourcesContent":["/**\n * Shared HTTP error response builders.\n *\n * Centralizes the canonical `new Response(\"...\", { status: 4xx | 5xx })` patterns\n * that previously were scattered across server modules. Each helper standardizes\n * the canonical body for its status; the optional `headers` argument lets callers\n * merge middleware/middleware-context headers without re-implementing the\n * `new Response(...)` boilerplate.\n *\n * Sites with route-specific bodies (e.g. `\"404 - API route not found\"`,\n * `\"Image not found\"`, generated worker templates) intentionally remain inline\n * because their bodies are either tested-against fixtures or run inside template\n * strings that have no access to runtime imports.\n *\n * Follow-up to #1058 / #1071 / #1078, which extracted the first batch of these\n * helpers (action/page error responses, `forbiddenResponse`, `payloadTooLargeResponse`).\n */\n\ntype ErrorResponseInit = {\n headers?: HeadersInit;\n};\n\n/**\n * Build a 400 Bad Request plain-text response.\n *\n * Used for malformed percent-encoding, invalid HTTP methods (where Next.js\n * returns 400), and other request-shape validation failures.\n */\nexport function badRequestResponse(init?: ErrorResponseInit): Response {\n return new Response(\"Bad Request\", { status: 400, headers: init?.headers });\n}\n\n/**\n * Build a 403 Forbidden plain-text response.\n *\n * Used by CSRF origin validation and dev-server origin checks.\n */\nexport function forbiddenResponse(): Response {\n return new Response(\"Forbidden\", { status: 403, headers: { \"Content-Type\": \"text/plain\" } });\n}\n\n/**\n * Build a 404 Not Found plain-text response.\n *\n * The `headers` option lets call sites merge middleware response headers into\n * the 404, matching the pattern used by `app-rsc-handler` after a route match\n * fails but middleware has already contributed headers.\n */\nexport function notFoundResponse(init?: ErrorResponseInit): Response {\n return new Response(\"Not Found\", { status: 404, headers: init?.headers });\n}\n\n/**\n * Build a 405 Method Not Allowed plain-text response with the `Allow` header set.\n *\n * `allowedMethods` is rendered as the comma-separated `Allow` header value.\n * Existing headers (e.g. middleware response headers) can be merged via `init.headers`;\n * the `Allow` header takes precedence and overwrites any colliding entry.\n */\nexport function methodNotAllowedResponse(\n allowedMethods: string,\n init?: ErrorResponseInit,\n): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"Allow\", allowedMethods);\n return new Response(\"Method Not Allowed\", { status: 405, headers });\n}\n\n/**\n * Build a 413 Payload Too Large plain-text response.\n *\n * Used by server action body-size enforcement.\n */\nexport function payloadTooLargeResponse(): Response {\n return new Response(\"Payload Too Large\", { status: 413 });\n}\n\n/**\n * Build a 500 Internal Server Error plain-text response.\n *\n * The `message` argument lets dev-mode handlers surface failure details while\n * production paths fall back to the canonical body. Pass `undefined` (or omit)\n * to use the canonical \"Internal Server Error\" body.\n */\nexport function internalServerErrorResponse(message?: string, init?: ErrorResponseInit): Response {\n return new Response(message ?? \"Internal Server Error\", {\n status: 500,\n headers: init?.headers,\n });\n}\n"],"mappings":";;;;;;;AA4BA,SAAgB,mBAAmB,MAAoC;CACrE,OAAO,IAAI,SAAS,eAAe;EAAE,QAAQ;EAAK,SAAS,MAAM;EAAS,CAAC;;;;;;;AAQ7E,SAAgB,oBAA8B;CAC5C,OAAO,IAAI,SAAS,aAAa;EAAE,QAAQ;EAAK,SAAS,EAAE,gBAAgB,cAAc;EAAE,CAAC;;;;;;;;;AAU9F,SAAgB,iBAAiB,MAAoC;CACnE,OAAO,IAAI,SAAS,aAAa;EAAE,QAAQ;EAAK,SAAS,MAAM;EAAS,CAAC;;;;;;;;;AAU3E,SAAgB,yBACd,gBACA,MACU;CACV,MAAM,UAAU,IAAI,QAAQ,MAAM,QAAQ;CAC1C,QAAQ,IAAI,SAAS,eAAe;CACpC,OAAO,IAAI,SAAS,sBAAsB;EAAE,QAAQ;EAAK;EAAS,CAAC;;;;;;;AAQrE,SAAgB,0BAAoC;CAClD,OAAO,IAAI,SAAS,qBAAqB,EAAE,QAAQ,KAAK,CAAC;;;;;;;;;AAU3D,SAAgB,4BAA4B,SAAkB,MAAoC;CAChG,OAAO,IAAI,SAAS,WAAW,yBAAyB;EACtD,QAAQ;EACR,SAAS,MAAM;EAChB,CAAC"}
1
+ {"version":3,"file":"http-error-responses.js","names":[],"sources":["../../src/server/http-error-responses.ts"],"sourcesContent":["/**\n * Shared HTTP error response builders.\n *\n * Centralizes the canonical `new Response(\"...\", { status: 4xx | 5xx })` patterns\n * that previously were scattered across server modules. Each helper standardizes\n * the canonical body for its status; the optional `headers` argument lets callers\n * merge middleware/middleware-context headers without re-implementing the\n * `new Response(...)` boilerplate.\n *\n * Sites with route-specific bodies (e.g. `\"404 - API route not found\"`,\n * `\"Image not found\"`, generated worker templates) intentionally remain inline\n * because their bodies are either tested-against fixtures or run inside template\n * strings that have no access to runtime imports.\n *\n * Follow-up to #1058 / #1071 / #1078, which extracted the first batch of these\n * helpers (action/page error responses, `forbiddenResponse`, `payloadTooLargeResponse`).\n */\n\ntype ErrorResponseInit = {\n headers?: HeadersInit;\n};\n\n/**\n * Build a 400 Bad Request plain-text response.\n *\n * Used for malformed percent-encoding, invalid HTTP methods (where Next.js\n * returns 400), and other request-shape validation failures.\n */\nexport function badRequestResponse(init?: ErrorResponseInit): Response {\n return new Response(\"Bad Request\", { status: 400, headers: init?.headers });\n}\n\n/**\n * Build a 403 Forbidden plain-text response.\n *\n * Used by CSRF origin validation and dev-server origin checks.\n */\nexport function forbiddenResponse(): Response {\n return new Response(\"Forbidden\", { status: 403, headers: { \"Content-Type\": \"text/plain\" } });\n}\n\n/**\n * Build a 404 Not Found plain-text response.\n *\n * The body matches Next.js's plain-text 404 response exactly. Next.js writes\n * `res.end('This page could not be found')` (no trailing period) for the\n * fallback 404 path; see in `.nextjs-ref`:\n * - packages/next/src/server/route-modules/pages/pages-handler.ts L121, L535\n * - packages/next/src/build/templates/app-route.ts L170, L349\n * - packages/next/src/build/templates/app-page.ts L701, L1043\n * (The React-rendered not-found component in `packages/next/src/client/components/builtin/not-found.tsx`\n * uses the same text with a trailing period — that variant is rendered as HTML,\n * not returned as the plain-text body.)\n *\n * The `headers` option lets call sites merge middleware response headers into\n * the 404, matching the pattern used by `app-rsc-handler` after a route match\n * fails but middleware has already contributed headers.\n */\nexport function notFoundResponse(init?: ErrorResponseInit): Response {\n return new Response(\"This page could not be found\", {\n status: 404,\n headers: init?.headers,\n });\n}\n\n/**\n * Build a 404 plain-text response for invalid `_next/static/*` paths.\n *\n * Next.js short-circuits invalid `_next/static/*` requests with a plain-text\n * `\"Not Found\"` body (NOT the rendered HTML 404 page) — saves bandwidth on\n * what is almost certainly a misbehaving client requesting a stale chunk.\n *\n * Body and content-type match Next.js exactly:\n * res.statusCode = 404\n * res.setHeader('Content-Type', 'text/plain; charset=utf-8')\n * res.end('Not Found')\n *\n * @see packages/next/src/server/lib/router-server.ts in `.nextjs-ref`\n */\nexport function notFoundStaticAssetResponse(): Response {\n return new Response(\"Not Found\", {\n status: 404,\n headers: { \"Content-Type\": \"text/plain; charset=utf-8\" },\n });\n}\n\n/**\n * Build a 405 Method Not Allowed plain-text response with the `Allow` header set.\n *\n * `allowedMethods` is rendered as the comma-separated `Allow` header value.\n * Existing headers (e.g. middleware response headers) can be merged via `init.headers`;\n * the `Allow` header takes precedence and overwrites any colliding entry.\n */\nexport function methodNotAllowedResponse(\n allowedMethods: string,\n init?: ErrorResponseInit,\n): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"Allow\", allowedMethods);\n return new Response(\"Method Not Allowed\", { status: 405, headers });\n}\n\n/**\n * Build a 413 Payload Too Large plain-text response.\n *\n * Used by server action body-size enforcement.\n */\nexport function payloadTooLargeResponse(): Response {\n return new Response(\"Payload Too Large\", { status: 413 });\n}\n\n/**\n * Build a 500 Internal Server Error plain-text response.\n *\n * The `message` argument lets dev-mode handlers surface failure details while\n * production paths fall back to the canonical body. Pass `undefined` (or omit)\n * to use the canonical \"Internal Server Error\" body.\n */\nexport function internalServerErrorResponse(message?: string, init?: ErrorResponseInit): Response {\n return new Response(message ?? \"Internal Server Error\", {\n status: 500,\n headers: init?.headers,\n });\n}\n"],"mappings":";;;;;;;AA4BA,SAAgB,mBAAmB,MAAoC;CACrE,OAAO,IAAI,SAAS,eAAe;EAAE,QAAQ;EAAK,SAAS,MAAM;EAAS,CAAC;;;;;;;AAQ7E,SAAgB,oBAA8B;CAC5C,OAAO,IAAI,SAAS,aAAa;EAAE,QAAQ;EAAK,SAAS,EAAE,gBAAgB,cAAc;EAAE,CAAC;;;;;;;;;;;;;;;;;;;AAoB9F,SAAgB,iBAAiB,MAAoC;CACnE,OAAO,IAAI,SAAS,gCAAgC;EAClD,QAAQ;EACR,SAAS,MAAM;EAChB,CAAC;;;;;;;;;;;;;;;;AAiBJ,SAAgB,8BAAwC;CACtD,OAAO,IAAI,SAAS,aAAa;EAC/B,QAAQ;EACR,SAAS,EAAE,gBAAgB,6BAA6B;EACzD,CAAC;;;;;;;;;AAUJ,SAAgB,yBACd,gBACA,MACU;CACV,MAAM,UAAU,IAAI,QAAQ,MAAM,QAAQ;CAC1C,QAAQ,IAAI,SAAS,eAAe;CACpC,OAAO,IAAI,SAAS,sBAAsB;EAAE,QAAQ;EAAK;EAAS,CAAC;;;;;;;AAQrE,SAAgB,0BAAoC;CAClD,OAAO,IAAI,SAAS,qBAAqB,EAAE,QAAQ,KAAK,CAAC;;;;;;;;;AAU3D,SAAgB,4BAA4B,SAAkB,MAAoC;CAChG,OAAO,IAAI,SAAS,WAAW,yBAAyB;EACtD,QAAQ;EACR,SAAS,MAAM;EAChB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { RenderObservation } from "./cache-proof.js";
1
2
  import { CacheHandlerValue, CachedAppPageValue, CachedPagesValue, IncrementalCacheValue } from "../shims/cache.js";
2
3
  import { OnRequestErrorContext } from "./instrumentation.js";
3
4
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
@@ -20,6 +21,10 @@ declare function isrGet(key: string): Promise<ISRCacheEntry | null>;
20
21
  * Store a value in the ISR cache with a revalidation period.
21
22
  */
22
23
  declare function isrSet(key: string, data: IncrementalCacheValue, revalidateSeconds: number, tags?: string[], expireSeconds?: number): Promise<void>;
24
+ declare function isrSetPrerenderedAppPage(key: string, data: CachedAppPageValue, metadata: {
25
+ expireSeconds?: number;
26
+ revalidateSeconds?: number;
27
+ }): Promise<void>;
23
28
  /**
24
29
  * Trigger a background regeneration for a cache key.
25
30
  *
@@ -46,7 +51,7 @@ declare function buildPagesCacheValue(html: string, pageData: object, status?: n
46
51
  /**
47
52
  * Build a CachedAppPageValue for the App Router ISR cache.
48
53
  */
49
- declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, status?: number): CachedAppPageValue;
54
+ declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, status?: number, renderObservation?: RenderObservation): CachedAppPageValue;
50
55
  /**
51
56
  * Compute an ISR cache key for a given router type and pathname.
52
57
  * Long pathnames are hashed to stay within KV key-length limits (512 bytes).
@@ -57,7 +62,7 @@ declare function appIsrHtmlKey(pathname: string): string;
57
62
  * Build the ISR cache key for an RSC payload.
58
63
  *
59
64
  * Note: the key format changed from `rsc:<hash>` to `rsc:slots:<hash>` (and
60
- * optionally `rsc:slots:<hash>:preserve-ui`). Existing cached entries under
65
+ * optionally `rsc:slots:<hash>:<render-mode-variant>`). Existing cached entries under
61
66
  * the old format will become unreachable after deployment. This is acceptable
62
67
  * because ISR entries have TTLs and will be regenerated on the next request.
63
68
  */
@@ -73,5 +78,5 @@ declare function setRevalidateDuration(key: string, seconds: number): void;
73
78
  */
74
79
  declare function getRevalidateDuration(key: string): number | undefined;
75
80
  //#endregion
76
- export { ISRCacheEntry, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
81
+ export { ISRCacheEntry, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
77
82
  //# sourceMappingURL=isr-cache.d.ts.map
@@ -3,7 +3,7 @@ import { reportRequestError } from "./instrumentation.js";
3
3
  import { fnv1a64 } from "../utils/hash.js";
4
4
  import { getCacheHandler } from "../shims/cache.js";
5
5
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
6
- import { APP_RSC_RENDER_MODE_NAVIGATION, shouldUsePreserveUiCacheVariant } from "./app-rsc-render-mode.js";
6
+ import { APP_RSC_RENDER_MODE_NAVIGATION, getRscRenderModeCacheVariant } from "./app-rsc-render-mode.js";
7
7
  //#region src/server/isr-cache.ts
8
8
  /**
9
9
  * ISR (Incremental Static Regeneration) cache layer.
@@ -48,6 +48,22 @@ async function isrSet(key, data, revalidateSeconds, tags, expireSeconds) {
48
48
  tags: tags ?? []
49
49
  });
50
50
  }
51
+ async function isrSetPrerenderedAppPage(key, data, metadata) {
52
+ const handler = getCacheHandler();
53
+ const revalidateSeconds = metadata.revalidateSeconds;
54
+ if (process.env.NEXT_PRIVATE_DEBUG_CACHE) console.debug("[vinext] ISR: seed", key);
55
+ await handler.set(key, data, revalidateSeconds === void 0 ? {} : metadata.expireSeconds === void 0 ? {
56
+ cacheControl: { revalidate: revalidateSeconds },
57
+ revalidate: revalidateSeconds
58
+ } : {
59
+ cacheControl: {
60
+ revalidate: revalidateSeconds,
61
+ expire: metadata.expireSeconds
62
+ },
63
+ revalidate: revalidateSeconds
64
+ });
65
+ if (revalidateSeconds !== void 0) setRevalidateDuration(key, revalidateSeconds);
66
+ }
51
67
  const _PENDING_REGEN_KEY = Symbol.for("vinext.isrCache.pendingRegenerations");
52
68
  const _g = globalThis;
53
69
  const pendingRegenerations = _g[_PENDING_REGEN_KEY] ??= /* @__PURE__ */ new Map();
@@ -100,8 +116,8 @@ function buildPagesCacheValue(html, pageData, status) {
100
116
  /**
101
117
  * Build a CachedAppPageValue for the App Router ISR cache.
102
118
  */
103
- function buildAppPageCacheValue(html, rscData, status) {
104
- return {
119
+ function buildAppPageCacheValue(html, rscData, status, renderObservation) {
120
+ const value = {
105
121
  kind: "APP_PAGE",
106
122
  html,
107
123
  rscData,
@@ -109,6 +125,8 @@ function buildAppPageCacheValue(html, rscData, status) {
109
125
  postponed: void 0,
110
126
  status
111
127
  };
128
+ if (renderObservation) value.renderObservation = renderObservation;
129
+ return value;
112
130
  }
113
131
  function normalizeCachePathname(pathname) {
114
132
  return pathname === "/" ? "/" : pathname.replace(/\/$/, "");
@@ -144,13 +162,13 @@ function appIsrHtmlKey(pathname) {
144
162
  * Build the ISR cache key for an RSC payload.
145
163
  *
146
164
  * Note: the key format changed from `rsc:<hash>` to `rsc:slots:<hash>` (and
147
- * optionally `rsc:slots:<hash>:preserve-ui`). Existing cached entries under
165
+ * optionally `rsc:slots:<hash>:<render-mode-variant>`). Existing cached entries under
148
166
  * the old format will become unreachable after deployment. This is acceptable
149
167
  * because ISR entries have TTLs and will be regenerated on the next request.
150
168
  */
151
169
  function appIsrRscKey(pathname, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION) {
152
170
  const normalizedMountedSlotsHeader = normalizeMountedSlotsHeader(mountedSlotsHeader);
153
- const variant = [normalizedMountedSlotsHeader ? `slots:${fnv1a64(normalizedMountedSlotsHeader)}` : null, shouldUsePreserveUiCacheVariant(renderMode) ? "preserve-ui" : null].filter((part) => part !== null).join(":");
171
+ const variant = [normalizedMountedSlotsHeader ? `slots:${fnv1a64(normalizedMountedSlotsHeader)}` : null, getRscRenderModeCacheVariant(renderMode)].filter((part) => part !== null).join(":");
154
172
  return appIsrCacheKey(pathname, variant ? `rsc:${variant}` : "rsc");
155
173
  }
156
174
  function appIsrRouteKey(pathname) {
@@ -179,6 +197,6 @@ function getRevalidateDuration(key) {
179
197
  return revalidateDurations.get(key);
180
198
  }
181
199
  //#endregion
182
- export { appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
200
+ export { appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
183
201
 
184
202
  //# sourceMappingURL=isr-cache.js.map