vinext 0.0.51 → 0.0.53

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 (423) hide show
  1. package/README.md +1 -1
  2. package/dist/build/clean-output.d.ts +14 -0
  3. package/dist/build/clean-output.js +36 -0
  4. package/dist/build/clean-output.js.map +1 -0
  5. package/dist/build/precompress.d.ts +7 -7
  6. package/dist/build/precompress.js +18 -17
  7. package/dist/build/precompress.js.map +1 -1
  8. package/dist/build/prerender.d.ts +9 -16
  9. package/dist/build/prerender.js +88 -50
  10. package/dist/build/prerender.js.map +1 -1
  11. package/dist/build/run-prerender.js +10 -1
  12. package/dist/build/run-prerender.js.map +1 -1
  13. package/dist/build/static-export.d.ts +5 -0
  14. package/dist/build/static-export.js +8 -3
  15. package/dist/build/static-export.js.map +1 -1
  16. package/dist/check.js +4 -0
  17. package/dist/check.js.map +1 -1
  18. package/dist/cli-args.d.ts +1 -0
  19. package/dist/cli-args.js +5 -0
  20. package/dist/cli-args.js.map +1 -1
  21. package/dist/cli.js +58 -4
  22. package/dist/cli.js.map +1 -1
  23. package/dist/client/instrumentation-client-inject.d.ts +34 -0
  24. package/dist/client/instrumentation-client-inject.js +57 -0
  25. package/dist/client/instrumentation-client-inject.js.map +1 -0
  26. package/dist/client/navigation-runtime.d.ts +60 -0
  27. package/dist/client/navigation-runtime.js +171 -0
  28. package/dist/client/navigation-runtime.js.map +1 -0
  29. package/dist/client/pages-router-link-navigation.d.ts +26 -0
  30. package/dist/client/pages-router-link-navigation.js +14 -0
  31. package/dist/client/pages-router-link-navigation.js.map +1 -0
  32. package/dist/client/vinext-next-data.d.ts +14 -3
  33. package/dist/client/vinext-next-data.js +50 -1
  34. package/dist/client/vinext-next-data.js.map +1 -0
  35. package/dist/client/window-next.d.ts +10 -2
  36. package/dist/client/window-next.js.map +1 -1
  37. package/dist/cloudflare/kv-cache-handler.js +2 -1
  38. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  39. package/dist/cloudflare/tpr.js +1 -1
  40. package/dist/cloudflare/tpr.js.map +1 -1
  41. package/dist/config/config-matchers.d.ts +63 -16
  42. package/dist/config/config-matchers.js +145 -9
  43. package/dist/config/config-matchers.js.map +1 -1
  44. package/dist/config/next-config.d.ts +32 -5
  45. package/dist/config/next-config.js +55 -15
  46. package/dist/config/next-config.js.map +1 -1
  47. package/dist/deploy.js +130 -46
  48. package/dist/deploy.js.map +1 -1
  49. package/dist/entries/app-browser-entry.js +9 -3
  50. package/dist/entries/app-browser-entry.js.map +1 -1
  51. package/dist/entries/app-rsc-entry.d.ts +4 -2
  52. package/dist/entries/app-rsc-entry.js +76 -16
  53. package/dist/entries/app-rsc-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-manifest.d.ts +1 -0
  55. package/dist/entries/app-rsc-manifest.js +53 -6
  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 +40 -3
  61. package/dist/entries/pages-client-entry.js.map +1 -1
  62. package/dist/entries/pages-server-entry.js +261 -31
  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 +161 -46
  68. package/dist/index.js.map +1 -1
  69. package/dist/plugins/css-data-url.d.ts +7 -0
  70. package/dist/plugins/css-data-url.js +81 -0
  71. package/dist/plugins/css-data-url.js.map +1 -0
  72. package/dist/plugins/fonts.js +30 -5
  73. package/dist/plugins/fonts.js.map +1 -1
  74. package/dist/plugins/middleware-server-only.d.ts +54 -0
  75. package/dist/plugins/middleware-server-only.js +91 -0
  76. package/dist/plugins/middleware-server-only.js.map +1 -0
  77. package/dist/plugins/optimize-imports.js +4 -4
  78. package/dist/plugins/optimize-imports.js.map +1 -1
  79. package/dist/plugins/strip-server-exports.js +5 -8
  80. package/dist/plugins/strip-server-exports.js.map +1 -1
  81. package/dist/routing/app-route-graph.d.ts +20 -1
  82. package/dist/routing/app-route-graph.js +58 -6
  83. package/dist/routing/app-route-graph.js.map +1 -1
  84. package/dist/routing/app-router.d.ts +2 -2
  85. package/dist/routing/app-router.js +2 -2
  86. package/dist/routing/app-router.js.map +1 -1
  87. package/dist/routing/route-trie.js +13 -18
  88. package/dist/routing/route-trie.js.map +1 -1
  89. package/dist/routing/utils.d.ts +12 -1
  90. package/dist/routing/utils.js +18 -1
  91. package/dist/routing/utils.js.map +1 -1
  92. package/dist/server/api-handler.js +153 -42
  93. package/dist/server/api-handler.js.map +1 -1
  94. package/dist/server/app-browser-action-result.d.ts +16 -1
  95. package/dist/server/app-browser-action-result.js +15 -1
  96. package/dist/server/app-browser-action-result.js.map +1 -1
  97. package/dist/server/app-browser-entry.js +309 -155
  98. package/dist/server/app-browser-entry.js.map +1 -1
  99. package/dist/server/app-browser-interception-context.d.ts +24 -0
  100. package/dist/server/app-browser-interception-context.js +32 -0
  101. package/dist/server/app-browser-interception-context.js.map +1 -0
  102. package/dist/server/app-browser-navigation-controller.d.ts +3 -1
  103. package/dist/server/app-browser-navigation-controller.js +5 -1
  104. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  105. package/dist/server/app-browser-rsc-redirect.d.ts +2 -1
  106. package/dist/server/app-browser-rsc-redirect.js +2 -2
  107. package/dist/server/app-browser-rsc-redirect.js.map +1 -1
  108. package/dist/server/app-browser-state.d.ts +18 -1
  109. package/dist/server/app-browser-state.js +19 -1
  110. package/dist/server/app-browser-state.js.map +1 -1
  111. package/dist/server/app-browser-stream.d.ts +5 -14
  112. package/dist/server/app-browser-stream.js +13 -7
  113. package/dist/server/app-browser-stream.js.map +1 -1
  114. package/dist/server/app-browser-visible-commit.d.ts +2 -1
  115. package/dist/server/app-browser-visible-commit.js +1 -0
  116. package/dist/server/app-browser-visible-commit.js.map +1 -1
  117. package/dist/server/app-elements-wire.d.ts +10 -5
  118. package/dist/server/app-elements-wire.js +84 -2
  119. package/dist/server/app-elements-wire.js.map +1 -1
  120. package/dist/server/app-elements.d.ts +3 -2
  121. package/dist/server/app-elements.js +3 -2
  122. package/dist/server/app-elements.js.map +1 -1
  123. package/dist/server/app-fallback-renderer.d.ts +12 -3
  124. package/dist/server/app-fallback-renderer.js +15 -8
  125. package/dist/server/app-fallback-renderer.js.map +1 -1
  126. package/dist/server/app-history-state.js +6 -2
  127. package/dist/server/app-history-state.js.map +1 -1
  128. package/dist/server/app-interception-context-header.d.ts +33 -0
  129. package/dist/server/app-interception-context-header.js +44 -0
  130. package/dist/server/app-interception-context-header.js.map +1 -0
  131. package/dist/server/app-middleware.d.ts +13 -0
  132. package/dist/server/app-middleware.js +3 -1
  133. package/dist/server/app-middleware.js.map +1 -1
  134. package/dist/server/app-mounted-slots-header.d.ts +19 -0
  135. package/dist/server/app-mounted-slots-header.js +40 -1
  136. package/dist/server/app-mounted-slots-header.js.map +1 -1
  137. package/dist/server/app-optimistic-routing.d.ts +54 -0
  138. package/dist/server/app-optimistic-routing.js +208 -0
  139. package/dist/server/app-optimistic-routing.js.map +1 -0
  140. package/dist/server/app-page-boundary-render.d.ts +1 -0
  141. package/dist/server/app-page-boundary-render.js +2 -0
  142. package/dist/server/app-page-boundary-render.js.map +1 -1
  143. package/dist/server/app-page-boundary.d.ts +1 -0
  144. package/dist/server/app-page-boundary.js +2 -0
  145. package/dist/server/app-page-boundary.js.map +1 -1
  146. package/dist/server/app-page-cache.d.ts +15 -1
  147. package/dist/server/app-page-cache.js +68 -7
  148. package/dist/server/app-page-cache.js.map +1 -1
  149. package/dist/server/app-page-dispatch.d.ts +5 -0
  150. package/dist/server/app-page-dispatch.js +39 -5
  151. package/dist/server/app-page-dispatch.js.map +1 -1
  152. package/dist/server/app-page-element-builder.d.ts +2 -1
  153. package/dist/server/app-page-element-builder.js +7 -3
  154. package/dist/server/app-page-element-builder.js.map +1 -1
  155. package/dist/server/app-page-execution.d.ts +29 -1
  156. package/dist/server/app-page-execution.js +91 -4
  157. package/dist/server/app-page-execution.js.map +1 -1
  158. package/dist/server/app-page-head.d.ts +1 -0
  159. package/dist/server/app-page-head.js +29 -2
  160. package/dist/server/app-page-head.js.map +1 -1
  161. package/dist/server/app-page-probe.js +1 -1
  162. package/dist/server/app-page-render-observation.js +1 -1
  163. package/dist/server/app-page-render.d.ts +3 -0
  164. package/dist/server/app-page-render.js +7 -3
  165. package/dist/server/app-page-render.js.map +1 -1
  166. package/dist/server/app-page-response.d.ts +11 -1
  167. package/dist/server/app-page-response.js +18 -5
  168. package/dist/server/app-page-response.js.map +1 -1
  169. package/dist/server/app-page-route-wiring.d.ts +1 -0
  170. package/dist/server/app-page-route-wiring.js +35 -15
  171. package/dist/server/app-page-route-wiring.js.map +1 -1
  172. package/dist/server/app-page-stream.d.ts +4 -0
  173. package/dist/server/app-page-stream.js +3 -0
  174. package/dist/server/app-page-stream.js.map +1 -1
  175. package/dist/server/app-prerender-static-params.d.ts +2 -1
  176. package/dist/server/app-prerender-static-params.js +44 -8
  177. package/dist/server/app-prerender-static-params.js.map +1 -1
  178. package/dist/server/app-route-handler-cache.d.ts +2 -2
  179. package/dist/server/app-route-handler-cache.js +3 -2
  180. package/dist/server/app-route-handler-cache.js.map +1 -1
  181. package/dist/server/app-route-handler-dispatch.d.ts +7 -1
  182. package/dist/server/app-route-handler-dispatch.js +4 -1
  183. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  184. package/dist/server/app-route-handler-execution.d.ts +18 -2
  185. package/dist/server/app-route-handler-execution.js +1 -0
  186. package/dist/server/app-route-handler-execution.js.map +1 -1
  187. package/dist/server/app-route-handler-response.js +6 -5
  188. package/dist/server/app-route-handler-response.js.map +1 -1
  189. package/dist/server/app-router-entry.js +6 -2
  190. package/dist/server/app-router-entry.js.map +1 -1
  191. package/dist/server/app-rsc-handler.d.ts +11 -1
  192. package/dist/server/app-rsc-handler.js +48 -21
  193. package/dist/server/app-rsc-handler.js.map +1 -1
  194. package/dist/server/app-rsc-render-mode.d.ts +4 -3
  195. package/dist/server/app-rsc-render-mode.js +7 -1
  196. package/dist/server/app-rsc-render-mode.js.map +1 -1
  197. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  198. package/dist/server/app-rsc-request-normalization.js +6 -2
  199. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  200. package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
  201. package/dist/server/app-rsc-response-finalizer.js +10 -3
  202. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  203. package/dist/server/app-rsc-route-matching.js +2 -2
  204. package/dist/server/app-rsc-route-matching.js.map +1 -1
  205. package/dist/server/app-segment-config.d.ts +4 -1
  206. package/dist/server/app-segment-config.js +6 -1
  207. package/dist/server/app-segment-config.js.map +1 -1
  208. package/dist/server/app-server-action-execution.d.ts +1 -0
  209. package/dist/server/app-server-action-execution.js +5 -1
  210. package/dist/server/app-server-action-execution.js.map +1 -1
  211. package/dist/server/app-ssr-entry.d.ts +2 -0
  212. package/dist/server/app-ssr-entry.js +92 -55
  213. package/dist/server/app-ssr-entry.js.map +1 -1
  214. package/dist/server/app-ssr-stream.d.ts +30 -2
  215. package/dist/server/app-ssr-stream.js +95 -8
  216. package/dist/server/app-ssr-stream.js.map +1 -1
  217. package/dist/server/app-static-generation.d.ts +1 -0
  218. package/dist/server/app-static-generation.js +2 -1
  219. package/dist/server/app-static-generation.js.map +1 -1
  220. package/dist/server/artifact-compatibility.d.ts +1 -1
  221. package/dist/server/artifact-compatibility.js.map +1 -1
  222. package/dist/server/cache-headers.d.ts +7 -0
  223. package/dist/server/cache-headers.js +19 -0
  224. package/dist/server/cache-headers.js.map +1 -0
  225. package/dist/server/cache-proof.d.ts +49 -3
  226. package/dist/server/cache-proof.js +78 -22
  227. package/dist/server/cache-proof.js.map +1 -1
  228. package/dist/server/client-reuse-manifest.d.ts +99 -0
  229. package/dist/server/client-reuse-manifest.js +212 -0
  230. package/dist/server/client-reuse-manifest.js.map +1 -0
  231. package/dist/server/default-global-error-module.d.ts +20 -0
  232. package/dist/server/default-global-error-module.js +20 -0
  233. package/dist/server/default-global-error-module.js.map +1 -0
  234. package/dist/server/default-not-found-module.d.ts +20 -0
  235. package/dist/server/default-not-found-module.js +20 -0
  236. package/dist/server/default-not-found-module.js.map +1 -0
  237. package/dist/server/dev-server.d.ts +10 -2
  238. package/dist/server/dev-server.js +99 -36
  239. package/dist/server/dev-server.js.map +1 -1
  240. package/dist/server/edge-api-runtime.d.ts +5 -0
  241. package/dist/server/edge-api-runtime.js +8 -0
  242. package/dist/server/edge-api-runtime.js.map +1 -0
  243. package/dist/server/headers.d.ts +22 -1
  244. package/dist/server/headers.js +22 -1
  245. package/dist/server/headers.js.map +1 -1
  246. package/dist/server/http-error-responses.d.ts +16 -1
  247. package/dist/server/http-error-responses.js +21 -1
  248. package/dist/server/http-error-responses.js.map +1 -1
  249. package/dist/server/image-optimization.d.ts +13 -4
  250. package/dist/server/image-optimization.js +15 -4
  251. package/dist/server/image-optimization.js.map +1 -1
  252. package/dist/server/isr-cache.d.ts +6 -2
  253. package/dist/server/isr-cache.js +20 -4
  254. package/dist/server/isr-cache.js.map +1 -1
  255. package/dist/server/middleware-runtime.d.ts +15 -0
  256. package/dist/server/middleware-runtime.js +59 -7
  257. package/dist/server/middleware-runtime.js.map +1 -1
  258. package/dist/server/middleware.d.ts +1 -1
  259. package/dist/server/middleware.js +5 -3
  260. package/dist/server/middleware.js.map +1 -1
  261. package/dist/server/navigation-planner.d.ts +9 -3
  262. package/dist/server/navigation-planner.js +98 -25
  263. package/dist/server/navigation-planner.js.map +1 -1
  264. package/dist/server/navigation-trace.d.ts +2 -1
  265. package/dist/server/navigation-trace.js +1 -0
  266. package/dist/server/navigation-trace.js.map +1 -1
  267. package/dist/server/pages-api-route.d.ts +45 -1
  268. package/dist/server/pages-api-route.js +27 -4
  269. package/dist/server/pages-api-route.js.map +1 -1
  270. package/dist/server/pages-body-parser-config.d.ts +60 -0
  271. package/dist/server/pages-body-parser-config.js +79 -0
  272. package/dist/server/pages-body-parser-config.js.map +1 -0
  273. package/dist/server/pages-data-route.d.ts +77 -0
  274. package/dist/server/pages-data-route.js +98 -0
  275. package/dist/server/pages-data-route.js.map +1 -0
  276. package/dist/server/pages-default-404.d.ts +31 -0
  277. package/dist/server/pages-default-404.js +40 -0
  278. package/dist/server/pages-default-404.js.map +1 -0
  279. package/dist/server/pages-i18n.d.ts +51 -1
  280. package/dist/server/pages-i18n.js +61 -1
  281. package/dist/server/pages-i18n.js.map +1 -1
  282. package/dist/server/pages-node-compat.d.ts +10 -0
  283. package/dist/server/pages-node-compat.js +12 -1
  284. package/dist/server/pages-node-compat.js.map +1 -1
  285. package/dist/server/pages-page-data.d.ts +69 -2
  286. package/dist/server/pages-page-data.js +47 -31
  287. package/dist/server/pages-page-data.js.map +1 -1
  288. package/dist/server/pages-page-response.d.ts +13 -1
  289. package/dist/server/pages-page-response.js +16 -11
  290. package/dist/server/pages-page-response.js.map +1 -1
  291. package/dist/server/prerender-route-params.d.ts +14 -0
  292. package/dist/server/prerender-route-params.js +94 -0
  293. package/dist/server/prerender-route-params.js.map +1 -0
  294. package/dist/server/prod-server.d.ts +15 -37
  295. package/dist/server/prod-server.js +143 -107
  296. package/dist/server/prod-server.js.map +1 -1
  297. package/dist/server/proxy-trust.d.ts +41 -0
  298. package/dist/server/proxy-trust.js +70 -0
  299. package/dist/server/proxy-trust.js.map +1 -0
  300. package/dist/server/request-pipeline.d.ts +13 -4
  301. package/dist/server/request-pipeline.js +32 -14
  302. package/dist/server/request-pipeline.js.map +1 -1
  303. package/dist/server/seed-cache.d.ts +12 -31
  304. package/dist/server/seed-cache.js +30 -37
  305. package/dist/server/seed-cache.js.map +1 -1
  306. package/dist/server/server-action-not-found.js +8 -3
  307. package/dist/server/server-action-not-found.js.map +1 -1
  308. package/dist/server/skip-cache-proof.d.ts +41 -0
  309. package/dist/server/skip-cache-proof.js +101 -0
  310. package/dist/server/skip-cache-proof.js.map +1 -0
  311. package/dist/server/static-file-cache.d.ts +1 -1
  312. package/dist/server/static-file-cache.js +8 -7
  313. package/dist/server/static-file-cache.js.map +1 -1
  314. package/dist/server/streaming-metadata.d.ts +5 -0
  315. package/dist/server/streaming-metadata.js +10 -0
  316. package/dist/server/streaming-metadata.js.map +1 -0
  317. package/dist/shims/app-router-scroll-state.d.ts +12 -0
  318. package/dist/shims/app-router-scroll-state.js +38 -0
  319. package/dist/shims/app-router-scroll-state.js.map +1 -0
  320. package/dist/shims/app-router-scroll.d.ts +14 -0
  321. package/dist/shims/app-router-scroll.js +100 -0
  322. package/dist/shims/app-router-scroll.js.map +1 -0
  323. package/dist/shims/before-interactive-context.d.ts +30 -0
  324. package/dist/shims/before-interactive-context.js +10 -0
  325. package/dist/shims/before-interactive-context.js.map +1 -0
  326. package/dist/shims/cache-runtime.d.ts +1 -1
  327. package/dist/shims/cache-runtime.js +14 -1
  328. package/dist/shims/cache-runtime.js.map +1 -1
  329. package/dist/shims/client-locale.d.ts +15 -0
  330. package/dist/shims/client-locale.js +13 -0
  331. package/dist/shims/client-locale.js.map +1 -0
  332. package/dist/shims/default-global-error.d.ts +32 -0
  333. package/dist/shims/default-global-error.js +181 -0
  334. package/dist/shims/default-global-error.js.map +1 -0
  335. package/dist/shims/default-not-found.d.ts +12 -0
  336. package/dist/shims/default-not-found.js +61 -0
  337. package/dist/shims/default-not-found.js.map +1 -0
  338. package/dist/shims/document.d.ts +59 -3
  339. package/dist/shims/document.js +36 -5
  340. package/dist/shims/document.js.map +1 -1
  341. package/dist/shims/error-boundary.d.ts +2 -2
  342. package/dist/shims/font-local.d.ts +5 -0
  343. package/dist/shims/font-local.js +6 -2
  344. package/dist/shims/font-local.js.map +1 -1
  345. package/dist/shims/form.js +13 -6
  346. package/dist/shims/form.js.map +1 -1
  347. package/dist/shims/head.js +4 -4
  348. package/dist/shims/head.js.map +1 -1
  349. package/dist/shims/headers.d.ts +6 -2
  350. package/dist/shims/headers.js +64 -21
  351. package/dist/shims/headers.js.map +1 -1
  352. package/dist/shims/image.d.ts +1 -1
  353. package/dist/shims/image.js +4 -4
  354. package/dist/shims/image.js.map +1 -1
  355. package/dist/shims/internal/pages-data-target.d.ts +58 -0
  356. package/dist/shims/internal/pages-data-target.js +91 -0
  357. package/dist/shims/internal/pages-data-target.js.map +1 -0
  358. package/dist/shims/internal/pages-data-url.d.ts +42 -0
  359. package/dist/shims/internal/pages-data-url.js +73 -0
  360. package/dist/shims/internal/pages-data-url.js.map +1 -0
  361. package/dist/shims/link.d.ts +21 -3
  362. package/dist/shims/link.js +189 -30
  363. package/dist/shims/link.js.map +1 -1
  364. package/dist/shims/metadata.d.ts +2 -1
  365. package/dist/shims/metadata.js +65 -6
  366. package/dist/shims/metadata.js.map +1 -1
  367. package/dist/shims/navigation.d.ts +8 -2
  368. package/dist/shims/navigation.js +67 -23
  369. package/dist/shims/navigation.js.map +1 -1
  370. package/dist/shims/og.d.ts +18 -2
  371. package/dist/shims/og.js +49 -1
  372. package/dist/shims/og.js.map +1 -0
  373. package/dist/shims/request-state-types.d.ts +1 -1
  374. package/dist/shims/root-params.d.ts +3 -1
  375. package/dist/shims/root-params.js +11 -3
  376. package/dist/shims/root-params.js.map +1 -1
  377. package/dist/shims/router-state.d.ts +1 -0
  378. package/dist/shims/router-state.js.map +1 -1
  379. package/dist/shims/router.d.ts +12 -5
  380. package/dist/shims/router.js +535 -86
  381. package/dist/shims/router.js.map +1 -1
  382. package/dist/shims/script.js +86 -12
  383. package/dist/shims/script.js.map +1 -1
  384. package/dist/shims/server.d.ts +21 -4
  385. package/dist/shims/server.js +30 -9
  386. package/dist/shims/server.js.map +1 -1
  387. package/dist/shims/slot.js +5 -1
  388. package/dist/shims/slot.js.map +1 -1
  389. package/dist/shims/unified-request-context.d.ts +1 -1
  390. package/dist/shims/url-safety.d.ts +23 -1
  391. package/dist/shims/url-safety.js +29 -2
  392. package/dist/shims/url-safety.js.map +1 -1
  393. package/dist/shims/url-utils.d.ts +2 -1
  394. package/dist/shims/url-utils.js +15 -4
  395. package/dist/shims/url-utils.js.map +1 -1
  396. package/dist/typegen.d.ts +10 -0
  397. package/dist/typegen.js +242 -0
  398. package/dist/typegen.js.map +1 -0
  399. package/dist/utils/asset-prefix.d.ts +33 -5
  400. package/dist/utils/asset-prefix.js +39 -6
  401. package/dist/utils/asset-prefix.js.map +1 -1
  402. package/dist/utils/cache-control-metadata.d.ts +2 -1
  403. package/dist/utils/cache-control-metadata.js +1 -3
  404. package/dist/utils/cache-control-metadata.js.map +1 -1
  405. package/dist/utils/domain-locale.d.ts +2 -1
  406. package/dist/utils/domain-locale.js +9 -1
  407. package/dist/utils/domain-locale.js.map +1 -1
  408. package/dist/utils/html-limited-bots.d.ts +5 -0
  409. package/dist/utils/html-limited-bots.js +15 -0
  410. package/dist/utils/html-limited-bots.js.map +1 -0
  411. package/dist/utils/lazy-chunks.d.ts +1 -1
  412. package/dist/utils/lazy-chunks.js +1 -1
  413. package/dist/utils/lazy-chunks.js.map +1 -1
  414. package/dist/utils/prerender-output-paths.d.ts +15 -0
  415. package/dist/utils/prerender-output-paths.js +24 -0
  416. package/dist/utils/prerender-output-paths.js.map +1 -0
  417. package/dist/utils/query.d.ts +23 -1
  418. package/dist/utils/query.js +46 -2
  419. package/dist/utils/query.js.map +1 -1
  420. package/dist/utils/record.d.ts +5 -0
  421. package/dist/utils/record.js +8 -0
  422. package/dist/utils/record.js.map +1 -0
  423. package/package.json +11 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-global-error.js","names":[],"sources":["../../src/shims/default-global-error.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\n\n/**\n * Ported from Next.js's built-in default global error component:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/builtin/global-error.tsx\n *\n * Rendered when an unhandled error reaches the root error boundary and the\n * user has not supplied their own `app/global-error.tsx`. Matches the\n * markup, inline styles, and theme CSS that Next.js's\n * `test/e2e/app-dir/default-error-page-ui/default-error-page-ui.test.ts`\n * exercises:\n * - `<h1>` reads \"This page couldn't load\"\n * - `<p>` contains \"Reload to try again, or go back\" (client error) or\n * \"A server error occurred. Reload to try again.\" (server error)\n * - First `<button>` is \"Reload\" (form submit triggers a page reload)\n * - Second `<button>` is \"Back\" (only for client errors)\n * - Server errors render an \"ERROR <digest>\" footer\n * - SVG warning icon is 32x32\n */\n\ntype DefaultGlobalErrorProps = {\n error: { digest?: string } | null | undefined;\n reset?: () => void;\n};\n\nconst errorStyles = {\n container: {\n fontFamily:\n 'system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"',\n height: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n card: {\n marginTop: \"-32px\",\n maxWidth: \"325px\",\n padding: \"32px 28px\",\n textAlign: \"left\" as const,\n },\n icon: {\n marginBottom: \"24px\",\n },\n title: {\n fontSize: \"24px\",\n fontWeight: 500,\n letterSpacing: \"-0.02em\",\n lineHeight: \"32px\",\n margin: \"0 0 12px 0\",\n color: \"var(--next-error-title)\",\n },\n message: {\n fontSize: \"14px\",\n fontWeight: 400,\n lineHeight: \"21px\",\n margin: \"0 0 20px 0\",\n color: \"var(--next-error-message)\",\n },\n form: {\n margin: 0,\n },\n buttonGroup: {\n display: \"flex\",\n gap: \"8px\",\n alignItems: \"center\",\n },\n button: {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"32px\",\n padding: \"0 12px\",\n fontSize: \"14px\",\n fontWeight: 500,\n lineHeight: \"20px\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n color: \"var(--next-error-btn-text)\",\n background: \"var(--next-error-btn-bg)\",\n border: \"var(--next-error-btn-border)\",\n },\n buttonSecondary: {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"32px\",\n padding: \"0 12px\",\n fontSize: \"14px\",\n fontWeight: 500,\n lineHeight: \"20px\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n color: \"var(--next-error-btn-secondary-text)\",\n background: \"var(--next-error-btn-secondary-bg)\",\n border: \"var(--next-error-btn-secondary-border)\",\n },\n digestFooter: {\n position: \"fixed\" as const,\n bottom: \"32px\",\n left: \"0\",\n right: \"0\",\n textAlign: \"center\" as const,\n fontFamily: 'ui-monospace,SFMono-Regular,\"SF Mono\",Menlo,Consolas,monospace',\n fontSize: \"12px\",\n lineHeight: \"18px\",\n fontWeight: 400,\n margin: \"0\",\n color: \"var(--next-error-digest)\",\n },\n} as const;\n\nconst errorThemeCss = `\n:root {\n --next-error-bg: #fff;\n --next-error-text: #171717;\n --next-error-title: #171717;\n --next-error-message: #171717;\n --next-error-digest: #666666;\n --next-error-btn-text: #fff;\n --next-error-btn-bg: #171717;\n --next-error-btn-border: none;\n --next-error-btn-secondary-text: #171717;\n --next-error-btn-secondary-bg: transparent;\n --next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);\n}\n@media (prefers-color-scheme: dark) {\n :root {\n --next-error-bg: #0a0a0a;\n --next-error-text: #ededed;\n --next-error-title: #ededed;\n --next-error-message: #ededed;\n --next-error-digest: #a0a0a0;\n --next-error-btn-text: #0a0a0a;\n --next-error-btn-bg: #ededed;\n --next-error-btn-border: none;\n --next-error-btn-secondary-text: #ededed;\n --next-error-btn-secondary-bg: transparent;\n --next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);\n }\n}\nbody { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\n`.replace(/\\n\\s*/g, \"\");\n\nfunction WarningIcon() {\n return (\n <svg width=\"32\" height=\"32\" viewBox=\"-0.2 -1.5 32 32\" fill=\"none\" style={errorStyles.icon}>\n <path\n d=\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\"\n fill=\"var(--next-error-title)\"\n />\n </svg>\n );\n}\n\nfunction handleBackClick() {\n if (typeof window === \"undefined\") return;\n if (window.history.length > 1) {\n window.history.back();\n } else {\n window.location.href = \"/\";\n }\n}\n\nfunction DefaultGlobalError({ error }: DefaultGlobalErrorProps) {\n const digest: string | undefined = error?.digest;\n const isServerError = !!digest;\n\n const message = isServerError\n ? \"A server error occurred. Reload to try again.\"\n : \"Reload to try again, or go back.\";\n\n return (\n <html id=\"__next_error__\">\n <head>\n <style dangerouslySetInnerHTML={{ __html: errorThemeCss }} />\n </head>\n <body>\n <div style={errorStyles.container}>\n <div style={errorStyles.card}>\n <WarningIcon />\n <h1 style={errorStyles.title}>This page couldn&#x2019;t load</h1>\n <p style={errorStyles.message}>{message}</p>\n <div style={errorStyles.buttonGroup}>\n <form style={errorStyles.form}>\n <button type=\"submit\" style={errorStyles.button}>\n Reload\n </button>\n </form>\n {!isServerError && (\n <button type=\"button\" style={errorStyles.buttonSecondary} onClick={handleBackClick}>\n Back\n </button>\n )}\n </div>\n </div>\n </div>\n {digest && <p style={errorStyles.digestFooter}>ERROR {digest}</p>}\n </body>\n </html>\n );\n}\n\nexport default DefaultGlobalError;\n"],"mappings":";;;;AA2BA,MAAM,cAAc;CAClB,WAAW;EACT,YACE;EACF,QAAQ;EACR,SAAS;EACT,YAAY;EACZ,gBAAgB;EACjB;CACD,MAAM;EACJ,WAAW;EACX,UAAU;EACV,SAAS;EACT,WAAW;EACZ;CACD,MAAM,EACJ,cAAc,QACf;CACD,OAAO;EACL,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,QAAQ;EACR,OAAO;EACR;CACD,SAAS;EACP,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,QAAQ;EACR,OAAO;EACR;CACD,MAAM,EACJ,QAAQ,GACT;CACD,aAAa;EACX,SAAS;EACT,KAAK;EACL,YAAY;EACb;CACD,QAAQ;EACN,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACR,SAAS;EACT,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,cAAc;EACd,QAAQ;EACR,OAAO;EACP,YAAY;EACZ,QAAQ;EACT;CACD,iBAAiB;EACf,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACR,SAAS;EACT,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,cAAc;EACd,QAAQ;EACR,OAAO;EACP,YAAY;EACZ,QAAQ;EACT;CACD,cAAc;EACZ,UAAU;EACV,QAAQ;EACR,MAAM;EACN,OAAO;EACP,WAAW;EACX,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,QAAQ;EACR,OAAO;EACR;CACF;AAED,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BpB,QAAQ,UAAU,GAAG;AAEvB,SAAS,cAAc;CACrB,OACE,oBAAC,OAAD;EAAK,OAAM;EAAK,QAAO;EAAK,SAAQ;EAAkB,MAAK;EAAO,OAAO,YAAY;YACnF,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;GACL,CAAA;EACE,CAAA;;AAIV,SAAS,kBAAkB;CACzB,IAAI,OAAO,WAAW,aAAa;CACnC,IAAI,OAAO,QAAQ,SAAS,GAC1B,OAAO,QAAQ,MAAM;MAErB,OAAO,SAAS,OAAO;;AAI3B,SAAS,mBAAmB,EAAE,SAAkC;CAC9D,MAAM,SAA6B,OAAO;CAC1C,MAAM,gBAAgB,CAAC,CAAC;CAExB,MAAM,UAAU,gBACZ,kDACA;CAEJ,OACE,qBAAC,QAAD;EAAM,IAAG;YAAT,CACE,oBAAC,QAAD,EAAA,UACE,oBAAC,SAAD,EAAO,yBAAyB,EAAE,QAAQ,eAAe,EAAI,CAAA,EACxD,CAAA,EACP,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,OAAD;GAAK,OAAO,YAAY;aACtB,qBAAC,OAAD;IAAK,OAAO,YAAY;cAAxB;KACE,oBAAC,aAAD,EAAe,CAAA;KACf,oBAAC,MAAD;MAAI,OAAO,YAAY;gBAAO;MAAmC,CAAA;KACjE,oBAAC,KAAD;MAAG,OAAO,YAAY;gBAAU;MAAY,CAAA;KAC5C,qBAAC,OAAD;MAAK,OAAO,YAAY;gBAAxB,CACE,oBAAC,QAAD;OAAM,OAAO,YAAY;iBACvB,oBAAC,UAAD;QAAQ,MAAK;QAAS,OAAO,YAAY;kBAAQ;QAExC,CAAA;OACJ,CAAA,EACN,CAAC,iBACA,oBAAC,UAAD;OAAQ,MAAK;OAAS,OAAO,YAAY;OAAiB,SAAS;iBAAiB;OAE3E,CAAA,CAEP;;KACF;;GACF,CAAA,EACL,UAAU,qBAAC,KAAD;GAAG,OAAO,YAAY;aAAtB,CAAoC,UAAO,OAAW;KAC5D,EAAA,CAAA,CACF"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+
3
+ //#region src/shims/default-not-found.d.ts
4
+ /**
5
+ * Mirrors `<HTTPAccessErrorFallback status={404} message="This page could not be found." />`
6
+ * from Next.js. Kept in sync with the upstream component's structure so HTML
7
+ * snapshot diffs between Next.js and vinext stay minimal.
8
+ */
9
+ declare function DefaultNotFound(): React.ReactElement;
10
+ //#endregion
11
+ export { DefaultNotFound as default };
12
+ //# sourceMappingURL=default-not-found.d.ts.map
@@ -0,0 +1,61 @@
1
+ import React from "react";
2
+ //#region src/shims/default-not-found.tsx
3
+ /**
4
+ * Ported from Next.js's built-in default not-found component:
5
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/builtin/not-found.tsx
6
+ * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/http-access-fallback/error-fallback.tsx
7
+ *
8
+ * Rendered when an App Router request resolves to a 404 and the user has not
9
+ * supplied their own `app/not-found.tsx` (or `app/global-not-found.tsx`).
10
+ * Matches Next.js's `HTTPAccessErrorFallback` exactly: a centered 404 / message
11
+ * pair with minified theme CSS and dark-mode media query.
12
+ *
13
+ * The message string `"This page could not be found."` (note the trailing
14
+ * period) is the canonical body asserted by Next.js's deploy suite
15
+ * (`test/e2e/app-dir/prefetching-not-found/prefetching-not-found.test.ts`,
16
+ * `test/e2e/basepath/error-pages.test.ts`).
17
+ */
18
+ const styles = {
19
+ error: {
20
+ fontFamily: "system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"",
21
+ height: "100vh",
22
+ textAlign: "center",
23
+ display: "flex",
24
+ flexDirection: "column",
25
+ alignItems: "center",
26
+ justifyContent: "center"
27
+ },
28
+ desc: { display: "inline-block" },
29
+ h1: {
30
+ display: "inline-block",
31
+ margin: "0 20px 0 0",
32
+ padding: "0 23px 0 0",
33
+ fontSize: 24,
34
+ fontWeight: 500,
35
+ verticalAlign: "top",
36
+ lineHeight: "49px"
37
+ },
38
+ h2: {
39
+ fontSize: 14,
40
+ fontWeight: 400,
41
+ lineHeight: "49px",
42
+ margin: 0
43
+ }
44
+ };
45
+ const STATUS = 404;
46
+ const MESSAGE = "This page could not be found.";
47
+ /**
48
+ * Mirrors `<HTTPAccessErrorFallback status={404} message="This page could not be found." />`
49
+ * from Next.js. Kept in sync with the upstream component's structure so HTML
50
+ * snapshot diffs between Next.js and vinext stay minimal.
51
+ */
52
+ function DefaultNotFound() {
53
+ return React.createElement(React.Fragment, null, React.createElement("title", null, `${STATUS}: ${MESSAGE}`), React.createElement("div", { style: styles.error }, React.createElement("div", null, React.createElement("style", { dangerouslySetInnerHTML: { __html: "body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}" } }), React.createElement("h1", {
54
+ className: "next-error-h1",
55
+ style: styles.h1
56
+ }, STATUS), React.createElement("div", { style: styles.desc }, React.createElement("h2", { style: styles.h2 }, MESSAGE)))));
57
+ }
58
+ //#endregion
59
+ export { DefaultNotFound as default };
60
+
61
+ //# sourceMappingURL=default-not-found.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-not-found.js","names":[],"sources":["../../src/shims/default-not-found.tsx"],"sourcesContent":["/**\n * Ported from Next.js's built-in default not-found component:\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/builtin/not-found.tsx\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/http-access-fallback/error-fallback.tsx\n *\n * Rendered when an App Router request resolves to a 404 and the user has not\n * supplied their own `app/not-found.tsx` (or `app/global-not-found.tsx`).\n * Matches Next.js's `HTTPAccessErrorFallback` exactly: a centered 404 / message\n * pair with minified theme CSS and dark-mode media query.\n *\n * The message string `\"This page could not be found.\"` (note the trailing\n * period) is the canonical body asserted by Next.js's deploy suite\n * (`test/e2e/app-dir/prefetching-not-found/prefetching-not-found.test.ts`,\n * `test/e2e/basepath/error-pages.test.ts`).\n */\nimport React from \"react\";\n\nconst styles = {\n error: {\n fontFamily:\n 'system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"',\n height: \"100vh\",\n textAlign: \"center\" as const,\n display: \"flex\",\n flexDirection: \"column\" as const,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n desc: {\n display: \"inline-block\",\n },\n h1: {\n display: \"inline-block\",\n margin: \"0 20px 0 0\",\n padding: \"0 23px 0 0\",\n fontSize: 24,\n fontWeight: 500,\n verticalAlign: \"top\",\n lineHeight: \"49px\",\n },\n h2: {\n fontSize: 14,\n fontWeight: 400,\n lineHeight: \"49px\",\n margin: 0,\n },\n} satisfies Record<string, React.CSSProperties>;\n\nconst STATUS = 404;\nconst MESSAGE = \"This page could not be found.\";\n\n/**\n * Mirrors `<HTTPAccessErrorFallback status={404} message=\"This page could not be found.\" />`\n * from Next.js. Kept in sync with the upstream component's structure so HTML\n * snapshot diffs between Next.js and vinext stay minimal.\n */\nexport default function DefaultNotFound(): React.ReactElement {\n return React.createElement(\n React.Fragment,\n null,\n React.createElement(\"title\", null, `${STATUS}: ${MESSAGE}`),\n React.createElement(\n \"div\",\n { style: styles.error },\n React.createElement(\n \"div\",\n null,\n React.createElement(\"style\", {\n dangerouslySetInnerHTML: {\n __html:\n \"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\",\n },\n }),\n React.createElement(\n \"h1\",\n {\n className: \"next-error-h1\",\n style: styles.h1,\n },\n STATUS,\n ),\n React.createElement(\n \"div\",\n { style: styles.desc },\n React.createElement(\"h2\", { style: styles.h2 }, MESSAGE),\n ),\n ),\n ),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAM,SAAS;CACb,OAAO;EACL,YACE;EACF,QAAQ;EACR,WAAW;EACX,SAAS;EACT,eAAe;EACf,YAAY;EACZ,gBAAgB;EACjB;CACD,MAAM,EACJ,SAAS,gBACV;CACD,IAAI;EACF,SAAS;EACT,QAAQ;EACR,SAAS;EACT,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACb;CACD,IAAI;EACF,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,QAAQ;EACT;CACF;AAED,MAAM,SAAS;AACf,MAAM,UAAU;;;;;;AAOhB,SAAwB,kBAAsC;CAC5D,OAAO,MAAM,cACX,MAAM,UACN,MACA,MAAM,cAAc,SAAS,MAAM,GAAG,OAAO,IAAI,UAAU,EAC3D,MAAM,cACJ,OACA,EAAE,OAAO,OAAO,OAAO,EACvB,MAAM,cACJ,OACA,MACA,MAAM,cAAc,SAAS,EAC3B,yBAAyB,EACvB,QACE,iOACH,EACF,CAAC,EACF,MAAM,cACJ,MACA;EACE,WAAW;EACX,OAAO,OAAO;EACf,EACD,OACD,EACD,MAAM,cACJ,OACA,EAAE,OAAO,OAAO,MAAM,EACtB,MAAM,cAAc,MAAM,EAAE,OAAO,OAAO,IAAI,EAAE,QAAQ,CACzD,CACF,CACF,CACF"}
@@ -29,9 +29,65 @@ declare function Main(): _$react_jsx_runtime0.JSX.Element;
29
29
  */
30
30
  declare function NextScript(): _$react_jsx_runtime0.JSX.Element;
31
31
  /**
32
- * Default Document component - used when no custom _document.tsx exists.
32
+ * Loose stand-ins for Next.js's `DocumentContext` / `DocumentInitialProps`.
33
+ * The shim doesn't currently invoke `getInitialProps` on user `_document.tsx`
34
+ * files (separate gap), but the signatures here match Next.js's so subclasses
35
+ * that delegate via `await Document.getInitialProps(ctx)` typecheck against
36
+ * the same shape they'd see under real Next.js.
37
+ *
38
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/utils.ts
33
39
  */
34
- declare function Document(): _$react_jsx_runtime0.JSX.Element;
40
+ type DocumentContext = {
41
+ renderPage?: (options?: {
42
+ enhanceApp?: (App: React.ComponentType<{
43
+ children?: React.ReactNode;
44
+ }>) => unknown;
45
+ enhanceComponent?: (Comp: React.ComponentType<unknown>) => unknown;
46
+ }) => {
47
+ html: string;
48
+ head?: ReadonlyArray<React.ReactElement>;
49
+ };
50
+ defaultGetInitialProps?: (ctx: DocumentContext, options?: {
51
+ nonce?: string;
52
+ }) => Promise<DocumentInitialProps>;
53
+ pathname?: string;
54
+ query?: Record<string, string | string[] | undefined>;
55
+ asPath?: string;
56
+ err?: any;
57
+ };
58
+ type DocumentInitialProps = {
59
+ html: string;
60
+ head?: ReadonlyArray<React.ReactElement>;
61
+ styles?: React.ReactElement[] | Iterable<React.ReactNode> | React.ReactElement;
62
+ };
63
+ /**
64
+ * Default Document component — also the base class user `_document.tsx` files
65
+ * `extend`. Must be a class (not a function) to match Next.js's `next/document`
66
+ * default export so `class MyDocument extends Document` produces a constructible
67
+ * class that React can instantiate during SSR. Returning a function here breaks
68
+ * any user `_document.tsx` that uses the class-based form because `extends`
69
+ * against a non-constructor produces a class that can only be called without
70
+ * `new`, which React refuses to do.
71
+ *
72
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/pages/_document.tsx
73
+ * Ported behavior: Next.js's default `Document` is a `class Document extends
74
+ * React.Component`. Custom documents extend it and override `getInitialProps`
75
+ * and `render`. Generic default matches Next.js (`P = {}`).
76
+ */
77
+ declare class Document<P = {}> extends React.Component<P & {
78
+ children?: React.ReactNode;
79
+ }> {
80
+ /**
81
+ * `getInitialProps` is invoked by the SSR pipeline. The default implementation
82
+ * is a stub: vinext does not yet plumb the Pages Router `renderPage` /
83
+ * `defaultGetInitialProps` chain into the SSR entry, so subclasses that
84
+ * delegate via `await Document.getInitialProps(ctx)` receive an empty shell
85
+ * (`html: ""`). This matches the runtime contract user code expects without
86
+ * pretending the chain is wired up.
87
+ */
88
+ static getInitialProps(_ctx: DocumentContext): Promise<DocumentInitialProps>;
89
+ render(): React.ReactNode;
90
+ }
35
91
  //#endregion
36
- export { Head, Html, Main, NextScript, Document as default };
92
+ export { DocumentContext, DocumentInitialProps, Head, Html, Main, NextScript, Document as default };
37
93
  //# sourceMappingURL=document.d.ts.map
@@ -1,6 +1,13 @@
1
- import "react";
1
+ import React from "react";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/shims/document.tsx
4
+ /**
5
+ * next/document shim
6
+ *
7
+ * Provides Html, Head, Main, NextScript components for custom _document.tsx.
8
+ * During SSR these render placeholder markers that the dev server replaces
9
+ * with actual content.
10
+ */
4
11
  function Html({ children, lang, ...props }) {
5
12
  return /* @__PURE__ */ jsx("html", {
6
13
  lang,
@@ -40,11 +47,35 @@ function NextScript() {
40
47
  return /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: "<!-- __NEXT_SCRIPTS__ -->" } });
41
48
  }
42
49
  /**
43
- * Default Document component - used when no custom _document.tsx exists.
50
+ * Default Document component also the base class user `_document.tsx` files
51
+ * `extend`. Must be a class (not a function) to match Next.js's `next/document`
52
+ * default export so `class MyDocument extends Document` produces a constructible
53
+ * class that React can instantiate during SSR. Returning a function here breaks
54
+ * any user `_document.tsx` that uses the class-based form because `extends`
55
+ * against a non-constructor produces a class that can only be called without
56
+ * `new`, which React refuses to do.
57
+ *
58
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/pages/_document.tsx
59
+ * Ported behavior: Next.js's default `Document` is a `class Document extends
60
+ * React.Component`. Custom documents extend it and override `getInitialProps`
61
+ * and `render`. Generic default matches Next.js (`P = {}`).
44
62
  */
45
- function Document() {
46
- return /* @__PURE__ */ jsxs(Html, { children: [/* @__PURE__ */ jsx(Head, {}), /* @__PURE__ */ jsxs("body", { children: [/* @__PURE__ */ jsx(Main, {}), /* @__PURE__ */ jsx(NextScript, {})] })] });
47
- }
63
+ var Document = class extends React.Component {
64
+ /**
65
+ * `getInitialProps` is invoked by the SSR pipeline. The default implementation
66
+ * is a stub: vinext does not yet plumb the Pages Router `renderPage` /
67
+ * `defaultGetInitialProps` chain into the SSR entry, so subclasses that
68
+ * delegate via `await Document.getInitialProps(ctx)` receive an empty shell
69
+ * (`html: ""`). This matches the runtime contract user code expects without
70
+ * pretending the chain is wired up.
71
+ */
72
+ static async getInitialProps(_ctx) {
73
+ return { html: "" };
74
+ }
75
+ render() {
76
+ return /* @__PURE__ */ jsxs(Html, { children: [/* @__PURE__ */ jsx(Head, {}), /* @__PURE__ */ jsxs("body", { children: [/* @__PURE__ */ jsx(Main, {}), /* @__PURE__ */ jsx(NextScript, {})] })] });
77
+ }
78
+ };
48
79
  //#endregion
49
80
  export { Head, Html, Main, NextScript, Document as default };
50
81
 
@@ -1 +1 @@
1
- {"version":3,"file":"document.js","names":[],"sources":["../../src/shims/document.tsx"],"sourcesContent":["/**\n * next/document shim\n *\n * Provides Html, Head, Main, NextScript components for custom _document.tsx.\n * During SSR these render placeholder markers that the dev server replaces\n * with actual content.\n */\nimport React from \"react\";\n\nexport function Html({\n children,\n lang,\n ...props\n}: React.HTMLAttributes<HTMLHtmlElement> & { children?: React.ReactNode }) {\n return (\n <html lang={lang} {...props}>\n {children}\n </html>\n );\n}\n\n/**\n * Document Head - renders <head> with children.\n * The dev server injects meta tags, styles, etc.\n */\nexport function Head({ children }: { children?: React.ReactNode }) {\n return (\n <head>\n <meta charSet=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n {children}\n </head>\n );\n}\n\n/**\n * Main - renders the page content container.\n */\nexport function Main() {\n return <div id=\"__next\" dangerouslySetInnerHTML={{ __html: \"__NEXT_MAIN__\" }} />;\n}\n\n/**\n * NextScript - renders a placeholder that the dev-server replaces with\n * actual hydration scripts (__NEXT_DATA__ + entry module).\n * Uses dangerouslySetInnerHTML so the HTML comment survives renderToString.\n */\nexport function NextScript() {\n return <span dangerouslySetInnerHTML={{ __html: \"<!-- __NEXT_SCRIPTS__ -->\" }} />;\n}\n\n/**\n * Default Document component - used when no custom _document.tsx exists.\n */\nexport default function Document() {\n return (\n <Html>\n <Head />\n <body>\n <Main />\n <NextScript />\n </body>\n </Html>\n );\n}\n"],"mappings":";;;AASA,SAAgB,KAAK,EACnB,UACA,MACA,GAAG,SACsE;CACzE,OACE,oBAAC,QAAD;EAAY;EAAM,GAAI;EACnB;EACI,CAAA;;;;;;AAQX,SAAgB,KAAK,EAAE,YAA4C;CACjE,OACE,qBAAC,QAAD,EAAA,UAAA;EACE,oBAAC,QAAD,EAAM,SAAQ,SAAU,CAAA;EACxB,oBAAC,QAAD;GAAM,MAAK;GAAW,SAAQ;GAAwC,CAAA;EACrE;EACI,EAAA,CAAA;;;;;AAOX,SAAgB,OAAO;CACrB,OAAO,oBAAC,OAAD;EAAK,IAAG;EAAS,yBAAyB,EAAE,QAAQ,iBAAiB;EAAI,CAAA;;;;;;;AAQlF,SAAgB,aAAa;CAC3B,OAAO,oBAAC,QAAD,EAAM,yBAAyB,EAAE,QAAQ,6BAA6B,EAAI,CAAA;;;;;AAMnF,SAAwB,WAAW;CACjC,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,MAAD,EAAQ,CAAA,EACR,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,MAAD,EAAQ,CAAA,EACR,oBAAC,YAAD,EAAc,CAAA,CACT,EAAA,CAAA,CACF,EAAA,CAAA"}
1
+ {"version":3,"file":"document.js","names":[],"sources":["../../src/shims/document.tsx"],"sourcesContent":["/**\n * next/document shim\n *\n * Provides Html, Head, Main, NextScript components for custom _document.tsx.\n * During SSR these render placeholder markers that the dev server replaces\n * with actual content.\n */\nimport React from \"react\";\n\nexport function Html({\n children,\n lang,\n ...props\n}: React.HTMLAttributes<HTMLHtmlElement> & { children?: React.ReactNode }) {\n return (\n <html lang={lang} {...props}>\n {children}\n </html>\n );\n}\n\n/**\n * Document Head - renders <head> with children.\n * The dev server injects meta tags, styles, etc.\n */\nexport function Head({ children }: { children?: React.ReactNode }) {\n return (\n <head>\n <meta charSet=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n {children}\n </head>\n );\n}\n\n/**\n * Main - renders the page content container.\n */\nexport function Main() {\n return <div id=\"__next\" dangerouslySetInnerHTML={{ __html: \"__NEXT_MAIN__\" }} />;\n}\n\n/**\n * NextScript - renders a placeholder that the dev-server replaces with\n * actual hydration scripts (__NEXT_DATA__ + entry module).\n * Uses dangerouslySetInnerHTML so the HTML comment survives renderToString.\n */\nexport function NextScript() {\n return <span dangerouslySetInnerHTML={{ __html: \"<!-- __NEXT_SCRIPTS__ -->\" }} />;\n}\n\n/**\n * Loose stand-ins for Next.js's `DocumentContext` / `DocumentInitialProps`.\n * The shim doesn't currently invoke `getInitialProps` on user `_document.tsx`\n * files (separate gap), but the signatures here match Next.js's so subclasses\n * that delegate via `await Document.getInitialProps(ctx)` typecheck against\n * the same shape they'd see under real Next.js.\n *\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/utils.ts\n */\nexport type DocumentContext = {\n // The full `DocumentContext` includes `renderPage`, `defaultGetInitialProps`,\n // and the inherited `NextPageContext` (`pathname`, `query`, `req`, `res`,\n // `err`, `asPath`, ...). They're declared as optional here because vinext\n // does not yet plumb them through; widening to optional avoids forcing user\n // code to assert their presence.\n renderPage?: (options?: {\n enhanceApp?: (App: React.ComponentType<{ children?: React.ReactNode }>) => unknown;\n enhanceComponent?: (Comp: React.ComponentType<unknown>) => unknown;\n }) => { html: string; head?: ReadonlyArray<React.ReactElement> };\n defaultGetInitialProps?: (\n ctx: DocumentContext,\n options?: { nonce?: string },\n ) => Promise<DocumentInitialProps>;\n pathname?: string;\n query?: Record<string, string | string[] | undefined>;\n asPath?: string;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n err?: any;\n};\n\nexport type DocumentInitialProps = {\n html: string;\n head?: ReadonlyArray<React.ReactElement>;\n styles?: React.ReactElement[] | Iterable<React.ReactNode> | React.ReactElement;\n};\n\n/**\n * Default Document component — also the base class user `_document.tsx` files\n * `extend`. Must be a class (not a function) to match Next.js's `next/document`\n * default export so `class MyDocument extends Document` produces a constructible\n * class that React can instantiate during SSR. Returning a function here breaks\n * any user `_document.tsx` that uses the class-based form because `extends`\n * against a non-constructor produces a class that can only be called without\n * `new`, which React refuses to do.\n *\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/pages/_document.tsx\n * Ported behavior: Next.js's default `Document` is a `class Document extends\n * React.Component`. Custom documents extend it and override `getInitialProps`\n * and `render`. Generic default matches Next.js (`P = {}`).\n */\n// oxlint-disable-next-line @typescript-eslint/no-empty-object-type\nexport default class Document<P = {}> extends React.Component<P & { children?: React.ReactNode }> {\n /**\n * `getInitialProps` is invoked by the SSR pipeline. The default implementation\n * is a stub: vinext does not yet plumb the Pages Router `renderPage` /\n * `defaultGetInitialProps` chain into the SSR entry, so subclasses that\n * delegate via `await Document.getInitialProps(ctx)` receive an empty shell\n * (`html: \"\"`). This matches the runtime contract user code expects without\n * pretending the chain is wired up.\n */\n static async getInitialProps(_ctx: DocumentContext): Promise<DocumentInitialProps> {\n return { html: \"\" };\n }\n\n render(): React.ReactNode {\n return (\n <Html>\n <Head />\n <body>\n <Main />\n <NextScript />\n </body>\n </Html>\n );\n }\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,KAAK,EACnB,UACA,MACA,GAAG,SACsE;CACzE,OACE,oBAAC,QAAD;EAAY;EAAM,GAAI;EACnB;EACI,CAAA;;;;;;AAQX,SAAgB,KAAK,EAAE,YAA4C;CACjE,OACE,qBAAC,QAAD,EAAA,UAAA;EACE,oBAAC,QAAD,EAAM,SAAQ,SAAU,CAAA;EACxB,oBAAC,QAAD;GAAM,MAAK;GAAW,SAAQ;GAAwC,CAAA;EACrE;EACI,EAAA,CAAA;;;;;AAOX,SAAgB,OAAO;CACrB,OAAO,oBAAC,OAAD;EAAK,IAAG;EAAS,yBAAyB,EAAE,QAAQ,iBAAiB;EAAI,CAAA;;;;;;;AAQlF,SAAgB,aAAa;CAC3B,OAAO,oBAAC,QAAD,EAAM,yBAAyB,EAAE,QAAQ,6BAA6B,EAAI,CAAA;;;;;;;;;;;;;;;;AAsDnF,IAAqB,WAArB,cAA8C,MAAM,UAA8C;;;;;;;;;CAShG,aAAa,gBAAgB,MAAsD;EACjF,OAAO,EAAE,MAAM,IAAI;;CAGrB,SAA0B;EACxB,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,MAAD,EAAQ,CAAA,EACR,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,MAAD,EAAQ,CAAA,EACR,oBAAC,YAAD,EAAc,CAAA,CACT,EAAA,CAAA,CACF,EAAA,CAAA"}
@@ -32,7 +32,7 @@ declare class RedirectErrorBoundary extends React.Component<{
32
32
  children?: React.ReactNode;
33
33
  });
34
34
  static getDerivedStateFromError(error: unknown): RedirectBoundaryState;
35
- render(): string | number | bigint | boolean | _$react_jsx_runtime0.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
35
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | _$react_jsx_runtime0.JSX.Element | null | undefined;
36
36
  }
37
37
  declare function RedirectBoundary({
38
38
  children
@@ -49,7 +49,7 @@ declare class ErrorBoundaryInner extends React.Component<ErrorBoundaryInnerProps
49
49
  static getDerivedStateFromProps(props: ErrorBoundaryInnerProps, state: ErrorBoundaryState): ErrorBoundaryState | null;
50
50
  static getDerivedStateFromError(error: unknown): Partial<ErrorBoundaryState>;
51
51
  reset: () => void;
52
- render(): string | number | bigint | boolean | _$react_jsx_runtime0.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
52
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | _$react_jsx_runtime0.JSX.Element | null | undefined;
53
53
  }
54
54
  declare function ErrorBoundary({
55
55
  fallback,
@@ -19,6 +19,11 @@ type LocalFontOptions = {
19
19
  prop: string;
20
20
  value: string;
21
21
  }>;
22
+ _vinext?: {
23
+ font?: {
24
+ family?: unknown;
25
+ };
26
+ };
22
27
  };
23
28
  type FontResult = {
24
29
  className: string;
@@ -27,6 +27,10 @@ import { escapeCSSString, formatFontClassRule, resolveSingleFaceStyle, sanitizeC
27
27
  function sanitizeCSSProperty(prop) {
28
28
  if (/^(--)?[a-zA-Z][a-zA-Z0-9-]*$/.test(prop)) return prop;
29
29
  }
30
+ function sanitizeInternalFontFamily(name) {
31
+ if (typeof name !== "string" || name.length === 0) return void 0;
32
+ if (/^[$_a-zA-Z][$_a-zA-Z0-9]*$/.test(name)) return name;
33
+ }
30
34
  let classCounter = 0;
31
35
  const injectedFonts = /* @__PURE__ */ new Set();
32
36
  function generateFontFaceCSS(family, options, sources) {
@@ -179,7 +183,7 @@ function localFont(options) {
179
183
  const id = classCounter++;
180
184
  const sources = normalizeSources(options);
181
185
  const singleSource = sources.length === 1 ? sources[0] : void 0;
182
- const family = `__local_font_${id}`;
186
+ const family = sanitizeInternalFontFamily(options._vinext?.font?.family) ?? `__local_font_${id}`;
183
187
  const className = `__font_local_${id}`;
184
188
  const fontFamily = `'${family}', ${(options.fallback ?? ["sans-serif"]).map(sanitizeFallback).join(", ")}`;
185
189
  const cssVarName = options.variable ? sanitizeCSSVarName(options.variable) : void 0;
@@ -190,7 +194,7 @@ function localFont(options) {
190
194
  style: singleSource.style ?? options.style
191
195
  }) : { fontFamily };
192
196
  collectFontPreloads(sources);
193
- injectFontFaceCSS(generateFontFaceCSS(family, options, sources), family);
197
+ injectFontFaceCSS(generateFontFaceCSS(family, options, sources), className);
194
198
  injectClassNameRule(className, style);
195
199
  if (cssVarName) injectVariableClassRule(variableClassName, cssVarName, fontFamily);
196
200
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"font-local.js","names":[],"sources":["../../src/shims/font-local.ts"],"sourcesContent":["/**\n * next/font/local shim\n *\n * Provides a runtime-compatible shim for Next.js local fonts.\n * Generates @font-face CSS declarations and returns an object\n * with className, style, and variable properties.\n *\n * Supports both client-side injection and SSR collection,\n * matching the patterns used by the Google font shim.\n *\n * Usage:\n * import localFont from 'next/font/local';\n * const myFont = localFont({ src: './my-font.woff2' });\n * // myFont.className -> unique CSS class\n * // myFont.style -> { fontFamily: \"'__local_font_0', sans-serif\" }\n * // myFont.variable -> generated class name when requested\n */\nimport {\n escapeCSSString,\n formatFontClassRule,\n resolveSingleFaceStyle,\n sanitizeCSSVarName,\n sanitizeFallback,\n sanitizeFontDescriptorValue,\n type FontStyle,\n} from \"./font-utils.js\";\n\n/**\n * Validate a CSS property name for use in declarations.\n *\n * Only allows standard CSS property names (lowercase letters and hyphens)\n * and custom properties (--prefixed). Rejects anything that could inject\n * CSS rules via crafted property names.\n */\nfunction sanitizeCSSProperty(prop: string): string | undefined {\n if (/^(--)?[a-zA-Z][a-zA-Z0-9-]*$/.test(prop)) return prop;\n return undefined;\n}\n\nlet classCounter = 0;\nconst injectedFonts = new Set<string>();\n\ntype LocalFontSrc = {\n path: string;\n weight?: string;\n style?: string;\n};\n\ntype LocalFontOptions = {\n src: string | LocalFontSrc | LocalFontSrc[];\n display?: string;\n weight?: string;\n style?: string;\n fallback?: string[];\n preload?: boolean;\n variable?: string;\n adjustFontFallback?: boolean | string;\n declarations?: Array<{ prop: string; value: string }>;\n};\n\ntype FontResult = {\n className: string;\n style: FontStyle;\n variable?: string;\n};\n\nfunction generateFontFaceCSS(\n family: string,\n options: LocalFontOptions,\n sources: LocalFontSrc[],\n): string {\n const display = options.display ?? \"swap\";\n const rules: string[] = [];\n\n for (const src of sources) {\n const weight = sanitizeFontDescriptorValue(src.weight ?? options.weight ?? \"400\") ?? \"400\";\n const style = sanitizeFontDescriptorValue(src.style ?? options.style ?? \"normal\") ?? \"normal\";\n const format = src.path.endsWith(\".woff2\")\n ? \"woff2\"\n : src.path.endsWith(\".woff\")\n ? \"woff\"\n : src.path.endsWith(\".ttf\")\n ? \"truetype\"\n : src.path.endsWith(\".otf\")\n ? \"opentype\"\n : \"woff2\";\n\n rules.push(`@font-face {\n font-family: '${escapeCSSString(family)}';\n src: url('${escapeCSSString(src.path)}') format('${format}');\n font-weight: ${weight};\n font-style: ${style};\n font-display: ${display};\n}`);\n }\n\n // Add extra declarations if provided — sanitize prop/value to prevent injection\n if (options.declarations) {\n for (const decl of options.declarations) {\n const safeProp = sanitizeCSSProperty(decl.prop);\n const safeValue = sanitizeFontDescriptorValue(decl.value);\n if (safeProp && safeValue) {\n rules.push(\n `@font-face { font-family: '${escapeCSSString(family)}'; ${safeProp}: ${safeValue}; }`,\n );\n }\n }\n }\n\n return rules.join(\"\\n\");\n}\n\n// SSR: collect font styles for injection in <head>\nconst ssrFontStyles: string[] = [];\n\n// SSR: collect font file URLs for <link rel=\"preload\"> injection\nconst ssrFontPreloads: Array<{ href: string; type: string }> = [];\nconst ssrFontPreloadHrefs = new Set<string>();\n\n/**\n * Get collected SSR font styles (used by the renderer).\n * Note: We don't clear the arrays because fonts are loaded at module import\n * time and need to persist across all requests in the Workers environment.\n */\nexport function getSSRFontStyles(): string[] {\n return [...ssrFontStyles];\n}\n\n/**\n * Get collected SSR font preload data (used by the renderer).\n * Returns an array of { href, type } objects for emitting\n * <link rel=\"preload\" as=\"font\" ...> tags.\n */\nexport function getSSRFontPreloads(): Array<{ href: string; type: string }> {\n return [...ssrFontPreloads];\n}\n\nfunction injectFontFaceCSS(css: string, id: string): void {\n if (injectedFonts.has(id)) return;\n injectedFonts.add(id);\n\n // On server, store the CSS for SSR injection\n if (typeof document === \"undefined\") {\n ssrFontStyles.push(css);\n return;\n }\n\n const style = document.createElement(\"style\");\n style.textContent = css;\n style.setAttribute(\"data-vinext-font\", id);\n document.head.appendChild(style);\n}\n\n/** Track which className CSS rules have been injected. */\nconst injectedClassRules = new Set<string>();\n\n/**\n * Inject a CSS rule that maps a className to the exported font style.\n *\n * This is what makes `<div className={font.className}>` apply the font.\n *\n * In Next.js, the .className class sets font-family and any single\n * font-weight/font-style. CSS variables are handled separately by .variable.\n */\nfunction injectClassNameRule(className: string, fontStyle: FontStyle): void {\n if (injectedClassRules.has(className)) return;\n injectedClassRules.add(className);\n\n const css = formatFontClassRule(className, fontStyle);\n\n // On server, store the CSS for SSR injection\n if (typeof document === \"undefined\") {\n ssrFontStyles.push(css);\n return;\n }\n\n // On client, inject a <style> tag\n const style = document.createElement(\"style\");\n style.textContent = css;\n style.setAttribute(\"data-vinext-font-class\", className);\n document.head.appendChild(style);\n}\n\n/** Track which variable class CSS rules have been injected. */\nconst injectedVariableRules = new Set<string>();\n\n/** Track which :root CSS variable rules have been injected. */\nconst injectedRootVariables = new Set<string>();\n\n/**\n * Inject a CSS rule that sets a CSS variable on an element.\n * This is what makes `<html className={font.variable}>` set the CSS variable\n * that can be referenced by other styles (e.g., Tailwind's font-sans).\n *\n * In Next.js, the .variable class ONLY sets the CSS variable — it does NOT\n * set font-family. This is critical because apps commonly apply multiple\n * .variable classes to <body> (e.g., geistSans.variable + geistMono.variable).\n * If we also set font-family here, the last class wins due to CSS cascade,\n * causing all text to use that font (e.g., everything becomes monospace).\n */\nfunction injectVariableClassRule(\n variableClassName: string,\n cssVarName: string,\n fontFamily: string,\n): void {\n if (injectedVariableRules.has(variableClassName)) return;\n injectedVariableRules.add(variableClassName);\n\n // Only set the CSS variable — do NOT set font-family.\n // This matches Next.js behavior where .variable classes only define CSS variables.\n let css = `.${variableClassName} { ${cssVarName}: ${fontFamily}; }\\n`;\n\n // Also inject at :root so CSS variable inheritance works throughout the page.\n // This ensures Tailwind utilities like `font-sans` that reference these\n // variables via var(--font-geist-sans) work correctly.\n if (!injectedRootVariables.has(cssVarName)) {\n injectedRootVariables.add(cssVarName);\n css += `:root { ${cssVarName}: ${fontFamily}; }\\n`;\n }\n\n // On server, store the CSS for SSR injection\n if (typeof document === \"undefined\") {\n ssrFontStyles.push(css);\n return;\n }\n\n // On client, inject a <style> tag\n const style = document.createElement(\"style\");\n style.textContent = css;\n style.setAttribute(\"data-vinext-font-variable\", variableClassName);\n document.head.appendChild(style);\n}\n\n/**\n * Normalize the `src` option into a flat array of `{ path, weight?, style? }`.\n * Handles string, single object, and array forms.\n */\nfunction normalizeSources(options: LocalFontOptions): LocalFontSrc[] {\n if (Array.isArray(options.src)) return options.src;\n if (typeof options.src === \"string\") return [{ path: options.src }];\n return [options.src];\n}\n\n/**\n * Determine the MIME type for a font file based on its extension.\n * Uses endsWith() only — matching the approach in generateFontFaceCSS —\n * to avoid false positives from substring matches (e.g. \".woff\" matching \".woff2\").\n */\nfunction getFontMimeType(pathOrUrl: string): string {\n if (pathOrUrl.endsWith(\".woff2\")) return \"font/woff2\";\n if (pathOrUrl.endsWith(\".woff\")) return \"font/woff\";\n if (pathOrUrl.endsWith(\".ttf\")) return \"font/ttf\";\n if (pathOrUrl.endsWith(\".otf\")) return \"font/opentype\";\n return \"font/woff2\";\n}\n\n/**\n * Collect font source URLs for preload link generation.\n * Only collects on the server (SSR). Deduplicates by href using a Set for O(1) lookups.\n */\nfunction collectFontPreloads(sources: LocalFontSrc[]): void {\n if (typeof document !== \"undefined\") return; // client-side, skip\n\n for (const src of sources) {\n const href = src.path;\n // Only collect URLs that are absolute (start with /) — relative paths\n // would resolve incorrectly from different page URLs. The vinext:local-fonts\n // Vite transform should have already resolved them to absolute URLs.\n if (href && href.startsWith(\"/\") && !ssrFontPreloadHrefs.has(href)) {\n ssrFontPreloadHrefs.add(href);\n ssrFontPreloads.push({ href, type: getFontMimeType(href) });\n }\n }\n}\n\nexport default function localFont(options: LocalFontOptions): FontResult {\n const id = classCounter++;\n const sources = normalizeSources(options);\n const singleSource = sources.length === 1 ? sources[0] : undefined;\n const family = `__local_font_${id}`;\n const className = `__font_local_${id}`;\n const fallback = options.fallback ?? [\"sans-serif\"];\n // Sanitize each fallback name to prevent CSS injection via crafted values\n const fontFamily = `'${family}', ${fallback.map(sanitizeFallback).join(\", \")}`;\n // Validate CSS variable name — reject anything that could inject CSS\n const cssVarName = options.variable ? sanitizeCSSVarName(options.variable) : undefined;\n // In Next.js, `variable` returns a CLASS NAME that sets the CSS variable.\n // Users apply this class to set the CSS variable on that element.\n const variableClassName = `__variable_local_${id}`;\n const style = singleSource\n ? resolveSingleFaceStyle({\n fontFamily,\n weight: singleSource.weight ?? options.weight,\n style: singleSource.style ?? options.style,\n })\n : { fontFamily };\n\n // Collect font URLs for preload <link> tags (SSR only)\n collectFontPreloads(sources);\n\n // Inject @font-face declarations\n const css = generateFontFaceCSS(family, options, sources);\n injectFontFaceCSS(css, family);\n\n // Inject the className -> font-family CSS rule\n injectClassNameRule(className, style);\n\n // Inject a CSS rule for the variable class name if variable is specified.\n // This is what makes `<html className={font.variable}>` set the CSS variable.\n if (cssVarName) {\n injectVariableClassRule(variableClassName, cssVarName, fontFamily);\n }\n\n return {\n className,\n style,\n ...(cssVarName ? { variable: variableClassName } : {}),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"font-local.js","names":[],"sources":["../../src/shims/font-local.ts"],"sourcesContent":["/**\n * next/font/local shim\n *\n * Provides a runtime-compatible shim for Next.js local fonts.\n * Generates @font-face CSS declarations and returns an object\n * with className, style, and variable properties.\n *\n * Supports both client-side injection and SSR collection,\n * matching the patterns used by the Google font shim.\n *\n * Usage:\n * import localFont from 'next/font/local';\n * const myFont = localFont({ src: './my-font.woff2' });\n * // myFont.className -> unique CSS class\n * // myFont.style -> { fontFamily: \"'__local_font_0', sans-serif\" }\n * // myFont.variable -> generated class name when requested\n */\nimport {\n escapeCSSString,\n formatFontClassRule,\n resolveSingleFaceStyle,\n sanitizeCSSVarName,\n sanitizeFallback,\n sanitizeFontDescriptorValue,\n type FontStyle,\n} from \"./font-utils.js\";\n\n/**\n * Validate a CSS property name for use in declarations.\n *\n * Only allows standard CSS property names (lowercase letters and hyphens)\n * and custom properties (--prefixed). Rejects anything that could inject\n * CSS rules via crafted property names.\n */\nfunction sanitizeCSSProperty(prop: string): string | undefined {\n if (/^(--)?[a-zA-Z][a-zA-Z0-9-]*$/.test(prop)) return prop;\n return undefined;\n}\n\nfunction sanitizeInternalFontFamily(name: unknown): string | undefined {\n if (typeof name !== \"string\" || name.length === 0) return undefined;\n if (/^[$_a-zA-Z][$_a-zA-Z0-9]*$/.test(name)) return name;\n return undefined;\n}\n\nlet classCounter = 0;\nconst injectedFonts = new Set<string>();\n\ntype LocalFontSrc = {\n path: string;\n weight?: string;\n style?: string;\n};\n\ntype LocalFontOptions = {\n src: string | LocalFontSrc | LocalFontSrc[];\n display?: string;\n weight?: string;\n style?: string;\n fallback?: string[];\n preload?: boolean;\n variable?: string;\n adjustFontFallback?: boolean | string;\n declarations?: Array<{ prop: string; value: string }>;\n _vinext?: {\n font?: {\n family?: unknown;\n };\n };\n};\n\ntype FontResult = {\n className: string;\n style: FontStyle;\n variable?: string;\n};\n\nfunction generateFontFaceCSS(\n family: string,\n options: LocalFontOptions,\n sources: LocalFontSrc[],\n): string {\n const display = options.display ?? \"swap\";\n const rules: string[] = [];\n\n for (const src of sources) {\n const weight = sanitizeFontDescriptorValue(src.weight ?? options.weight ?? \"400\") ?? \"400\";\n const style = sanitizeFontDescriptorValue(src.style ?? options.style ?? \"normal\") ?? \"normal\";\n const format = src.path.endsWith(\".woff2\")\n ? \"woff2\"\n : src.path.endsWith(\".woff\")\n ? \"woff\"\n : src.path.endsWith(\".ttf\")\n ? \"truetype\"\n : src.path.endsWith(\".otf\")\n ? \"opentype\"\n : \"woff2\";\n\n rules.push(`@font-face {\n font-family: '${escapeCSSString(family)}';\n src: url('${escapeCSSString(src.path)}') format('${format}');\n font-weight: ${weight};\n font-style: ${style};\n font-display: ${display};\n}`);\n }\n\n // Add extra declarations if provided — sanitize prop/value to prevent injection\n if (options.declarations) {\n for (const decl of options.declarations) {\n const safeProp = sanitizeCSSProperty(decl.prop);\n const safeValue = sanitizeFontDescriptorValue(decl.value);\n if (safeProp && safeValue) {\n rules.push(\n `@font-face { font-family: '${escapeCSSString(family)}'; ${safeProp}: ${safeValue}; }`,\n );\n }\n }\n }\n\n return rules.join(\"\\n\");\n}\n\n// SSR: collect font styles for injection in <head>\nconst ssrFontStyles: string[] = [];\n\n// SSR: collect font file URLs for <link rel=\"preload\"> injection\nconst ssrFontPreloads: Array<{ href: string; type: string }> = [];\nconst ssrFontPreloadHrefs = new Set<string>();\n\n/**\n * Get collected SSR font styles (used by the renderer).\n * Note: We don't clear the arrays because fonts are loaded at module import\n * time and need to persist across all requests in the Workers environment.\n */\nexport function getSSRFontStyles(): string[] {\n return [...ssrFontStyles];\n}\n\n/**\n * Get collected SSR font preload data (used by the renderer).\n * Returns an array of { href, type } objects for emitting\n * <link rel=\"preload\" as=\"font\" ...> tags.\n */\nexport function getSSRFontPreloads(): Array<{ href: string; type: string }> {\n return [...ssrFontPreloads];\n}\n\nfunction injectFontFaceCSS(css: string, id: string): void {\n if (injectedFonts.has(id)) return;\n injectedFonts.add(id);\n\n // On server, store the CSS for SSR injection\n if (typeof document === \"undefined\") {\n ssrFontStyles.push(css);\n return;\n }\n\n const style = document.createElement(\"style\");\n style.textContent = css;\n style.setAttribute(\"data-vinext-font\", id);\n document.head.appendChild(style);\n}\n\n/** Track which className CSS rules have been injected. */\nconst injectedClassRules = new Set<string>();\n\n/**\n * Inject a CSS rule that maps a className to the exported font style.\n *\n * This is what makes `<div className={font.className}>` apply the font.\n *\n * In Next.js, the .className class sets font-family and any single\n * font-weight/font-style. CSS variables are handled separately by .variable.\n */\nfunction injectClassNameRule(className: string, fontStyle: FontStyle): void {\n if (injectedClassRules.has(className)) return;\n injectedClassRules.add(className);\n\n const css = formatFontClassRule(className, fontStyle);\n\n // On server, store the CSS for SSR injection\n if (typeof document === \"undefined\") {\n ssrFontStyles.push(css);\n return;\n }\n\n // On client, inject a <style> tag\n const style = document.createElement(\"style\");\n style.textContent = css;\n style.setAttribute(\"data-vinext-font-class\", className);\n document.head.appendChild(style);\n}\n\n/** Track which variable class CSS rules have been injected. */\nconst injectedVariableRules = new Set<string>();\n\n/** Track which :root CSS variable rules have been injected. */\nconst injectedRootVariables = new Set<string>();\n\n/**\n * Inject a CSS rule that sets a CSS variable on an element.\n * This is what makes `<html className={font.variable}>` set the CSS variable\n * that can be referenced by other styles (e.g., Tailwind's font-sans).\n *\n * In Next.js, the .variable class ONLY sets the CSS variable — it does NOT\n * set font-family. This is critical because apps commonly apply multiple\n * .variable classes to <body> (e.g., geistSans.variable + geistMono.variable).\n * If we also set font-family here, the last class wins due to CSS cascade,\n * causing all text to use that font (e.g., everything becomes monospace).\n */\nfunction injectVariableClassRule(\n variableClassName: string,\n cssVarName: string,\n fontFamily: string,\n): void {\n if (injectedVariableRules.has(variableClassName)) return;\n injectedVariableRules.add(variableClassName);\n\n // Only set the CSS variable — do NOT set font-family.\n // This matches Next.js behavior where .variable classes only define CSS variables.\n let css = `.${variableClassName} { ${cssVarName}: ${fontFamily}; }\\n`;\n\n // Also inject at :root so CSS variable inheritance works throughout the page.\n // This ensures Tailwind utilities like `font-sans` that reference these\n // variables via var(--font-geist-sans) work correctly.\n if (!injectedRootVariables.has(cssVarName)) {\n injectedRootVariables.add(cssVarName);\n css += `:root { ${cssVarName}: ${fontFamily}; }\\n`;\n }\n\n // On server, store the CSS for SSR injection\n if (typeof document === \"undefined\") {\n ssrFontStyles.push(css);\n return;\n }\n\n // On client, inject a <style> tag\n const style = document.createElement(\"style\");\n style.textContent = css;\n style.setAttribute(\"data-vinext-font-variable\", variableClassName);\n document.head.appendChild(style);\n}\n\n/**\n * Normalize the `src` option into a flat array of `{ path, weight?, style? }`.\n * Handles string, single object, and array forms.\n */\nfunction normalizeSources(options: LocalFontOptions): LocalFontSrc[] {\n if (Array.isArray(options.src)) return options.src;\n if (typeof options.src === \"string\") return [{ path: options.src }];\n return [options.src];\n}\n\n/**\n * Determine the MIME type for a font file based on its extension.\n * Uses endsWith() only — matching the approach in generateFontFaceCSS —\n * to avoid false positives from substring matches (e.g. \".woff\" matching \".woff2\").\n */\nfunction getFontMimeType(pathOrUrl: string): string {\n if (pathOrUrl.endsWith(\".woff2\")) return \"font/woff2\";\n if (pathOrUrl.endsWith(\".woff\")) return \"font/woff\";\n if (pathOrUrl.endsWith(\".ttf\")) return \"font/ttf\";\n if (pathOrUrl.endsWith(\".otf\")) return \"font/opentype\";\n return \"font/woff2\";\n}\n\n/**\n * Collect font source URLs for preload link generation.\n * Only collects on the server (SSR). Deduplicates by href using a Set for O(1) lookups.\n */\nfunction collectFontPreloads(sources: LocalFontSrc[]): void {\n if (typeof document !== \"undefined\") return; // client-side, skip\n\n for (const src of sources) {\n const href = src.path;\n // Only collect URLs that are absolute (start with /) — relative paths\n // would resolve incorrectly from different page URLs. The vinext:local-fonts\n // Vite transform should have already resolved them to absolute URLs.\n if (href && href.startsWith(\"/\") && !ssrFontPreloadHrefs.has(href)) {\n ssrFontPreloadHrefs.add(href);\n ssrFontPreloads.push({ href, type: getFontMimeType(href) });\n }\n }\n}\n\nexport default function localFont(options: LocalFontOptions): FontResult {\n const id = classCounter++;\n const sources = normalizeSources(options);\n const singleSource = sources.length === 1 ? sources[0] : undefined;\n const family = sanitizeInternalFontFamily(options._vinext?.font?.family) ?? `__local_font_${id}`;\n const className = `__font_local_${id}`;\n const fallback = options.fallback ?? [\"sans-serif\"];\n // Sanitize each fallback name to prevent CSS injection via crafted values\n const fontFamily = `'${family}', ${fallback.map(sanitizeFallback).join(\", \")}`;\n // Validate CSS variable name — reject anything that could inject CSS\n const cssVarName = options.variable ? sanitizeCSSVarName(options.variable) : undefined;\n // In Next.js, `variable` returns a CLASS NAME that sets the CSS variable.\n // Users apply this class to set the CSS variable on that element.\n const variableClassName = `__variable_local_${id}`;\n const style = singleSource\n ? resolveSingleFaceStyle({\n fontFamily,\n weight: singleSource.weight ?? options.weight,\n style: singleSource.style ?? options.style,\n })\n : { fontFamily };\n\n // Collect font URLs for preload <link> tags (SSR only)\n collectFontPreloads(sources);\n\n // Inject @font-face declarations\n const css = generateFontFaceCSS(family, options, sources);\n // The exposed family can repeat across modules; the generated class stays\n // unique for each localFont call and is the correct injection identity.\n injectFontFaceCSS(css, className);\n\n // Inject the className -> font-family CSS rule\n injectClassNameRule(className, style);\n\n // Inject a CSS rule for the variable class name if variable is specified.\n // This is what makes `<html className={font.variable}>` set the CSS variable.\n if (cssVarName) {\n injectVariableClassRule(variableClassName, cssVarName, fontFamily);\n }\n\n return {\n className,\n style,\n ...(cssVarName ? { variable: variableClassName } : {}),\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { isDangerousScheme } from "./url-safety.js";
3
- import { toSameOriginPath } from "./url-utils.js";
3
+ import { toSameOriginPath, withBasePath } from "./url-utils.js";
4
+ import { hasAppNavigationRuntime } from "../client/navigation-runtime.js";
4
5
  import { navigateClientSide } from "./navigation.js";
5
6
  import { forwardRef, useActionState } from "react";
6
7
  import { jsx } from "react/jsx-runtime";
@@ -22,6 +23,7 @@ import { jsx } from "react/jsx-runtime";
22
23
  * <button type="submit">Search</button>
23
24
  * </Form>
24
25
  */
26
+ const __basePath = process.env.__NEXT_ROUTER_BASEPATH ?? "";
25
27
  const SUPPORTED_FORM_ENCTYPE = "application/x-www-form-urlencoded";
26
28
  const SUPPORTED_FORM_METHOD = "GET";
27
29
  const SUPPORTED_FORM_TARGET = "_self";
@@ -112,6 +114,7 @@ const Form = forwardRef(function Form(props, ref) {
112
114
  ...rest
113
115
  });
114
116
  }
117
+ const actionHref = withBasePath(action, __basePath);
115
118
  async function handleSubmit(e) {
116
119
  if (onSubmit) {
117
120
  onSubmit(e);
@@ -120,7 +123,7 @@ const Form = forwardRef(function Form(props, ref) {
120
123
  const submitter = getSubmitter(e.nativeEvent);
121
124
  if (submitter && hasUnsupportedSubmitterAttributes(submitter)) return;
122
125
  if (getEffectiveMethod(submitter, rest.method) !== "GET") return;
123
- const effectiveAction = getEffectiveAction(submitter, action);
126
+ const effectiveAction = getEffectiveAction(submitter, actionHref);
124
127
  if (process.env.NODE_ENV !== "production" && submitter?.getAttribute("formaction") !== null) checkFormActionUrl(effectiveAction, "formAction");
125
128
  if (!isSafeAction(effectiveAction)) {
126
129
  if (process.env.NODE_ENV !== "production") console.warn(`<Form> blocked unsafe action: ${effectiveAction}`);
@@ -129,17 +132,21 @@ const Form = forwardRef(function Form(props, ref) {
129
132
  }
130
133
  e.preventDefault();
131
134
  const url = createFormSubmitDestinationUrl(effectiveAction, e.currentTarget, submitter);
132
- if (typeof window.__VINEXT_RSC_NAVIGATE__ === "function") await navigateClientSide(url, replace ? "replace" : "push", scroll);
133
- else {
135
+ if (hasAppNavigationRuntime()) await navigateClientSide(url, replace ? "replace" : "push", scroll);
136
+ else try {
137
+ const Router = (await import("./router.js")).default;
138
+ if (replace) await Router.replace(url, void 0, { scroll });
139
+ else await Router.push(url, void 0, { scroll });
140
+ } catch {
134
141
  if (replace) window.history.replaceState({}, "", url);
135
142
  else window.history.pushState({}, "", url);
136
143
  window.dispatchEvent(new PopStateEvent("popstate"));
144
+ if (scroll) window.scrollTo(0, 0);
137
145
  }
138
- if (typeof window.__VINEXT_RSC_NAVIGATE__ !== "function" && scroll) window.scrollTo(0, 0);
139
146
  }
140
147
  return /* @__PURE__ */ jsx("form", {
141
148
  ref,
142
- action,
149
+ action: actionHref,
143
150
  onSubmit: (event) => {
144
151
  handleSubmit(event);
145
152
  },
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","names":[],"sources":["../../src/shims/form.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * next/form shim\n *\n * Progressive enhancement form component. In Next.js, this replaces\n * the standard <form> element with one that intercepts submissions\n * and performs client-side navigation for GET forms (search forms).\n *\n * For POST forms with server actions, it delegates to React's built-in\n * form action handling.\n *\n * Usage:\n * import Form from 'next/form';\n * <Form action=\"/search\">\n * <input name=\"q\" />\n * <button type=\"submit\">Search</button>\n * </Form>\n */\n\nimport { forwardRef, useActionState, type FormHTMLAttributes, type ForwardedRef } from \"react\";\nimport { navigateClientSide } from \"./navigation.js\";\nimport { isDangerousScheme } from \"./url-safety.js\";\nimport { toSameOriginPath } from \"./url-utils.js\";\n\n// Re-export useActionState from React 19 to match Next.js's next/form module\nexport { useActionState };\n\ntype FormSubmitter = HTMLButtonElement | HTMLInputElement;\nconst SUPPORTED_FORM_ENCTYPE = \"application/x-www-form-urlencoded\";\nconst SUPPORTED_FORM_METHOD = \"GET\";\nconst SUPPORTED_FORM_TARGET = \"_self\";\n\nfunction isSafeAction(action: string): boolean {\n // Block dangerous URI schemes\n if (isDangerousScheme(action)) return false;\n // Block protocol-relative URLs (//evil.com/...)\n if (action.startsWith(\"//\")) return false;\n // Block absolute URLs to external origins (client-side: compare origins)\n if (/^https?:\\/\\//i.test(action)) {\n if (typeof window !== \"undefined\") {\n try {\n const actionUrl = new URL(action);\n return actionUrl.origin === window.location.origin;\n } catch {\n return false;\n }\n }\n // Server-side: block all absolute URLs (can't compare origins)\n return false;\n }\n return true;\n}\n\nfunction getSubmitter(nativeEvent: unknown): FormSubmitter | null {\n const submitter =\n nativeEvent &&\n typeof nativeEvent === \"object\" &&\n \"submitter\" in nativeEvent &&\n nativeEvent.submitter instanceof Element\n ? nativeEvent.submitter\n : null;\n\n if (submitter instanceof HTMLButtonElement || submitter instanceof HTMLInputElement) {\n return submitter;\n }\n return null;\n}\n\nfunction getEffectiveMethod(\n submitter: FormSubmitter | null,\n formMethod: FormHTMLAttributes<HTMLFormElement>[\"method\"],\n): string {\n const override = submitter?.getAttribute(\"formmethod\");\n return (override ?? formMethod ?? \"GET\").toUpperCase();\n}\n\nfunction getEffectiveAction(submitter: FormSubmitter | null, formAction: string): string {\n return submitter?.getAttribute(\"formaction\") ?? formAction;\n}\n\nfunction checkFormActionUrl(action: string, source: \"action\" | \"formAction\"): void {\n const aPropName = source === \"action\" ? \"an `action`\" : \"a `formAction`\";\n\n let testUrl: URL;\n try {\n testUrl = new URL(action, \"http://n\");\n } catch {\n console.error(`<Form> received ${aPropName} that cannot be parsed as a URL: \"${action}\".`);\n return;\n }\n\n if (testUrl.searchParams.size) {\n console.warn(\n `<Form> received ${aPropName} that contains search params: \"${action}\". This is not supported, and they will be ignored. ` +\n `If you need to pass in additional search params, use an \\`<input type=\"hidden\" />\\` instead.`,\n );\n }\n}\n\nfunction hasUnsupportedSubmitterAttributes(submitter: FormSubmitter): boolean {\n const formEncType = submitter.getAttribute(\"formenctype\");\n if (formEncType !== null && formEncType !== SUPPORTED_FORM_ENCTYPE) {\n console.error(\n `<Form>'s \\`encType\\` was set to an unsupported value via \\`formEncType=\"${formEncType}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`,\n );\n return true;\n }\n\n const formMethod = submitter.getAttribute(\"formmethod\");\n if (formMethod !== null && formMethod.toUpperCase() !== SUPPORTED_FORM_METHOD) {\n console.error(\n `<Form>'s \\`method\\` was set to an unsupported value via \\`formMethod=\"${formMethod}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`,\n );\n return true;\n }\n\n const formTarget = submitter.getAttribute(\"formtarget\");\n if (formTarget !== null && formTarget !== SUPPORTED_FORM_TARGET) {\n console.error(\n `<Form>'s \\`target\\` was set to an unsupported value via \\`formTarget=\"${formTarget}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`,\n );\n return true;\n }\n\n return false;\n}\n\nfunction createFormSubmitDestinationUrl(\n action: string,\n form: HTMLFormElement,\n submitter: FormSubmitter | null,\n): string {\n const targetUrl = new URL(action, window.location.href);\n if (targetUrl.searchParams.size) {\n targetUrl.search = \"\";\n }\n\n const formData = buildFormData(form, submitter);\n for (const [name, value] of formData) {\n targetUrl.searchParams.append(name, typeof value === \"string\" ? value : value.name);\n }\n\n return toSameOriginPath(targetUrl.href) ?? targetUrl.href;\n}\n\nfunction buildFormData(form: HTMLFormElement, submitter: FormSubmitter | null): FormData {\n if (!submitter) return new FormData(form);\n\n try {\n return new FormData(form, submitter);\n } catch {\n const formData = new FormData(form);\n if (!submitter.disabled && submitter.name) {\n formData.append(submitter.name, submitter.value);\n }\n return formData;\n }\n}\n\ntype FormProps = {\n /** Target URL for GET forms, or server action for POST forms */\n action: string | ((formData: FormData) => void | Promise<void>);\n /** Replace instead of push in history (default: false) */\n replace?: boolean;\n /** Scroll to top after navigation (default: true) */\n scroll?: boolean;\n} & FormHTMLAttributes<HTMLFormElement>;\n\nconst Form = forwardRef(function Form(props: FormProps, ref: ForwardedRef<HTMLFormElement>) {\n const { action, replace = false, scroll = true, onSubmit, ...rest } = props;\n\n // If action is a function (server action), pass it directly to React\n if (typeof action === \"function\") {\n return <form ref={ref} action={action} onSubmit={onSubmit} {...rest} />;\n }\n\n // Block dangerous action URLs. Render <form> without action attribute\n // so it submits to the current page (safe default).\n if (process.env.NODE_ENV !== \"production\") {\n checkFormActionUrl(action, \"action\");\n }\n\n if (!isSafeAction(action)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`<Form> blocked unsafe action: ${action}`);\n }\n return <form ref={ref} onSubmit={onSubmit} {...rest} />;\n }\n\n async function handleSubmit(e: React.SubmitEvent<HTMLFormElement>) {\n // Call user's onSubmit first\n if (onSubmit) {\n onSubmit(e);\n if (e.defaultPrevented) return;\n }\n\n const submitter = getSubmitter(e.nativeEvent);\n if (submitter && hasUnsupportedSubmitterAttributes(submitter)) {\n return;\n }\n\n // Only intercept GET forms for client-side navigation\n const method = getEffectiveMethod(submitter, rest.method);\n if (method !== \"GET\") return;\n\n const effectiveAction = getEffectiveAction(submitter, action as string);\n if (process.env.NODE_ENV !== \"production\" && submitter?.getAttribute(\"formaction\") !== null) {\n checkFormActionUrl(effectiveAction, \"formAction\");\n }\n if (!isSafeAction(effectiveAction)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`<Form> blocked unsafe action: ${effectiveAction}`);\n }\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const url = createFormSubmitDestinationUrl(effectiveAction, e.currentTarget, submitter);\n\n // Navigate client-side\n if (typeof window.__VINEXT_RSC_NAVIGATE__ === \"function\") {\n // App Router: use the shared navigator so URL/history publish stays\n // aligned with the committed RSC tree.\n await navigateClientSide(url, replace ? \"replace\" : \"push\", scroll);\n } else {\n // Pages Router: use router or fallback\n if (replace) {\n window.history.replaceState({}, \"\", url);\n } else {\n window.history.pushState({}, \"\", url);\n }\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n }\n\n // App Router: scroll is handled inside navigateClientSide (called above).\n // Pages Router: scroll manually since pushState/popstate doesn't auto-scroll.\n if (typeof window.__VINEXT_RSC_NAVIGATE__ !== \"function\" && scroll) {\n window.scrollTo(0, 0);\n }\n }\n\n return (\n <form\n ref={ref}\n action={action}\n onSubmit={(event) => {\n void handleSubmit(event);\n }}\n {...rest}\n />\n );\n});\n\nexport default Form;\n"],"mappings":"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"}
1
+ {"version":3,"file":"form.js","names":[],"sources":["../../src/shims/form.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * next/form shim\n *\n * Progressive enhancement form component. In Next.js, this replaces\n * the standard <form> element with one that intercepts submissions\n * and performs client-side navigation for GET forms (search forms).\n *\n * For POST forms with server actions, it delegates to React's built-in\n * form action handling.\n *\n * Usage:\n * import Form from 'next/form';\n * <Form action=\"/search\">\n * <input name=\"q\" />\n * <button type=\"submit\">Search</button>\n * </Form>\n */\n\nimport { forwardRef, useActionState, type FormHTMLAttributes, type ForwardedRef } from \"react\";\nimport { hasAppNavigationRuntime } from \"../client/navigation-runtime.js\";\nimport { navigateClientSide } from \"./navigation.js\";\nimport { isDangerousScheme } from \"./url-safety.js\";\nimport { toSameOriginPath, withBasePath } from \"./url-utils.js\";\n\n// Mirrors `__NEXT_ROUTER_BASEPATH` exposure in `next/link` / `next/router`.\n// `addBasePath` is only applied to the form-level `action` prop. A submitter's\n// `formAction` is intentionally untouched, matching Next.js (the comment in\n// upstream `form.tsx` notes \"this should not have basePath added, because we\n// can't add it before hydration\").\nconst __basePath: string = process.env.__NEXT_ROUTER_BASEPATH ?? \"\";\n\n// Re-export useActionState from React 19 to match Next.js's next/form module\nexport { useActionState };\n\ntype FormSubmitter = HTMLButtonElement | HTMLInputElement;\nconst SUPPORTED_FORM_ENCTYPE = \"application/x-www-form-urlencoded\";\nconst SUPPORTED_FORM_METHOD = \"GET\";\nconst SUPPORTED_FORM_TARGET = \"_self\";\n\nfunction isSafeAction(action: string): boolean {\n // Block dangerous URI schemes\n if (isDangerousScheme(action)) return false;\n // Block protocol-relative URLs (//evil.com/...)\n if (action.startsWith(\"//\")) return false;\n // Block absolute URLs to external origins (client-side: compare origins)\n if (/^https?:\\/\\//i.test(action)) {\n if (typeof window !== \"undefined\") {\n try {\n const actionUrl = new URL(action);\n return actionUrl.origin === window.location.origin;\n } catch {\n return false;\n }\n }\n // Server-side: block all absolute URLs (can't compare origins)\n return false;\n }\n return true;\n}\n\nfunction getSubmitter(nativeEvent: unknown): FormSubmitter | null {\n const submitter =\n nativeEvent &&\n typeof nativeEvent === \"object\" &&\n \"submitter\" in nativeEvent &&\n nativeEvent.submitter instanceof Element\n ? nativeEvent.submitter\n : null;\n\n if (submitter instanceof HTMLButtonElement || submitter instanceof HTMLInputElement) {\n return submitter;\n }\n return null;\n}\n\nfunction getEffectiveMethod(\n submitter: FormSubmitter | null,\n formMethod: FormHTMLAttributes<HTMLFormElement>[\"method\"],\n): string {\n const override = submitter?.getAttribute(\"formmethod\");\n return (override ?? formMethod ?? \"GET\").toUpperCase();\n}\n\nfunction getEffectiveAction(submitter: FormSubmitter | null, formAction: string): string {\n return submitter?.getAttribute(\"formaction\") ?? formAction;\n}\n\nfunction checkFormActionUrl(action: string, source: \"action\" | \"formAction\"): void {\n const aPropName = source === \"action\" ? \"an `action`\" : \"a `formAction`\";\n\n let testUrl: URL;\n try {\n testUrl = new URL(action, \"http://n\");\n } catch {\n console.error(`<Form> received ${aPropName} that cannot be parsed as a URL: \"${action}\".`);\n return;\n }\n\n if (testUrl.searchParams.size) {\n console.warn(\n `<Form> received ${aPropName} that contains search params: \"${action}\". This is not supported, and they will be ignored. ` +\n `If you need to pass in additional search params, use an \\`<input type=\"hidden\" />\\` instead.`,\n );\n }\n}\n\nfunction hasUnsupportedSubmitterAttributes(submitter: FormSubmitter): boolean {\n const formEncType = submitter.getAttribute(\"formenctype\");\n if (formEncType !== null && formEncType !== SUPPORTED_FORM_ENCTYPE) {\n console.error(\n `<Form>'s \\`encType\\` was set to an unsupported value via \\`formEncType=\"${formEncType}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`,\n );\n return true;\n }\n\n const formMethod = submitter.getAttribute(\"formmethod\");\n if (formMethod !== null && formMethod.toUpperCase() !== SUPPORTED_FORM_METHOD) {\n console.error(\n `<Form>'s \\`method\\` was set to an unsupported value via \\`formMethod=\"${formMethod}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`,\n );\n return true;\n }\n\n const formTarget = submitter.getAttribute(\"formtarget\");\n if (formTarget !== null && formTarget !== SUPPORTED_FORM_TARGET) {\n console.error(\n `<Form>'s \\`target\\` was set to an unsupported value via \\`formTarget=\"${formTarget}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`,\n );\n return true;\n }\n\n return false;\n}\n\nfunction createFormSubmitDestinationUrl(\n action: string,\n form: HTMLFormElement,\n submitter: FormSubmitter | null,\n): string {\n const targetUrl = new URL(action, window.location.href);\n if (targetUrl.searchParams.size) {\n targetUrl.search = \"\";\n }\n\n const formData = buildFormData(form, submitter);\n for (const [name, value] of formData) {\n targetUrl.searchParams.append(name, typeof value === \"string\" ? value : value.name);\n }\n\n return toSameOriginPath(targetUrl.href) ?? targetUrl.href;\n}\n\nfunction buildFormData(form: HTMLFormElement, submitter: FormSubmitter | null): FormData {\n if (!submitter) return new FormData(form);\n\n try {\n return new FormData(form, submitter);\n } catch {\n const formData = new FormData(form);\n if (!submitter.disabled && submitter.name) {\n formData.append(submitter.name, submitter.value);\n }\n return formData;\n }\n}\n\ntype FormProps = {\n /** Target URL for GET forms, or server action for POST forms */\n action: string | ((formData: FormData) => void | Promise<void>);\n /** Replace instead of push in history (default: false) */\n replace?: boolean;\n /** Scroll to top after navigation (default: true) */\n scroll?: boolean;\n} & FormHTMLAttributes<HTMLFormElement>;\n\nconst Form = forwardRef(function Form(props: FormProps, ref: ForwardedRef<HTMLFormElement>) {\n const { action, replace = false, scroll = true, onSubmit, ...rest } = props;\n\n // If action is a function (server action), pass it directly to React\n if (typeof action === \"function\") {\n return <form ref={ref} action={action} onSubmit={onSubmit} {...rest} />;\n }\n\n // Block dangerous action URLs. Render <form> without action attribute\n // so it submits to the current page (safe default).\n if (process.env.NODE_ENV !== \"production\") {\n checkFormActionUrl(action, \"action\");\n }\n\n if (!isSafeAction(action)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`<Form> blocked unsafe action: ${action}`);\n }\n return <form ref={ref} onSubmit={onSubmit} {...rest} />;\n }\n\n // Prefix basePath to the navigating `action` prop (matches Next.js's\n // `addBasePath(actionProp)` in `client/form.tsx` and `client/app-dir/form.tsx`).\n // This becomes both the rendered `action=` attribute (so JS-disabled\n // submissions still hit the right URL) and the soft-navigation target.\n const actionHref = withBasePath(action, __basePath);\n\n async function handleSubmit(e: React.SubmitEvent<HTMLFormElement>) {\n // Call user's onSubmit first\n if (onSubmit) {\n onSubmit(e);\n if (e.defaultPrevented) return;\n }\n\n const submitter = getSubmitter(e.nativeEvent);\n if (submitter && hasUnsupportedSubmitterAttributes(submitter)) {\n return;\n }\n\n // Only intercept GET forms for client-side navigation\n const method = getEffectiveMethod(submitter, rest.method);\n if (method !== \"GET\") return;\n\n // NOTE: a submitter's `formAction` is intentionally NOT base-path-prefixed\n // here, matching Next.js. Upstream `form.tsx` notes: \"this should not have\n // `basePath` added, because we can't add it before hydration\".\n const effectiveAction = getEffectiveAction(submitter, actionHref);\n if (process.env.NODE_ENV !== \"production\" && submitter?.getAttribute(\"formaction\") !== null) {\n checkFormActionUrl(effectiveAction, \"formAction\");\n }\n if (!isSafeAction(effectiveAction)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(`<Form> blocked unsafe action: ${effectiveAction}`);\n }\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const url = createFormSubmitDestinationUrl(effectiveAction, e.currentTarget, submitter);\n\n // Navigate client-side\n if (hasAppNavigationRuntime()) {\n // App Router: use the shared navigator so URL/history publish stays\n // aligned with the committed RSC tree.\n await navigateClientSide(url, replace ? \"replace\" : \"push\", scroll);\n } else {\n // Pages Router: delegate to the Router singleton so navigation flows\n // through `performNavigation` (route events, HTML fetch, scroll\n // handling). Mirrors what `<Link>` does at link.tsx:619-623.\n try {\n const routerModule = await import(\"./router.js\");\n const Router = routerModule.default;\n if (replace) {\n await Router.replace(url, undefined, { scroll });\n } else {\n await Router.push(url, undefined, { scroll });\n }\n } catch {\n // Fallback: pushState + popstate keeps the URL in sync even if the\n // Router singleton import fails (e.g. in test/SSR-only contexts).\n if (replace) {\n window.history.replaceState({}, \"\", url);\n } else {\n window.history.pushState({}, \"\", url);\n }\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n if (scroll) {\n window.scrollTo(0, 0);\n }\n }\n }\n }\n\n return (\n <form\n ref={ref}\n action={actionHref}\n onSubmit={(event) => {\n void handleSubmit(event);\n }}\n {...rest}\n />\n );\n});\n\nexport default Form;\n"],"mappings":"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"}
@@ -159,9 +159,9 @@ function headChildToHTML(tag, props) {
159
159
  attrs.push(key);
160
160
  }
161
161
  const attrStr = attrs.length ? " " + attrs.join(" ") : "";
162
- if (SELF_CLOSING_HEAD_TAGS.has(tag)) return `<${tag}${attrStr} data-vinext-head="true" />`;
162
+ if (SELF_CLOSING_HEAD_TAGS.has(tag)) return `<${tag}${attrStr} data-next-head="" />`;
163
163
  if (RAW_CONTENT_TAGS.has(tag) && innerHTML) innerHTML = escapeInlineContent(innerHTML, tag);
164
- return `<${tag}${attrStr} data-vinext-head="true">${innerHTML}</${tag}>`;
164
+ return `<${tag}${attrStr} data-next-head="">${innerHTML}</${tag}>`;
165
165
  }
166
166
  function escapeHTML(s) {
167
167
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -204,13 +204,13 @@ function _applyHeadPropsToElement(domEl, props) {
204
204
  }
205
205
  }
206
206
  function syncClientHead() {
207
- document.querySelectorAll("[data-vinext-head]").forEach((el) => el.remove());
207
+ document.querySelectorAll("[data-next-head]").forEach((el) => el.remove());
208
208
  for (const child of reduceHeadChildren([..._clientHeadChildren.values()])) {
209
209
  if (typeof child.type !== "string") continue;
210
210
  const domEl = document.createElement(child.type);
211
211
  const props = child.props;
212
212
  _applyHeadPropsToElement(domEl, props);
213
- domEl.setAttribute("data-vinext-head", "true");
213
+ domEl.setAttribute("data-next-head", "");
214
214
  document.head.appendChild(domEl);
215
215
  }
216
216
  }