void 0.21.9 → 0.23.0

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 (293) hide show
  1. package/README.md +5 -1
  2. package/dist/{account-cmd-DZZGK80W.mjs → account-cmd-C84Ee8cO.mjs} +5 -5
  3. package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
  4. package/dist/application-routing-B7QEjqSR.mjs +27 -0
  5. package/dist/{auth-CZuiVsFh.mjs → auth-CCjt0hcq.mjs} +1 -1
  6. package/dist/{auth-DLNN0D3Z.mjs → auth-CSkdO2Bb.mjs} +4 -47
  7. package/dist/{auth-link-B_CeugBw.mjs → auth-link-CioEg6uY.mjs} +5 -5
  8. package/dist/{auth-router-BgEFRuvZ.mjs → auth-router-BsR981d4.mjs} +5 -5
  9. package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
  10. package/dist/{build-cmd-Dpt0jd-x.mjs → build-cmd-LzvNJORH.mjs} +19 -7
  11. package/dist/{cache-7_UeZdTk.mjs → cache-C4MvnrMH.mjs} +4 -4
  12. package/dist/{cancel-deploy-D23R1RXT.mjs → cancel-deploy-abUxpP2n.mjs} +4 -4
  13. package/dist/{cf-build-output-CGT03qCD.mjs → cf-build-output-BPqOT964.mjs} +141 -63
  14. package/dist/cf-build-output-_0HNWysu.mjs +2 -0
  15. package/dist/cli/cli.mjs +114 -460
  16. package/dist/cli/cloudflare-operation-process.mjs +1103 -0
  17. package/dist/cli/env-schema-probe.d.mts +2 -1
  18. package/dist/cli/env-schema-probe.mjs +3 -3
  19. package/dist/client-Cu7jWiF1.mjs +2 -0
  20. package/dist/{client-QTl6ko_D.mjs → client-RV8NVeB8.mjs} +165 -21
  21. package/dist/{cloudflare-auth-C4_GPZr0.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -43
  22. package/dist/{cloudflare-cmd-bSmZ1d5L.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +9 -10
  23. package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
  24. package/dist/{cloudflare-connect-jAwacxxP.mjs → cloudflare-connect-B8uPZ4nx.mjs} +4 -4
  25. package/dist/{cloudflare-operations-BipGMJ5O.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
  26. package/dist/{cloudflare-operations-sMZXpk_S.mjs → cloudflare-operations-fxHb-byx.mjs} +118 -203
  27. package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
  28. package/dist/{config-CF69HgXc.d.mts → config-BMHb8RCj.d.mts} +2 -2
  29. package/dist/{config-CafTW6Cz.mjs → config-Br_JZD6u.mjs} +2 -7
  30. package/dist/config-C_XRIPx2.mjs +89 -0
  31. package/dist/{config-s7Xj7tPb.mjs → config-CyQ-wVd7.mjs} +1 -1
  32. package/dist/config-entry.d.mts +1 -1
  33. package/dist/{config-write-BSduPMY8.mjs → config-write-B1f88wJA.mjs} +1 -1
  34. package/dist/{connect-BsUSRzln.mjs → connect-Bd4kJd9U.mjs} +6 -6
  35. package/dist/{create-project-BniEV0OW.mjs → create-project-Boczwj5r.mjs} +1 -1
  36. package/dist/{create-project-DBfFSZKY.mjs → create-project-bMf6ffLZ.mjs} +9 -5
  37. package/dist/{db-hRrvZaq_.mjs → db-8uG64XLl.mjs} +26 -26
  38. package/dist/{delete-D6dZ9B6B.mjs → delete-NvbiyeJf.mjs} +4 -4
  39. package/dist/{deploy-WaAQez1O.mjs → deploy-DzAIwqNU.mjs} +944 -607
  40. package/dist/{deploy-DDz7c8LK.mjs → deploy-bjXdFCtn.mjs} +1 -1
  41. package/dist/{dist-BR1quN_w.mjs → dist-AoCzRTJE.mjs} +226 -60
  42. package/dist/{dist-C5fND3R0.mjs → dist-BuDuKZJv.mjs} +1 -1
  43. package/dist/{dist-Dn6nn2IU.mjs → dist-CTBk70IR.mjs} +42 -42
  44. package/dist/{domain-Dmhvb2oU.mjs → domain-y5Tvydvo.mjs} +5 -5
  45. package/dist/{email-DFi-s2t4.mjs → email-B3umsW75.mjs} +15 -30
  46. package/dist/{env-Csi-tMbT.mjs → env-BS6qYHDb.mjs} +6 -6
  47. package/dist/{env-public-D_6u46fX.d.mts → env-public-BX_r8HR6.d.mts} +2 -1
  48. package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
  49. package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.mjs} +1 -1
  50. package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
  51. package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
  52. package/dist/{gen-Dz3X1Qab.mjs → gen-B580--vC.mjs} +5 -5
  53. package/dist/gen-BVaUUumi.mjs +2 -0
  54. package/dist/{github-cmd-BED3_9JD.mjs → github-cmd-v45BdfKX.mjs} +6 -8
  55. package/dist/{handler-BXJTXd02.d.mts → handler-CZ4nAylQ.d.mts} +2 -1
  56. package/dist/{headers-BOg_velo.mjs → headers-DWi2IXWx.mjs} +1 -1
  57. package/dist/help-DofyZuY7.mjs +2 -0
  58. package/dist/{help-DC7gdz7L.mjs → help-daGKjXGk.mjs} +268 -666
  59. package/dist/index.d.mts +1 -1
  60. package/dist/index.mjs +305 -1490
  61. package/dist/info-B97bTX9N.mjs +113 -0
  62. package/dist/{init-WO0JlPx8.mjs → init-Bvy7zrBo.mjs} +51 -20
  63. package/dist/limits-Bq5LG8Id.d.mts +27 -0
  64. package/dist/limits-Cjuk2VPm.mjs +68 -0
  65. package/dist/{link-CsHOinF7.mjs → link-CDqqCjFl.mjs} +5 -5
  66. package/dist/{list-CDb-4bZ1.mjs → list-CZj0dzKY.mjs} +5 -5
  67. package/dist/{live-CKiJilLr.d.mts → live-Chw1eIMv.d.mts} +1 -1
  68. package/dist/{local-d1-CC8sKFGu.mjs → local-d1-2CMnpuW_.mjs} +2 -2
  69. package/dist/login-DYt_An22.mjs +2 -0
  70. package/dist/{login-DvqXsfGs.mjs → login-UZKFM_u7.mjs} +5 -5
  71. package/dist/{logs-BdfiOezj.mjs → logs-CUZ6t9t3.mjs} +5 -5
  72. package/dist/migrate-8_2u55MD.mjs +2 -0
  73. package/dist/{migrate-B8KuoYsO.mjs → migrate-DHul7PRV.mjs} +5 -4
  74. package/dist/{node-BM43oz4G.mjs → node-BkyRWRx8.mjs} +2 -2
  75. package/dist/operator-args-CLgKGlwU.mjs +690 -0
  76. package/dist/{operator-cmd-03819ATr.mjs → operator-cmd-DBA6dl0m.mjs} +69 -23
  77. package/dist/output-Dm_A4Tbv.mjs +81 -0
  78. package/dist/pages/client.d.mts +34 -2
  79. package/dist/pages/client.mjs +59 -3
  80. package/dist/pages/index.d.mts +1 -1
  81. package/dist/pages/index.mjs +3 -3
  82. package/dist/pages/islands-plugin.d.mts +16 -6
  83. package/dist/pages/islands-plugin.mjs +2 -2
  84. package/dist/pages/protocol.d.mts +2 -2
  85. package/dist/pages/protocol.mjs +2 -308
  86. package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
  87. package/dist/{output-CCH48AMM.mjs → picocolors-BTps1_gs.mjs} +2 -76
  88. package/dist/plan-D1Q5rf-r.mjs +2 -0
  89. package/dist/plan-NPpwZ_kc.mjs +58 -0
  90. package/dist/platform-args-BJdRtlLq.mjs +506 -0
  91. package/dist/platform-args-D3RXyR6h.mjs +2 -0
  92. package/dist/{platform-auth-config-z92h63q5.mjs → platform-auth-config-B56E9YP1.mjs} +4 -4
  93. package/dist/{platform-auth-protection-DeE3yr2R.mjs → platform-auth-protection-BDWO_aER.mjs} +3 -3
  94. package/dist/{platform-auth-recovery-o_340Ixx.mjs → platform-auth-recovery-1gg4CSRe.mjs} +4 -4
  95. package/dist/{platform-cmd-C4ZV3Vpy.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
  96. package/dist/{platform-cmd-DNl8WosH.mjs → platform-cmd-DMcQStSc.mjs} +26 -5
  97. package/dist/{platform-domain-CU1JtJkW.mjs → platform-domain-BNkcz0OB.mjs} +36 -9
  98. package/dist/{platform-lifecycle-Bc047IeT.mjs → platform-lifecycle-9OyBALhH.mjs} +850 -276
  99. package/dist/{platform-lifecycle-Bs2qx1E3.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
  100. package/dist/{platform-management-CVpGI9Y5.mjs → platform-management-CjwLVQwN.mjs} +59 -11
  101. package/dist/{platform-management-C8tt6D8h.mjs → platform-management-CnyTdcWX.mjs} +1 -1
  102. package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
  103. package/dist/{platform-recovery-dvUaptLr.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
  104. package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
  105. package/dist/{prepare-DyZ-Yok5.mjs → prepare-B5Mkic5u.mjs} +3 -3
  106. package/dist/{prepare-C3kt3Rst.mjs → prepare-DOsL0CC9.mjs} +4 -20
  107. package/dist/prepare-cgvDMtSb.mjs +2 -0
  108. package/dist/{project-cmd-B44I8J_W.mjs → project-cmd-CNzrqvBv.mjs} +30 -16
  109. package/dist/{project-team-BkbYIsXN.mjs → project-team-DQOWPfQT.mjs} +4 -4
  110. package/dist/{project-token-C8xEEQnB.mjs → project-token-CTDYU0Cc.mjs} +4 -4
  111. package/dist/project-zero-trust-BNAkW-_0.mjs +63 -0
  112. package/dist/{protocol-ZH3jP4a7.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
  113. package/dist/protocol-U7bfjHmA.mjs +331 -0
  114. package/dist/{provision-DNtrtaVD.mjs → provision-C4ORE7G7.mjs} +1 -1
  115. package/dist/{provision-BhreDAOS.mjs → provision-CJFgTZY8.mjs} +111 -215
  116. package/dist/{requests-DFyhBMaf.mjs → requests-MhxYnau8.mjs} +4 -4
  117. package/dist/resource-name-C7LVpcRm.mjs +11 -0
  118. package/dist/{rollback-DHHxXZiS.mjs → rollback-CJ6iSDoU.mjs} +5 -5
  119. package/dist/route-url-CG7U-cRN.mjs +15 -0
  120. package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
  121. package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
  122. package/dist/runtime/ai.d.mts +12 -8
  123. package/dist/runtime/ai.mjs +84 -17
  124. package/dist/runtime/better-auth-mysql.mjs +1 -1
  125. package/dist/runtime/better-auth-pg.mjs +1 -1
  126. package/dist/runtime/better-auth.mjs +1 -1
  127. package/dist/runtime/client-react.mjs +2 -2
  128. package/dist/runtime/client-solid.mjs +2 -2
  129. package/dist/runtime/client-svelte.mjs +2 -2
  130. package/dist/runtime/client-vue.mjs +2 -2
  131. package/dist/runtime/client.mjs +2 -2
  132. package/dist/runtime/durable.d.mts +3 -1
  133. package/dist/runtime/durable.mjs +4 -1
  134. package/dist/runtime/email/testing.mjs +1 -1
  135. package/dist/runtime/env-public.d.mts +1 -1
  136. package/dist/runtime/fetch-stream.mjs +1 -1
  137. package/dist/runtime/fetch.mjs +1 -1
  138. package/dist/runtime/handler.d.mts +1 -1
  139. package/dist/runtime/kv.mjs +0 -1
  140. package/dist/runtime/limits.d.mts +2 -0
  141. package/dist/runtime/limits.mjs +2 -0
  142. package/dist/runtime/live-client.d.mts +1 -1
  143. package/dist/runtime/live-server.mjs +25 -16
  144. package/dist/runtime/live.d.mts +1 -1
  145. package/dist/runtime/migration-handler.mjs +62 -42
  146. package/dist/runtime/route-url.d.mts +4 -0
  147. package/dist/runtime/route-url.mjs +2 -0
  148. package/dist/runtime/routing.d.mts +180 -0
  149. package/dist/runtime/routing.mjs +1082 -0
  150. package/dist/runtime/sandbox-container.d.mts +3 -0
  151. package/dist/runtime/sandbox-container.mjs +2 -0
  152. package/dist/runtime/sandbox.d.mts +4 -32
  153. package/dist/runtime/sandbox.mjs +151 -75
  154. package/dist/runtime/sse.mjs +1 -1
  155. package/dist/runtime/validator.d.mts +1 -1
  156. package/dist/runtime/ws-server.d.mts +4 -2
  157. package/dist/runtime/ws-server.mjs +27 -2
  158. package/dist/runtime/ws.d.mts +2 -2
  159. package/dist/runtime/ws.mjs +8 -6
  160. package/dist/sandbox-XZAqzFlG.d.mts +52 -0
  161. package/dist/sandbox-container-Bo0eiFKz.d.mts +73 -0
  162. package/dist/sandbox-container-C6ItmVuN.mjs +281 -0
  163. package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
  164. package/dist/{secret-DN9sSNiV.mjs → secret-Dli5fP0B.mjs} +6 -6
  165. package/dist/{skills-O6FUaizK.mjs → skills-D1II1Juz.mjs} +1 -1
  166. package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
  167. package/dist/{subcommand-prompt-BuGYkAkC.mjs → subcommand-prompt-CY1C4fvl.mjs} +2 -2
  168. package/dist/validate-Dq_L3s0S.mjs +2 -0
  169. package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
  170. package/dist/{wrangler-BymcxrRa.mjs → wrangler-7K-bW_DL.mjs} +14 -235
  171. package/dist/{ws-BwcqizuH.d.mts → ws-CL1w7GXU.d.mts} +13 -2
  172. package/package.json +48 -33
  173. package/sandbox.Dockerfile +4 -0
  174. package/schema.json +10 -22
  175. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
  176. package/skills/void/SKILL.md +50 -133
  177. package/skills/void/docs/guide/ai.md +94 -84
  178. package/skills/void/docs/guide/app-types.md +3 -32
  179. package/skills/void/docs/guide/auth.md +12 -116
  180. package/skills/void/docs/guide/database/d1.md +9 -54
  181. package/skills/void/docs/guide/database/mysql.md +1 -1
  182. package/skills/void/docs/guide/database/postgresql.md +5 -26
  183. package/skills/void/docs/guide/database.md +23 -75
  184. package/skills/void/docs/guide/deployment.md +27 -113
  185. package/skills/void/docs/guide/durable-state.md +43 -18
  186. package/skills/void/docs/guide/edge/headers.md +3 -47
  187. package/skills/void/docs/guide/edge/prerendering.md +5 -20
  188. package/skills/void/docs/guide/edge/redirects.md +11 -64
  189. package/skills/void/docs/guide/edge/revalidation.md +6 -19
  190. package/skills/void/docs/guide/edge/rewrites.md +56 -284
  191. package/skills/void/docs/guide/edge/static-assets.md +23 -72
  192. package/skills/void/docs/guide/email/domains.md +112 -0
  193. package/skills/void/docs/guide/email/receiving.md +139 -0
  194. package/skills/void/docs/guide/email/sending.md +231 -0
  195. package/skills/void/docs/guide/email.md +13 -619
  196. package/skills/void/docs/guide/env-migration.md +11 -11
  197. package/skills/void/docs/guide/env-vars.md +9 -29
  198. package/skills/void/docs/guide/index.md +0 -15
  199. package/skills/void/docs/guide/jobs.md +3 -18
  200. package/skills/void/docs/guide/kv.md +5 -11
  201. package/skills/void/docs/guide/live.md +5 -56
  202. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
  203. package/skills/void/docs/guide/pages-routing/head.md +10 -10
  204. package/skills/void/docs/guide/pages-routing/islands.md +6 -36
  205. package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
  206. package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
  207. package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
  208. package/skills/void/docs/guide/pages-routing/overview.md +7 -17
  209. package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
  210. package/skills/void/docs/guide/platform/administration/access.md +1 -4
  211. package/skills/void/docs/guide/platform/administration/email.md +35 -8
  212. package/skills/void/docs/guide/platform/administration/operations.md +26 -4
  213. package/skills/void/docs/guide/platform/administration/plans.md +126 -0
  214. package/skills/void/docs/guide/platform/administration/projects.md +5 -2
  215. package/skills/void/docs/guide/platform/administration/zero-trust.md +189 -0
  216. package/skills/void/docs/guide/platform/development/local.md +2 -2
  217. package/skills/void/docs/guide/platform/development/runtime.md +3 -13
  218. package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
  219. package/skills/void/docs/guide/platform/installation/credentials.md +6 -4
  220. package/skills/void/docs/guide/platform/installation/domains.md +31 -3
  221. package/skills/void/docs/guide/platform/installation/first-deployment.md +6 -0
  222. package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
  223. package/skills/void/docs/guide/platform/installation/prerequisites.md +21 -16
  224. package/skills/void/docs/guide/platform/installation/setup.md +9 -5
  225. package/skills/void/docs/guide/platform/installation/uninstall.md +17 -2
  226. package/skills/void/docs/guide/platform-administration.md +2 -0
  227. package/skills/void/docs/guide/queues.md +7 -9
  228. package/skills/void/docs/guide/quickstart.md +38 -37
  229. package/skills/void/docs/guide/remote-dev.md +4 -9
  230. package/skills/void/docs/guide/sandboxes.md +78 -41
  231. package/skills/void/docs/guide/server-routing.md +9 -72
  232. package/skills/void/docs/guide/sse.md +4 -18
  233. package/skills/void/docs/guide/ssg.md +3 -15
  234. package/skills/void/docs/guide/ssr.md +14 -62
  235. package/skills/void/docs/guide/storage.md +9 -4
  236. package/skills/void/docs/guide/type-safety.md +3 -14
  237. package/skills/void/docs/guide/typed-fetch.md +3 -7
  238. package/skills/void/docs/guide/websockets.md +68 -40
  239. package/skills/void/docs/integrations/agents.md +3 -3
  240. package/skills/void/docs/integrations/cloudflare.md +85 -316
  241. package/skills/void/docs/integrations/frameworks/analog.md +5 -64
  242. package/skills/void/docs/integrations/frameworks/astro.md +4 -73
  243. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
  244. package/skills/void/docs/integrations/frameworks/overview.md +11 -54
  245. package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
  246. package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
  247. package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
  248. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
  249. package/skills/void/docs/reference/api/auth.md +156 -0
  250. package/skills/void/docs/reference/api/client.md +87 -0
  251. package/skills/void/docs/reference/api/database.md +95 -0
  252. package/skills/void/docs/reference/api/durable.md +46 -0
  253. package/skills/void/docs/reference/api/env.md +50 -0
  254. package/skills/void/docs/reference/api/handlers.md +254 -0
  255. package/skills/void/docs/reference/api/pages.md +241 -0
  256. package/skills/void/docs/reference/api/plugin.md +39 -0
  257. package/skills/void/docs/reference/api/resources.md +109 -0
  258. package/skills/void/docs/reference/api/rewrites.md +76 -0
  259. package/skills/void/docs/reference/api/types.md +92 -0
  260. package/skills/void/docs/reference/api.md +56 -1218
  261. package/skills/void/docs/reference/cli/auth.md +88 -0
  262. package/skills/void/docs/reference/cli/database.md +128 -0
  263. package/skills/void/docs/reference/cli/deploy.md +85 -0
  264. package/skills/void/docs/reference/cli/domains.md +41 -0
  265. package/skills/void/docs/reference/cli/email.md +129 -0
  266. package/skills/void/docs/reference/cli/generate.md +116 -0
  267. package/skills/void/docs/reference/cli/github.md +189 -0
  268. package/skills/void/docs/reference/cli/platform-config.md +92 -0
  269. package/skills/void/docs/reference/cli/platform-email.md +81 -0
  270. package/skills/void/docs/reference/cli/platform-installation.md +127 -0
  271. package/skills/void/docs/reference/cli/platform-operations.md +90 -0
  272. package/skills/void/docs/reference/cli/platform-users.md +89 -0
  273. package/skills/void/docs/reference/cli/platform-zero-trust.md +45 -0
  274. package/skills/void/docs/reference/cli/platform.md +70 -0
  275. package/skills/void/docs/reference/cli/project.md +214 -0
  276. package/skills/void/docs/reference/cli/secrets.md +76 -0
  277. package/skills/void/docs/reference/cli/setup.md +70 -0
  278. package/skills/void/docs/reference/cli.md +33 -1621
  279. package/skills/void/docs/reference/config.md +26 -32
  280. package/skills/void/docs/reference/resource-inference.md +3 -58
  281. package/skills/void/docs/reference/structure.md +14 -41
  282. package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
  283. package/dist/cli/cf-compat.mjs +0 -968
  284. package/dist/client-4cDVv7BO.mjs +0 -2
  285. package/dist/gen-Vnv2f65C.mjs +0 -2
  286. package/dist/help-DQMfeKMz.mjs +0 -2
  287. package/dist/login-DFQk7rbW.mjs +0 -2
  288. package/dist/migrate-TsHGBnDA.mjs +0 -2
  289. package/dist/plan-BEZ8VJW0.mjs +0 -256
  290. package/dist/plan-DpuOr14e.mjs +0 -2
  291. package/dist/prepare-BZXkjdNe.mjs +0 -2
  292. package/dist/validate-EKmJWxmy.mjs +0 -2
  293. /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
package/dist/index.mjs CHANGED
@@ -1,34 +1,37 @@
1
1
  import { n as __toESM } from "./rolldown-runtime-DXIUcv95.mjs";
2
2
  import { a as join, l as relative, n as dirname, u as resolve } from "./dist-BVqXeR_h.mjs";
3
- import { d as require_picocolors } from "./output-CCH48AMM.mjs";
4
- import { G as resolveWorkerDirName, St as hasDocumentRoutes, V as resolveDistDir, ct as prerenderPagesNode, dt as collectRevalidate, ft as hasRevalidate, mt as SEND_EMAIL_BINDING, ot as generateQueueResolverSource, pt as scanDurableObjectModules, st as prerenderPages, ut as collectPages, wt as resolveAssetRoutingPolicy, xt as hasApiRoutes } from "./deploy-WaAQez1O.mjs";
5
- import { i as resolveProjectPaths, n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-GgcMozYz.mjs";
6
- import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-DPByhVck.mjs";
3
+ import { t as require_picocolors } from "./picocolors-BTps1_gs.mjs";
4
+ import { d as walk, n as FRAMEWORK_SCAN_DIRS, p as applyBindingOverrides, t as DEFAULT_SCAN_DIRS, u as inferBindingsFromSource } from "./plugin-inference-CXWnn79A.mjs";
5
+ import { n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-GgcMozYz.mjs";
6
+ import { n as loadVoidAuthConfig } from "./config-DPByhVck.mjs";
7
+ import { d as isNodeTarget, m as readConfig, u as getDatabaseDialect } from "./config-Br_JZD6u.mjs";
8
+ import { i as isMemberExpression, n as isIdentifier, r as isLiteral } from "./ast-CPGPjb0V.mjs";
9
+ import { t as isRouteEnabledForEnvironment } from "./parse-filename-CUbj-1MP.mjs";
10
+ import { r as scanQueuesSync, s as scanJobsSync, t as analyzeApplicationSync } from "./application-analysis-BVsVqc11.mjs";
11
+ import { a as validateSsrEntries, n as SSR_SERVER_ENTRY_RELATIVE_PATHS, o as validateSsrEntry, t as SSR_CLIENT_ENTRY_RELATIVE_PATHS } from "./entry-CF5wvH4w.mjs";
12
+ import { r as hasEmailHandlers } from "./email--tEtMoj_.mjs";
13
+ import { i as resolveLayoutIds } from "./scan-C7okrLyM.mjs";
14
+ import { a as hasSandboxSqliteMigration, c as resolveSandboxConfig, i as assertSandboxNamespaceConfig, l as sandboxContainerConfig, n as DEFAULT_SANDBOX_CLASS_NAME, r as SANDBOX_MIGRATION_TAG } from "./config-C_XRIPx2.mjs";
15
+ import { Ct as hasDocumentRoutes, G as resolveWorkerDirName, St as hasApiRoutes, Tt as resolveAssetRoutingPolicy, V as resolveDistDir, ct as selectNativeVersionMetadataBinding, ft as collectPages, ht as SEND_EMAIL_BINDING, lt as prerenderPages, mt as hasRevalidate, ot as generateQueueResolverSource, pt as collectRevalidate, st as CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV, ut as prerenderPagesNode } from "./deploy-DzAIwqNU.mjs";
7
16
  import { r as scopedAccessCredentials } from "./cf-access-DRsQRe6k.mjs";
8
- import { a as getApiUrl, c as getToken, o as getProxyUrl, u as isStagingMode } from "./auth-DLNN0D3Z.mjs";
17
+ import { a as getApiUrl, c as getToken, o as getProxyUrl, u as isStagingMode } from "./auth-CSkdO2Bb.mjs";
9
18
  import { r as ensurePlatformProxyAccess } from "./cf-access-P0iZnu0q.mjs";
10
19
  import { i as readDeploymentPlatform, o as readProjectConfig } from "./project-C0Fqu05O.mjs";
11
- import { d as isNodeTarget, h as resolveBindingNames, m as readConfig, u as getDatabaseDialect } from "./config-CafTW6Cz.mjs";
12
- import { C as readWranglerWebSocketTombstones, D as syncWranglerWebSockets, E as syncWranglerDurableObjects, L as materializeCloudflareConfig, M as isSandboxEnabled, P as resolveSandboxConfig, T as syncWranglerBindings, V as stashCloudflareDeployPointer, a as LIVE_MIGRATION_TAG, d as ensureWranglerNodejsAlsFlag, g as readExistingLiveBindingConfig, h as normalizeWranglerCompatibilityFlags, j as SANDBOX_MIGRATION_TAG, l as ensureWranglerCompat, m as nextDurableObjectMigrationTag, p as hasDurableObjectSqliteMigration, u as ensureWranglerCompatibilityDate, w as resolveLiveBindingConfig, y as readWranglerCompat, z as restoreCloudflarePreviewPointer } from "./wrangler-BymcxrRa.mjs";
20
+ import { a as restoreCloudflarePreviewPointer, r as materializeCloudflareConfig, s as stashCloudflareDeployPointer } from "./cloudflare-config-Bktvwtpf.mjs";
21
+ import { D as syncWranglerDurableObjects, E as syncWranglerBindings, O as syncWranglerWebSockets, T as resolveLiveBindingConfig, _ as readExistingLiveBindingConfig, a as LIVE_MIGRATION_TAG, b as readWranglerCompat, d as ensureWranglerCompatibilityDate, f as ensureWranglerNodejsAlsFlag, g as normalizeWranglerCompatibilityFlags, h as nextDurableObjectMigrationTag, m as hasDurableObjectSqliteMigration, p as findBindingNameOwner, u as ensureWranglerCompat, w as readWranglerWebSocketTombstones } from "./wrangler-7K-bW_DL.mjs";
13
22
  import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-ChfPKsVd.mjs";
14
- import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-BOg_velo.mjs";
23
+ import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-DWi2IXWx.mjs";
15
24
  import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-B8GeM0RM.mjs";
16
- import { i as isMemberExpression, n as isIdentifier, r as isLiteral } from "./ast-CPGPjb0V.mjs";
17
- import { i as resolveLayoutIds } from "./scan-4tfN-PSn.mjs";
18
- import { a as scanJobsSync, i as scanQueuesSync, n as scanRoutePatternsSync, r as scanRoutes, t as scanMiddlewareSync } from "./scan-ClYmX3sa.mjs";
19
- import { c as inferBindingsFromSource, i as inferProjectBindings, l as walk, n as FRAMEWORK_SCAN_DIRS, r as detectFramework, s as scanWebSocketRoutesSync, t as DEFAULT_SCAN_DIRS } from "./plugin-inference-BMfKRSqE.mjs";
20
- import { n as writeLocalD1PersistState, t as resolveLocalD1Target } from "./local-d1-CC8sKFGu.mjs";
25
+ import { n as writeLocalD1PersistState, t as resolveLocalD1Target } from "./local-d1-2CMnpuW_.mjs";
21
26
  import { n as parseDotenvFile } from "./dotenv-VQxupEUv.mjs";
22
27
  import { i as generateDbDts, n as generateQueueTypes, r as DRIZZLE_OPERATORS, t as generateRouteTypes } from "./route-types-Clm4WD0B.mjs";
23
28
  import { t as discoverSchema } from "./discover-BcPPiF1o.mjs";
24
29
  import { _ as parseCapturedMessage, a as DEV_INBOX_ENV_VAR, c as DEV_INBOX_TOKEN_ENV_VAR, f as clearDevBuffer, g as listDevMessages, l as DEV_INBOX_TOKEN_HEADER, m as findDevMessage, n as DEV_INBOX_ACK_VALUE, o as DEV_INBOX_MAX_CAPTURE_BYTES, s as DEV_INBOX_PREFIX, t as DEV_INBOX_ACK_HEADER, u as DEV_INBOX_TOKEN_QUERY, v as pushToDevBuffer, y as registerEmailSink } from "./dev-inbox-P0u4tM8Y.mjs";
25
- import { t as MagicString } from "./dist-BR1quN_w.mjs";
30
+ import { t as MagicString } from "./dist-AoCzRTJE.mjs";
26
31
  import { n as findEnvFileForPaths, r as generateEnvTypes, t as findEnvFile } from "./env-types-C2_bIk_b.mjs";
27
- import { y as loadUserEnvFile } from "./env-validation-BB4GkLxn.mjs";
32
+ import { y as loadUserEnvFile } from "./env-validation-BPn7vk-V.mjs";
28
33
  import { a as loadLocalEnv, o as resolveRemoteMode, r as findLegacyEnvFiles, s as stripInternalEnvKeys, t as CLIENT_ENV_PREFIX$2 } from "./env-_v349JBd.mjs";
29
- import { t as isRouteEnabledForEnvironment } from "./parse-filename-DioPHiR9.mjs";
30
- import { a as validateSsrEntries, n as SSR_SERVER_ENTRY_RELATIVE_PATHS, o as validateSsrEntry, t as SSR_CLIENT_ENTRY_RELATIVE_PATHS } from "./entry-CF5wvH4w.mjs";
31
- import { a as scanEmailHandlersSync, r as hasEmailHandlers } from "./email--tEtMoj_.mjs";
34
+ import { n as completeApplicationAnalysis } from "./application-routing-B7QEjqSR.mjs";
32
35
  import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-Beb2Am5S.mjs";
33
36
  import { n as INTERNAL_BINDING_PREFIXES, t as INTERNAL_BINDING_EXACT_NAMES } from "./env-raw-Cx8ElDdj.mjs";
34
37
  import { n as defer } from "./defer-YsYDUoii.mjs";
@@ -40,9 +43,66 @@ import { appendSqliteClassMigration } from "@void/deploy-core";
40
43
  import { normalizePath, parseSync } from "vite";
41
44
  import { timingSafeEqual } from "node:crypto";
42
45
  import { homedir } from "node:os";
46
+ import { isDeepStrictEqual } from "node:util";
43
47
  import { init, parse } from "es-module-lexer";
44
- //#region src/pages/dev-css-assets.ts
48
+ import { compilePattern } from "@void/edge";
49
+ //#region src/cloudflare-durable-patch.ts
45
50
  var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
51
+ function entries(value, label) {
52
+ if (value === void 0) return [];
53
+ if (!Array.isArray(value) || value.some((entry) => !entry || typeof entry !== "object" || Array.isArray(entry))) throw new Error(`Cloudflare ${label} configuration must be an array of objects.`);
54
+ return value;
55
+ }
56
+ function byIdentity(rows, field, label, unique = false) {
57
+ const map = /* @__PURE__ */ new Map();
58
+ for (const row of rows) {
59
+ const id = row[field];
60
+ if (typeof id !== "string" || !id) throw new Error(`Cloudflare ${label} is missing its ${field}.`);
61
+ const previous = map.get(id);
62
+ if (previous && unique) throw new Error(`Cloudflare ${label} ${JSON.stringify(id)} is configured more than once.`);
63
+ if (previous && !isDeepStrictEqual(previous, row)) throw new Error(`Cloudflare ${label} ${JSON.stringify(id)} has conflicting configuration.`);
64
+ if (!previous) map.set(id, row);
65
+ }
66
+ return map;
67
+ }
68
+ /** Finish cumulative feature planning without repeating the Cloudflare plugin's array fallback. */
69
+ function finalizeDurableObjectPatch(resolved, patch, generatedLocalBindings) {
70
+ const baselineObjects = resolved.durable_objects;
71
+ const pendingObjects = patch.durable_objects;
72
+ const baselineBindings = byIdentity(entries(baselineObjects?.bindings, "Durable Object bindings"), "name", "Durable Object binding", true);
73
+ const pendingBindings = byIdentity(entries(pendingObjects?.bindings, "Durable Object bindings"), "name", "Durable Object binding");
74
+ const history = entries(resolved.migrations, "Durable Object migrations");
75
+ const baselineMigrations = byIdentity(history, "tag", "Durable Object migration", true);
76
+ for (const local of generatedLocalBindings) for (const map of [baselineBindings, pendingBindings]) {
77
+ const existing = map.get(local.name);
78
+ if (existing && (existing.class_name !== local.class_name || existing.script_name !== void 0 || existing.environment !== void 0)) throw new Error(`Cloudflare generated Durable Object binding ${JSON.stringify(local.name)} conflicts with its configured identity.`);
79
+ }
80
+ if (pendingObjects?.bindings !== void 0) {
81
+ const additions = [];
82
+ for (const [name, row] of pendingBindings) {
83
+ const existing = baselineBindings.get(name);
84
+ if (existing && !isDeepStrictEqual(existing, row)) throw new Error(`Cloudflare Durable Object binding ${JSON.stringify(name)} has conflicting configuration.`);
85
+ if (!existing) additions.push(row);
86
+ }
87
+ patch.durable_objects = {
88
+ ...pendingObjects,
89
+ bindings: additions
90
+ };
91
+ }
92
+ if (patch.migrations !== void 0) {
93
+ const pending = byIdentity(entries(patch.migrations, "Durable Object migrations"), "tag", "Durable Object migration");
94
+ const additions = [];
95
+ for (const [tag, row] of pending) {
96
+ const previous = baselineMigrations.get(tag);
97
+ if (previous && !isDeepStrictEqual(previous, row)) throw new Error(`Cloudflare Durable Object migration ${JSON.stringify(tag)} has conflicting configuration.`);
98
+ if (!previous) additions.push(row);
99
+ }
100
+ patch.migrations = [...history, ...additions];
101
+ resolved.migrations = [];
102
+ }
103
+ }
104
+ //#endregion
105
+ //#region src/pages/dev-css-assets.ts
46
106
  const DEV_CSS_ASSET_MODULE_ID = "virtual:void-pages-dev-assets";
47
107
  const DEV_CSS_ASSET_ENDPOINT = "/__void/dev/pages-css";
48
108
  const DEV_CSS_ASSET_GUARD_HEADER = "X-Void-Dev-Asset-Request";
@@ -723,7 +783,7 @@ function createPrimaryDb(d1) {
723
783
  const migrationsDir = paths.migrationsDir;
724
784
  if (!(existsSync(migrationsDir) && readdirSync(migrationsDir).some((f) => f.endsWith(".sql")))) {
725
785
  if (dialect === "sqlite") {
726
- const { getApplicationTables, getMiniflareDatabasePath } = await import("./runner-B8wXwWlo.mjs");
786
+ const { getApplicationTables, getMiniflareDatabasePath } = await import("./runner-CXA9Fh8h.mjs");
727
787
  if ((await getApplicationTables(getMiniflareDatabasePath(options.localD1PersistRoot ?? join(root, ".void"), options.localD1DatabaseId ?? "local")).catch(() => [])).length > 0) return;
728
788
  }
729
789
  voidWarn(`Schema found but no migrations in ${paths.sourceRelative("db/migrations")}/.\n \`void db push\` syncs the schema to your local DB without creating migration files.
@@ -2005,7 +2065,7 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
2005
2065
  return;
2006
2066
  }
2007
2067
  const { collectMigrations } = await import("./collect-DLyFDiKW.mjs");
2008
- const { validateMigrations } = await import("./validate-EKmJWxmy.mjs");
2068
+ const { validateMigrations } = await import("./validate-Dq_L3s0S.mjs");
2009
2069
  const allMigrations = collectMigrations(migrationsDir);
2010
2070
  const appliedNames = dialect === "mysql" ? await import("./runner-mysql-CEG5JozK.mjs").then((runner) => runner.getMySqlAppliedMigrations(url)) : await import("./runner-pg-Bh4AgZdj.mjs").then((runner) => runner.getPgAppliedMigrations(url));
2011
2071
  const appliedSet = new Set(appliedNames);
@@ -2018,9 +2078,9 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
2018
2078
  const applied = dialect === "mysql" ? await import("./runner-mysql-CEG5JozK.mjs").then((runner) => runner.runMySqlMigrations(migrationsDir, url)) : await import("./runner-pg-Bh4AgZdj.mjs").then((runner) => runner.runPgMigrations(migrationsDir, url));
2019
2079
  if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
2020
2080
  } else if (hasSqlMigrations) {
2021
- const { runMigrations, getMiniflareDatabasePath, getAppliedMigrations } = await import("./runner-B8wXwWlo.mjs");
2081
+ const { runMigrations, getMiniflareDatabasePath, getAppliedMigrations } = await import("./runner-CXA9Fh8h.mjs");
2022
2082
  const { collectMigrations } = await import("./collect-DLyFDiKW.mjs");
2023
- const { validateMigrations } = await import("./validate-EKmJWxmy.mjs");
2083
+ const { validateMigrations } = await import("./validate-Dq_L3s0S.mjs");
2024
2084
  const dbPath = getMiniflareDatabasePath(persistRoot, databaseId);
2025
2085
  const allMigrations = collectMigrations(migrationsDir);
2026
2086
  const appliedRows = await getAppliedMigrations(dbPath);
@@ -2035,7 +2095,7 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
2035
2095
  if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
2036
2096
  }
2037
2097
  if (auth?.enabled) {
2038
- const { runLocalVoidAuthMigrations } = await import("./node-BM43oz4G.mjs");
2098
+ const { runLocalVoidAuthMigrations } = await import("./node-BkyRWRx8.mjs");
2039
2099
  await runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, auth.configPath);
2040
2100
  voidLog("Applied Better Auth migrations");
2041
2101
  }
@@ -2326,569 +2386,33 @@ function restartPlugin() {
2326
2386
  };
2327
2387
  }
2328
2388
  //#endregion
2389
+ //#region src/client-asset-manifest.ts
2390
+ /** Attach cache provenance to the existing manifest without changing its entry inventory. */
2391
+ function stampClientAssetCachePolicy(bundle, manifestPath, headerRules = []) {
2392
+ const asset = bundle[manifestPath];
2393
+ if (asset?.type !== "asset") return;
2394
+ const fingerprinted = /* @__PURE__ */ new Set();
2395
+ const authoredCachePatterns = headerRules.filter((rule) => rule.headers.some(([name]) => name.toLowerCase() === "cache-control")).map((rule) => compilePattern(rule.pattern).regex);
2396
+ for (const item of Object.values(bundle)) if (item.type === "chunk" && typeof item.preliminaryFileName === "string" && item.preliminaryFileName !== item.fileName) {
2397
+ if (!authoredCachePatterns.some((pattern) => pattern.test("/" + item.fileName))) fingerprinted.add(item.fileName);
2398
+ }
2399
+ const manifest = JSON.parse(String(asset.source));
2400
+ for (const entry of Object.values(manifest)) if (entry.file && fingerprinted.has(entry.file)) entry.immutableFiles = [entry.file];
2401
+ else delete entry.immutableFiles;
2402
+ asset.source = JSON.stringify(manifest, null, 2);
2403
+ }
2404
+ //#endregion
2329
2405
  //#region src/router/compile.ts
2330
- /**
2331
- * Script tag injected into dev HTML to load the binding-hint virtual module.
2332
- * The virtual module (served by restartPlugin) listens for `void:new-binding`
2333
- * HMR events and shows a toast with a click-to-restart action.
2334
- */
2335
- const BINDING_HINT_SCRIPT = `<script type="module" src="/@id/virtual:void/binding-hint"><\/script>`;
2336
- const DEFAULT_ERROR_PAGE_FONT_STACK = "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif";
2337
- const EDGE_MODULE_PATH = fileURLToPath(import.meta.resolve("@void/edge"));
2406
+ const ROUTE_URL_PATH = fileURLToPath(import.meta.resolve("#self/runtime/route-url"));
2407
+ const ROUTING_RUNTIME_PATH = fileURLToPath(import.meta.resolve("#self/runtime/routing"));
2338
2408
  function pushDefaultErrorPageHelpers(lines, options) {
2339
- const dev = options.dev === true;
2340
- lines.push(`const __VOID_ERROR_PAGE_FONT_STACK = ${JSON.stringify(DEFAULT_ERROR_PAGE_FONT_STACK)};`);
2341
- lines.push(`const __VOID_DEV = ${JSON.stringify(dev)};`);
2342
- lines.push(`const __VOID_PROJECT_ROOT = ${JSON.stringify(options.projectRoot)};`);
2343
- lines.push(`const __VOID_HOME_DIR = ${JSON.stringify(options.homeDir)};`);
2344
- lines.push(`function __voidEscapeHtml(value) {`);
2345
- lines.push(` return String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");`);
2346
- lines.push(`}`);
2347
- lines.push("");
2348
- lines.push(`function __voidShouldServeHtmlErrorPage(request) {`);
2349
- lines.push(` if (request.method !== "GET" && request.method !== "HEAD") return false;`);
2350
- lines.push(` const url = new URL(request.url);`);
2351
- lines.push(` if (url.pathname === "/api" || url.pathname.startsWith("/api/")) return false;`);
2352
- lines.push(` if (/\\/[^/]+\\.[^/]+$/.test(url.pathname)) return false;`);
2353
- lines.push(` const destination = request.headers.get("sec-fetch-dest");`);
2354
- lines.push(` if (destination && destination !== "document" && destination !== "empty") return false;`);
2355
- lines.push(` const accept = request.headers.get("accept");`);
2356
- lines.push(` return !accept || accept.includes("text/html") || accept.includes("*/*");`);
2357
- lines.push(`}`);
2358
- lines.push("");
2359
- lines.push(`function __voidNormalizeFsPath(value) {`);
2360
- lines.push(` return typeof value === "string" ? value.replaceAll("\\\\", "/") : "";`);
2361
- lines.push(`}`);
2362
- lines.push("");
2363
- lines.push(`function __voidIsAbsolutePath(value) {`);
2364
- lines.push(` return value.startsWith("/") || /^[A-Za-z]:\\//.test(value);`);
2365
- lines.push(`}`);
2366
- lines.push("");
2367
- lines.push(`function __voidDisplayPath(value) {`);
2368
- lines.push(` const path = __voidNormalizeFsPath(value);`);
2369
- lines.push(` const homeDir = __voidNormalizeFsPath(__VOID_HOME_DIR);`);
2370
- lines.push(` const projectRoot = __voidNormalizeFsPath(__VOID_PROJECT_ROOT);`);
2371
- lines.push(` if (!path) return "";`);
2372
- lines.push(` if (projectRoot && (path === projectRoot || path.startsWith(projectRoot + "/"))) {`);
2373
- lines.push(` const suffix = path.slice(projectRoot.length).replace(/^\\/?/, "");`);
2374
- lines.push(` return suffix ? "./" + suffix : "./";`);
2375
- lines.push(` }`);
2376
- lines.push(` if (homeDir && (path === homeDir || path.startsWith(homeDir + "/"))) {`);
2377
- lines.push(` const suffix = path.slice(homeDir.length).replace(/^\\/?/, "");`);
2378
- lines.push(` return suffix ? "~/" + suffix : "~/";`);
2379
- lines.push(` }`);
2380
- lines.push(` return path;`);
2381
- lines.push(`}`);
2382
- lines.push("");
2383
- lines.push(`function __voidEditorHref(value, line, column) {`);
2384
- lines.push(` const path = __voidNormalizeFsPath(value);`);
2385
- lines.push(` if (!__voidIsAbsolutePath(path)) return "";`);
2386
- lines.push(` return "vscode://file/" + encodeURI(path).replaceAll("#", "%23").replaceAll("?", "%3F") + ":" + String(line) + ":" + String(column);`);
2387
- lines.push(`}`);
2388
- lines.push("");
2389
- lines.push(`function __voidCreateStackFrame(functionName, file, line, column, raw) {`);
2390
- lines.push(` const normalizedFile = __voidNormalizeFsPath(file);`);
2391
- lines.push(` const lineNumber = Number(line);`);
2392
- lines.push(` const columnNumber = Number(column);`);
2393
- lines.push(` if (!normalizedFile || !Number.isFinite(lineNumber) || lineNumber <= 0) return null;`);
2394
- lines.push(` const safeColumn = Number.isFinite(columnNumber) && columnNumber > 0 ? columnNumber : 1;`);
2395
- lines.push(` return {`);
2396
- lines.push(` functionName: functionName || "",`);
2397
- lines.push(` file: normalizedFile,`);
2398
- lines.push(` line: lineNumber,`);
2399
- lines.push(` column: safeColumn,`);
2400
- lines.push(` displayPath: __voidDisplayPath(normalizedFile),`);
2401
- lines.push(` href: __voidEditorHref(normalizedFile, lineNumber, safeColumn),`);
2402
- lines.push(` raw: raw || "",`);
2403
- lines.push(` };`);
2404
- lines.push(`}`);
2405
- lines.push("");
2406
- lines.push(`function __voidParseFrameLocation(value) {`);
2407
- lines.push(` const match = value.match(/^(.*):(\\d+):(\\d+)$/);`);
2408
- lines.push(` if (!match) return null;`);
2409
- lines.push(` return __voidCreateStackFrame("", match[1], Number(match[2]), Number(match[3]), value);`);
2410
- lines.push(`}`);
2411
- lines.push("");
2412
- lines.push(`function __voidParseStackFrames(stack) {`);
2413
- lines.push(` if (!stack) return [];`);
2414
- lines.push(` const frames = [];`);
2415
- lines.push(` for (const rawLine of stack.split(/\\n+/)) {`);
2416
- lines.push(` const line = rawLine.trim();`);
2417
- lines.push(` if (!line) continue;`);
2418
- lines.push(` let frame = null;`);
2419
- lines.push(` let match = line.match(/^at\\s+(?:async\\s+)?(.+?)\\s+\\((.+)\\)$/);`);
2420
- lines.push(` if (match) {`);
2421
- lines.push(` const location = __voidParseFrameLocation(match[2]);`);
2422
- lines.push(` frame = location ? { ...location, functionName: match[1] } : null;`);
2423
- lines.push(` } else {`);
2424
- lines.push(` match = line.match(/^at\\s+(.+)$/);`);
2425
- lines.push(` if (match) {`);
2426
- lines.push(` frame = __voidParseFrameLocation(match[1]);`);
2427
- lines.push(` } else {`);
2428
- lines.push(` match = line.match(/^(.*?)@(.+)$/);`);
2429
- lines.push(` if (match) {`);
2430
- lines.push(` const location = __voidParseFrameLocation(match[2]);`);
2431
- lines.push(` frame = location ? { ...location, functionName: match[1] } : null;`);
2432
- lines.push(` }`);
2433
- lines.push(` }`);
2434
- lines.push(` }`);
2435
- lines.push(` if (frame) frames.push({ ...frame, raw: line });`);
2436
- lines.push(` }`);
2437
- lines.push(` return frames;`);
2438
- lines.push(`}`);
2439
- lines.push("");
2440
- lines.push(`function __voidGetStackFrames(error) {`);
2441
- lines.push(` if (!(error instanceof Error)) return [];`);
2442
- lines.push(` if (!error.stack && typeof Error.captureStackTrace === "function") {`);
2443
- lines.push(` try {`);
2444
- lines.push(` Error.captureStackTrace(error, __voidGetStackFrames);`);
2445
- lines.push(` } catch {`);
2446
- lines.push(` // Ignore runtimes that reject captureStackTrace on thrown errors.`);
2447
- lines.push(` }`);
2448
- lines.push(` }`);
2449
- lines.push(` const originalPrepareStackTrace = Error.prepareStackTrace;`);
2450
- lines.push(` try {`);
2451
- lines.push(` Error.prepareStackTrace = (_, callSites) => callSites;`);
2452
- lines.push(` const structured = error.stack;`);
2453
- lines.push(` if (Array.isArray(structured)) {`);
2454
- lines.push(` const frames = [];`);
2455
- lines.push(` for (const callSite of structured) {`);
2456
- lines.push(` try {`);
2457
- lines.push(` const fileName = callSite.getFileName?.() || callSite.getScriptNameOrSourceURL?.();`);
2458
- lines.push(` const line = callSite.getLineNumber?.();`);
2459
- lines.push(` const column = callSite.getColumnNumber?.();`);
2460
- lines.push(` const functionName = callSite.getFunctionName?.() || callSite.getMethodName?.() || "";`);
2461
- lines.push(` const frame = __voidCreateStackFrame(functionName, fileName || "", line, column, String(callSite));`);
2462
- lines.push(` if (frame) frames.push(frame);`);
2463
- lines.push(` } catch {`);
2464
- lines.push(` // Ignore malformed CallSite entries and continue rendering.`);
2465
- lines.push(` }`);
2466
- lines.push(` }`);
2467
- lines.push(` if (frames.length > 0) return frames;`);
2468
- lines.push(` }`);
2469
- lines.push(` } catch {`);
2470
- lines.push(` // Fall through to string parsing.`);
2471
- lines.push(` } finally {`);
2472
- lines.push(` Error.prepareStackTrace = originalPrepareStackTrace;`);
2473
- lines.push(` }`);
2474
- lines.push(` return __voidParseStackFrames(typeof error.stack === "string" ? error.stack : "");`);
2475
- lines.push(`}`);
2476
- lines.push("");
2477
- lines.push(`function __voidDescribeThrownValue(value) {`);
2478
- lines.push(` if (value instanceof Error) {`);
2479
- lines.push(` return {`);
2480
- lines.push(` name: value.name || "Error",`);
2481
- lines.push(` message: value.message || "",`);
2482
- lines.push(` stack: typeof value.stack === "string" ? value.stack : "",`);
2483
- lines.push(` frames: __voidGetStackFrames(value),`);
2484
- lines.push(` };`);
2485
- lines.push(` }`);
2486
- lines.push(` if (typeof value === "string") {`);
2487
- lines.push(` return { name: "Thrown value", message: value, stack: "", frames: [] };`);
2488
- lines.push(` }`);
2489
- lines.push(` let message = "";`);
2490
- lines.push(` try {`);
2491
- lines.push(` if (typeof value === "object" && value !== null) {`);
2492
- lines.push(` message = JSON.stringify(value, null, 2) ?? String(value);`);
2493
- lines.push(` } else {`);
2494
- lines.push(` message = String(value);`);
2495
- lines.push(` }`);
2496
- lines.push(` } catch {`);
2497
- lines.push(` message = String(value);`);
2498
- lines.push(` }`);
2499
- lines.push(` return { name: "Thrown value", message, stack: "", frames: [] };`);
2500
- lines.push(`}`);
2501
- lines.push("");
2502
- lines.push(`function __voidRenderStack(entry) {`);
2503
- lines.push(` if (Array.isArray(entry.frames) && entry.frames.length > 0) {`);
2504
- lines.push(` const items = entry.frames.map((frame) => {`);
2505
- lines.push(` const name = frame.functionName || "(anonymous)";`);
2506
- lines.push(` const location = frame.displayPath + ":" + frame.line + ":" + frame.column;`);
2507
- lines.push(` const body = \`<span class="__void-error-frame-function">\${__voidEscapeHtml(name)}</span><span class="__void-error-frame-location">\${__voidEscapeHtml(location)}</span>\`;`);
2508
- lines.push(` if (frame.href) {`);
2509
- lines.push(` return \`<a class="__void-error-frame" href="\${__voidEscapeHtml(frame.href)}">\${body}</a>\`;`);
2510
- lines.push(` }`);
2511
- lines.push(` return \`<div class="__void-error-frame is-static">\${body}</div>\`;`);
2512
- lines.push(` }).join("");`);
2513
- lines.push(` return \`<div class="__void-error-stack"><div class="__void-error-stack-label">Stack trace</div><div class="__void-error-frames">\${items}</div></div>\`;`);
2514
- lines.push(` }`);
2515
- lines.push(` if (!entry.stack) return "";`);
2516
- lines.push(` return \`<div class="__void-error-stack"><div class="__void-error-stack-label">Stack trace</div><pre>\${__voidEscapeHtml(entry.stack)}</pre></div>\`;`);
2517
- lines.push(`}`);
2518
- lines.push("");
2519
- lines.push(`function __voidCollectErrorChain(error) {`);
2520
- lines.push(` const chain = [];`);
2521
- lines.push(` const seen = new Set();`);
2522
- lines.push(` let current = error;`);
2523
- lines.push(` let depth = 0;`);
2524
- lines.push(` while (current != null && depth < 8 && !seen.has(current)) {`);
2525
- lines.push(` seen.add(current);`);
2526
- lines.push(` const entry = __voidDescribeThrownValue(current);`);
2527
- lines.push(` chain.push({`);
2528
- lines.push(` label: depth === 0 ? "Error" : "Cause " + depth,`);
2529
- lines.push(` ...entry,`);
2530
- lines.push(` });`);
2531
- lines.push(` current = current instanceof Error ? current.cause : undefined;`);
2532
- lines.push(` depth += 1;`);
2533
- lines.push(` }`);
2534
- lines.push(` if (current != null) {`);
2535
- lines.push(` chain.push({`);
2536
- lines.push(` label: "Cause " + depth,`);
2537
- lines.push(` name: "Truncated",`);
2538
- lines.push(` message: "Additional nested causes were omitted.",`);
2539
- lines.push(` stack: "",`);
2540
- lines.push(` frames: [],`);
2541
- lines.push(` });`);
2542
- lines.push(` }`);
2543
- lines.push(` if (chain.length === 0) {`);
2544
- lines.push(` chain.push({`);
2545
- lines.push(` label: "Error",`);
2546
- lines.push(` name: "Unknown error",`);
2547
- lines.push(` message: "No error details were available.",`);
2548
- lines.push(` stack: "",`);
2549
- lines.push(` frames: [],`);
2550
- lines.push(` });`);
2551
- lines.push(` }`);
2552
- lines.push(` return chain;`);
2553
- lines.push(`}`);
2554
- lines.push("");
2555
- lines.push(`function __voidRenderDevErrorOverlay(request, status, title, error) {`);
2556
- lines.push(` const chain = __voidCollectErrorChain(error);`);
2557
- lines.push(` const errorCountLabel = chain.length + (chain.length === 1 ? " Error" : " Errors");`);
2558
- lines.push(` const sections = chain.map((entry, index) => {`);
2559
- lines.push(` const heading = entry.name || (index === 0 ? title : "Cause");`);
2560
- lines.push(` const message = entry.message || title;`);
2561
- lines.push(` const stack = __voidRenderStack(entry);`);
2562
- lines.push(` if (index === 0) {`);
2563
- lines.push(` return \`<section class="__void-error-section is-root"><p class="__void-error-message">\${__voidEscapeHtml(message)}</p>\${stack}</section>\`;`);
2564
- lines.push(` }`);
2565
- lines.push(` return \`<section class="__void-error-section"><div class="__void-error-kicker">\${__voidEscapeHtml(entry.label)}</div><h2>\${__voidEscapeHtml(heading)}</h2><p>\${__voidEscapeHtml(message)}</p>\${stack}</section>\`;`);
2566
- lines.push(` }).join("");`);
2567
- lines.push(` return \`<style>`);
2568
- lines.push(` .__void-error-overlay {`);
2569
- lines.push(` position: fixed;`);
2570
- lines.push(` inset: 0;`);
2571
- lines.push(` z-index: 2147483647;`);
2572
- lines.push(` pointer-events: none;`);
2573
- lines.push(` font-family: \${__VOID_ERROR_PAGE_FONT_STACK};`);
2574
- lines.push(` color: #f5f5f5;`);
2575
- lines.push(` }`);
2576
- lines.push(` .__void-error-backdrop {`);
2577
- lines.push(` position: absolute;`);
2578
- lines.push(` inset: 0;`);
2579
- lines.push(` background: rgba(10, 10, 10, 0.52);`);
2580
- lines.push(` backdrop-filter: blur(4px);`);
2581
- lines.push(` transition: opacity 180ms ease;`);
2582
- lines.push(` }`);
2583
- lines.push(` .__void-error-panel {`);
2584
- lines.push(` position: absolute;`);
2585
- lines.push(` inset: auto auto 24px 24px;`);
2586
- lines.push(` inline-size: min(760px, calc(100vw - 48px));`);
2587
- lines.push(` max-block-size: min(80dvh, 920px);`);
2588
- lines.push(` overflow: auto;`);
2589
- lines.push(` pointer-events: auto;`);
2590
- lines.push(` border-radius: 32px;`);
2591
- lines.push(` corner-shape: squircle;`);
2592
- lines.push(` border: 1px solid rgba(255, 255, 255, 0.14);`);
2593
- lines.push(` background: linear-gradient(180deg, rgba(24, 24, 27, 0.98), rgba(9, 9, 11, 0.98));`);
2594
- lines.push(` box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);`);
2595
- lines.push(` padding: 12px 16px;`);
2596
- lines.push(` transition: transform 180ms ease, opacity 180ms ease;`);
2597
- lines.push(` transform-origin: bottom left;`);
2598
- lines.push(` }`);
2599
- lines.push(` .__void-error-close {`);
2600
- lines.push(` position: absolute;`);
2601
- lines.push(` inset: 12px 12px auto auto;`);
2602
- lines.push(` inline-size: 36px;`);
2603
- lines.push(` block-size: 36px;`);
2604
- lines.push(` border: 0;`);
2605
- lines.push(` border-radius: 999px;`);
2606
- lines.push(` background: rgba(255, 255, 255, 0.08);`);
2607
- lines.push(` color: #fafafa;`);
2608
- lines.push(` cursor: pointer;`);
2609
- lines.push(` display: grid;`);
2610
- lines.push(` place-items: center;`);
2611
- lines.push(` padding: 0;`);
2612
- lines.push(` }`);
2613
- lines.push(` .__void-error-close:hover {`);
2614
- lines.push(` background: rgba(255, 255, 255, 0.14);`);
2615
- lines.push(` }`);
2616
- lines.push(` .__void-error-close svg {`);
2617
- lines.push(` inline-size: 16px;`);
2618
- lines.push(` block-size: 16px;`);
2619
- lines.push(` display: block;`);
2620
- lines.push(` }`);
2621
- lines.push(` .__void-error-minimized {`);
2622
- lines.push(` position: absolute;`);
2623
- lines.push(` inset: auto auto 24px 24px;`);
2624
- lines.push(` pointer-events: none;`);
2625
- lines.push(` opacity: 0;`);
2626
- lines.push(` transform: scale(0.92);`);
2627
- lines.push(` transform-origin: bottom left;`);
2628
- lines.push(` border: 1px solid rgba(248, 113, 113, 0.35);`);
2629
- lines.push(` border-radius: 32px;`);
2630
- lines.push(` corner-shape: squircle;`);
2631
- lines.push(` background: rgba(24, 24, 27, 0.96);`);
2632
- lines.push(` color: #fca5a5;`);
2633
- lines.push(` padding: 12px 8px;`);
2634
- lines.push(` box-shadow: 0 18px 36px rgba(0, 0, 0, 0.28);`);
2635
- lines.push(` cursor: pointer;`);
2636
- lines.push(` font: 700 13px/1 \${__VOID_ERROR_PAGE_FONT_STACK};`);
2637
- lines.push(` letter-spacing: 0.04em;`);
2638
- lines.push(` text-transform: uppercase;`);
2639
- lines.push(` transition: transform 180ms ease, opacity 180ms ease;`);
2640
- lines.push(` }`);
2641
- lines.push(` .__void-error-header {`);
2642
- lines.push(` display: flex;`);
2643
- lines.push(` flex-direction: column;`);
2644
- lines.push(` gap: 6px;`);
2645
- lines.push(` margin-block-end: 0;`);
2646
- lines.push(` padding-right: 52px;`);
2647
- lines.push(` }`);
2648
- lines.push(` .__void-error-status {`);
2649
- lines.push(` margin: 0;`);
2650
- lines.push(` color: #fca5a5;`);
2651
- lines.push(` font-size: 12px;`);
2652
- lines.push(` font-weight: 700;`);
2653
- lines.push(` letter-spacing: 0.12em;`);
2654
- lines.push(` text-transform: uppercase;`);
2655
- lines.push(` }`);
2656
- lines.push(` .__void-error-section {`);
2657
- lines.push(` border-top: 1px solid rgba(255, 255, 255, 0.08);`);
2658
- lines.push(` padding-top: 16px;`);
2659
- lines.push(` margin-top: 16px;`);
2660
- lines.push(` }`);
2661
- lines.push(` .__void-error-section.is-root {`);
2662
- lines.push(` border-top: 0;`);
2663
- lines.push(` padding-top: 0;`);
2664
- lines.push(` margin-top: 0;`);
2665
- lines.push(` }`);
2666
- lines.push(` .__void-error-message {`);
2667
- lines.push(` margin: 0;`);
2668
- lines.push(` color: #fff;`);
2669
- lines.push(` font-size: 1.7rem;`);
2670
- lines.push(` line-height: 1.15;`);
2671
- lines.push(` letter-spacing: -0.03em;`);
2672
- lines.push(` white-space: pre-wrap;`);
2673
- lines.push(` word-break: break-word;`);
2674
- lines.push(` }`);
2675
- lines.push(` .__void-error-kicker {`);
2676
- lines.push(` margin-bottom: 6px;`);
2677
- lines.push(` color: #fda4af;`);
2678
- lines.push(` font-size: 12px;`);
2679
- lines.push(` font-weight: 700;`);
2680
- lines.push(` letter-spacing: 0.08em;`);
2681
- lines.push(` text-transform: uppercase;`);
2682
- lines.push(` }`);
2683
- lines.push(` .__void-error-section h2 {`);
2684
- lines.push(` margin: 0 0 8px;`);
2685
- lines.push(` font-size: 1.05rem;`);
2686
- lines.push(` color: #fff;`);
2687
- lines.push(` }`);
2688
- lines.push(` .__void-error-section p {`);
2689
- lines.push(` margin: 0;`);
2690
- lines.push(` color: #e4e4e7;`);
2691
- lines.push(` white-space: pre-wrap;`);
2692
- lines.push(` word-break: break-word;`);
2693
- lines.push(` }`);
2694
- lines.push(` .__void-error-stack {`);
2695
- lines.push(` margin-top: 18px;`);
2696
- lines.push(` border: 1px solid rgba(255, 255, 255, 0.08);`);
2697
- lines.push(` border-radius: 32px;`);
2698
- lines.push(` background: rgba(255, 255, 255, 0.03);`);
2699
- lines.push(` corner-shape: squircle;`);
2700
- lines.push(` overflow: hidden;`);
2701
- lines.push(` }`);
2702
- lines.push(` .__void-error-stack-label {`);
2703
- lines.push(` padding: 12px 14px 10px;`);
2704
- lines.push(` color: #f4f4f5;`);
2705
- lines.push(` font-size: 12px;`);
2706
- lines.push(` font-weight: 700;`);
2707
- lines.push(` letter-spacing: 0.08em;`);
2708
- lines.push(` text-transform: uppercase;`);
2709
- lines.push(` border-bottom: 1px solid rgba(255, 255, 255, 0.08);`);
2710
- lines.push(` }`);
2711
- lines.push(` .__void-error-frames {`);
2712
- lines.push(` display: flex;`);
2713
- lines.push(` flex-direction: column;`);
2714
- lines.push(` }`);
2715
- lines.push(` .__void-error-frame {`);
2716
- lines.push(` display: flex;`);
2717
- lines.push(` align-items: baseline;`);
2718
- lines.push(` justify-content: space-between;`);
2719
- lines.push(` gap: 16px;`);
2720
- lines.push(` padding: 12px 14px;`);
2721
- lines.push(` color: inherit;`);
2722
- lines.push(` text-decoration: none;`);
2723
- lines.push(` border-top: 1px solid rgba(255, 255, 255, 0.06);`);
2724
- lines.push(` }`);
2725
- lines.push(` .__void-error-frame:first-child {`);
2726
- lines.push(` border-top: 0;`);
2727
- lines.push(` }`);
2728
- lines.push(` .__void-error-frame:hover {`);
2729
- lines.push(` background: rgba(255, 255, 255, 0.05);`);
2730
- lines.push(` }`);
2731
- lines.push(` .__void-error-frame.is-static {`);
2732
- lines.push(` cursor: default;`);
2733
- lines.push(` }`);
2734
- lines.push(` .__void-error-frame-function {`);
2735
- lines.push(` flex: 1 1 auto;`);
2736
- lines.push(` min-width: 0;`);
2737
- lines.push(` color: #fafafa;`);
2738
- lines.push(` font: 600 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;`);
2739
- lines.push(` white-space: nowrap;`);
2740
- lines.push(` overflow: hidden;`);
2741
- lines.push(` text-overflow: ellipsis;`);
2742
- lines.push(` }`);
2743
- lines.push(` .__void-error-frame-location {`);
2744
- lines.push(` flex: 0 1 52%;`);
2745
- lines.push(` min-width: 0;`);
2746
- lines.push(` color: #fda4af;`);
2747
- lines.push(` font: 500 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;`);
2748
- lines.push(` text-align: right;`);
2749
- lines.push(` white-space: nowrap;`);
2750
- lines.push(` overflow: hidden;`);
2751
- lines.push(` text-overflow: ellipsis;`);
2752
- lines.push(` }`);
2753
- lines.push(` .__void-error-section pre {`);
2754
- lines.push(` margin: 0;`);
2755
- lines.push(` padding: 12px 14px;`);
2756
- lines.push(` overflow: auto;`);
2757
- lines.push(` color: #e4e4e7;`);
2758
- lines.push(` font: 500 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;`);
2759
- lines.push(` white-space: pre-wrap;`);
2760
- lines.push(` word-break: break-word;`);
2761
- lines.push(` }`);
2762
- lines.push(` .__void-error-overlay.is-minimized .__void-error-backdrop {`);
2763
- lines.push(` opacity: 0;`);
2764
- lines.push(` pointer-events: none;`);
2765
- lines.push(` }`);
2766
- lines.push(` .__void-error-overlay.is-minimized .__void-error-panel {`);
2767
- lines.push(` opacity: 0;`);
2768
- lines.push(` pointer-events: none;`);
2769
- lines.push(` transform: scale(0.92);`);
2770
- lines.push(` }`);
2771
- lines.push(` .__void-error-overlay.is-minimized .__void-error-minimized {`);
2772
- lines.push(` opacity: 1;`);
2773
- lines.push(` pointer-events: auto;`);
2774
- lines.push(` transform: scale(1);`);
2775
- lines.push(` }`);
2776
- lines.push(` @media (max-width: 720px) {`);
2777
- lines.push(` .__void-error-panel {`);
2778
- lines.push(` inset: auto 12px 12px 12px;`);
2779
- lines.push(` inline-size: auto;`);
2780
- lines.push(` max-block-size: min(70dvh, 920px);`);
2781
- lines.push(` padding: 16px;`);
2782
- lines.push(` }`);
2783
- lines.push(` .__void-error-minimized {`);
2784
- lines.push(` inset: auto auto 12px 12px;`);
2785
- lines.push(` }`);
2786
- lines.push(` .__void-error-frame {`);
2787
- lines.push(` flex-direction: column;`);
2788
- lines.push(` align-items: flex-start;`);
2789
- lines.push(` }`);
2790
- lines.push(` .__void-error-frame-location {`);
2791
- lines.push(` text-align: left;`);
2792
- lines.push(` }`);
2793
- lines.push(` }`);
2794
- lines.push(` </style>`);
2795
- lines.push(`<aside class="__void-error-overlay" data-void-error-overlay role="dialog" aria-label="Void dev error overlay"><div class="__void-error-backdrop" data-void-error-backdrop></div><section class="__void-error-panel"><button type="button" class="__void-error-close" data-void-error-close aria-label="Minimize error overlay"><svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M3.757 3.757 12.243 12.243M12.243 3.757 3.757 12.243" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/></svg></button><header class="__void-error-header"><p class="__void-error-status">\${__voidEscapeHtml(String(status) + ": " + title)}</p></header>\${sections}</section><button type="button" class="__void-error-minimized" data-void-error-toggle aria-label="Show dev error overlay" aria-expanded="true">\${__voidEscapeHtml(errorCountLabel)}</button><script>(function(){const script=document.currentScript;if(!(script instanceof HTMLScriptElement))return;const root=script.closest("[data-void-error-overlay]");if(!(root instanceof HTMLElement))return;const backdrop=root.querySelector("[data-void-error-backdrop]");const closeButton=root.querySelector("[data-void-error-close]");const toggle=root.querySelector("[data-void-error-toggle]");const setMinimized=(minimized)=>{root.classList.toggle("is-minimized", minimized);if(toggle instanceof HTMLElement)toggle.setAttribute("aria-expanded", minimized ? "false" : "true");};if(backdrop instanceof HTMLElement)backdrop.addEventListener("click",()=>setMinimized(true));if(closeButton instanceof HTMLElement)closeButton.addEventListener("click",()=>setMinimized(true));if(toggle instanceof HTMLElement)toggle.addEventListener("click",()=>setMinimized(false));})();<\/script></aside>\`;`);
2796
- lines.push(`}`);
2797
- lines.push("");
2798
- lines.push(`function __voidInjectDevErrorOverlay(html, overlay) {`);
2799
- lines.push(` return /<\\/body\\s*>/i.test(html) ? html.replace(/<\\/body\\s*>/i, overlay + "</body>") : html + overlay;`);
2800
- lines.push(`}`);
2801
- lines.push("");
2802
- lines.push(`function __voidGetErrorAssetCss(error) {`);
2803
- lines.push(` const tags = error && (typeof error === "object" || typeof error === "function") ? error.__voidPageAssetTags : null;`);
2804
- lines.push(` return tags && typeof tags.css === "string" ? tags.css : "";`);
2805
- lines.push(`}`);
2806
- lines.push("");
2807
- lines.push(`function __voidInjectErrorAssetCss(html, css) {`);
2808
- lines.push(` if (!css) return html;`);
2809
- lines.push(` return /<\\/head\\s*>/i.test(html) ? html.replace(/<\\/head\\s*>/i, css + "</head>") : css + html;`);
2810
- lines.push(`}`);
2811
- lines.push("");
2812
- lines.push(`function __voidRenderErrorPage(request, status, title, error) {`);
2813
- lines.push(` const heading = status + ": " + title;`);
2814
- lines.push(` const prefix = status + ": ";`);
2815
- lines.push(` const overlay = __VOID_DEV && status === 500 && error ? __voidRenderDevErrorOverlay(request, status, title, error) : "";`);
2816
- lines.push(` return \`<!doctype html>`);
2817
- lines.push(`<html lang="en">`);
2818
- lines.push(` <head>`);
2819
- lines.push(` <meta charset="utf-8">`);
2820
- lines.push(` <meta name="viewport" content="width=device-width, initial-scale=1">`);
2821
- lines.push(` <title>\${__voidEscapeHtml(heading)}</title>`);
2822
- lines.push(` \${__voidGetErrorAssetCss(error)}`);
2823
- lines.push(` <style>`);
2824
- lines.push(` :root {`);
2825
- lines.push(` color-scheme: light dark;`);
2826
- lines.push(` font-family: \${__VOID_ERROR_PAGE_FONT_STACK};`);
2827
- lines.push(` background: #f5f5f5;`);
2828
- lines.push(` color: #171717;`);
2829
- lines.push(` }`);
2830
- lines.push(` * { box-sizing: border-box; }`);
2831
- lines.push(` body {`);
2832
- lines.push(` margin: 0;`);
2833
- lines.push(` min-block-size: 100dvh;`);
2834
- lines.push(` display: grid;`);
2835
- lines.push(` place-items: center;`);
2836
- lines.push(` padding: 24px;`);
2837
- lines.push(` background: radial-gradient(circle at top, rgba(255, 255, 255, 0.96), rgba(245, 245, 245, 0.96) 52%), linear-gradient(180deg, #fafafa 0%, #f1f1f1 100%);`);
2838
- lines.push(` font: 500 16px/1.5 \${__VOID_ERROR_PAGE_FONT_STACK};`);
2839
- lines.push(` }`);
2840
- lines.push(` main {`);
2841
- lines.push(` inline-size: min(100%, 560px);`);
2842
- lines.push(` padding: 32px 36px;`);
2843
- lines.push(` border: 1px solid #d4d4d8;`);
2844
- lines.push(` border-radius: 32px;`);
2845
- lines.push(` corner-shape: squircle;`);
2846
- lines.push(` background: rgba(255, 255, 255, 0.88);`);
2847
- lines.push(` text-align: center;`);
2848
- lines.push(` backdrop-filter: blur(12px);`);
2849
- lines.push(` }`);
2850
- lines.push(` h1 {`);
2851
- lines.push(` margin: 0;`);
2852
- lines.push(` font: 400 clamp(1.5rem, 1.2rem + 1vw, 2rem) / 1.1 \${__VOID_ERROR_PAGE_FONT_STACK};`);
2853
- lines.push(` letter-spacing: -0.03em;`);
2854
- lines.push(` }`);
2855
- lines.push(` strong {`);
2856
- lines.push(` font-weight: 600;`);
2857
- lines.push(` }`);
2858
- lines.push(` @media (prefers-color-scheme: dark) {`);
2859
- lines.push(` :root {`);
2860
- lines.push(` background: #0a0a0a;`);
2861
- lines.push(` color: #f5f5f5;`);
2862
- lines.push(` }`);
2863
- lines.push(` body {`);
2864
- lines.push(` background: radial-gradient(circle at top, rgba(38, 38, 38, 0.96), rgba(10, 10, 10, 0.96) 52%), linear-gradient(180deg, #171717 0%, #0a0a0a 100%);`);
2865
- lines.push(` }`);
2866
- lines.push(` main {`);
2867
- lines.push(` border-color: #27272a;`);
2868
- lines.push(` background: rgba(23, 23, 23, 0.88);`);
2869
- lines.push(` }`);
2870
- lines.push(` }`);
2871
- lines.push(` </style>`);
2872
- lines.push(` </head>`);
2873
- lines.push(` <body>`);
2874
- lines.push(` <main>`);
2875
- lines.push(` <h1><strong>\${__voidEscapeHtml(prefix)}</strong>\${__voidEscapeHtml(title)}</h1>`);
2876
- lines.push(` </main>`);
2877
- lines.push(` \${overlay}`);
2878
- lines.push(` </body>`);
2879
- lines.push(`</html>\`;`);
2880
- lines.push(`}`);
2881
- lines.push("");
2882
- lines.push(`function __voidCreateErrorResponse(request, status, title, error) {`);
2883
- lines.push(` if (!__voidShouldServeHtmlErrorPage(request)) {`);
2884
- lines.push(` return new Response(title, { status });`);
2885
- lines.push(` }`);
2886
- lines.push(` return new Response(request.method === "HEAD" ? null : __voidRenderErrorPage(request, status, title, error), {`);
2887
- lines.push(` status,`);
2888
- lines.push(` headers: { "content-type": "text/html; charset=utf-8" },`);
2889
- lines.push(` });`);
2890
- lines.push(`}`);
2891
- lines.push("");
2409
+ lines.push(`const __errorRenderer = __createErrorRenderer(${JSON.stringify({
2410
+ dev: options.dev === true,
2411
+ projectRoot: options.projectRoot,
2412
+ homeDir: options.homeDir
2413
+ })});`);
2414
+ lines.push("const serveCustomErrorPage = __errorRenderer.serveCustomPage;");
2415
+ lines.push("app.onError(__errorRenderer.onError);");
2892
2416
  }
2893
2417
  /**
2894
2418
  * Generate the code for the virtual route table module (virtual:void-routes).
@@ -2903,8 +2427,7 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
2903
2427
  const managedDispatch = options.nodeTarget !== true && options.dev !== true && options.managedDispatch === true;
2904
2428
  lines.push(`import { AsyncLocalStorage } from "node:async_hooks";`);
2905
2429
  lines.push(`import { Hono } from ${JSON.stringify(options.honoPath)};`);
2906
- lines.push(`import { convertReturnValue } from ${JSON.stringify(options.responsePath)};`);
2907
- lines.push(`import { VoidAssetRewriteError as __VoidAssetRewriteError } from ${JSON.stringify(options.handlerPath)};`);
2430
+ lines.push(`import { createRoutingRuntime as __createRoutingRuntime, createHttpRouteHandler as __createHttpRouteHandler, createErrorRenderer as __createErrorRenderer, createPageGetHandler as __createPageGetHandler, createPageMutationHandler as __createPageMutationHandler, createPagesFallback as __createPagesFallback, createModuleLoader as __createModuleLoader, createClientAssetTags as __createClientAssetTags, createManifestLoader as __createManifestLoader, createSsrFallback as __createSsrFallback, createAssetNotFound as __createAssetNotFound } from ${JSON.stringify(ROUTING_RUNTIME_PATH)};`);
2908
2431
  if (options.nodeTarget) lines.push(`const withRuntimeEnv = (_env, fn) => fn();`);
2909
2432
  else lines.push(`import { withRuntimeEnv } from ${JSON.stringify(options.runtimeEnvPath)};`);
2910
2433
  if (auth) {
@@ -2937,9 +2460,6 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
2937
2460
  lines.push("");
2938
2461
  }
2939
2462
  lines.push(`const app = new Hono();`);
2940
- lines.push(`export const requestContext = new AsyncLocalStorage();`);
2941
- lines.push("const __voidOriginalUrls = new WeakMap();");
2942
- lines.push("const __voidFallbackHandled = new WeakSet();");
2943
2463
  const ASSET_EXTENSIONS = [
2944
2464
  "png",
2945
2465
  "jpg",
@@ -2978,81 +2498,15 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
2978
2498
  if (m) usedExts.add(m[1].toLowerCase());
2979
2499
  }
2980
2500
  const blockedExts = ASSET_EXTENSIONS.filter((e) => !usedExts.has(e));
2981
- if (blockedExts.length > 0) lines.push(`const __voidAssetRewriteExtRE = /\\.(${blockedExts.join("|")})$/i;`);
2982
- else lines.push("const __voidAssetRewriteExtRE = /(?!)/;");
2983
- lines.push(`const __VOID_DEV_ROUTING = ${JSON.stringify(options.dev === true)};`);
2984
- lines.push("function __voidAnnotateRouting(response, trace) {");
2985
- lines.push(" if (!__VOID_DEV_ROUTING || !response) return response;");
2986
- lines.push(" const headers = new Headers(response.headers);");
2987
- lines.push(" headers.set(\"X-Void-Routing\", trace);");
2988
- lines.push(" return new Response(response.body, { status: response.status, statusText: response.statusText, headers });");
2989
- lines.push("}");
2990
- lines.push("");
2991
- lines.push("function __voidShouldMarkNoMatch(request) {");
2992
- lines.push(" const url = new URL(request.url);");
2993
- lines.push(" if (request.method !== \"GET\" && request.method !== \"HEAD\") return false;");
2994
- lines.push(" if (url.pathname === \"/api\" || url.pathname.startsWith(\"/api/\")) return false;");
2995
- lines.push(" if (/\\/[^/]+\\.[^/]+$/.test(url.pathname)) return false;");
2996
- lines.push(" return true;");
2997
- lines.push("}");
2998
- lines.push("function __voidMarkNoMatch(request, response) {");
2999
- lines.push(" if (!response || response.status !== 404 || !__voidShouldMarkNoMatch(request)) return response;");
3000
- lines.push(" const headers = new Headers(response.headers);");
3001
- lines.push(" headers.set(\"X-Void-No-Match\", \"1\");");
3002
- lines.push(" return new Response(response.body, { status: response.status, statusText: response.statusText, headers });");
3003
- lines.push("}");
3004
- lines.push("");
3005
- ensureMergeQueryHelperEmitted(lines);
3006
- lines.push("app.use(async (c, next) => {");
3007
- if (managedDispatch) {
3008
- lines.push(" if (!__voidOriginalUrls.has(c.req.raw)) {");
3009
- lines.push(" const __h = c.req.raw.headers.get(\"X-Void-Original-URL\");");
3010
- lines.push(" if (__h != null) {");
3011
- lines.push(" try { __voidOriginalUrls.set(c.req.raw, new URL(__h)); } catch {}");
3012
- lines.push(" }");
3013
- lines.push(" }");
3014
- }
3015
- lines.push(" c.rewrite = (path) => {");
3016
- lines.push(" if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {");
3017
- lines.push(" throw new Error(\"c.rewrite() only accepts internal, path-absolute destinations — they must start with a single \\\"/\\\" (a leading \\\"//\\\" parses as protocol-relative and would proxy cross-origin); use fetch() for external URLs\");");
3018
- lines.push(" }");
3019
- lines.push(" const __qIdx = path.indexOf(\"?\");");
3020
- lines.push(" const __hIdx = path.indexOf(\"#\");");
3021
- lines.push(" const __firstDelim = __qIdx === -1 ? __hIdx : __hIdx === -1 ? __qIdx : Math.min(__qIdx, __hIdx);");
3022
- lines.push(" const __assetCheckPath = __firstDelim === -1 ? path : path.slice(0, __firstDelim);");
3023
- lines.push(" if (__voidAssetRewriteExtRE.test(__assetCheckPath)) {");
3024
- lines.push(" throw new __VoidAssetRewriteError(path);");
3025
- lines.push(" }");
3026
- lines.push(" const __pathOnly = __firstDelim === -1 ? path : path.slice(0, __firstDelim);");
3027
- lines.push(" const __searchOnly = __qIdx === -1 ? \"\" : path.slice(__qIdx, __hIdx === -1 ? path.length : __hIdx);");
3028
- lines.push(" const rewriteUrl = new URL(c.req.url);");
3029
- lines.push(" rewriteUrl.pathname = __pathOnly;");
3030
- lines.push(" if (__searchOnly) rewriteUrl.search = __searchOnly;");
3031
- lines.push(" const rewriteReq = new Request(rewriteUrl.toString(), c.req.raw);");
3032
- lines.push(" const __prior = __voidOriginalUrls.get(c.req.raw);");
3033
- lines.push(" __voidOriginalUrls.set(rewriteReq, __prior ?? new URL(c.req.url));");
3034
- if (options.nodeTarget) lines.push(" const __rewritePromise = app.fetch(rewriteReq, c.env);");
3035
- else lines.push(" const __rewritePromise = app.fetch(rewriteReq, c.env, c.executionCtx);");
3036
- lines.push(" if (!__VOID_DEV_ROUTING) return __rewritePromise;");
3037
- lines.push(" return __rewritePromise.then((res) => __voidAnnotateRouting(res, \"c.rewrite -> \" + path + \" (middleware)\"));");
3038
- lines.push(" };");
3039
- lines.push(" const __origRedirect = c.redirect.bind(c);");
3040
- lines.push(" c.redirect = (location, status) => {");
3041
- lines.push(" if (typeof location === \"string\" && location.startsWith(\"/\") && !location.startsWith(\"//\")) {");
3042
- lines.push(" const search = new URL(c.req.raw.url).search;");
3043
- lines.push(" return __origRedirect(__mergeQueryIntoLocation(location, search), status);");
3044
- lines.push(" }");
3045
- lines.push(" return __origRedirect(location, status);");
3046
- lines.push(" };");
3047
- lines.push(" c.originalUrl = () => __voidOriginalUrls.get(c.req.raw) ?? null;");
3048
- lines.push(" c.isRewritten = () => __voidOriginalUrls.has(c.req.raw);");
3049
- lines.push(" await next();");
3050
- lines.push("});");
3051
- lines.push("");
3052
- lines.push("app.use(async (c, next) => {");
3053
- if (options.nodeTarget) lines.push(" await requestContext.run({ request: c.req.raw }, next);");
3054
- else lines.push(" await requestContext.run({ request: c.req.raw, executionCtx: c.executionCtx }, next);");
3055
- lines.push("});");
2501
+ lines.push(`const __routingRuntime = __createRoutingRuntime(app, ${JSON.stringify({
2502
+ dev: options.dev === true,
2503
+ nodeTarget: options.nodeTarget === true,
2504
+ managedDispatch,
2505
+ blockedAssetExtensions: blockedExts
2506
+ })});`);
2507
+ lines.push("export const requestContext = __routingRuntime.requestContext;");
2508
+ lines.push("app.use(__routingRuntime.contextMiddleware);");
2509
+ lines.push("app.use(__routingRuntime.requestMiddleware);");
3056
2510
  lines.push("");
3057
2511
  const emitEdgeRules = !managedDispatch;
3058
2512
  if (emitEdgeRules && options.redirectRules?.length) compileRoutingRulesMiddleware(lines, options.redirectRules, options.dev === true, options.nodeTarget === true);
@@ -3086,30 +2540,15 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
3086
2540
  const seenFiles = /* @__PURE__ */ new Set();
3087
2541
  for (const route of scan.routes) {
3088
2542
  const filePath = `${routesDir}/${route.filePath}`;
3089
- const varName = `_mod_${route.filePath.replace(/[^a-zA-Z0-9]/g, "_")}`;
3090
2543
  const loaderName = `_load_${route.filePath.replace(/[^a-zA-Z0-9]/g, "_")}`;
3091
2544
  if (!seenFiles.has(route.filePath)) {
3092
2545
  seenFiles.add(route.filePath);
3093
- if (options.dev !== true) lines.push(`let ${varName};`);
3094
- lines.push(`async function ${loaderName}() {`);
3095
- if (options.dev === true) lines.push(` return import(${JSON.stringify(filePath)});`);
3096
- else {
3097
- lines.push(` if (!${varName}) ${varName} = await import(${JSON.stringify(filePath)});`);
3098
- lines.push(` return ${varName};`);
3099
- }
3100
- lines.push(`}`);
2546
+ lines.push(`const ${loaderName} = __createModuleLoader(() => import(${JSON.stringify(filePath)}), ${JSON.stringify(options.dev !== true)});`);
3101
2547
  }
3102
- if (route.methods.length === 0) {
3103
- lines.push(`app.all(${JSON.stringify(route.pattern)}, async (c) => {`);
3104
- lines.push(` const mod = await ${loaderName}();`);
3105
- lines.push(` return convertReturnValue(await mod.default(c));`);
3106
- lines.push(`});`);
3107
- } else for (const method of route.methods) {
2548
+ if (route.methods.length === 0) lines.push(`app.all(${JSON.stringify(route.pattern)}, __createHttpRouteHandler(${loaderName}, "default"));`);
2549
+ else for (const method of route.methods) {
3108
2550
  const honoMethod = method.toLowerCase();
3109
- lines.push(`app.${honoMethod}(${JSON.stringify(route.pattern)}, async (c) => {`);
3110
- lines.push(` const mod = await ${loaderName}();`);
3111
- lines.push(` return convertReturnValue(await mod.${method}(c));`);
3112
- lines.push(`});`);
2551
+ lines.push(`app.${honoMethod}(${JSON.stringify(route.pattern)}, __createHttpRouteHandler(${loaderName}, ${JSON.stringify(method)}));`);
3113
2552
  }
3114
2553
  }
3115
2554
  lines.push("");
@@ -3120,7 +2559,8 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
3120
2559
  pattern: route.pattern,
3121
2560
  params: route.params,
3122
2561
  className: route.className,
3123
- bindingName: route.bindingName
2562
+ bindingName: route.bindingName,
2563
+ ...route.name !== void 0 && { name: route.name }
3124
2564
  })}, ${auth ? "__voidAuthOptions" : "undefined"}, ${auth ? "__resolveVoidAuthState" : "undefined"});`);
3125
2565
  }
3126
2566
  lines.push("");
@@ -3128,10 +2568,12 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
3128
2568
  pattern: route.pattern,
3129
2569
  params: route.params,
3130
2570
  className: route.className,
3131
- bindingName: route.bindingName
2571
+ bindingName: route.bindingName,
2572
+ ...route.name !== void 0 && { name: route.name }
3132
2573
  })))};`);
3133
2574
  lines.push("");
3134
2575
  }
2576
+ for (let i = 0; i < webSockets.length; i++) lines.push(`__voidWebSocketRoutes[${i}].key = websocket${i}.key;`);
3135
2577
  for (const className of options.webSocketTombstones ?? []) lines.push(`export const ${className} = __createWebSocketTombstoneDurableObject(${JSON.stringify(className)});`);
3136
2578
  if (options.webSocketTombstones?.length) lines.push("");
3137
2579
  if (options.hasLive) {
@@ -3139,150 +2581,20 @@ function compileRouteTable(scan, routesDir, middlewareDir, jobsDir, queuesDir, s
3139
2581
  lines.push("");
3140
2582
  }
3141
2583
  if (pages && scan.pages.pages.length > 0) compilePageRoutes(lines, scan, pages, options);
2584
+ for (let i = 0; i < webSockets.length; i++) lines.push(`app.all(${JSON.stringify(webSockets[i].pattern)}, (c) => __forwardWebSocketRequest(c.req.raw, c.env, __voidWebSocketRoutes[${i}]));`);
2585
+ if (webSockets.length > 0) lines.push("");
2586
+ if (pages && scan.pages.pages.length > 0) lines.push(`app.notFound(__createPagesFallback({ routing: __routingRuntime, errors: __errorRenderer, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${JSON.stringify(emitEdgeRules && options.fallbackRules?.length ? options.dev ? options.fallbackRules : stripOriginForProd(options.fallbackRules) : void 0)} }));`);
3142
2587
  compilePrerenderCollector(lines, scan, ssr, options);
3143
2588
  if (ssr) {
3144
- const clientEntryUrl = `/${ssr.clientEntryRelativePath}`;
3145
- lines.push(`const SSR_CLIENT_ENTRY_ID = ${JSON.stringify(ssr.clientEntryRelativePath)};`);
3146
- lines.push(`const SSR_CLIENT_ENTRY_URL = ${JSON.stringify(clientEntryUrl)};`);
3147
- lines.push(`let cachedSsrManifest = null;`);
3148
- lines.push("");
3149
- lines.push(`function escapeHtml(value) {`);
3150
- lines.push(` return String(value).replace(/"/g, "&quot;");`);
3151
- lines.push(`}`);
3152
- lines.push("");
3153
- lines.push(`function getDevClientTags() {`);
3154
- lines.push(` const preloadTags = [\`<script type="module" src="/@vite/client"><\/script>\`];`);
3155
- lines.push(` preloadTags.push(\`${BINDING_HINT_SCRIPT}\`);`);
3156
- if (options.reactRefresh) lines.push(` preloadTags.push(\`<script type="module">
3157
- import RefreshRuntime from "/@react-refresh";
3158
- RefreshRuntime.injectIntoGlobalHook(window);
3159
- window.$RefreshReg$ = () => {};
3160
- window.$RefreshSig$ = () => (type) => type;
3161
- window.__vite_plugin_react_preamble_installed__ = true;
3162
- <\/script>\`);`);
3163
- lines.push(` const bodyTag = \`<script type="module" src="\${escapeHtml(SSR_CLIENT_ENTRY_URL)}"><\/script>\`;`);
3164
- lines.push(` return { css: "", preloads: preloadTags.join("\\n"), body: bodyTag };`);
3165
- lines.push(`}`);
3166
- lines.push("");
3167
- lines.push(`function collectManifestFiles(manifest, entryId) {`);
3168
- lines.push(` const seen = new Set();`);
3169
- lines.push(` const toVisit = [entryId];`);
3170
- lines.push(` while (toVisit.length > 0) {`);
3171
- lines.push(` const currentId = toVisit.pop();`);
3172
- lines.push(` if (seen.has(currentId)) continue;`);
3173
- lines.push(` seen.add(currentId);`);
3174
- lines.push(` const chunk = manifest[currentId];`);
3175
- lines.push(` if (!chunk || !Array.isArray(chunk.imports)) continue;`);
3176
- lines.push(` for (const importedId of chunk.imports) toVisit.push(importedId);`);
3177
- lines.push(` }`);
3178
- lines.push(` return Array.from(seen);`);
3179
- lines.push(`}`);
3180
- lines.push("");
3181
- lines.push(`async function loadSsrManifest(request, env) {`);
3182
- lines.push(` if (cachedSsrManifest) return cachedSsrManifest;`);
3183
- lines.push(` if (typeof globalThis.__VITE_MANIFEST__ === "object" && globalThis.__VITE_MANIFEST__) {`);
3184
- lines.push(` cachedSsrManifest = globalThis.__VITE_MANIFEST__;`);
3185
- lines.push(` return cachedSsrManifest;`);
3186
- lines.push(` }`);
3187
- lines.push(` const assets = env?.ASSETS;`);
3188
- lines.push(` if (!assets || typeof assets.fetch !== "function") return null;`);
3189
- lines.push(` const manifestUrl = new URL("/.vite/manifest.json", request.url);`);
3190
- lines.push(` const response = await assets.fetch(new Request(manifestUrl.toString()));`);
3191
- lines.push(` if (!response.ok) return null;`);
3192
- lines.push(` cachedSsrManifest = await response.json();`);
3193
- lines.push(` return cachedSsrManifest;`);
3194
- lines.push(`}`);
3195
- lines.push("");
3196
- lines.push(`async function getClientAssetTags(request, env) {`);
3197
- lines.push(` const manifest = await loadSsrManifest(request, env);`);
3198
- lines.push(` if (!manifest || typeof manifest !== "object") {`);
3199
- lines.push(` if (!import.meta.env.DEV) return { css: "", preloads: "", body: "" };`);
3200
- lines.push(` return getDevClientTags();`);
3201
- lines.push(` }`);
3202
- lines.push(` const entry = manifest[SSR_CLIENT_ENTRY_ID];`);
3203
- lines.push(` if (!entry || typeof entry !== "object" || typeof entry.file !== "string") {`);
3204
- lines.push(` return { css: "", preloads: "", body: "" };`);
3205
- lines.push(` }`);
3206
- lines.push(` const ids = collectManifestFiles(manifest, SSR_CLIENT_ENTRY_ID);`);
3207
- lines.push(` const cssFiles = new Set();`);
3208
- lines.push(` const preloadFiles = new Set();`);
3209
- lines.push(` for (const id of ids) {`);
3210
- lines.push(` const chunk = manifest[id];`);
3211
- lines.push(` if (!chunk || typeof chunk !== "object") continue;`);
3212
- lines.push(` if (Array.isArray(chunk.css)) {`);
3213
- lines.push(` for (const cssFile of chunk.css) cssFiles.add(cssFile);`);
3214
- lines.push(` }`);
3215
- lines.push(` if (id !== SSR_CLIENT_ENTRY_ID && typeof chunk.file === "string") {`);
3216
- lines.push(` preloadFiles.add(chunk.file);`);
3217
- lines.push(` }`);
3218
- lines.push(` }`);
3219
- lines.push(` const cssTags = [];`);
3220
- lines.push(` for (const cssFile of cssFiles) {`);
3221
- lines.push(` cssTags.push(\`<link rel="stylesheet" href="/\${escapeHtml(cssFile)}">\`);`);
3222
- lines.push(` }`);
3223
- lines.push(` const preloadTags = [];`);
3224
- lines.push(` for (const preloadFile of preloadFiles) {`);
3225
- lines.push(` preloadTags.push(\`<link rel="modulepreload" href="/\${escapeHtml(preloadFile)}">\`);`);
3226
- lines.push(` }`);
3227
- lines.push(` const bodyTag = \`<script type="module" src="/\${escapeHtml(entry.file)}"><\/script>\`;`);
3228
- lines.push(` return { css: cssTags.join("\\n"), preloads: preloadTags.join("\\n"), body: bodyTag };`);
3229
- lines.push(`}`);
3230
- lines.push("");
3231
- lines.push(`function shouldHandleSsrRequest(c) {`);
3232
- lines.push(` const path = c.req.path;`);
3233
- lines.push(` if (path === "/api" || path.startsWith("/api/")) return false;`);
3234
- lines.push(` if (/\\/[^/]+\\.[^/]+$/.test(path)) return false;`);
3235
- lines.push(` const destination = c.req.header("sec-fetch-dest");`);
3236
- lines.push(` if (destination && destination !== "document" && destination !== "empty") return false;`);
3237
- lines.push(` return true;`);
3238
- lines.push(`}`);
3239
- lines.push("");
3240
- lines.push(`async function fetchFromAssets(c) {`);
3241
- lines.push(` const assets = c.env?.ASSETS;`);
3242
- lines.push(` if (!assets || typeof assets.fetch !== "function") {`);
3243
- lines.push(` return __voidMarkNoMatch(c.req.raw, new Response("Not Found", { status: 404 }));`);
3244
- lines.push(` }`);
3245
- lines.push(` const response = await assets.fetch(c.req.raw);`);
3246
- lines.push(` return response.status === 404 ? __voidMarkNoMatch(c.req.raw, new Response("Not Found", { status: 404 })) : response;`);
3247
- lines.push(`}`);
3248
- lines.push("");
3249
- lines.push(`async function renderSsrResponse(c, mod) {`);
3250
- lines.push(` const render = typeof mod.render === "function" ? mod.render : mod.default;`);
3251
- lines.push(` if (typeof render !== "function") {`);
3252
- lines.push(` throw new Error("ssr: Invalid entry. Export render(c, assetTags).");`);
3253
- lines.push(` }`);
3254
- lines.push(` const assetTags = await getClientAssetTags(c.req.raw, c.env);`);
3255
- lines.push(` return render(c, assetTags);`);
3256
- lines.push(`}`);
3257
- lines.push("");
3258
- lines.push(`app.notFound(async (c) => {`);
3259
- if (options.nodeTarget && options.fallbackRules?.length) emitFallbackRulesCheck(lines, options.fallbackRules, options.dev === true, " ", options.nodeTarget === true);
3260
- lines.push(` if (!shouldHandleSsrRequest(c)) {`);
3261
- if (!options.nodeTarget && emitEdgeRules && options.fallbackRules?.length) {
3262
- lines.push(` const __assetRes = await fetchFromAssets(c);`);
3263
- lines.push(` if (__assetRes.status !== 404) return __assetRes;`);
3264
- emitFallbackRulesCheck(lines, options.fallbackRules, options.dev === true, " ", false);
3265
- lines.push(` return __assetRes;`);
3266
- } else lines.push(` return fetchFromAssets(c);`);
3267
- lines.push(` }`);
3268
- lines.push(` const mod = await import(${JSON.stringify(ssr.serverEntryPath)});`);
3269
- lines.push(` return renderSsrResponse(c, mod);`);
3270
- lines.push(`});`);
3271
- lines.push("");
3272
- } else if (emitEdgeRules && (options.fallbackRules?.length || !options.nodeTarget && options.headerRules?.length) && !(pages && scan.pages.pages.length > 0)) {
3273
- lines.push(`app.notFound(async (c) => {`);
3274
- if (!options.nodeTarget) {
3275
- lines.push(` const assets = c.env?.ASSETS;`);
3276
- lines.push(` if (assets && typeof assets.fetch === "function") {`);
3277
- lines.push(` const __assetRes = await assets.fetch(c.req.raw);`);
3278
- lines.push(` if (__assetRes.status !== 404) return __assetRes;`);
3279
- lines.push(` }`);
3280
- }
3281
- if (options.fallbackRules?.length) emitFallbackRulesCheck(lines, options.fallbackRules, options.dev === true, " ", options.nodeTarget === true);
3282
- lines.push(` return __voidMarkNoMatch(c.req.raw, new Response("Not Found", { status: 404 }));`);
3283
- lines.push(`});`);
3284
- lines.push("");
3285
- }
2589
+ lines.push(`const getClientAssetTags = __createClientAssetTags(${JSON.stringify({
2590
+ entryId: ssr.clientEntryRelativePath,
2591
+ entryUrl: "/" + ssr.clientEntryRelativePath,
2592
+ kind: "ssr",
2593
+ dev: options.dev === true,
2594
+ reactRefresh: options.reactRefresh
2595
+ })});`);
2596
+ lines.push(`app.notFound(__createSsrFallback({ routing: __routingRuntime, nodeTarget: ${JSON.stringify(options.nodeTarget === true)}, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${JSON.stringify(emitEdgeRules && options.fallbackRules?.length ? options.dev ? options.fallbackRules : stripOriginForProd(options.fallbackRules) : void 0)}, load: () => import(${JSON.stringify(ssr.serverEntryPath)}), assets: getClientAssetTags }));`);
2597
+ } else if (emitEdgeRules && (options.fallbackRules?.length || !options.nodeTarget && options.headerRules?.length) && !(pages && scan.pages.pages.length > 0)) lines.push(`app.notFound(__createAssetNotFound({ routing: __routingRuntime, nodeTarget: ${JSON.stringify(options.nodeTarget === true)}, assetsDir: ${JSON.stringify(options.assetsDir)}, fallbackRules: ${JSON.stringify(options.fallbackRules?.length ? options.dev ? options.fallbackRules : stripOriginForProd(options.fallbackRules) : void 0)} }));`);
3286
2598
  if (scan.jobs.length > 0) {
3287
2599
  for (let i = 0; i < scan.jobs.length; i++) {
3288
2600
  const job = scan.jobs[i];
@@ -3617,8 +2929,6 @@ function compilePrerenderCollector(lines, scan, ssr, options) {
3617
2929
  lines.push("");
3618
2930
  }
3619
2931
  function compilePageRoutes(lines, scan, pages, options) {
3620
- lines.push(`import { handlePageGet, handlePageMutation } from ${JSON.stringify(pages.protocolPath)};`);
3621
- lines.push(`import { renderHeadToString, renderHtmlAttrs, renderBodyAttrs } from ${JSON.stringify(pages.headPath)};`);
3622
2932
  lines.push(`import * as __voidPagesRenderer from "virtual:void-pages-renderer";`);
3623
2933
  if (options.dev) lines.push(`import { getVoidPagesDevCss } from "virtual:void-pages-dev-assets";`);
3624
2934
  const hasIslandPages = scan.pages.pages.some((p) => p.renderMode === "island");
@@ -3632,42 +2942,6 @@ function compilePageRoutes(lines, scan, pages, options) {
3632
2942
  lines.push(`const __voidHeadConfig = ${JSON.stringify(pages.headConfig ?? null)};`);
3633
2943
  lines.push("");
3634
2944
  pushDefaultErrorPageHelpers(lines, options);
3635
- const clientEntryId = pages.clientEntryId;
3636
- lines.push(`const PAGES_CLIENT_ENTRY_ID = ${JSON.stringify(clientEntryId)};`);
3637
- lines.push(`const PAGES_CLIENT_ENTRY_URL = ${JSON.stringify("/@id/__x00__" + clientEntryId)};`);
3638
- lines.push(`let cachedPagesManifest = null;`);
3639
- lines.push("");
3640
- lines.push(`function escapeHtmlAttr(value) {`);
3641
- lines.push(` return String(value).replace(/"/g, "&quot;");`);
3642
- lines.push(`}`);
3643
- lines.push("");
3644
- lines.push(`function getPagesDevClientTags() {`);
3645
- lines.push(` const preloads = \`<script type="module" src="/@vite/client"><\/script>\\n${BINDING_HINT_SCRIPT}\`;`);
3646
- lines.push(` const bodyTag = \`<script type="module" src="\${escapeHtmlAttr(PAGES_CLIENT_ENTRY_URL)}"><\/script>\`;`);
3647
- lines.push(` return { css: "", preloads, body: bodyTag };`);
3648
- lines.push(`}`);
3649
- lines.push("");
3650
- if (options.dev) {
3651
- lines.push(`async function collectVoidDevCss(request, env, kind, componentId, rootPhases) {`);
3652
- lines.push(` const devCss = await getVoidPagesDevCss(request, env, { kind, componentId, rootPhases });`);
3653
- lines.push(` return Array.isArray(devCss) ? devCss : [];`);
3654
- lines.push(`}`);
3655
- lines.push("");
3656
- }
3657
- lines.push(`function collectPagesManifestFiles(manifest, entryId) {`);
3658
- lines.push(` const seen = new Set();`);
3659
- lines.push(` const toVisit = [entryId];`);
3660
- lines.push(` for (let index = 0; index < toVisit.length; index++) {`);
3661
- lines.push(` const currentId = toVisit[index];`);
3662
- lines.push(` if (seen.has(currentId)) continue;`);
3663
- lines.push(` seen.add(currentId);`);
3664
- lines.push(` const chunk = manifest[currentId];`);
3665
- lines.push(` if (!chunk || !Array.isArray(chunk.imports)) continue;`);
3666
- lines.push(` for (const importedId of chunk.imports) toVisit.push(importedId);`);
3667
- lines.push(` }`);
3668
- lines.push(` return Array.from(seen);`);
3669
- lines.push(`}`);
3670
- lines.push("");
3671
2945
  const relPagesDir = pages.pagesDirRelative;
3672
2946
  const pageCssKeys = {};
3673
2947
  const pageDevRootPhases = {};
@@ -3701,155 +2975,27 @@ function compilePageRoutes(lines, scan, pages, options) {
3701
2975
  pageCssKeys[page.componentId] = keys;
3702
2976
  pageDevRootPhases[page.componentId] = routeRootPhases.filter((phase) => phase.length > 0);
3703
2977
  }
3704
- lines.push(`const PAGE_CSS_KEYS = ${JSON.stringify(pageCssKeys)};`);
3705
- if (options.dev) lines.push(`const PAGE_DEV_ROOT_PHASES = ${JSON.stringify(pageDevRootPhases)};`);
3706
- lines.push("");
3707
- lines.push(`function collectRouteCss(manifest, entryId, pageKeys) {`);
3708
- lines.push(` const cssFiles = new Set();`);
3709
- lines.push(` const visited = new Set();`);
3710
- lines.push(` function visit(id) {`);
3711
- lines.push(` if (visited.has(id)) return;`);
3712
- lines.push(` visited.add(id);`);
3713
- lines.push(` const chunk = manifest[id];`);
3714
- lines.push(` if (!chunk) return;`);
3715
- lines.push(` if (Array.isArray(chunk.css)) {`);
3716
- lines.push(` for (const f of chunk.css) cssFiles.add(f);`);
3717
- lines.push(` }`);
3718
- lines.push(` if (Array.isArray(chunk.imports)) {`);
3719
- lines.push(` for (const i of chunk.imports) visit(i);`);
3720
- lines.push(` }`);
3721
- lines.push(` }`);
3722
- lines.push(` visit(entryId);`);
3723
- lines.push(` for (const key of pageKeys) {`);
3724
- lines.push(` visit(key);`);
3725
- lines.push(` }`);
3726
- lines.push(` return cssFiles;`);
3727
- lines.push(`}`);
3728
- lines.push("");
3729
- lines.push(`async function loadPagesManifest(request, env) {`);
3730
- lines.push(` if (cachedPagesManifest) return cachedPagesManifest;`);
3731
- lines.push(` if (typeof globalThis.__VITE_MANIFEST__ === "object" && globalThis.__VITE_MANIFEST__) {`);
3732
- lines.push(` cachedPagesManifest = globalThis.__VITE_MANIFEST__;`);
3733
- lines.push(` return cachedPagesManifest;`);
3734
- lines.push(` }`);
3735
- lines.push(` const assets = env?.ASSETS;`);
3736
- lines.push(` if (!assets || typeof assets.fetch !== "function") return null;`);
3737
- lines.push(` const manifestUrl = new URL("/.vite/manifest.json", request.url);`);
3738
- lines.push(` const response = await assets.fetch(new Request(manifestUrl.toString()));`);
3739
- lines.push(` if (!response.ok) return null;`);
3740
- lines.push(` cachedPagesManifest = await response.json();`);
3741
- lines.push(` return cachedPagesManifest;`);
3742
- lines.push(`}`);
3743
- lines.push("");
3744
- lines.push(`async function getPagesAssetTags(request, env, componentId) {`);
3745
- lines.push(` const manifest = await loadPagesManifest(request, env);`);
3746
- lines.push(` if (!manifest || typeof manifest !== "object") {`);
3747
- lines.push(` if (!import.meta.env.DEV) return { css: "", preloads: "", body: "" };`);
3748
- if (options.dev) {
3749
- lines.push(` const tags = getPagesDevClientTags();`);
3750
- lines.push(` return { ...tags, devCss: await collectVoidDevCss(request, env, "pages", componentId, PAGE_DEV_ROOT_PHASES[componentId] || [[PAGES_CLIENT_ENTRY_URL]]) };`);
3751
- } else lines.push(` return getPagesDevClientTags();`);
3752
- lines.push(` }`);
3753
- lines.push(` const entry = manifest[PAGES_CLIENT_ENTRY_ID];`);
3754
- lines.push(` if (!entry || typeof entry !== "object" || typeof entry.file !== "string") {`);
3755
- lines.push(` return { css: "", preloads: "", body: "" };`);
3756
- lines.push(` }`);
3757
- lines.push(` const ids = collectPagesManifestFiles(manifest, PAGES_CLIENT_ENTRY_ID);`);
3758
- lines.push(` const pageKeys = componentId ? (PAGE_CSS_KEYS[componentId] || []) : [];`);
3759
- lines.push(` const cssFiles = collectRouteCss(manifest, PAGES_CLIENT_ENTRY_ID, pageKeys);`);
3760
- lines.push(` const preloadFiles = new Set();`);
3761
- lines.push(` for (const id of ids) {`);
3762
- lines.push(` const chunk = manifest[id];`);
3763
- lines.push(` if (!chunk || typeof chunk !== "object") continue;`);
3764
- lines.push(` if (id !== PAGES_CLIENT_ENTRY_ID && typeof chunk.file === "string") {`);
3765
- lines.push(` preloadFiles.add(chunk.file);`);
3766
- lines.push(` }`);
3767
- lines.push(` }`);
3768
- lines.push(` const cssTags = [];`);
3769
- lines.push(` for (const cssFile of cssFiles) {`);
3770
- lines.push(` cssTags.push(\`<link rel="stylesheet" href="/\${escapeHtmlAttr(cssFile)}">\`);`);
3771
- lines.push(` }`);
3772
- lines.push(` const preloadTags = [];`);
3773
- lines.push(` for (const preloadFile of preloadFiles) {`);
3774
- lines.push(` preloadTags.push(\`<link rel="modulepreload" href="/\${escapeHtmlAttr(preloadFile)}">\`);`);
3775
- lines.push(` }`);
3776
- lines.push(` const bodyTag = \`<script type="module" src="/\${escapeHtmlAttr(entry.file)}"><\/script>\`;`);
3777
- lines.push(` return { css: cssTags.join("\\n"), preloads: preloadTags.join("\\n"), body: bodyTag };`);
3778
- lines.push(`}`);
3779
- lines.push("");
3780
- if (hasIslandPages && pages.islandClientEntryId) {
3781
- const islandEntryId = pages.islandClientEntryId;
3782
- lines.push(`const ISLANDS_CLIENT_ENTRY_ID = ${JSON.stringify(islandEntryId)};`);
3783
- lines.push(`const ISLANDS_CLIENT_ENTRY_URL = ${JSON.stringify("/@id/__x00__" + islandEntryId)};`);
3784
- if (pages.mdClientEntryId) {
3785
- lines.push(`const MD_CLIENT_ENTRY_ID = ${JSON.stringify(pages.mdClientEntryId)};`);
3786
- lines.push(`const MD_CLIENT_ENTRY_URL = ${JSON.stringify("/@id/__x00__" + pages.mdClientEntryId)};`);
3787
- }
3788
- lines.push("");
3789
- lines.push(`function getIslandsDevClientTags() {`);
3790
- lines.push(` const preloads = \`<script type="module" src="/@vite/client"><\/script>\\n${BINDING_HINT_SCRIPT}\`;`);
3791
- lines.push(` let bodyTag = \`<script type="module" src="\${escapeHtmlAttr(ISLANDS_CLIENT_ENTRY_URL)}"><\/script>\`;`);
3792
- if (pages.mdClientEntryId) lines.push(` bodyTag += \`\\n<script type="module" src="\${escapeHtmlAttr(MD_CLIENT_ENTRY_URL)}"><\/script>\`;`);
3793
- lines.push(` return { css: "", preloads, body: bodyTag };`);
3794
- lines.push(`}`);
3795
- lines.push("");
3796
- lines.push(`async function getIslandsAssetTags(request, env, componentId) {`);
3797
- lines.push(` const manifest = await loadPagesManifest(request, env);`);
3798
- lines.push(` if (!manifest || typeof manifest !== "object") {`);
3799
- lines.push(` if (!import.meta.env.DEV) return { css: "", preloads: "", body: "" };`);
3800
- if (options.dev) {
3801
- lines.push(` const tags = getIslandsDevClientTags();`);
3802
- lines.push(` return { ...tags, devCss: await collectVoidDevCss(request, env, "islands", componentId, PAGE_DEV_ROOT_PHASES[componentId] || [[ISLANDS_CLIENT_ENTRY_URL]]) };`);
3803
- } else lines.push(` return getIslandsDevClientTags();`);
3804
- lines.push(` }`);
3805
- lines.push(` const entry = manifest[ISLANDS_CLIENT_ENTRY_ID];`);
3806
- lines.push(` if (!entry || typeof entry !== "object" || typeof entry.file !== "string") {`);
3807
- lines.push(` return { css: "", preloads: "", body: "" };`);
3808
- lines.push(` }`);
3809
- lines.push(` const ids = collectPagesManifestFiles(manifest, ISLANDS_CLIENT_ENTRY_ID);`);
3810
- if (pages.mdClientEntryId) {
3811
- lines.push(` const mdEntry = manifest[MD_CLIENT_ENTRY_ID];`);
3812
- lines.push(` if (mdEntry && typeof mdEntry.file === "string") {`);
3813
- lines.push(` const mdIds = collectPagesManifestFiles(manifest, MD_CLIENT_ENTRY_ID);`);
3814
- lines.push(` for (const mdId of mdIds) ids.push(mdId);`);
3815
- lines.push(` }`);
3816
- }
3817
- lines.push(` const pageKeys = componentId ? (PAGE_CSS_KEYS[componentId] || []) : [];`);
3818
- lines.push(` const cssFiles = collectRouteCss(manifest, ISLANDS_CLIENT_ENTRY_ID, pageKeys);`);
3819
- if (pages.mdClientEntryId) {
3820
- lines.push(` if (mdEntry && typeof mdEntry.file === "string") {`);
3821
- lines.push(` const mdKeys = [];`);
3822
- lines.push(` const mdCss = collectRouteCss(manifest, MD_CLIENT_ENTRY_ID, mdKeys);`);
3823
- lines.push(` for (const f of mdCss) cssFiles.add(f);`);
3824
- lines.push(` }`);
3825
- }
3826
- lines.push(` const preloadFiles = new Set();`);
3827
- lines.push(` for (const id of ids) {`);
3828
- lines.push(` const chunk = manifest[id];`);
3829
- lines.push(` if (!chunk || typeof chunk !== "object") continue;`);
3830
- const excludeFromPreload = pages.mdClientEntryId ? `id !== ISLANDS_CLIENT_ENTRY_ID && id !== MD_CLIENT_ENTRY_ID` : `id !== ISLANDS_CLIENT_ENTRY_ID`;
3831
- lines.push(` if (${excludeFromPreload} && typeof chunk.file === "string") {`);
3832
- lines.push(` preloadFiles.add(chunk.file);`);
3833
- lines.push(` }`);
3834
- lines.push(` }`);
3835
- lines.push(` const cssTags = [];`);
3836
- lines.push(` for (const cssFile of cssFiles) {`);
3837
- lines.push(` cssTags.push(\`<link rel="stylesheet" href="/\${escapeHtmlAttr(cssFile)}">\`);`);
3838
- lines.push(` }`);
3839
- lines.push(` const preloadTags = [];`);
3840
- lines.push(` for (const preloadFile of preloadFiles) {`);
3841
- lines.push(` preloadTags.push(\`<link rel="modulepreload" href="/\${escapeHtmlAttr(preloadFile)}">\`);`);
3842
- lines.push(` }`);
3843
- lines.push(` let bodyTag = \`<script type="module" src="/\${escapeHtmlAttr(entry.file)}"><\/script>\`;`);
3844
- if (pages.mdClientEntryId) {
3845
- lines.push(` if (mdEntry && typeof mdEntry.file === "string") {`);
3846
- lines.push(` bodyTag += \`\\n<script type="module" src="/\${escapeHtmlAttr(mdEntry.file)}"><\/script>\`;`);
3847
- lines.push(` }`);
3848
- }
3849
- lines.push(` return { css: cssTags.join("\\n"), preloads: preloadTags.join("\\n"), body: bodyTag };`);
3850
- lines.push(`}`);
3851
- lines.push("");
3852
- }
2978
+ lines.push("const __loadPagesManifest = __createManifestLoader();");
2979
+ const assetMetadata = {
2980
+ pageCssKeys,
2981
+ devRootPhases: options.dev ? pageDevRootPhases : void 0,
2982
+ dev: options.dev === true
2983
+ };
2984
+ const devCssOption = options.dev ? ", devCss: getVoidPagesDevCss" : "";
2985
+ lines.push(`const getPagesAssetTags = __createClientAssetTags({ ...${JSON.stringify({
2986
+ ...assetMetadata,
2987
+ entryId: pages.clientEntryId,
2988
+ entryUrl: "/@id/__x00__" + pages.clientEntryId,
2989
+ kind: "pages"
2990
+ })}${devCssOption} }, __loadPagesManifest);`);
2991
+ if (hasIslandPages && pages.islandClientEntryId) lines.push(`const getIslandsAssetTags = __createClientAssetTags({ ...${JSON.stringify({
2992
+ ...assetMetadata,
2993
+ entryId: pages.islandClientEntryId,
2994
+ entryUrl: "/@id/__x00__" + pages.islandClientEntryId,
2995
+ extraEntryId: pages.mdClientEntryId,
2996
+ extraEntryUrl: pages.mdClientEntryId ? "/@id/__x00__" + pages.mdClientEntryId : void 0,
2997
+ kind: "islands"
2998
+ })}${devCssOption} }, __loadPagesManifest);`);
3853
2999
  const seenServerFiles = /* @__PURE__ */ new Set();
3854
3000
  for (const page of scan.pages.pages) {
3855
3001
  const safeId = page.componentId.replace(/[^a-zA-Z0-9]/g, "_");
@@ -3857,13 +3003,8 @@ function compilePageRoutes(lines, scan, pages, options) {
3857
3003
  if (page.serverPath) serverImportPath = `${pages.pagesDir}/${page.serverPath}`;
3858
3004
  if (serverImportPath && !seenServerFiles.has(serverImportPath)) {
3859
3005
  seenServerFiles.add(serverImportPath);
3860
- const varName = `_pmod_${safeId}`;
3861
3006
  const loaderName = `_pload_${safeId}`;
3862
- lines.push(`let ${varName};`);
3863
- lines.push(`async function ${loaderName}() {`);
3864
- lines.push(` if (!${varName}) ${varName} = await import(${JSON.stringify(serverImportPath)});`);
3865
- lines.push(` return ${varName};`);
3866
- lines.push(`}`);
3007
+ lines.push(`const ${loaderName} = __createModuleLoader(() => import(${JSON.stringify(serverImportPath)}));`);
3867
3008
  }
3868
3009
  let mdHeadRef = null;
3869
3010
  if (!serverImportPath && page.metadata && (page.metadata.title || page.metadata.description)) {
@@ -3879,105 +3020,11 @@ function compilePageRoutes(lines, scan, pages, options) {
3879
3020
  }
3880
3021
  const renderer = page.renderMode === "island" ? "renderIslandPage" : "renderPage";
3881
3022
  const assetTags = page.renderMode === "island" && pages.islandClientEntryId ? "getIslandsAssetTags" : "getPagesAssetTags";
3882
- const renderOptions = `, ${JSON.stringify({ renderMode: page.renderMode })}`;
3883
- lines.push(`app.get(${JSON.stringify(page.pattern)}, async (c) => {`);
3884
- if (serverImportPath) {
3885
- const loaderName = `_pload_${safeId}`;
3886
- lines.push(` const mod = await ${loaderName}();`);
3887
- lines.push(` return handlePageGet(mod.loader, mod.head, c, ${JSON.stringify(page.componentId)}, ${renderer}, ${assetTags}, __voidHeadConfig${renderOptions});`);
3888
- } else {
3889
- const headArg = mdHeadRef ?? "undefined";
3890
- lines.push(` return handlePageGet(undefined, ${headArg}, c, ${JSON.stringify(page.componentId)}, ${renderer}, ${assetTags}, __voidHeadConfig${renderOptions});`);
3891
- }
3892
- lines.push(`});`);
3893
- if (page.methods.includes("action") || page.methods.includes("actions")) {
3894
- const loaderName = `_pload_${safeId}`;
3895
- lines.push(`app.on(["POST", "PUT", "PATCH", "DELETE"], ${JSON.stringify(page.pattern)}, async (c) => {`);
3896
- lines.push(` const mod = await ${loaderName}();`);
3897
- if (page.methods.includes("actions")) {
3898
- lines.push(` const actionName = new URL(c.req.url).searchParams.keys().next().value;`);
3899
- lines.push(` const handler = actionName ? mod.actions?.[actionName] : mod.actions?.default;`);
3900
- lines.push(` if (!handler) return new Response("Unknown action" + (actionName ? ": " + actionName : ""), { status: 404 });`);
3901
- } else lines.push(` const handler = mod.action;`);
3902
- lines.push(` return handlePageMutation(handler, mod.loader, mod.head, c, ${JSON.stringify(page.componentId)}, ${renderer}, ${assetTags}, __voidHeadConfig${renderOptions});`);
3903
- lines.push(`});`);
3904
- }
3023
+ const routeOptions = `{ ${serverImportPath ? "load: _pload_" + safeId + ", " : ""}${mdHeadRef ? "head: " + mdHeadRef + ", " : ""}componentId: ${JSON.stringify(page.componentId)}, render: ${renderer}, assets: ${assetTags}, headConfig: __voidHeadConfig, renderOptions: ${JSON.stringify({ renderMode: page.renderMode })} }`;
3024
+ lines.push(`app.get(${JSON.stringify(page.pattern)}, __createPageGetHandler(${routeOptions}));`);
3025
+ if (page.methods.includes("action") || page.methods.includes("actions")) lines.push(`app.on(["POST", "PUT", "PATCH", "DELETE"], ${JSON.stringify(page.pattern)}, __createPageMutationHandler({ ...${routeOptions}, namedActions: ${JSON.stringify(page.methods.includes("actions"))} }));`);
3905
3026
  }
3906
3027
  lines.push("");
3907
- lines.push(`async function fetchPagesAsset(c) {`);
3908
- lines.push(` if (c.req.method !== "GET" && c.req.method !== "HEAD") {`);
3909
- lines.push(` return new Response("Not Found", { status: 404 });`);
3910
- lines.push(` }`);
3911
- lines.push(` const assets = c.env?.ASSETS;`);
3912
- lines.push(` if (!assets || typeof assets.fetch !== "function") {`);
3913
- lines.push(` return __voidMarkNoMatch(c.req.raw, new Response("Not Found", { status: 404 }));`);
3914
- lines.push(` }`);
3915
- lines.push(` return assets.fetch(c.req.raw);`);
3916
- lines.push(`}`);
3917
- lines.push("");
3918
- lines.push(`async function serveCustomErrorPage(c, status, fallbackText, error) {`);
3919
- lines.push(` try {`);
3920
- lines.push(` const assets = c.env?.ASSETS;`);
3921
- lines.push(` if (assets && typeof assets.fetch === "function") {`);
3922
- lines.push(` const errReq = new Request(new URL("/" + status + ".html", c.req.url));`);
3923
- lines.push(` const errRes = await assets.fetch(errReq);`);
3924
- lines.push(` if (errRes.ok) {`);
3925
- lines.push(` const assetCss = __voidGetErrorAssetCss(error);`);
3926
- lines.push(` if (assetCss) {`);
3927
- lines.push(` const html = __voidInjectErrorAssetCss(await errRes.text(), assetCss);`);
3928
- lines.push(` const body = __VOID_DEV && status === 500 && error && __voidShouldServeHtmlErrorPage(c.req.raw) ? __voidInjectDevErrorOverlay(html, __voidRenderDevErrorOverlay(c.req.raw, status, fallbackText, error)) : html;`);
3929
- lines.push(` return new Response(c.req.method === "HEAD" ? null : body, {`);
3930
- lines.push(` status,`);
3931
- lines.push(` headers: { "content-type": "text/html; charset=utf-8" },`);
3932
- lines.push(` });`);
3933
- lines.push(` }`);
3934
- lines.push(` if (__VOID_DEV && status === 500 && error && __voidShouldServeHtmlErrorPage(c.req.raw)) {`);
3935
- lines.push(` const overlay = __voidRenderDevErrorOverlay(c.req.raw, status, fallbackText, error);`);
3936
- lines.push(` const html = await errRes.text();`);
3937
- lines.push(` return new Response(c.req.method === "HEAD" ? null : __voidInjectDevErrorOverlay(html, overlay), {`);
3938
- lines.push(` status,`);
3939
- lines.push(` headers: { "content-type": "text/html; charset=utf-8" },`);
3940
- lines.push(` });`);
3941
- lines.push(` }`);
3942
- lines.push(` return new Response(errRes.body, { status, headers: { "content-type": "text/html; charset=utf-8" } });`);
3943
- lines.push(` }`);
3944
- lines.push(` }`);
3945
- lines.push(` } catch {}`);
3946
- lines.push(` return __voidCreateErrorResponse(c.req.raw, status, fallbackText, error);`);
3947
- lines.push(`}`);
3948
- lines.push("");
3949
- lines.push(`app.onError((err, c) => {`);
3950
- lines.push(` if (err && typeof err === "object" && "getResponse" in err) return err.getResponse();`);
3951
- lines.push(` console.error(err);`);
3952
- lines.push(` return serveCustomErrorPage(c, 500, "Internal Server Error", err);`);
3953
- lines.push(`});`);
3954
- lines.push("");
3955
- lines.push(`app.notFound(async (c) => {`);
3956
- lines.push(` const path = c.req.path;`);
3957
- lines.push(` if (path === "/api" || path.startsWith("/api/")) {`);
3958
- lines.push(` return c.text("Not Found", 404);`);
3959
- lines.push(` }`);
3960
- lines.push(` if (c.req.method !== "GET" && c.req.method !== "HEAD") {`);
3961
- lines.push(` return c.text("Not Found", 404);`);
3962
- lines.push(` }`);
3963
- lines.push(` const assetRes = await fetchPagesAsset(c);`);
3964
- lines.push(` if (assetRes.status !== 404) return assetRes;`);
3965
- if (!(options.nodeTarget !== true && options.dev !== true && options.managedDispatch === true) && options.fallbackRules?.length) emitFallbackRulesCheck(lines, options.fallbackRules, options.dev === true, " ", options.nodeTarget === true);
3966
- lines.push(` if (path.includes("/.")) {`);
3967
- lines.push(` return serveCustomErrorPage(c, 404, "Not Found");`);
3968
- lines.push(` }`);
3969
- lines.push(` const lastSeg = path.substring(path.lastIndexOf("/") + 1);`);
3970
- lines.push(` if (lastSeg.includes(".")) {`);
3971
- lines.push(` return serveCustomErrorPage(c, 404, "Not Found");`);
3972
- lines.push(` }`);
3973
- lines.push(` if (path !== "/" && path.endsWith("/")) {`);
3974
- lines.push(` const url = new URL(c.req.url);`);
3975
- lines.push(` url.pathname = path.slice(0, -1);`);
3976
- lines.push(` return Response.redirect(url.href, 301);`);
3977
- lines.push(` }`);
3978
- lines.push(` return __voidMarkNoMatch(c.req.raw, await serveCustomErrorPage(c, 404, "Not Found"));`);
3979
- lines.push(`});`);
3980
- lines.push("");
3981
3028
  }
3982
3029
  /**
3983
3030
  * Generate the asset fallthrough helper shared by native Void workers and
@@ -3996,48 +3043,12 @@ function compilePageRoutes(lines, scan, pages, options) {
3996
3043
  * anything other than the SPA shell.
3997
3044
  */
3998
3045
  function compileAssetFallbackHelper(assetsDir = "assets", serveSpaFallback = false, notFound = "none") {
3999
- const fallthroughCode = serveSpaFallback ? ` // SPA fallback: when HTML-owning features make
4000
- // assetConfig.not_found_handling = 'none', the asset binding returns 404
4001
- // instead of falling back to index.html itself. Do that fallback here, after
4002
- // user routes/middleware have run, so auth gates and OAuth callbacks see the request first.
4003
- // Pages and SSR apps leave this disabled so intentional HTML 404s stay 404.
4004
- const accept = request.headers.get("accept") ?? "";
4005
- if (accept.includes("text/html")) {
4006
- const indexUrl = new URL("/index.html", request.url);
4007
- const indexAsset = await env.ASSETS.fetch(new Request(indexUrl, { method: request.method }));
4008
- if (indexAsset.status === 200) {
4009
- const res = new Response(indexAsset.body, {
4010
- status: 200,
4011
- headers: indexAsset.headers,
4012
- });
4013
- res.headers.set("Cache-Control", "no-store");
4014
- res.headers.set("Content-Type", "text/html; charset=utf-8");
4015
- return res;
4016
- }
4017
- }
4018
- return response;` : notFound === "404-page" ? ` const accept = request.headers.get("accept") ?? "";
4019
- const assetContentType = asset.headers.get("content-type") ?? "";
4020
- if (accept.includes("text/html") && assetContentType.includes("text/html")) {
4021
- const res = new Response(asset.body, asset);
4022
- res.headers.set("Cache-Control", "no-store");
4023
- return res;
4024
- }
4025
- return response;` : ` return response;`;
4026
- return `
4027
- async function serveWithAssets(request, env, response) {
4028
- if (response.status !== 404 || !env.ASSETS || (request.method !== "GET" && request.method !== "HEAD")) return response;
4029
- const asset = await env.ASSETS.fetch(new Request(request.url, { method: request.method, headers: request.headers }));
4030
- if (asset.status !== 404) {
4031
- const res = new Response(asset.body, asset);
4032
- if (new URL(request.url).pathname.startsWith(${JSON.stringify("/" + assetsDir + "/")})) {
4033
- res.headers.set("Cache-Control", "public, max-age=31536000, immutable");
4034
- } else {
4035
- res.headers.set("Cache-Control", "no-store");
4036
- }
4037
- return res;
4038
- }
4039
- ${fallthroughCode}
4040
- }
3046
+ return `import { createAssetFallback as __createAssetFallback } from ${JSON.stringify(ROUTING_RUNTIME_PATH)};
3047
+ const serveWithAssets = __createAssetFallback(${JSON.stringify({
3048
+ assetsDir,
3049
+ serveSpaFallback,
3050
+ notFound
3051
+ })});
4041
3052
  `;
4042
3053
  }
4043
3054
  /**
@@ -4059,16 +3070,17 @@ function deriveEmailRuntimePath(runtimeEnvPath) {
4059
3070
  return runtimeEnvPath.replace(/_?env(\.[^/]+)?$/, (_m, ext) => "email" + (ext ?? ""));
4060
3071
  }
4061
3072
  function compileWorkerEntry(options = {}) {
4062
- const { hasQueues = false, remote, assetsDir = "assets", webSocketClasses = [], runtimeEnvPath = "void/_env", runtimeEmailPath, envSchemaModule, sandbox, serveSpaFallback = false, hasEmail = false, live, isr, notFound = "none", durableObjects = [] } = options;
3073
+ const { hasQueues = false, versionMetadataBinding, remote, assetsDir = "assets", webSocketClasses = [], runtimeEnvPath = "void/_env", runtimeEmailPath, envSchemaModule, sandbox, serveSpaFallback = false, hasEmail = false, live, isr, notFound = "none", durableObjects = [] } = options;
4063
3074
  const remotePath = remote?.remotePath;
4064
3075
  const remoteBindingNames = JSON.stringify(remote?.bindingNames);
4065
3076
  const createRemoteEnvCall = `createRemoteEnv(env${remote?.bindingNames ? `, ${remoteBindingNames}` : ""})`;
4066
3077
  const hasSandbox = sandbox === true || typeof sandbox === "object";
4067
- const sandboxClassName = typeof sandbox === "object" ? sandbox.className ?? "Sandbox" : "Sandbox";
3078
+ const sandboxClassName = typeof sandbox === "object" ? sandbox.className ?? "SandboxV1" : DEFAULT_SANDBOX_CLASS_NAME;
4068
3079
  const sandboxBindingName = typeof sandbox === "object" ? sandbox.bindingName ?? "SANDBOX" : "SANDBOX";
4069
3080
  const sandboxRuntimePath = typeof sandbox === "object" ? sandbox.runtimePath ?? "void/sandbox" : "void/sandbox";
4070
3081
  const sandboxImport = hasSandbox ? `import { VoidPlatformSandbox as __VoidSandbox, __setSandboxBindingName } from ${JSON.stringify(sandboxRuntimePath)};\n` : "";
4071
- const sandboxExport = hasSandbox ? sandboxClassName === "Sandbox" ? `export { __VoidSandbox as Sandbox };\n__setSandboxBindingName(${JSON.stringify(sandboxBindingName)});\n` : `export class ${sandboxClassName} extends __VoidSandbox {}\n__setSandboxBindingName(${JSON.stringify(sandboxBindingName)});\n` : "";
3082
+ const sandboxInstanceType = typeof sandbox === "object" ? sandbox.instanceType : void 0;
3083
+ const sandboxExport = hasSandbox ? sandboxClassName === "SandboxV1" && !sandboxInstanceType ? `export { __VoidSandbox as SandboxV1 };\n__setSandboxBindingName(${JSON.stringify(sandboxBindingName)});\n` : `export class ${sandboxClassName} extends __VoidSandbox {${sandboxInstanceType ? ` protected override instanceType = ${JSON.stringify(sandboxInstanceType)} as const; ` : ""}}\n__setSandboxBindingName(${JSON.stringify(sandboxBindingName)});\n` : "";
4072
3084
  const hasLive = live === true || typeof live === "object";
4073
3085
  const liveBindingName = typeof live === "object" ? live.bindingName ?? "VOID_LIVE" : "VOID_LIVE";
4074
3086
  const liveClassName = typeof live === "object" ? live.className ?? "VoidLiveStreamDurableObject" : "VoidLiveStreamDurableObject";
@@ -4076,88 +3088,24 @@ function compileWorkerEntry(options = {}) {
4076
3088
  const liveRuntimeImport = hasLive ? `import { __setLiveBindingName } from "void/live";\n` : "";
4077
3089
  const liveExport = hasLive ? liveClassName === "VoidLiveStreamDurableObject" ? `export { VoidLiveStreamDurableObject };\n__setLiveBindingName(${JSON.stringify(liveBindingName)});\n` : `export { VoidLiveStreamDurableObject as ${liveClassName} };\n__setLiveBindingName(${JSON.stringify(liveBindingName)});\n` : "";
4078
3090
  const durableObjectImports = durableObjects.map(({ filePath }, index) => `import __voidDurableObject${index} from ${JSON.stringify(filePath)};`).join("\n");
4079
- const durableObjectExports = durableObjects.map(({ bindingName, className }, index) => `__voidDurableObject${index}.__bind(${JSON.stringify(bindingName)});\nexport const ${className} = __voidDurableObject${index}.class;`).join("\n");
3091
+ const durableObjectExports = durableObjects.map(({ bindingName, className, name }, index) => `__voidDurableObject${index}.__bind(${JSON.stringify(bindingName)}${name !== void 0 ? `, ${JSON.stringify(name)}` : ""});\nexport const ${className} = __voidDurableObject${index}.class;`).join("\n");
4080
3092
  const runtimeEnvImport = `import { withRuntimeEnv } from ${JSON.stringify(runtimeEnvPath)};\n`;
4081
3093
  const remoteImport = remote ? `import { createRemoteEnv } from ${JSON.stringify(remote.remotePath)};\n` : "";
4082
3094
  const envSchemaImport = envSchemaModule ? `import ${JSON.stringify(envSchemaModule.importPath)};\nimport { _validateEnvOnce } from ${JSON.stringify(envSchemaModule.helperPath)};\n` : "";
4083
3095
  const envValidateCall = envSchemaModule ? " await _validateEnvOnce(env);\n" : "";
4084
- const fetchEnvValidateCall = envSchemaModule ? " if (request.method !== \"POST\" || new URL(request.url).pathname !== \"/__void/prerender-paths\") await _validateEnvOnce(env);\n" : "";
4085
3096
  const exactNames = isr ? INTERNAL_BINDING_EXACT_NAMES : [];
4086
- const prefixCheck = [...INTERNAL_BINDING_PREFIXES.map((p) => `prop.startsWith(${JSON.stringify(p)})`), ...exactNames.map((n) => `prop === ${JSON.stringify(n)}`)].join(" || ");
4087
- const filterBindingsHelper = `
4088
- function __filterInternalBindings(env) {
4089
- return new Proxy(env, {
4090
- get(target, prop, receiver) {
4091
- if (typeof prop === "string" && (${prefixCheck})) return undefined;
4092
- return Reflect.get(target, prop, receiver);
4093
- },
4094
- has(target, prop) {
4095
- if (typeof prop === "string" && (${prefixCheck})) return false;
4096
- return Reflect.has(target, prop);
4097
- },
4098
- ownKeys(target) {
4099
- return Reflect.ownKeys(target).filter(
4100
- (key) => typeof key !== "string" || (${[...INTERNAL_BINDING_PREFIXES.map((p) => `!key.startsWith(${JSON.stringify(p)})`), ...exactNames.map((n) => `key !== ${JSON.stringify(n)}`)].join(" && ")})
4101
- );
4102
- },
4103
- getOwnPropertyDescriptor(target, prop) {
4104
- if (typeof prop === "string" && (${prefixCheck})) return undefined;
4105
- return Reflect.getOwnPropertyDescriptor(target, prop);
4106
- },
4107
- });
4108
- }
3097
+ const filterBindingsHelper = `import { filterInternalBindings as __filterBindings, createWorkerFetch as __createWorkerFetch } from ${JSON.stringify(ROUTING_RUNTIME_PATH)};
3098
+ const __filterInternalBindings = (env) => __filterBindings(env, ${JSON.stringify(INTERNAL_BINDING_PREFIXES)}, ${JSON.stringify(exactNames)});
4109
3099
  `;
4110
3100
  const assetHelper = compileAssetFallbackHelper(assetsDir, serveSpaFallback, notFound);
4111
3101
  const isrImport = isr ? `import { handleIsr } from ${JSON.stringify(isr.runtimePath)};\nimport { __VOID_ISR_REVALIDATE, __VOID_ISR_PAGES, __VOID_ISR_PATH_REVALIDATE, __VOID_ISR_DEPLOYMENT_ID } from 'virtual:void-routes';\n` : "";
4112
- const isrEnvCapture = isr ? ` env.__VOID_ISR_DEPLOYMENT_ID ??= __VOID_ISR_DEPLOYMENT_ID;\n env.__VOID_ISR_HOST = new URL(request.url).hostname;\n` : "";
4113
3102
  const isrDeploymentStamp = isr ? ` env.__VOID_ISR_DEPLOYMENT_ID ??= __VOID_ISR_DEPLOYMENT_ID;\n` : "";
4114
- const renderBlock = isr ? ` const __render = async (req) => serveWithAssets(req, env, await app.fetch(req, userEnv, ctx));
4115
- if (env.ISR_CACHE && request.headers.get("upgrade")?.toLowerCase() !== "websocket") {
4116
- const __isr = await handleIsr(request, env, ctx, { revalidate: __VOID_ISR_REVALIDATE, pages: __VOID_ISR_PAGES, pathRevalidate: __VOID_ISR_PATH_REVALIDATE, deploymentId: __VOID_ISR_DEPLOYMENT_ID, queryAllowlist: ${JSON.stringify(isr?.queryAllowlist)} }, __render);
4117
- if (__isr) return __isr;
4118
- }
4119
- return __render(request);` : ` return serveWithAssets(request, env, await app.fetch(request, userEnv, ctx));`;
4120
- const fetchHandler = remotePath ? `async (request, env, ctx) => {
4121
- ${fetchEnvValidateCall} if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};
4122
- ${isrEnvCapture} return __withRawEnv(env, () => {
4123
- const userEnv = __filterInternalBindings(env);
4124
- return withRuntimeEnv(env, async () => {
4125
- const internal = await __handleInternal(request, env, ctx);
4126
- if (internal) return internal;
4127
- ${renderBlock}
4128
- });
4129
- });
4130
- }` : `async (request, env, ctx) => {
4131
- ${fetchEnvValidateCall}${isrEnvCapture} return __withRawEnv(env, () => {
4132
- const userEnv = __filterInternalBindings(env);
4133
- return withRuntimeEnv(env, async () => {
4134
- const internal = await __handleInternal(request, env, ctx);
4135
- if (internal) return internal;
4136
- ${renderBlock}
4137
- });
4138
- });
4139
- }`;
4140
- const internalRouteHelper = `async function __handleInternal(request, env, ctx) {
4141
- const url = new URL(request.url);
4142
- ${hasEmail ? `if (url.pathname === "/__void/email/receipt/v1") return __handleEmailReceipt(request, env, ctx);` : ""}
4143
- // Readiness probe — platform polls this to confirm the worker is live after WfP upload.
4144
- // Handled here (before app.fetch) so user middleware cannot block it.
4145
- if (request.method === "GET" && url.pathname === "/__void/ready") {
4146
- return Response.json({ ready: true });
4147
- }
4148
- const routeInternal = await __voidHandleInternalRoute(request, env, ctx);
4149
- if (routeInternal) return routeInternal;
4150
- if (request.method !== "POST" || url.pathname !== "/__void/prerender-paths") return null;
4151
- const __expected = env.__VOID_PROXY_TOKEN;
4152
- if (__expected) {
4153
- const __token = request.headers.get("x-void-internal");
4154
- if (!__token || __token !== __expected) {
4155
- return Response.json({ error: "unauthorized" }, { status: 401 });
4156
- }
4157
- }
4158
- const paths = await __voidCollectPrerenderPaths(request, env, ctx);
4159
- return Response.json({ paths });
4160
- }`;
3103
+ const fetchHandler = `__createWorkerFetch({
3104
+ app, assets: serveWithAssets, withRawEnv: __withRawEnv, withRuntimeEnv,
3105
+ filterBindings: __filterInternalBindings,
3106
+ internalRoute: __voidHandleInternalRoute,
3107
+ collectPrerenderPaths: __voidCollectPrerenderPaths${versionMetadataBinding ? ", versionMetadataBinding: " + JSON.stringify(versionMetadataBinding) : ""}${envSchemaModule ? ", validateEnv: _validateEnvOnce" : ""}${remotePath ? ", remoteEnv: (env) => " + createRemoteEnvCall : ""}${hasEmail ? ", emailReceipt: __handleEmailReceipt" : ""}${isr ? ", isr: { deploymentId: __VOID_ISR_DEPLOYMENT_ID, handle: (request, env, ctx, render) => handleIsr(request, env, ctx, { revalidate: __VOID_ISR_REVALIDATE, pages: __VOID_ISR_PAGES, pathRevalidate: __VOID_ISR_PATH_REVALIDATE, deploymentId: __VOID_ISR_DEPLOYMENT_ID, queryAllowlist: " + JSON.stringify(isr.queryAllowlist) + " }, render) }" : ""}
3108
+ })`;
4161
3109
  const scheduledHandler = remotePath ? `async function handleScheduled(controller, env, ctx) {
4162
3110
  ${envValidateCall} if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};
4163
3111
  ${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
@@ -4225,7 +3173,6 @@ ${hasQueues ? ` async queue(batch) { return __voidQueue(batch, this.env, this.c
4225
3173
  }\n` : ""}}`;
4226
3174
  if (hasQueues) return `${sandboxImport}${entryImport}${liveRuntimeImport}import app, { scheduled, __voidCollectPrerenderPaths, __voidHandleInternalRoute, __withRawEnv, __processQueue${emailImport}${webSocketClasses.length > 0 ? `, ${webSocketClasses.join(", ")}` : ""}${liveRouteImport} } from 'virtual:void-routes';
4227
3175
  ${durableObjectImports}\n${runtimeEnvImport}${emailProxyImport}${envSchemaImport}${remoteImport}${isrImport}${filterBindingsHelper}${assetHelper}
4228
- ${internalRouteHelper}
4229
3176
  ${fetchDeclaration}
4230
3177
  ${scheduledHandler}
4231
3178
  ${emailHandler}
@@ -4258,7 +3205,6 @@ ${durableObjectExports}
4258
3205
  ${entryClass}`;
4259
3206
  return `${sandboxImport}${entryImport}${liveRuntimeImport}import app, { scheduled, __voidCollectPrerenderPaths, __voidHandleInternalRoute, __withRawEnv${emailImport}${webSocketClasses.length > 0 ? `, ${webSocketClasses.join(", ")}` : ""}${liveRouteImport} } from 'virtual:void-routes';
4260
3207
  ${durableObjectImports}\n${runtimeEnvImport}${emailProxyImport}${envSchemaImport}${remoteImport}${isrImport}${filterBindingsHelper}${assetHelper}
4261
- ${internalRouteHelper}
4262
3208
  ${fetchDeclaration}
4263
3209
  ${scheduledHandler}
4264
3210
  ${emailHandler}
@@ -4342,6 +3288,7 @@ export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};`;
4342
3288
  }
4343
3289
  function compileNodeClient(authClientPath) {
4344
3290
  return `import app, { requestContext } from "virtual:void-routes";
3291
+ import { interpolateRouteParams } from ${JSON.stringify(ROUTE_URL_PATH)};
4345
3292
  export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};
4346
3293
 
4347
3294
  export class FetchError extends Error {
@@ -4355,12 +3302,7 @@ export class FetchError extends Error {
4355
3302
  }
4356
3303
 
4357
3304
  export async function fetch(path, options) {
4358
- let url = path;
4359
- if (options?.params) {
4360
- for (const [key, value] of Object.entries(options.params)) {
4361
- url = url.replace(":" + key, encodeURIComponent(value));
4362
- }
4363
- }
3305
+ let url = interpolateRouteParams(path, options?.params);
4364
3306
 
4365
3307
  if (options?.query) {
4366
3308
  const qs = new URLSearchParams(options.query).toString();
@@ -4407,180 +3349,22 @@ export async function fetch(path, options) {
4407
3349
  return data;
4408
3350
  }`;
4409
3351
  }
4410
- /** Import the shared cached routing helpers only for modules that use rules. */
4411
- function ensureCompilePatternEmitted(lines) {
4412
- if (lines.some((line) => line.includes("compilePattern as __compilePattern"))) return;
4413
- lines.push(`import { compilePattern as __compilePattern, substituteParams as __substituteParams } from ${JSON.stringify(EDGE_MODULE_PATH)};`);
4414
- lines.push("const __matchPatternWarned = new Set();");
4415
- lines.push("function __matchPattern(pattern, pathname) {");
4416
- lines.push(" try {");
4417
- lines.push(" return __compilePattern(pattern).regex.test(pathname);");
4418
- lines.push(" } catch (err) {");
4419
- lines.push(" if (!__matchPatternWarned.has(pattern)) {");
4420
- lines.push(" __matchPatternWarned.add(pattern);");
4421
- lines.push(" console.warn(`[void] failed to compile route pattern ${JSON.stringify(pattern)}: ${err && err.message ? err.message : err}`);");
4422
- lines.push(" }");
4423
- lines.push(" return false;");
4424
- lines.push(" }");
4425
- lines.push("}");
4426
- lines.push("");
4427
- }
4428
- function ensureMergeQueryHelperEmitted(lines) {
4429
- if (lines.some((line) => line.includes("mergeQueryIntoLocation as __mergeQueryIntoLocation"))) return;
4430
- lines.push(`import { mergeQueryIntoLocation as __mergeQueryIntoLocation } from ${JSON.stringify(EDGE_MODULE_PATH)};`);
4431
- }
4432
- /**
4433
- * Shared body for routing-rule evaluation: match rules in order (last wins),
4434
- * substitute captures into destination, handle rewrite (200) or redirect (3xx).
4435
- * Used by both the pre-pipeline routing middleware and the post-pipeline
4436
- * fallback (notFound) middleware.
4437
- */
4438
- function emitApplyRoutingRules(lines, rulesVar, indent, nodeTarget, markFallbackHandled = false) {
4439
- lines.push(`${indent}let matched;`);
4440
- lines.push(`${indent}for (const rule of ${rulesVar}) {`);
4441
- lines.push(`${indent} if (rule.host && rule.host !== requestHost) continue;`);
4442
- lines.push(`${indent} let regex;`);
4443
- lines.push(`${indent} try {`);
4444
- lines.push(`${indent} ({ regex } = __compilePattern(rule.source));`);
4445
- lines.push(`${indent} } catch (err) {`);
4446
- lines.push(`${indent} if (!__matchPatternWarned.has(rule.source)) {`);
4447
- lines.push(`${indent} __matchPatternWarned.add(rule.source);`);
4448
- lines.push(`${indent} console.warn(\`[void] skipping routing rule with invalid source \${JSON.stringify(rule.source)}: \${err && err.message ? err.message : err}\`);`);
4449
- lines.push(`${indent} }`);
4450
- lines.push(`${indent} continue;`);
4451
- lines.push(`${indent} }`);
4452
- lines.push(`${indent} const m = regex.exec(pathname);`);
4453
- lines.push(`${indent} if (m) { matched = { rule, params: m.groups || {} }; break; }`);
4454
- lines.push(`${indent}}`);
4455
- lines.push(`${indent}if (matched) {`);
4456
- lines.push(`${indent} const dest = __substituteParams(matched.rule.destination, matched.params);`);
4457
- lines.push(`${indent} if (matched.rule.status === 200) {`);
4458
- lines.push(`${indent} const __qIdx = dest.indexOf("?");`);
4459
- lines.push(`${indent} const __pathOnly = __qIdx === -1 ? dest : dest.slice(0, __qIdx);`);
4460
- lines.push(`${indent} const __searchOnly = __qIdx === -1 ? "" : dest.slice(__qIdx);`);
4461
- lines.push(`${indent} const rewriteUrl = new URL(c.req.url);`);
4462
- lines.push(`${indent} rewriteUrl.pathname = __pathOnly;`);
4463
- lines.push(`${indent} if (__searchOnly) rewriteUrl.search = __searchOnly;`);
4464
- lines.push(`${indent} const rewriteReq = new Request(rewriteUrl.toString(), c.req.raw);`);
4465
- lines.push(`${indent} const __prior = __voidOriginalUrls.get(c.req.raw);`);
4466
- lines.push(`${indent} __voidOriginalUrls.set(rewriteReq, __prior ?? new URL(c.req.url));`);
4467
- if (markFallbackHandled) lines.push(`${indent} __voidFallbackHandled.add(rewriteReq);`);
4468
- if (nodeTarget) lines.push(`${indent} const __r = await app.fetch(rewriteReq, c.env);`);
4469
- else lines.push(`${indent} const __r = await app.fetch(rewriteReq, c.env, c.executionCtx);`);
4470
- lines.push(`${indent} if (!__VOID_DEV_ROUTING) return __r;`);
4471
- lines.push(`${indent} const __kind = matched.rule.force === true ? "rewrite" : "fallback";`);
4472
- lines.push(`${indent} const __trace = __kind + "[" + matched.rule.source + "] -> " + dest + " (" + (matched.rule.origin || "unknown") + ")";`);
4473
- lines.push(`${indent} return __voidAnnotateRouting(__r, __trace);`);
4474
- lines.push(`${indent} }`);
4475
- lines.push(`${indent} const location = __mergeQueryIntoLocation(dest, new URL(c.req.url).search);`);
4476
- lines.push(`${indent} const __redir = c.redirect(location, matched.rule.status);`);
4477
- lines.push(`${indent} if (!__VOID_DEV_ROUTING) return __redir;`);
4478
- lines.push(`${indent} const __rtrace = "redirect[" + matched.rule.source + "] -> " + dest + " " + matched.rule.status + " (" + (matched.rule.origin || "unknown") + ")";`);
4479
- lines.push(`${indent} return __voidAnnotateRouting(__redir, __rtrace);`);
4480
- lines.push(`${indent}}`);
4481
- }
4482
- /**
4483
- * Strip dev-only `origin` metadata from a rule list before embedding in the
4484
- * generated worker code. Keeps production bundles free of authoring hints.
4485
- *
4486
- * Keep in sync with `stripDevOnlyRuleFields` in `cli/package.ts`. This helper
4487
- * intentionally preserves `force` because the Node/Bun/Deno-target codegen
4488
- * reads it at runtime to label the `X-Void-Routing` trace header as either
4489
- * `rewrite[...]` (force) or `fallback[...]`. The CLI version strips both
4490
- * fields because the deploy manifest never transmits either to the dispatch
4491
- * worker (phase is implied by which bucket the rule ships in).
4492
- */
4493
3352
  function stripOriginForProd(rules) {
4494
3353
  return rules.map(({ origin: _origin, ...rest }) => rest);
4495
3354
  }
4496
- /**
4497
- * Emit routing rules middleware — handles both redirects (3xx) and rewrites (200).
4498
- * Last match wins. Rewrites re-dispatch with a guard header to prevent loops.
4499
- * Redirects preserve the request's query string in the Location header.
4500
- *
4501
- * When `dev === true` the per-rule `origin` metadata is preserved in the
4502
- * compiled rule table and a matched rule's trace is emitted on the
4503
- * `X-Void-Routing` response header. In production the origin field is
4504
- * stripped and no trace header is emitted.
4505
- */
4506
- function compileRoutingRulesMiddleware(lines, rules, dev, nodeTarget) {
4507
- ensureCompilePatternEmitted(lines);
3355
+ function compileRoutingRulesMiddleware(lines, rules, dev, _nodeTarget) {
4508
3356
  lines.push("// Routing rules: redirects + rewrites (applied before route handlers)");
4509
3357
  lines.push(`const __routingRules = ${JSON.stringify(dev ? rules : stripOriginForProd(rules))};`);
4510
- lines.push("app.use(\"*\", async (c, next) => {");
4511
- lines.push(" if (__voidOriginalUrls.has(c.req.raw)) return next();");
4512
- lines.push(" const __reqUrl = new URL(c.req.url);");
4513
- lines.push(" const pathname = __reqUrl.pathname;");
4514
- lines.push(" const requestHost = __reqUrl.hostname;");
4515
- emitApplyRoutingRules(lines, "__routingRules", " ", nodeTarget);
4516
- if (dev) {
4517
- lines.push(" await next();");
4518
- lines.push(" if (__VOID_DEV_ROUTING && c.res && !c.res.headers.has(\"X-Void-Routing\")) {");
4519
- lines.push(" try { c.res.headers.set(\"X-Void-Routing\", \"pass-through\"); } catch {}");
4520
- lines.push(" }");
4521
- } else lines.push(" return next();");
4522
- lines.push("});");
4523
- lines.push("");
4524
- }
4525
- /**
4526
- * Emit a fallback-rule check inside Hono's `notFound` hook. Fires only when
4527
- * the pipeline didn't match a route — the "asset-miss / no route matched"
4528
- * phase. Re-dispatches through `app.fetch` on a rule match so the re-dispatched
4529
- * request runs through the full middleware + route stack with
4530
- * `X-Void-Original-URL` set; falls through to the caller's existing notFound
4531
- * body when no rule matches.
4532
- *
4533
- * Indent `indent` so the emitted statements nest cleanly within the caller's
4534
- * block. Expects `__matchPattern`, `__voidOriginalUrls`, `__mergeQueryIntoLocation`,
4535
- * `__substituteParams`, and `__voidAnnotateRouting` to already be in scope —
4536
- * which they are, because `compileRoutingRulesMiddleware` runs earlier in
4537
- * compile order and emits every one of them.
4538
- */
4539
- function emitFallbackRulesCheck(lines, rules, dev, indent, nodeTarget) {
4540
- ensureCompilePatternEmitted(lines);
4541
- const tableMarker = "// Fallback rules (applied on no-match, post-route)";
4542
- if (!lines.includes(tableMarker)) {
4543
- lines.push(tableMarker);
4544
- lines.push(`const __fallbackRules = ${JSON.stringify(dev ? rules : stripOriginForProd(rules))};`);
4545
- lines.push("");
4546
- }
4547
- lines.push(`${indent}if (!__voidFallbackHandled.has(c.req.raw)) {`);
4548
- lines.push(`${indent} const __reqUrl = new URL(c.req.url);`);
4549
- lines.push(`${indent} const pathname = __reqUrl.pathname;`);
4550
- lines.push(`${indent} const requestHost = __reqUrl.hostname;`);
4551
- emitApplyRoutingRules(lines, "__fallbackRules", `${indent} `, nodeTarget, true);
4552
- lines.push(`${indent}}`);
3358
+ lines.push("app.use(\"*\", __routingRuntime.routingMiddleware(__routingRules));");
4553
3359
  }
4554
- /**
4555
- * Emit header middleware — applies matching header rules to every response.
4556
- * All matching rules merge; last match wins for same header name.
4557
- */
4558
3360
  function compileHeaderMiddleware(lines, rules) {
4559
- ensureCompilePatternEmitted(lines);
4560
3361
  lines.push("// Header rules (applied to responses)");
4561
3362
  lines.push(`const __headerRules = ${JSON.stringify(rules)};`);
4562
- lines.push("app.use(\"*\", async (c, next) => {");
4563
- lines.push(" await next();");
4564
- lines.push(" const pathname = new URL(c.req.url).pathname;");
4565
- lines.push(" const matched = [];");
4566
- lines.push(" for (const rule of __headerRules) {");
4567
- lines.push(" if (__matchPattern(rule.pattern, pathname)) matched.push(...rule.headers);");
4568
- lines.push(" }");
4569
- lines.push(" if (matched.length === 0) return;");
4570
- lines.push(" const headers = new Headers(c.res.headers);");
4571
- lines.push(" for (const [name, value] of matched) {");
4572
- lines.push(" headers.set(name, value);");
4573
- lines.push(" }");
4574
- lines.push(" c.res = new Response(c.res.body, {");
4575
- lines.push(" headers,");
4576
- lines.push(" status: c.res.status,");
4577
- lines.push(" statusText: c.res.statusText,");
4578
- lines.push(" });");
4579
- lines.push("});");
4580
- lines.push("");
3363
+ lines.push("app.use(\"*\", __routingRuntime.headerMiddleware(__headerRules));");
4581
3364
  }
4582
3365
  function compileWorkerClient(authClientPath) {
4583
3366
  return `import app, { requestContext } from "virtual:void-routes";
3367
+ import { interpolateRouteParams } from ${JSON.stringify(ROUTE_URL_PATH)};
4584
3368
  import { env } from "cloudflare:workers";
4585
3369
  export { auth, createAuthClient } from ${JSON.stringify(authClientPath)};
4586
3370
 
@@ -4595,12 +3379,7 @@ export class FetchError extends Error {
4595
3379
  }
4596
3380
 
4597
3381
  export async function fetch(path, options) {
4598
- let url = path;
4599
- if (options?.params) {
4600
- for (const [key, value] of Object.entries(options.params)) {
4601
- url = url.replace(":" + key, encodeURIComponent(value));
4602
- }
4603
- }
3382
+ let url = interpolateRouteParams(path, options?.params);
4604
3383
 
4605
3384
  if (options?.query) {
4606
3385
  const qs = new URLSearchParams(options.query).toString();
@@ -4706,13 +3485,20 @@ function routingPlugin(root, options) {
4706
3485
  const dts = generateQueueTypes(scan.queues, queuesDir, outDir);
4707
3486
  writeFileIfChanged(join(outDir, "queues.d.ts"), dts);
4708
3487
  }
4709
- async function rescan() {
4710
- scan = await scanRoutes(root, {
4711
- output: options.output,
4712
- paths,
4713
- environment: routeEnvironment
4714
- });
4715
- authConfigPath = findVoidAuthConfig(root, paths);
3488
+ async function rescan(refresh = false) {
3489
+ let analysis = options.getApplicationAnalysis?.(routeEnvironment, refresh);
3490
+ if (!analysis) {
3491
+ const config = readConfig(root);
3492
+ analysis = analyzeApplicationSync(root, {
3493
+ config: {
3494
+ ...config,
3495
+ output: options.output ?? config.output
3496
+ },
3497
+ environment: routeEnvironment
3498
+ });
3499
+ }
3500
+ scan = (await completeApplicationAnalysis(analysis)).scan;
3501
+ authConfigPath = analysis.authConfigPath;
4716
3502
  const entries = validateSsrEntries(root, paths);
4717
3503
  ssr = entries ? {
4718
3504
  serverEntryPath: entries.server.absolutePath,
@@ -4748,8 +3534,6 @@ function routingPlugin(root, options) {
4748
3534
  }
4749
3535
  const compileOptions = {
4750
3536
  honoPath: resolveFile("hono"),
4751
- responsePath: resolveFile("#self/response"),
4752
- handlerPath: resolveFile("#self/handler"),
4753
3537
  runtimeEnvPath: resolveFile("#self/_env"),
4754
3538
  runtimeEmailPath: resolveFile("#self/email"),
4755
3539
  emailDir,
@@ -4856,8 +3640,6 @@ function routingPlugin(root, options) {
4856
3640
  return {
4857
3641
  pagesDir,
4858
3642
  pagesDirRelative: relative(root, pagesDir).replaceAll("\\", "/"),
4859
- protocolPath: resolveFile("#self/pages-protocol"),
4860
- headPath: resolveFile("#self/pages-head"),
4861
3643
  clientEntryId: "virtual:void-pages-client",
4862
3644
  islandClientEntryId: hasIslandPages ? "virtual:void-islands-client" : void 0,
4863
3645
  mdClientEntryId,
@@ -4907,6 +3689,7 @@ function routingPlugin(root, options) {
4907
3689
  writeFileIfChanged(join(outDir, "app.ts"), compileNodeApp(options.target, compileOptions.honoPath, getEnvSchemaModule()));
4908
3690
  writeFileIfChanged(join(outDir, "index.ts"), compileNodeServer(options.target));
4909
3691
  } else writeFileIfChanged(join(outDir, "entry.ts"), compileWorkerEntry({
3692
+ versionMetadataBinding: options.getVersionMetadataBinding?.(),
4910
3693
  remote,
4911
3694
  webSocketClasses: options.websocketTombstones,
4912
3695
  runtimeEnvPath: compileOptions.runtimeEnvPath,
@@ -4915,6 +3698,7 @@ function routingPlugin(root, options) {
4915
3698
  sandbox: options.hasSandbox ? {
4916
3699
  bindingName: options.sandboxBindingName,
4917
3700
  className: options.sandboxClassName,
3701
+ instanceType: options.sandboxInstanceType,
4918
3702
  runtimePath: sandboxRuntimePath
4919
3703
  } : false,
4920
3704
  live: options.live,
@@ -4927,6 +3711,7 @@ function routingPlugin(root, options) {
4927
3711
  resolvedConfig = config;
4928
3712
  authClientPath = resolveAuthClientPath(config);
4929
3713
  compileOptions.dev = config.command === "serve";
3714
+ compileOptions.assetsDir = config.build.assetsDir;
4930
3715
  compileOptions.reactRefresh = config.plugins.some((plugin) => plugin.name === "vite:react-babel" || plugin.name === "vite:react-refresh" || plugin.name === "vite:react-swc");
4931
3716
  const resolvedPublicDir = config.publicDir && config.publicDir.length > 0 ? config.publicDir : null;
4932
3717
  if (resolvedPublicDir !== publicDir) {
@@ -4955,12 +3740,19 @@ function routingPlugin(root, options) {
4955
3740
  }
4956
3741
  }) } };
4957
3742
  const entries = validateSsrEntries(root, paths);
4958
- if (!entries || env.command !== "build") return;
3743
+ if (env.command !== "build") return;
4959
3744
  return { build: {
4960
- manifest: true,
4961
- rollupOptions: { input: entries.client.absolutePath }
3745
+ manifest: entries ? true : _.build?.manifest ?? true,
3746
+ ...entries ? { rollupOptions: { input: entries.client.absolutePath } } : {}
4962
3747
  } };
4963
3748
  },
3749
+ generateBundle: {
3750
+ order: "post",
3751
+ handler(_output, bundle) {
3752
+ const manifest = this.environment.config.build.manifest;
3753
+ if (this.environment.name === "client" && manifest) stampClientAssetCachePolicy(bundle, typeof manifest === "string" ? manifest : ".vite/manifest.json", compileOptions.headerRules);
3754
+ }
3755
+ },
4964
3756
  async buildStart() {
4965
3757
  await rescan();
4966
3758
  if (options.target && (scan?.websockets?.length ?? 0) > 0) throw new Error("routing: WebSocket routes require the default Cloudflare target.");
@@ -4972,7 +3764,7 @@ function routingPlugin(root, options) {
4972
3764
  const migrationsDir = paths.migrationsDir;
4973
3765
  if (existsSync(migrationsDir) || compileOptions.auth) {
4974
3766
  const { collectMigrations } = await import("./collect-DLyFDiKW.mjs");
4975
- const { buildMigrationPlanBundle } = await import("./plan-DpuOr14e.mjs");
3767
+ const { buildMigrationPlanBundle } = await import("./plan-D1Q5rf-r.mjs");
4976
3768
  const migrations = existsSync(migrationsDir) ? collectMigrations(migrationsDir) : [];
4977
3769
  const dialect = getDatabaseDialect(readConfig(root));
4978
3770
  compileOptions.migrationHandlerPath = resolveFile(dialect === "postgresql" ? "#self/runtime/migration-handler-pg" : dialect === "mysql" ? "#self/runtime/migration-handler-mysql" : "#self/runtime/migration-handler");
@@ -4997,6 +3789,7 @@ function routingPlugin(root, options) {
4997
3789
  queryAllowlist: buildConfig.routing?.revalidateQueryAllowlist
4998
3790
  } : void 0;
4999
3791
  writeFileIfChanged(join(outDir, "entry.ts"), compileWorkerEntry({
3792
+ versionMetadataBinding: options.getVersionMetadataBinding?.(),
5000
3793
  hasQueues: scan.queues.length > 0,
5001
3794
  remote,
5002
3795
  assetsDir: resolvedConfig?.build.assetsDir,
@@ -5007,6 +3800,7 @@ function routingPlugin(root, options) {
5007
3800
  sandbox: options.hasSandbox ? {
5008
3801
  bindingName: options.sandboxBindingName,
5009
3802
  className: options.sandboxClassName,
3803
+ instanceType: options.sandboxInstanceType,
5010
3804
  runtimePath: sandboxRuntimePath
5011
3805
  } : false,
5012
3806
  hasEmail: hasEmailHandlers(),
@@ -5050,7 +3844,7 @@ function routingPlugin(root, options) {
5050
3844
  const sourceConventionChanged = isInDirectory(normalizedPath, normalizedRoutesDir) || isInDirectory(normalizedPath, normalizedMiddlewareDir) || isInDirectory(normalizedPath, normalizedJobsDir) || isInDirectory(normalizedPath, normalizedQueuesDir) || isInDirectory(normalizedPath, normalizedEmailDir) || isInDirectory(normalizedPath, normalizedPagesDir) || isPotentialAuthConfigPath(normalizedPath) || isPotentialEnvFilePath(normalizedPath);
5051
3845
  if (!sourceConventionChanged && !isInDirectory(normalizedPath, normalizedSsrDir) && !isPotentialEnvFilePath(normalizedPath)) return;
5052
3846
  if (!sourceConventionChanged && isInDirectory(normalizedPath, normalizedSsrDir) && !ssrEntryAbsPaths.has(normalizedPath)) return;
5053
- await rescan();
3847
+ await rescan(true);
5054
3848
  resolveAuthCompileOptions();
5055
3849
  if (event !== "change" && options.onDevAssetRoutingPolicyChange?.(resolveCurrentAssetRoutingPolicy()) === true) {
5056
3850
  await devServer.restart();
@@ -5063,6 +3857,7 @@ function routingPlugin(root, options) {
5063
3857
  writeFileIfChanged(join(outDir, "app.ts"), compileNodeApp(options.target, compileOptions.honoPath, getEnvSchemaModule()));
5064
3858
  writeFileIfChanged(join(outDir, "index.ts"), compileNodeServer(options.target));
5065
3859
  } else writeFileIfChanged(join(outDir, "entry.ts"), compileWorkerEntry({
3860
+ versionMetadataBinding: options.getVersionMetadataBinding?.(),
5066
3861
  hasQueues: scan.queues.length > 0,
5067
3862
  remote,
5068
3863
  assetsDir: resolvedConfig?.build.assetsDir,
@@ -5073,6 +3868,7 @@ function routingPlugin(root, options) {
5073
3868
  sandbox: options.hasSandbox ? {
5074
3869
  bindingName: options.sandboxBindingName,
5075
3870
  className: options.sandboxClassName,
3871
+ instanceType: options.sandboxInstanceType,
5076
3872
  runtimePath: sandboxRuntimePath
5077
3873
  } : false,
5078
3874
  hasEmail: hasEmailHandlers(),
@@ -5540,8 +4336,8 @@ function readVoidDevCredentials(root) {
5540
4336
  * block the server. On completion, writes project.json and restarts the server.
5541
4337
  */
5542
4338
  async function runAiSetupPrompt(root, token, apiUrl, server) {
5543
- const { select, text, isCancel, log } = await import("./dist-C5fND3R0.mjs");
5544
- const { PlatformClient } = await import("./client-4cDVv7BO.mjs");
4339
+ const { select, text, isCancel, log } = await import("./dist-BuDuKZJv.mjs");
4340
+ const { PlatformClient } = await import("./client-Cu7jWiF1.mjs");
5545
4341
  const { attachSelectedPlatform, writeProjectConfig } = await import("./project-BuUwfj6f.mjs");
5546
4342
  const { inferDefaultSlug } = await import("./resolve-project-DtbidV4y.mjs");
5547
4343
  const client = new PlatformClient(token, apiUrl);
@@ -5570,7 +4366,7 @@ async function runAiSetupPrompt(root, token, apiUrl, server) {
5570
4366
  let slug;
5571
4367
  if (result === "__create__") {
5572
4368
  const { validateProjectSlug } = await import("./project-slug-DofjTFd-.mjs");
5573
- const { createProjectWithSlugRetry } = await import("./create-project-BniEV0OW.mjs");
4369
+ const { createProjectWithSlugRetry } = await import("./create-project-Boczwj5r.mjs");
5574
4370
  let created;
5575
4371
  try {
5576
4372
  created = await createProjectWithSlugRetry(client, inferDefaultSlug(root), async (defaultSlug) => {
@@ -5656,15 +4452,26 @@ function voidPlugin(options) {
5656
4452
  }
5657
4453
  }
5658
4454
  };
5659
- const paths = resolveProjectPaths(root, config);
4455
+ let application = analyzeApplicationSync(root, { config });
4456
+ const { paths, dialect, bindingNames, authConfigPath } = application;
4457
+ const analyses = /* @__PURE__ */ new Map([[void 0, application]]);
4458
+ const getApplicationAnalysis = (environment, refresh = false) => {
4459
+ let result = refresh ? void 0 : analyses.get(environment);
4460
+ if (!result) {
4461
+ result = analyzeApplicationSync(root, {
4462
+ config,
4463
+ environment
4464
+ });
4465
+ analyses.set(environment, result);
4466
+ }
4467
+ application = result;
4468
+ return result;
4469
+ };
5660
4470
  let routeEnvironment = "prod";
5661
4471
  assertNoRootSourceConventionConflicts(paths);
5662
- const dialect = getDatabaseDialect(config);
5663
- const detected = detectFramework(root);
4472
+ const detected = application.framework;
5664
4473
  const framework = detected?.class === "a" ? detected.name : void 0;
5665
4474
  const scanDirs = config.inference?.scanDirs ?? (detected ? FRAMEWORK_SCAN_DIRS : void 0);
5666
- const inferenceOptions = config.inference?.bindings ? { bindings: config.inference.bindings } : void 0;
5667
- const bindingNames = resolveBindingNames(config.inference?.bindings);
5668
4475
  const frameworkOwnsCloudflareRuntime = detected !== void 0 && (detected.class === "b" || detected.class === "c");
5669
4476
  const localD1PersistRoot = frameworkOwnsCloudflareRuntime ? join(root, ".wrangler", "state") : options?.persistTo ?? join(root, ".void");
5670
4477
  const localD1 = resolveLocalD1Target(root, {
@@ -5672,22 +4479,13 @@ function voidPlugin(options) {
5672
4479
  persistRoot: localD1PersistRoot
5673
4480
  });
5674
4481
  writeLocalD1PersistState(root, !isNodeTarget(config.target) && !frameworkOwnsCloudflareRuntime ? options?.persistTo : void 0);
5675
- const inferredBindings = inferProjectBindings(root, {
5676
- ...inferenceOptions,
5677
- paths
5678
- }, scanDirs);
5679
- const sandboxEnabled = isSandboxEnabled(config);
5680
- let bindings = sandboxEnabled ? {
5681
- ...inferredBindings,
5682
- needsSandbox: true
5683
- } : inferredBindings;
4482
+ let bindings = application.bindings;
5684
4483
  const sandboxConfig = bindings.needsSandbox ? resolveSandboxConfig(config, root) : void 0;
5685
- const authConfigPath = findVoidAuthConfig(root, paths);
5686
- let authEnabled = bindings.needsAuth || authConfigPath !== null || config.auth !== void 0;
4484
+ let authEnabled = application.authEnabled;
5687
4485
  if (detected && authEnabled) throw new Error("auth: Void-managed Better Auth is only supported in Void apps. Use Better Auth's official integration for this framework instead.");
5688
4486
  if (detected && bindings.needsSandbox) throw new Error("sandbox: Cloudflare Sandboxes are currently supported in Void apps only.");
5689
4487
  if (detected && bindings.needsLive) throw new Error("live: void/live is currently supported in Void apps only.");
5690
- const hasInboundEmail = hasEmailHandlers(scanEmailHandlersSync(paths.sourceRoot));
4488
+ const hasInboundEmail = hasEmailHandlers(application.email);
5691
4489
  if (detected && hasInboundEmail) throw new Error("email: inbound email handlers are only supported in Void apps. Remove the email/ directory — `sendEmail` from void/email keeps working.");
5692
4490
  const STUB_PREFIX = "\0void-client-stub:";
5693
4491
  const SERVER_ONLY_STUBS = {
@@ -5764,9 +4562,9 @@ function voidPlugin(options) {
5764
4562
  if (name !== "client") return { optimizeDeps: { exclude: ["void"] } };
5765
4563
  }
5766
4564
  };
5767
- const queues = framework ? [] : scanQueuesSync(root, paths.queuesDir);
5768
- const websocketRoutes = framework ? [] : scanWebSocketRoutesSync(root, paths);
5769
- const durableObjects = scanDurableObjectModules(root);
4565
+ const queues = framework ? [] : application.queues;
4566
+ const websocketRoutes = framework ? [] : application.allWebsockets;
4567
+ const durableObjects = application.durableObjects;
5770
4568
  if (detected && durableObjects.length > 0) throw new Error("durable: durable-objects/ is currently supported in Void apps only, not framework adapter mode.");
5771
4569
  for (const module of durableObjects) {
5772
4570
  const websocketCollision = websocketRoutes.find((route) => route.bindingName === module.bindingName || route.className === module.className);
@@ -5815,7 +4613,7 @@ function voidPlugin(options) {
5815
4613
  if (command !== "serve") return;
5816
4614
  if (syncWranglerBindings(root, {
5817
4615
  ...bindings,
5818
- needsD1: dialect === "sqlite" && bindings.needsD1
4616
+ needsD1: dialect === "sqlite" && application.needsDatabase
5819
4617
  }, {
5820
4618
  bindingNames,
5821
4619
  ...directCloudflareDestination && bindings.needsAI ? { directCloudflareAi: { gateway: config.ai?.gateway } } : {},
@@ -5891,12 +4689,13 @@ function voidPlugin(options) {
5891
4689
  }
5892
4690
  const remoteMode = resolveRemoteMode(config.remote);
5893
4691
  const workerConfig = {};
5894
- const jobs = scanJobsSync(root, paths.cronsDir);
4692
+ const jobs = application.jobs;
5895
4693
  if (jobs.length > 0) workerConfig.triggers = { crons: [...new Set(jobs.flatMap((job) => job.crons))] };
5896
4694
  let envSchemaFacts;
5897
4695
  let assetRouting;
5898
4696
  if (config.worker?.vars) workerConfig.vars = { ...config.worker.vars };
5899
4697
  let viteCommand = "build";
4698
+ let versionMetadataBinding;
5900
4699
  const wranglerCompat = isNodeTarget(config.target) ? void 0 : readWranglerCompat(root, config);
5901
4700
  if (wranglerCompat) {
5902
4701
  workerConfig.compatibility_date = wranglerCompat.compatibilityDate;
@@ -5934,7 +4733,7 @@ function voidPlugin(options) {
5934
4733
  }
5935
4734
  const d1Name = bindingNames?.d1 ?? "DB";
5936
4735
  const d1 = [];
5937
- if (dialect === "sqlite" && (bindings.needsD1 || authEnabled) && !hasBinding(resolved.d1_databases, d1Name)) d1.push({
4736
+ if (dialect === "sqlite" && application.needsDatabase && !hasBinding(resolved.d1_databases, d1Name)) d1.push({
5938
4737
  binding: d1Name,
5939
4738
  database_name: "default",
5940
4739
  database_id: "local"
@@ -6038,23 +4837,20 @@ function voidPlugin(options) {
6038
4837
  if (migrationAdditions.length > 0) result.migrations = [...existingMigrations, ...migrationAdditions];
6039
4838
  }
6040
4839
  if (bindings.needsSandbox && sandboxConfig) {
4840
+ assertSandboxNamespaceConfig({
4841
+ ...resolved,
4842
+ ...result
4843
+ }, sandboxConfig);
6041
4844
  const existingDurableObjectBindings = (result.durable_objects ?? resolved.durable_objects)?.bindings ?? [];
6042
4845
  if (!existingDurableObjectBindings.some((binding) => binding.name === sandboxConfig.binding)) result.durable_objects = { bindings: [...existingDurableObjectBindings, {
6043
4846
  name: sandboxConfig.binding,
6044
4847
  class_name: sandboxConfig.className
6045
4848
  }] };
6046
- const existingContainers = result.containers ?? resolved.containers ?? [];
6047
- if (!existingContainers.some((container) => container.class_name === sandboxConfig.className)) result.containers = [...existingContainers, {
6048
- name: sandboxConfig.containerName,
6049
- class_name: sandboxConfig.className,
6050
- image: sandboxConfig.image,
6051
- ...sandboxConfig.imageBuildContext && { image_build_context: sandboxConfig.imageBuildContext },
6052
- ...sandboxConfig.instanceType && { instance_type: sandboxConfig.instanceType },
6053
- ...sandboxConfig.maxInstances != null && { max_instances: sandboxConfig.maxInstances }
6054
- }];
4849
+ result.containers = [...(result.containers ?? resolved.containers ?? []).filter((container) => container.class_name !== sandboxConfig.className), sandboxContainerConfig(sandboxConfig)];
4850
+ resolved.containers = [];
6055
4851
  const currentMigrations = result.migrations ?? resolved.migrations;
6056
4852
  const existingMigrations = Array.isArray(currentMigrations) ? currentMigrations : [];
6057
- if (!existingMigrations.some((migration) => migration.tag === "void-sandbox-v1" || migration.new_sqlite_classes?.includes(sandboxConfig.className))) result.migrations = [...existingMigrations, {
4853
+ if (!hasSandboxSqliteMigration(existingMigrations, sandboxConfig.className)) result.migrations = [...existingMigrations, {
6058
4854
  tag: SANDBOX_MIGRATION_TAG,
6059
4855
  new_sqlite_classes: [sandboxConfig.className]
6060
4856
  }];
@@ -6096,6 +4892,33 @@ function voidPlugin(options) {
6096
4892
  result.vars = vars;
6097
4893
  }
6098
4894
  }
4895
+ versionMetadataBinding = selectNativeVersionMetadataBinding(resolved, {
4896
+ nativeBuild: viteCommand === "build" && process.env["VOID_CLOUDFLARE_DEPLOY_BUILD"] === "1",
4897
+ preserveBindings: process.env[CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV] === "1"
4898
+ });
4899
+ if (versionMetadataBinding) {
4900
+ const owner = findBindingNameOwner(result, "version_metadata", versionMetadataBinding);
4901
+ if (owner) throw new Error(`Cloudflare version metadata binding ${versionMetadataBinding} conflicts with ${owner}.`);
4902
+ if (!resolved.version_metadata) result.version_metadata = { binding: versionMetadataBinding };
4903
+ }
4904
+ finalizeDurableObjectPatch(resolved, result, [
4905
+ ...environmentWebsocketRoutes.map((route) => ({
4906
+ name: route.bindingName,
4907
+ class_name: route.className
4908
+ })),
4909
+ ...durableObjects.map((module) => ({
4910
+ name: module.bindingName,
4911
+ class_name: module.className
4912
+ })),
4913
+ ...bindings.needsSandbox && sandboxConfig ? [{
4914
+ name: sandboxConfig.binding,
4915
+ class_name: sandboxConfig.className
4916
+ }] : [],
4917
+ ...shouldEmitLive() && liveConfig ? [{
4918
+ name: liveConfig.bindingName,
4919
+ class_name: liveConfig.className
4920
+ }] : []
4921
+ ]);
6099
4922
  return result;
6100
4923
  }
6101
4924
  function applyEnvSchema(facts) {
@@ -6106,16 +4929,9 @@ function voidPlugin(options) {
6106
4929
  config(userConfig, { command, isPreview }) {
6107
4930
  viteCommand = command;
6108
4931
  routeEnvironment = command === "serve" && !isPreview ? "dev" : "prod";
6109
- const environmentBindings = inferProjectBindings(root, {
6110
- ...inferenceOptions,
6111
- paths,
6112
- environment: routeEnvironment
6113
- }, scanDirs);
6114
- bindings = sandboxEnabled ? {
6115
- ...environmentBindings,
6116
- needsSandbox: true
6117
- } : environmentBindings;
6118
- authEnabled = bindings.needsAuth || authConfigPath !== null || config.auth !== void 0;
4932
+ application = getApplicationAnalysis(routeEnvironment);
4933
+ bindings = application.bindings;
4934
+ authEnabled = application.authEnabled;
6119
4935
  if (command === "serve" && directCloudflareDestination && bindings.needsAI) process.env.CLOUDFLARE_AUTH_USE_KEYRING = "true";
6120
4936
  if (!framework && !isNodeTarget(config.target)) {
6121
4937
  managedCloudflareBuild = command === "build" && Boolean(process.env.VOID_DEPLOY_PROJECT_ID);
@@ -6194,13 +5010,11 @@ function voidPlugin(options) {
6194
5010
  }
6195
5011
  }
6196
5012
  };
6197
- const autoDetectBindings = !inferenceOptions;
6198
5013
  const autoDetectAuth = !authEnabled;
6199
5014
  const bindingWatchPlugin = {
6200
5015
  name: "void:binding-watch",
6201
5016
  apply: "serve",
6202
5017
  configureServer(server) {
6203
- if (!autoDetectBindings && !autoDetectAuth) return;
6204
5018
  const watchDirs = [.../* @__PURE__ */ new Set([...scanDirs ?? DEFAULT_SCAN_DIRS, "src"])].map((d) => join(root, d));
6205
5019
  let hintShown = false;
6206
5020
  const check = (path) => {
@@ -6208,16 +5022,14 @@ function voidPlugin(options) {
6208
5022
  if (!watchDirs.some((d) => path.startsWith(d))) return;
6209
5023
  try {
6210
5024
  const code = readFileSync(path, "utf-8");
6211
- const fileBindings = inferBindingsFromSource(code, path.split("/").pop());
5025
+ const fileBindings = applyBindingOverrides(inferBindingsFromSource(code, path.split("/").pop()), config.inference?.bindings);
6212
5026
  const newBindings = [];
6213
- if (autoDetectBindings) {
6214
- if (fileBindings.needsD1 && !bindings.needsD1) newBindings.push("D1 (void/db)");
6215
- if (fileBindings.needsKV && !bindings.needsKV) newBindings.push("KV (void/kv)");
6216
- if (fileBindings.needsR2 && !bindings.needsR2) newBindings.push("R2 (void/storage)");
6217
- if (fileBindings.needsAI && !bindings.needsAI) newBindings.push("AI (void/ai)");
6218
- if (fileBindings.needsSandbox && !bindings.needsSandbox) newBindings.push("Sandbox (void/sandbox)");
6219
- if (fileBindings.needsEmail && !bindings.needsEmail) newBindings.push("Email (void/email)");
6220
- }
5027
+ if (fileBindings.needsD1 && !bindings.needsD1) newBindings.push("D1 (void/db)");
5028
+ if (fileBindings.needsKV && !bindings.needsKV) newBindings.push("KV (void/kv)");
5029
+ if (fileBindings.needsR2 && !bindings.needsR2) newBindings.push("R2 (void/storage)");
5030
+ if (fileBindings.needsAI && !bindings.needsAI) newBindings.push("AI (void/ai)");
5031
+ if (fileBindings.needsSandbox && !bindings.needsSandbox) newBindings.push("Sandbox (void/sandbox)");
5032
+ if (fileBindings.needsEmail && !bindings.needsEmail) newBindings.push("Email (void/email)");
6221
5033
  if (autoDetectAuth && fileBindings.needsAuth) newBindings.push("Auth (void/auth)");
6222
5034
  if (newBindings.length > 0) {
6223
5035
  hintShown = true;
@@ -6287,14 +5099,14 @@ function voidPlugin(options) {
6287
5099
  clientStubsPlugin,
6288
5100
  serverRuntimeOptimizerPlugin,
6289
5101
  bindingRuntimePlugin(bindingNames),
6290
- drizzlePlugin(root, false, getDatabaseDialect(config), {
5102
+ drizzlePlugin(root, false, dialect, {
6291
5103
  d1BindingName: bindingNames?.d1,
6292
5104
  forceVirtualDb: authEnabled || bindingNames?.d1 !== void 0,
6293
5105
  localD1DatabaseId: localD1.databaseId,
6294
5106
  localD1PersistRoot: localD1.persistRoot,
6295
5107
  redirectDbTypePaths
6296
5108
  }),
6297
- migrationPlugin(root, getDatabaseDialect(config), localD1.databaseId, localD1.persistRoot),
5109
+ migrationPlugin(root, dialect, localD1.databaseId, localD1.persistRoot),
6298
5110
  ...vinextCompat ? [vinextCompat] : [],
6299
5111
  frameworkBuildWrapperPlugin,
6300
5112
  frameworkTriggersPlugin(root, { devTriggerToken }),
@@ -6330,6 +5142,7 @@ function voidPlugin(options) {
6330
5142
  envSchemaPlugin(root),
6331
5143
  ...pagesDevCssAssetsPlugin(root, devTriggerToken),
6332
5144
  routingPlugin(root, {
5145
+ getApplicationAnalysis,
6333
5146
  isAuthEnabled: () => false,
6334
5147
  devTriggerToken,
6335
5148
  headConfig: config.head,
@@ -6349,18 +5162,17 @@ function voidPlugin(options) {
6349
5162
  if (normalizedFlags && normalizedFlags !== existingFlags) workerConfig.compatibility_flags = normalizedFlags;
6350
5163
  const ssrEntry = validateSsrEntry(root, paths);
6351
5164
  const hasPages = existsSync(paths.pagesDir);
6352
- const hasMiddleware = scanMiddlewareSync(root, paths).length > 0;
6353
5165
  let assetRoutingPublicDir = join(root, "public");
6354
5166
  let managedCloudflareBuild = false;
6355
5167
  function resolveConfiguredAssetRoutingPolicy() {
6356
- const routePatterns = scanRoutePatternsSync(root, paths, routeEnvironment);
5168
+ const routePatterns = application.routes;
6357
5169
  const environmentWebsocketRoutes = websocketRoutes.filter((route) => isRouteEnabledForEnvironment(route, routeEnvironment));
6358
5170
  const policy = resolveAssetRoutingPolicy({
6359
5171
  isSsr: Boolean(ssrEntry),
6360
5172
  hasPages,
6361
5173
  hasApiRoutes: hasApiRoutes(routePatterns) || hasApiRoutes(environmentWebsocketRoutes) || authEnabled,
6362
5174
  hasDocumentRoutes: hasDocumentRoutes(routePatterns),
6363
- hasMiddleware,
5175
+ hasMiddleware: application.middleware.length > 0,
6364
5176
  hasWebSockets: hasDocumentRoutes(environmentWebsocketRoutes),
6365
5177
  authEnabled,
6366
5178
  liveEnabled: shouldEmitLive() && liveConfig !== void 0,
@@ -6413,7 +5225,9 @@ function voidPlugin(options) {
6413
5225
  ...bindings.needsSandbox ? [createSandboxSdkResolvePlugin()] : [],
6414
5226
  ...pagesDevCssAssetsPlugin(root, devTriggerToken),
6415
5227
  routingPlugin(root, {
5228
+ getApplicationAnalysis,
6416
5229
  isAuthEnabled: () => authEnabled,
5230
+ getVersionMetadataBinding: () => versionMetadataBinding,
6417
5231
  devTriggerToken,
6418
5232
  headConfig: config.head,
6419
5233
  output: config.output,
@@ -6426,6 +5240,7 @@ function voidPlugin(options) {
6426
5240
  },
6427
5241
  sandboxBindingName: sandboxConfig?.binding,
6428
5242
  sandboxClassName: sandboxConfig?.className,
5243
+ sandboxInstanceType: sandboxConfig?.instanceType,
6429
5244
  get live() {
6430
5245
  return shouldEmitLive() ? liveConfig : void 0;
6431
5246
  },