void 0.22.0 → 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 (276) hide show
  1. package/README.md +5 -1
  2. package/dist/{account-cmd-CjyxcGkM.mjs → account-cmd-C84Ee8cO.mjs} +4 -4
  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-BLO4ptzo.mjs → auth-link-CioEg6uY.mjs} +4 -4
  8. package/dist/{auth-router-ZUg9MF_U.mjs → auth-router-BsR981d4.mjs} +4 -4
  9. package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
  10. package/dist/{build-cmd-BxR5FROK.mjs → build-cmd-LzvNJORH.mjs} +17 -5
  11. package/dist/{cache-D0sWhgKI.mjs → cache-C4MvnrMH.mjs} +2 -2
  12. package/dist/{cancel-deploy-D4NUqFbi.mjs → cancel-deploy-abUxpP2n.mjs} +2 -2
  13. package/dist/{cf-build-output-BJ6yGEIS.mjs → cf-build-output-BPqOT964.mjs} +2 -1
  14. package/dist/cf-build-output-_0HNWysu.mjs +2 -0
  15. package/dist/cli/cli.mjs +80 -455
  16. package/dist/cli/{cf-compat.mjs → cloudflare-operation-process.mjs} +442 -421
  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-BTZ3XkrB.mjs → client-RV8NVeB8.mjs} +140 -21
  21. package/dist/{cloudflare-auth-DQkqoMYa.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -38
  22. package/dist/{cloudflare-cmd-BKlfGHAy.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +5 -5
  23. package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
  24. package/dist/{cloudflare-connect-Ctmrw579.mjs → cloudflare-connect-B8uPZ4nx.mjs} +3 -3
  25. package/dist/{cloudflare-operations-BT6OWFBk.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
  26. package/dist/{cloudflare-operations-B9tzgjmf.mjs → cloudflare-operations-fxHb-byx.mjs} +116 -172
  27. package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
  28. package/dist/{config-VavjpDnp.d.mts → config-BMHb8RCj.d.mts} +1 -0
  29. package/dist/config-C_XRIPx2.mjs +89 -0
  30. package/dist/config-entry.d.mts +1 -1
  31. package/dist/{connect-Dg-WkW-C.mjs → connect-Bd4kJd9U.mjs} +5 -5
  32. package/dist/{create-project-DdoqwFLF.mjs → create-project-Boczwj5r.mjs} +1 -1
  33. package/dist/{create-project-l9J7pbtm.mjs → create-project-bMf6ffLZ.mjs} +2 -2
  34. package/dist/{db-gp2sCXyN.mjs → db-8uG64XLl.mjs} +21 -21
  35. package/dist/{delete-TTedbH6B.mjs → delete-NvbiyeJf.mjs} +2 -2
  36. package/dist/{deploy-CH-o2CaZ.mjs → deploy-DzAIwqNU.mjs} +908 -582
  37. package/dist/{deploy-B19L2Bra.mjs → deploy-bjXdFCtn.mjs} +1 -1
  38. package/dist/{domain-JRF59P_r.mjs → domain-y5Tvydvo.mjs} +3 -3
  39. package/dist/{email-Bo6G9LOZ.mjs → email-B3umsW75.mjs} +13 -28
  40. package/dist/{env-BYOrWQnv.mjs → env-BS6qYHDb.mjs} +4 -4
  41. package/dist/{env-public-BxU_0yTL.d.mts → env-public-BX_r8HR6.d.mts} +1 -1
  42. package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
  43. package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.mjs} +1 -1
  44. package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
  45. package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
  46. package/dist/{gen-sCtlCOdA.mjs → gen-B580--vC.mjs} +2 -2
  47. package/dist/gen-BVaUUumi.mjs +2 -0
  48. package/dist/{github-cmd-0-7PexDq.mjs → github-cmd-v45BdfKX.mjs} +2 -2
  49. package/dist/{handler-HEcZsaij.d.mts → handler-CZ4nAylQ.d.mts} +1 -1
  50. package/dist/help-DofyZuY7.mjs +2 -0
  51. package/dist/{help-GKtwl07I.mjs → help-daGKjXGk.mjs} +229 -747
  52. package/dist/index.d.mts +1 -1
  53. package/dist/index.mjs +288 -1502
  54. package/dist/info-B97bTX9N.mjs +113 -0
  55. package/dist/{init-FZx3Elvz.mjs → init-Bvy7zrBo.mjs} +46 -15
  56. package/dist/limits-Bq5LG8Id.d.mts +27 -0
  57. package/dist/limits-Cjuk2VPm.mjs +68 -0
  58. package/dist/{link-BrQfb_CU.mjs → link-CDqqCjFl.mjs} +3 -3
  59. package/dist/{list-D44jmIAM.mjs → list-CZj0dzKY.mjs} +3 -3
  60. package/dist/{live-CKJlvlNp.d.mts → live-Chw1eIMv.d.mts} +1 -1
  61. package/dist/{local-d1-Bg9OzEEO.mjs → local-d1-2CMnpuW_.mjs} +2 -2
  62. package/dist/login-DYt_An22.mjs +2 -0
  63. package/dist/{login-CAsAsQ-_.mjs → login-UZKFM_u7.mjs} +3 -3
  64. package/dist/{logs-BjKvFnVM.mjs → logs-CUZ6t9t3.mjs} +3 -3
  65. package/dist/migrate-8_2u55MD.mjs +2 -0
  66. package/dist/{migrate-BPITvDJN.mjs → migrate-DHul7PRV.mjs} +2 -1
  67. package/dist/{node-Dt7z256D.mjs → node-BkyRWRx8.mjs} +1 -1
  68. package/dist/operator-args-CLgKGlwU.mjs +690 -0
  69. package/dist/{operator-cmd-BK5CCiT9.mjs → operator-cmd-DBA6dl0m.mjs} +68 -22
  70. package/dist/pages/client.d.mts +34 -2
  71. package/dist/pages/client.mjs +59 -3
  72. package/dist/pages/index.d.mts +1 -1
  73. package/dist/pages/index.mjs +1 -1
  74. package/dist/pages/islands-plugin.mjs +1 -1
  75. package/dist/pages/protocol.d.mts +2 -2
  76. package/dist/pages/protocol.mjs +2 -308
  77. package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
  78. package/dist/plan-D1Q5rf-r.mjs +2 -0
  79. package/dist/plan-NPpwZ_kc.mjs +58 -0
  80. package/dist/platform-args-BJdRtlLq.mjs +506 -0
  81. package/dist/platform-args-D3RXyR6h.mjs +2 -0
  82. package/dist/{platform-auth-config-BlN8xTdD.mjs → platform-auth-config-B56E9YP1.mjs} +3 -3
  83. package/dist/{platform-auth-protection-7d5aV2Jg.mjs → platform-auth-protection-BDWO_aER.mjs} +2 -2
  84. package/dist/{platform-auth-recovery-Dxij8ZbR.mjs → platform-auth-recovery-1gg4CSRe.mjs} +3 -3
  85. package/dist/{platform-cmd-E0FuL212.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
  86. package/dist/{platform-cmd-B3hwKrFK.mjs → platform-cmd-DMcQStSc.mjs} +24 -3
  87. package/dist/{platform-domain-D6Xcy9ZX.mjs → platform-domain-BNkcz0OB.mjs} +2 -2
  88. package/dist/{platform-lifecycle-k0E0xoxx.mjs → platform-lifecycle-9OyBALhH.mjs} +327 -215
  89. package/dist/{platform-lifecycle-DMh_qrry.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
  90. package/dist/{platform-management-Brz_BDiT.mjs → platform-management-CjwLVQwN.mjs} +6 -3
  91. package/dist/{platform-management-DOtss0BN.mjs → platform-management-CnyTdcWX.mjs} +1 -1
  92. package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
  93. package/dist/{platform-recovery-BvtcXON5.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
  94. package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
  95. package/dist/{prepare-C-6YZyyg.mjs → prepare-B5Mkic5u.mjs} +1 -1
  96. package/dist/{prepare-CRhJbVrG.mjs → prepare-DOsL0CC9.mjs} +4 -20
  97. package/dist/prepare-cgvDMtSb.mjs +2 -0
  98. package/dist/{project-cmd-BZLCqOqw.mjs → project-cmd-CNzrqvBv.mjs} +16 -16
  99. package/dist/{project-team-BvgM0WoX.mjs → project-team-DQOWPfQT.mjs} +2 -2
  100. package/dist/{project-token-l5DqK6Az.mjs → project-token-CTDYU0Cc.mjs} +2 -2
  101. package/dist/{project-zero-trust-v6Mvpp8y.mjs → project-zero-trust-BNAkW-_0.mjs} +2 -2
  102. package/dist/{protocol-BBa6cstI.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
  103. package/dist/protocol-U7bfjHmA.mjs +331 -0
  104. package/dist/{provision-Fr9pRqce.mjs → provision-C4ORE7G7.mjs} +1 -1
  105. package/dist/{provision-C4IGqkBf.mjs → provision-CJFgTZY8.mjs} +89 -198
  106. package/dist/{requests-DN-BbNiM.mjs → requests-MhxYnau8.mjs} +2 -2
  107. package/dist/resource-name-C7LVpcRm.mjs +11 -0
  108. package/dist/{rollback-D7rzSaZM.mjs → rollback-CJ6iSDoU.mjs} +3 -3
  109. package/dist/route-url-CG7U-cRN.mjs +15 -0
  110. package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
  111. package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
  112. package/dist/runtime/ai.d.mts +12 -8
  113. package/dist/runtime/ai.mjs +84 -17
  114. package/dist/runtime/better-auth-mysql.mjs +1 -1
  115. package/dist/runtime/better-auth-pg.mjs +1 -1
  116. package/dist/runtime/better-auth.mjs +1 -1
  117. package/dist/runtime/client-react.mjs +2 -2
  118. package/dist/runtime/client-solid.mjs +2 -2
  119. package/dist/runtime/client-svelte.mjs +2 -2
  120. package/dist/runtime/client-vue.mjs +2 -2
  121. package/dist/runtime/client.mjs +2 -2
  122. package/dist/runtime/durable.d.mts +3 -1
  123. package/dist/runtime/durable.mjs +4 -1
  124. package/dist/runtime/email/testing.mjs +1 -1
  125. package/dist/runtime/env-public.d.mts +1 -1
  126. package/dist/runtime/fetch-stream.mjs +1 -1
  127. package/dist/runtime/fetch.mjs +1 -1
  128. package/dist/runtime/handler.d.mts +1 -1
  129. package/dist/runtime/kv.mjs +0 -1
  130. package/dist/runtime/limits.d.mts +2 -0
  131. package/dist/runtime/limits.mjs +2 -0
  132. package/dist/runtime/live-client.d.mts +1 -1
  133. package/dist/runtime/live-server.mjs +25 -16
  134. package/dist/runtime/live.d.mts +1 -1
  135. package/dist/runtime/migration-handler.mjs +62 -42
  136. package/dist/runtime/route-url.d.mts +4 -0
  137. package/dist/runtime/route-url.mjs +2 -0
  138. package/dist/runtime/routing.d.mts +180 -0
  139. package/dist/runtime/routing.mjs +1082 -0
  140. package/dist/runtime/sandbox-container.d.mts +1 -1
  141. package/dist/runtime/sandbox-container.mjs +1 -1
  142. package/dist/runtime/sandbox.d.mts +3 -3
  143. package/dist/runtime/sandbox.mjs +75 -45
  144. package/dist/runtime/sse.mjs +1 -1
  145. package/dist/runtime/validator.d.mts +1 -1
  146. package/dist/runtime/ws-server.d.mts +4 -2
  147. package/dist/runtime/ws-server.mjs +27 -2
  148. package/dist/runtime/ws.d.mts +2 -2
  149. package/dist/runtime/ws.mjs +8 -6
  150. package/dist/{sandbox-qpNBT8a3.d.mts → sandbox-XZAqzFlG.d.mts} +11 -8
  151. package/dist/{sandbox-container-DdNEBfCc.d.mts → sandbox-container-Bo0eiFKz.d.mts} +2 -1
  152. package/dist/{sandbox-container-4fdqLnyb.mjs → sandbox-container-C6ItmVuN.mjs} +4 -2
  153. package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
  154. package/dist/{secret-BOtOl_cb.mjs → secret-Dli5fP0B.mjs} +4 -4
  155. package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
  156. package/dist/validate-Dq_L3s0S.mjs +2 -0
  157. package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
  158. package/dist/{wrangler-DQF1vKyf.mjs → wrangler-7K-bW_DL.mjs} +8 -239
  159. package/dist/{ws-BoY7vQML.d.mts → ws-CL1w7GXU.d.mts} +13 -2
  160. package/package.json +15 -8
  161. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
  162. package/skills/void/SKILL.md +50 -135
  163. package/skills/void/docs/guide/ai.md +94 -84
  164. package/skills/void/docs/guide/app-types.md +3 -32
  165. package/skills/void/docs/guide/auth.md +12 -116
  166. package/skills/void/docs/guide/database/d1.md +9 -54
  167. package/skills/void/docs/guide/database/mysql.md +1 -1
  168. package/skills/void/docs/guide/database/postgresql.md +5 -26
  169. package/skills/void/docs/guide/database.md +23 -75
  170. package/skills/void/docs/guide/deployment.md +27 -113
  171. package/skills/void/docs/guide/durable-state.md +43 -18
  172. package/skills/void/docs/guide/edge/headers.md +3 -47
  173. package/skills/void/docs/guide/edge/prerendering.md +5 -20
  174. package/skills/void/docs/guide/edge/redirects.md +11 -64
  175. package/skills/void/docs/guide/edge/revalidation.md +5 -18
  176. package/skills/void/docs/guide/edge/rewrites.md +56 -284
  177. package/skills/void/docs/guide/edge/static-assets.md +22 -72
  178. package/skills/void/docs/guide/email/domains.md +112 -0
  179. package/skills/void/docs/guide/email/receiving.md +139 -0
  180. package/skills/void/docs/guide/email/sending.md +231 -0
  181. package/skills/void/docs/guide/email.md +13 -619
  182. package/skills/void/docs/guide/env-migration.md +11 -11
  183. package/skills/void/docs/guide/env-vars.md +9 -29
  184. package/skills/void/docs/guide/index.md +0 -15
  185. package/skills/void/docs/guide/jobs.md +3 -18
  186. package/skills/void/docs/guide/kv.md +5 -11
  187. package/skills/void/docs/guide/live.md +5 -56
  188. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
  189. package/skills/void/docs/guide/pages-routing/head.md +10 -10
  190. package/skills/void/docs/guide/pages-routing/islands.md +6 -36
  191. package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
  192. package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
  193. package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
  194. package/skills/void/docs/guide/pages-routing/overview.md +7 -17
  195. package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
  196. package/skills/void/docs/guide/platform/administration/access.md +1 -4
  197. package/skills/void/docs/guide/platform/administration/email.md +35 -8
  198. package/skills/void/docs/guide/platform/administration/operations.md +26 -4
  199. package/skills/void/docs/guide/platform/administration/plans.md +126 -0
  200. package/skills/void/docs/guide/platform/administration/projects.md +5 -2
  201. package/skills/void/docs/guide/platform/administration/zero-trust.md +23 -152
  202. package/skills/void/docs/guide/platform/development/runtime.md +3 -13
  203. package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
  204. package/skills/void/docs/guide/platform/installation/credentials.md +6 -4
  205. package/skills/void/docs/guide/platform/installation/domains.md +30 -2
  206. package/skills/void/docs/guide/platform/installation/first-deployment.md +2 -0
  207. package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
  208. package/skills/void/docs/guide/platform/installation/prerequisites.md +20 -15
  209. package/skills/void/docs/guide/platform/installation/setup.md +9 -5
  210. package/skills/void/docs/guide/platform-administration.md +1 -0
  211. package/skills/void/docs/guide/queues.md +7 -9
  212. package/skills/void/docs/guide/quickstart.md +38 -37
  213. package/skills/void/docs/guide/remote-dev.md +4 -9
  214. package/skills/void/docs/guide/sandboxes.md +29 -21
  215. package/skills/void/docs/guide/server-routing.md +9 -72
  216. package/skills/void/docs/guide/sse.md +4 -18
  217. package/skills/void/docs/guide/ssg.md +3 -15
  218. package/skills/void/docs/guide/ssr.md +14 -62
  219. package/skills/void/docs/guide/storage.md +9 -4
  220. package/skills/void/docs/guide/type-safety.md +3 -14
  221. package/skills/void/docs/guide/typed-fetch.md +3 -7
  222. package/skills/void/docs/guide/websockets.md +68 -40
  223. package/skills/void/docs/integrations/agents.md +3 -3
  224. package/skills/void/docs/integrations/cloudflare.md +85 -316
  225. package/skills/void/docs/integrations/frameworks/analog.md +5 -64
  226. package/skills/void/docs/integrations/frameworks/astro.md +4 -73
  227. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
  228. package/skills/void/docs/integrations/frameworks/overview.md +11 -54
  229. package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
  230. package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
  231. package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
  232. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
  233. package/skills/void/docs/reference/api/auth.md +156 -0
  234. package/skills/void/docs/reference/api/client.md +87 -0
  235. package/skills/void/docs/reference/api/database.md +95 -0
  236. package/skills/void/docs/reference/api/durable.md +46 -0
  237. package/skills/void/docs/reference/api/env.md +50 -0
  238. package/skills/void/docs/reference/api/handlers.md +254 -0
  239. package/skills/void/docs/reference/api/pages.md +241 -0
  240. package/skills/void/docs/reference/api/plugin.md +39 -0
  241. package/skills/void/docs/reference/api/resources.md +109 -0
  242. package/skills/void/docs/reference/api/rewrites.md +76 -0
  243. package/skills/void/docs/reference/api/types.md +92 -0
  244. package/skills/void/docs/reference/api.md +56 -1218
  245. package/skills/void/docs/reference/cli/auth.md +88 -0
  246. package/skills/void/docs/reference/cli/database.md +128 -0
  247. package/skills/void/docs/reference/cli/deploy.md +85 -0
  248. package/skills/void/docs/reference/cli/domains.md +41 -0
  249. package/skills/void/docs/reference/cli/email.md +129 -0
  250. package/skills/void/docs/reference/cli/generate.md +116 -0
  251. package/skills/void/docs/reference/cli/github.md +189 -0
  252. package/skills/void/docs/reference/cli/platform-config.md +92 -0
  253. package/skills/void/docs/reference/cli/platform-email.md +81 -0
  254. package/skills/void/docs/reference/cli/platform-installation.md +127 -0
  255. package/skills/void/docs/reference/cli/platform-operations.md +90 -0
  256. package/skills/void/docs/reference/cli/platform-users.md +89 -0
  257. package/skills/void/docs/reference/cli/platform-zero-trust.md +45 -0
  258. package/skills/void/docs/reference/cli/platform.md +70 -0
  259. package/skills/void/docs/reference/cli/project.md +214 -0
  260. package/skills/void/docs/reference/cli/secrets.md +76 -0
  261. package/skills/void/docs/reference/cli/setup.md +70 -0
  262. package/skills/void/docs/reference/cli.md +32 -1682
  263. package/skills/void/docs/reference/config.md +12 -18
  264. package/skills/void/docs/reference/resource-inference.md +3 -58
  265. package/skills/void/docs/reference/structure.md +14 -41
  266. package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
  267. package/dist/client-Czz8o5jP.mjs +0 -2
  268. package/dist/gen-CNJ62MM7.mjs +0 -2
  269. package/dist/help-CmZzxUba.mjs +0 -2
  270. package/dist/login-CGcRKEoi.mjs +0 -2
  271. package/dist/migrate-CYfbKkXh.mjs +0 -2
  272. package/dist/plan-BEZ8VJW0.mjs +0 -256
  273. package/dist/plan-DpuOr14e.mjs +0 -2
  274. package/dist/prepare-Bm3iq-u4.mjs +0 -2
  275. package/dist/validate-EKmJWxmy.mjs +0 -2
  276. /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
@@ -154,11 +154,9 @@ Configuration for the [email integration](../guide/email.md).
154
154
  | ------ | -------- | -------------------------------------------------------------------------------------------------------------- |
155
155
  | `from` | `string` | Default sender for `sendEmail()`: one address, optionally with a display name (`Acme <noreply@mail.acme.com>`) |
156
156
 
157
- What `from` does depends on where the app runs:
157
+ During development, `email.from` is the default sender in the local inbox. On a Void platform, use your project's shared sender or registered domain.
158
158
 
159
- - **`void dev`** — becomes the default `from` of every `sendEmail()` call, captured in the dev inbox; no mail leaves the machine.
160
- - **`void deploy`** (managed platform) — not used: the sender is pinned to your project's own platform address, which Void fills in for you.
161
- - **`void deploy --platform cloudflare`** (your own Cloudflare account) — the address host (`mail.acme.com`) is the domain Void sets Email Routing and Email Sending up on, and the address becomes the default `from` (written into the worker as the `__VOID_EMAIL_FROM` var). The host must be a zone in the pinned Cloudflare account, or a subdomain of one; a subdomain is the usual choice, and the apex is refused when it already receives mail elsewhere. An app that uses email without `email.from` deploys without it and prints the line to add. Void never picks a zone or writes `void.config.ts` for you. See [Your own Cloudflare account](../guide/email.md#your-own-cloudflare-account).
159
+ For direct Cloudflare deployment, this address selects the mail domain and default sender. Use a zone or subdomain in your account; an existing mail provider's MX records are preserved. See [Email setup](../guide/email/domains.md#your-own-cloudflare-account).
162
160
 
163
161
  ### `head`
164
162
 
@@ -199,7 +197,7 @@ Output mode. Controls the default rendering strategy for pages.
199
197
  | `"server"` (default) | `false` | `export const prerender = true` | Deploy-time (platform ISR) |
200
198
  | `"static"` | `true` | `export const prerender = false` | Build or deploy post-build |
201
199
 
202
- When set to `"static"`, all pages are prerendered as static HTML files written to `dist/client/`. A standalone `vite build` renders them in the build; managed `void deploy` renders immediately afterward in the trusted deploy process so build plugins never receive platform credentials. Individual pages can opt out with `export const prerender = false`. Dynamic pages (with route params) without a `getPrerenderPaths()` export are implicitly not prerendered.
200
+ When set to `"static"`, pages are prerendered to HTML in `dist/client/`. Individual pages can opt out with `export const prerender = false`. Dynamic pages need `getPrerenderPaths()` to be prerendered.
203
201
 
204
202
  When omitted or set to `"server"`, pages are server-rendered on request. Individual pages can opt into deploy-time prerendering with `export const prerender = true`, or opt out of server-rendered component HTML with `export const ssr = false`.
205
203
 
@@ -209,7 +207,7 @@ When omitted or set to `"server"`, pages are server-rendered on request. Individ
209
207
 
210
208
  ### `remote`
211
209
 
212
- Use remote D1/KV/R2 bindings during local development instead of local miniflare. When enabled, the Void plugin replaces local bindings with proxy-backed versions that forward operations to your deployed project's real resources via the Void proxy.
210
+ Use a deployed Void project's D1, KV, and R2 resources during local development. Writes affect real data. See [Remote Development](../guide/remote-dev.md).
213
211
 
214
212
  ```json
215
213
  { "remote": true }
@@ -253,7 +251,7 @@ Enable and configure Cloudflare Sandboxes. Importing from `void/sandbox` enables
253
251
 
254
252
  Supported sizes are `lite` and `standard-1` through `standard-4`. Native deploys build Dockerfiles with Docker; registry images must be digest-pinned references from the Cloudflare managed registry. Custom images must include the matching Sandbox SDK helper. For a local Dockerfile, supply `platformImage` when deploying to a managed platform. See [Sandboxes](../guide/sandboxes.md) for image setup and runtime examples.
255
253
 
256
- Sandbox requires [Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans) and Containers access, checked before provisioning or building. Managed runtime tokens need Account / Containers: Edit and Account / Cloudchamber: Edit. Apps without Sandbox use neither Containers nor an entitlement check.
254
+ Sandbox requires [Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans) and Containers access. Managed runtime tokens need Account / Containers: Edit and Account / Cloudchamber: Edit. See [Sandbox deployment](../guide/sandboxes.md#deployment).
257
255
 
258
256
  ### `target`
259
257
 
@@ -345,7 +343,7 @@ Routing and edge configuration for headers, redirects, rewrites, and caching.
345
343
 
346
344
  #### `routing.headers`
347
345
 
348
- Custom response headers for dispatch-worker responses. Keys are URL patterns, values are arrays of `"Name: value"` strings. See [Custom Headers](../guide/edge/headers) for details.
346
+ Custom response headers. Keys are URL patterns, values are arrays of `"Name: value"` strings. See [Custom Headers](../guide/edge/headers) for details.
349
347
 
350
348
  ```json
351
349
  {
@@ -388,7 +386,7 @@ URL rewrites. Keys are source URL patterns, values are destination paths. Serves
388
386
  }
389
387
  ```
390
388
 
391
- Destinations use the `RewriteDestination` shape — typed route patterns plus `string`, so known routes autocomplete while dynamic paths remain accepted. See [Programmatic rewrites in middleware](../guide/edge/rewrites#programmatic-rewrites-in-middleware) for the trade-off and performance notes.
389
+ Destinations use the `RewriteDestination` shape — typed route patterns plus `string`, so known routes autocomplete while dynamic paths remain accepted. See [Programmatic rewrites](../guide/edge/rewrites#programmatic-rewrites-in-middleware).
392
390
 
393
391
  #### `routing.fallbacks`
394
392
 
@@ -416,7 +414,7 @@ Boolean switch for Void's ISR caching. When omitted or `true`, Void infers cachi
416
414
  }
417
415
  ```
418
416
 
419
- This does not disable `output: "static"` build-time HTML generation or delete existing KV resources. Set it to `true` to enable your configured cache policies again. Existing-Worker migration saves this choice before provisioning, so it remains consistent on retries and later deployments.
417
+ Build-time HTML generation with `output: "static"` is unaffected. Set `isr` to `true` to enable your configured cache policies again.
420
418
 
421
419
  #### `routing.revalidate`
422
420
 
@@ -464,7 +462,7 @@ Paths to prerender as static HTML at deploy time. Each path must start with `/`.
464
462
 
465
463
  #### `routing.notFound`
466
464
 
467
- Override how the asset layer answers a request that matched no asset and no worker route. One of `"single-page-application"`, `"404-page"`, or `"none"`. If omitted, Void infers it — see [Static Assets](../guide/edge/static-assets.md#unmatched-requests).
465
+ Override how the asset layer answers a request that matched no asset and no worker route. One of `"single-page-application"`, `"404-page"`, or `"none"`. If omitted, Void infers it — see [Static Assets](../guide/edge/static-assets.md#navigation-and-middleware).
468
466
 
469
467
  ```json
470
468
  {
@@ -474,13 +472,9 @@ Override how the asset layer answers a request that matched no asset and no work
474
472
  }
475
473
  ```
476
474
 
477
- Set `"404-page"` when your assets come from a static site generator (VitePress, Docusaurus, …) and you want unknown URLs to serve the generator's own `404.html` with a real HTTP 404. Without it, an app whose only backend is API routes keeps the inferred SPA fallback, so every unknown URL returns `index.html` with a `200` — correct for a single-page app, wrong for a generated site, and bad for crawlers.
475
+ Use `"404-page"` for a generated static site with a `404.html`, `"single-page-application"` for a client router, or `"none"` to keep the Worker's own 404. API and middleware routing remain unchanged.
478
476
 
479
- `run_worker_first` is untouched, so API routes, auth, and `/__void/*` still reach the worker first. When the worker owns HTML routing it also serves the resolved behavior itself, since `run_worker_first: ["/**"]` means the platform switch never runs — see [Unmatched requests](../guide/edge/static-assets.md#unmatched-requests).
480
-
481
- This does **not** apply to SvelteKit, Nuxt, Analog, or Astro deploys: those pin `not_found_handling` to `"none"` because the framework's own worker owns unmatched HTML, and `void deploy` warns if you set `routing.notFound` anyway.
482
-
483
- TanStack Start, React Router, and vinext honor it on a managed `void deploy`, which resolves the asset config itself. Void writes no `assets` policy into their generated Worker config (`dist/server` for TanStack Start and vinext App, `build/server` for React Router, `dist/ssr` for vinext Pages). A custom config must declare a complete `assets` policy — `binding`, `directory`, `not_found_handling`, and `run_worker_first`. Void leaves those fields untouched, so your own policy is honored; with none, Cloudflare's default applies. `vite build` warns when it is set. See [Static Assets](../guide/edge/static-assets.md#unmatched-requests) for the per-framework paths.
477
+ SvelteKit, Nuxt, Analog, and Astro use their own error pages and ignore this setting. For direct Cloudflare deployment with TanStack Start, React Router, or vinext, set a complete asset policy in your framework's Cloudflare config. See [Static Assets](../guide/edge/static-assets.md#navigation-and-middleware).
484
478
 
485
479
  ### `inference`
486
480
 
@@ -488,7 +482,7 @@ Configuration for build-time inference, including how Void detects your app type
488
482
 
489
483
  #### `inference.bindings`
490
484
 
491
- Explicitly control inferred Cloudflare bindings. If omitted, bindings are [automatically inferred](./resource-inference.md) by scanning your source files for binding usage. If provided, explicit values take precedence and inference is skipped entirely.
485
+ Explicitly control inferred Cloudflare bindings. If omitted, bindings are [automatically inferred](./resource-inference.md) by scanning your source files for binding usage. Explicit values override the named bindings; omitted bindings are still inferred. Auth and checked-in migrations still require a database even when `db` is `false`.
492
486
 
493
487
  Each binding accepts `true` (use default name), `false` (disable), or a string (custom binding name):
494
488
 
@@ -6,16 +6,6 @@ outline: deep
6
6
 
7
7
  Void automatically detects which Cloudflare resources your project uses by scanning source files at startup. In most cases, there is no manual configuration. Use a resource in code, and Void provisions the matching binding for local development.
8
8
 
9
- ## How It Works
10
-
11
- When `voidPlugin()` initializes, it synchronously scans your source files using a three-tier approach optimized for speed:
12
-
13
- 1. **Import detection:** uses `es-module-lexer` to check for `void/*` imports. This is the fastest pass and does not require AST parsing.
14
- 2. **Regex pre-check:** tests for patterns such as `env.DB` and `env.KV` so files without bindings can be skipped early.
15
- 3. **AST confirmation:** when the regex matches, parses the full AST to confirm `c.env.DB` or `env.DB` member expressions.
16
-
17
- This runs once before plugins initialize, so the results are available to configure the Cloudflare Vite plugin.
18
-
19
9
  ## Detected Bindings
20
10
 
21
11
  | Binding | Type | Detected by import | Detected by env access |
@@ -31,7 +21,7 @@ This runs once before plugins initialize, so the results are available to config
31
21
 
32
22
  Auth detection also triggers when importing the `auth` specifier from `void/client` or a framework-specific client subpath such as `void/client/react` (but not when importing only `fetch`).
33
23
 
34
- Durable state is inferred from files in `durable-objects/`. For example, `durable-objects/shopping-cart.ts` creates the `SHOPPING_CART` binding, exports `ShoppingCartDurableObject`, and adds a `new_sqlite_classes` migration. See [Durable State](../guide/durable-state.md).
24
+ Durable state is inferred from files in `durable-objects/`. For example, `durable-objects/shopping-cart.ts` creates the `SHOPPING_CART` binding, exports `ShoppingCartDurableObject`, and records its migration. See [Durable State](../guide/durable-state.md).
35
25
 
36
26
  ## Scanned Directories
37
27
 
@@ -86,7 +76,7 @@ Paths are relative to the project root. When `inference.scanDirs` is set, it rep
86
76
 
87
77
  ## Explicit Binding Overrides
88
78
 
89
- If inference doesn't match your setup, you can skip it entirely and declare bindings explicitly:
79
+ Override individual bindings when inference does not match your setup:
90
80
 
91
81
  ```json
92
82
  {
@@ -101,53 +91,8 @@ If inference doesn't match your setup, you can skip it entirely and declare bind
101
91
  }
102
92
  ```
103
93
 
104
- When `inference.bindings` is set, explicit values take full precedence and inference is skipped entirely.
94
+ Explicit values override only their named bindings. Omitted bindings continue to be inferred, so setting `kv` does not disable storage, auth, or other features. Auth and checked-in migrations still require a database even when `db` is `false`.
105
95
 
106
96
  ## File Types
107
97
 
108
98
  Inference scans files matching `**/*.{ts,tsx,mts,js,jsx,mjs}` within each directory. Non-JS files (CSS, HTML, images) are ignored.
109
-
110
- ## Common Patterns
111
-
112
- ### Pages mode with D1
113
-
114
- A page companion file in `pages/` triggers D1 inference:
115
-
116
- ```ts
117
- // pages/users.server.ts
118
- import { db } from 'void/db';
119
-
120
- export function loader() {
121
- return db.select().from(users);
122
- }
123
- ```
124
-
125
- ### Cron job with KV
126
-
127
- A scheduled handler in `crons/` triggers KV inference:
128
-
129
- ```ts
130
- // crons/cleanup.ts
131
- import { defineScheduled } from 'void';
132
- import { kv } from 'void/kv';
133
-
134
- export default defineScheduled(async () => {
135
- await kv.delete('temp-cache');
136
- });
137
- ```
138
-
139
- ### Route handler with R2
140
-
141
- A route handler in `routes/` triggers R2 inference:
142
-
143
- ```ts
144
- // routes/api/upload.ts
145
- import { defineHandler } from 'void';
146
- import { storage } from 'void/storage';
147
-
148
- export const POST = defineHandler(async (c) => {
149
- const file = await c.req.blob();
150
- await storage.put('uploads/file.bin', file);
151
- return c.json({ ok: true });
152
- });
153
- ```
@@ -10,12 +10,15 @@ const items = [
10
10
  { name: "db/", description: "Drizzle schema and SQL migrations", link: "#db" },
11
11
  { name: "crons/", description: "Scheduled cron jobs", link: "#crons" },
12
12
  { name: "queues/", description: "Async queue consumers", link: "#queues" },
13
+ { name: "email/", description: "Inbound email handlers", link: "#email" },
14
+ { name: "durable-objects/", description: "Durable State modules", link: "#durable-objects" },
13
15
  { name: "src/", description: "Shared app code", link: "#src" },
14
16
  { name: "public/", description: "Static assets (served as-is)", link: "#public" },
15
17
  { name: ".void/", description: "Auto-generated (gitignored)", link: "#void" },
16
18
  { name: "vite.config.ts", description: "Vite config with voidPlugin()", link: "#config-files" },
17
19
  { name: "void.config.ts", description: "Void project config (optional)", link: "#config-files" },
18
- { name: ".env", description: "Environment variables", link: "#config-files" },
20
+ { name: ".env", description: "Local environment values", link: "#config-files" },
21
+ { name: "env.ts", description: "Environment schema", link: "#config-files" },
19
22
  { name: "package.json" },
20
23
  { name: "tsconfig.json" },
21
24
  ];
@@ -47,18 +50,6 @@ const dbItems = [
47
50
  },
48
51
  ];
49
52
 
50
- const voidItems = [
51
- {
52
- name: ".void/",
53
- children: [
54
- { name: "db.d.ts", description: "Drizzle DB instance types" },
55
- { name: "routes.d.ts", description: "Typed fetch client types" },
56
- { name: "queues.d.ts", description: "Queue consumer types" },
57
- { name: "tsconfig.json", description: "TypeScript config fragment" },
58
- { name: "v3/", description: "Local dev state (D1, KV, R2)" },
59
- ],
60
- },
61
- ];
62
53
  </script>
63
54
 
64
55
  # Project Structure
@@ -102,11 +93,11 @@ Global middleware that runs on every request. Numeric prefixes control execution
102
93
 
103
94
  <FileTree :items="middlewareItems" default-expanded />
104
95
 
105
- Each file exports a `defineMiddleware()` handler. Use middleware to set shared context (auth, logging, rate limiting) available to all routes.
96
+ Each file default-exports a `defineMiddleware()` handler. Use middleware to set shared context (auth, logging, rate limiting) available to all routes.
106
97
 
107
98
  ## `db/`
108
99
 
109
- [Drizzle schema](/guide/database#schema-definition) and SQL migration files for the [D1 database](/guide/database).
100
+ [Drizzle schemas](/guide/database#schema-definition) and SQL migrations for D1, PostgreSQL, or MySQL.
110
101
 
111
102
  <FileTree :items="dbItems" default-expanded />
112
103
 
@@ -118,33 +109,19 @@ Generate schema with `void gen model` or write it by hand. Generate migrations w
118
109
 
119
110
  ## `crons/`
120
111
 
121
- [Scheduled jobs](/guide/jobs) that run on a cron schedule.
112
+ [Scheduled jobs](/guide/jobs). Each file exports a `cron` expression and a default `defineScheduled()` handler.
122
113
 
123
- ```ts
124
- // crons/heartbeat.ts
125
- import { defineScheduled } from 'void';
126
-
127
- export const cron = '*/5 * * * *';
114
+ ## `queues/`
128
115
 
129
- export default defineScheduled(async (controller, env) => {
130
- // runs every 5 minutes
131
- });
132
- ```
116
+ [Queue consumers](/guide/queues). Each file default-exports a `defineQueue()` handler.
133
117
 
134
- ## `queues/`
118
+ ## `email/`
135
119
 
136
- [Async queue consumers](/guide/queues) for background job processing.
120
+ [Inbound email handlers](../guide/email/receiving.md#inbound). A file's name selects the recipient; `_default.ts` handles other addresses.
137
121
 
138
- ```ts
139
- // queues/email.ts
140
- import { defineQueue } from 'void';
122
+ ## `durable-objects/`
141
123
 
142
- export default defineQueue(async (batch, env) => {
143
- for (const msg of batch.messages) {
144
- // process message
145
- }
146
- });
147
- ```
124
+ [Durable State](/guide/durable-state) modules. Each file default-exports a `defineDurableState()` definition.
148
125
 
149
126
  ## `src/`
150
127
 
@@ -156,11 +133,7 @@ Static assets served as-is at the root path. Files here are not processed by Vit
156
133
 
157
134
  ## `.void/`
158
135
 
159
- Auto-generated directory (gitignored). Contains:
160
-
161
- Generate or refresh it with `void prepare`, or let `vite dev` / `vite build` populate it during normal app workflows.
162
-
163
- <FileTree :items="voidItems" default-expanded />
136
+ Generated types and local development state (gitignored). Run `void prepare` to create the types, or let `vite dev` and `vite build` update them.
164
137
 
165
138
  ## Config Files
166
139
 
@@ -1,13 +0,0 @@
1
- //#region src/migrations/canonical-json.ts
2
- function canonicalJson(value) {
3
- if (value === null) return "null";
4
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return JSON.stringify(value);
5
- if (Array.isArray(value)) return `[${value.map((entry) => canonicalJson(entry)).join(",")}]`;
6
- if (typeof value === "object") {
7
- const object = value;
8
- return `{${Object.keys(object).sort().filter((key) => object[key] !== void 0).map((key) => `${JSON.stringify(key)}:${canonicalJson(object[key])}`).join(",")}}`;
9
- }
10
- throw new TypeError(`Unsupported canonical JSON value: ${typeof value}`);
11
- }
12
- //#endregion
13
- export { canonicalJson as t };
@@ -1,2 +0,0 @@
1
- import { n as PlatformClient } from "./client-BTZ3XkrB.mjs";
2
- export { PlatformClient };
@@ -1,2 +0,0 @@
1
- import { r as runGenCommand } from "./gen-sCtlCOdA.mjs";
2
- export { runGenCommand };
@@ -1,2 +0,0 @@
1
- import { r as printHelpPage } from "./help-GKtwl07I.mjs";
2
- export { printHelpPage };
@@ -1,2 +0,0 @@
1
- import { r as selectPlatformLoginMethod } from "./login-CAsAsQ-_.mjs";
2
- export { selectPlatformLoginMethod };
@@ -1,2 +0,0 @@
1
- import { n as runMigrateCommand } from "./migrate-BPITvDJN.mjs";
2
- export { runMigrateCommand };
@@ -1,256 +0,0 @@
1
- import { t as canonicalJson } from "./canonical-json-DuDiiUsQ.mjs";
2
- import { createHash } from "node:crypto";
3
- //#region src/migrations/tokenize.ts
4
- function* tokenizeSql(sql) {
5
- const sqlLength = sql.length;
6
- let index = 0;
7
- let runStart = 0;
8
- const flushRun = (upTo) => {
9
- if (upTo > runStart) return {
10
- kind: "sql",
11
- start: runStart,
12
- end: upTo
13
- };
14
- };
15
- while (index < sqlLength) {
16
- const character = sql[index];
17
- const next = index + 1 < sqlLength ? sql[index + 1] : "";
18
- if (character === "-" && next === "-") {
19
- const run = flushRun(index);
20
- if (run) yield run;
21
- let scanIndex = index + 2;
22
- while (scanIndex < sqlLength && sql[scanIndex] !== "\n") scanIndex++;
23
- yield {
24
- kind: "line-comment",
25
- start: index,
26
- end: scanIndex
27
- };
28
- index = scanIndex;
29
- runStart = index;
30
- continue;
31
- }
32
- if (character === "/" && next === "*") {
33
- const run = flushRun(index);
34
- if (run) yield run;
35
- let scanIndex = index + 2;
36
- while (scanIndex < sqlLength - 1 && !(sql[scanIndex] === "*" && sql[scanIndex + 1] === "/")) scanIndex++;
37
- const end = Math.min(scanIndex + 2, sqlLength);
38
- yield {
39
- kind: "block-comment",
40
- start: index,
41
- end
42
- };
43
- index = end;
44
- runStart = index;
45
- continue;
46
- }
47
- if (character === "'") {
48
- const run = flushRun(index);
49
- if (run) yield run;
50
- let scanIndex = index + 1;
51
- while (scanIndex < sqlLength) {
52
- if (sql[scanIndex] === "'" && sql[scanIndex + 1] === "'") {
53
- scanIndex += 2;
54
- continue;
55
- }
56
- if (sql[scanIndex] === "'") {
57
- scanIndex++;
58
- break;
59
- }
60
- scanIndex++;
61
- }
62
- yield {
63
- kind: "string",
64
- start: index,
65
- end: scanIndex
66
- };
67
- index = scanIndex;
68
- runStart = index;
69
- continue;
70
- }
71
- if (character === "\"" || character === "`" || character === "[") {
72
- const run = flushRun(index);
73
- if (run) yield run;
74
- const close = character === "[" ? "]" : character;
75
- let scanIndex = index + 1;
76
- while (scanIndex < sqlLength) {
77
- if (close !== "]" && sql[scanIndex] === close && sql[scanIndex + 1] === close) {
78
- scanIndex += 2;
79
- continue;
80
- }
81
- if (sql[scanIndex] === close) {
82
- scanIndex++;
83
- break;
84
- }
85
- scanIndex++;
86
- }
87
- yield {
88
- kind: "ident-quote",
89
- open: character,
90
- start: index,
91
- end: scanIndex
92
- };
93
- index = scanIndex;
94
- runStart = index;
95
- continue;
96
- }
97
- index++;
98
- }
99
- const tail = flushRun(sqlLength);
100
- if (tail) yield tail;
101
- }
102
- const UNSPLIT_MULTI_STATEMENT_PRAGMA = "-- void:allow-unsplit-multi-statement";
103
- const DESTRUCTIVE_PRAGMA = "-- void:allow-destructive";
104
- function canonicalSql(sql) {
105
- return (sql.charCodeAt(0) === 65279 ? sql.slice(1) : sql).replace(/\r\n?/g, "\n");
106
- }
107
- function sha256Hex(value) {
108
- return `sha256:${createHash("sha256").update(value).digest("hex")}`;
109
- }
110
- function getPlanHashInput(plan) {
111
- const base = {
112
- classifierVersion: plan.classifierVersion,
113
- dialect: plan.dialect,
114
- kind: plan.kind,
115
- name: plan.name,
116
- sqlHash: plan.sqlHash,
117
- stability: plan.stability
118
- };
119
- if (plan.kind === "breakpoint-framed") base.statements = plan.statements;
120
- return base;
121
- }
122
- function hashPlan(plan) {
123
- return sha256Hex(canonicalJson(getPlanHashInput(plan)));
124
- }
125
- function computeMigrationListHash(plans) {
126
- return sha256Hex(canonicalJson(plans.map((plan) => [
127
- plan.name,
128
- plan.sqlHash,
129
- plan.planHash
130
- ])));
131
- }
132
- function isStandalonePragmaLine(line, pragma) {
133
- return line.trim() === pragma;
134
- }
135
- function hasStandalonePragma(sql, pragma) {
136
- return canonicalSql(sql).split("\n").some((line) => isStandalonePragmaLine(line, pragma));
137
- }
138
- function isBreakpointComment(text) {
139
- return text.trim() === "--> statement-breakpoint";
140
- }
141
- function splitBreakpointFramedSql(sql) {
142
- const normalized = canonicalSql(sql);
143
- const statements = [];
144
- let cursor = 0;
145
- for (const segment of tokenizeSql(normalized)) {
146
- if (segment.kind !== "line-comment") continue;
147
- if (isBreakpointComment(normalized.slice(segment.start, segment.end))) {
148
- const statement = normalized.slice(cursor, segment.start).trim();
149
- if (statement) statements.push(statement);
150
- cursor = segment.end;
151
- }
152
- }
153
- const statement = normalized.slice(cursor).trim();
154
- if (statement) statements.push(statement);
155
- return statements;
156
- }
157
- function getExecutableSql(sql) {
158
- let out = "";
159
- for (const segment of tokenizeSql(sql)) if (segment.kind === "sql") out += sql.slice(segment.start, segment.end);
160
- else out += " ".repeat(segment.end - segment.start);
161
- return out;
162
- }
163
- function hasStatementBreakpointOutsideLiterals(sql) {
164
- const normalized = canonicalSql(sql);
165
- for (const segment of tokenizeSql(normalized)) {
166
- if (segment.kind !== "line-comment") continue;
167
- if (isBreakpointComment(normalized.slice(segment.start, segment.end))) return true;
168
- }
169
- return false;
170
- }
171
- function isSingleStatement(sql) {
172
- const normalized = canonicalSql(sql);
173
- let statements = 0;
174
- let inStatement = false;
175
- for (const segment of tokenizeSql(normalized)) {
176
- if (segment.kind === "line-comment" || segment.kind === "block-comment") continue;
177
- if (segment.kind === "string" || segment.kind === "ident-quote") {
178
- inStatement = true;
179
- continue;
180
- }
181
- for (let index = segment.start; index < segment.end; index++) {
182
- const character = normalized[index];
183
- if (character === ";") {
184
- if (inStatement) {
185
- statements++;
186
- inStatement = false;
187
- }
188
- continue;
189
- }
190
- if (character !== " " && character !== " " && character !== "\n" && character !== "\r") inStatement = true;
191
- }
192
- }
193
- if (inStatement) statements++;
194
- return statements === 1;
195
- }
196
- function includesTransactionControl(sql) {
197
- return getExecutableSql(sql).match(/(?:^|;)\s*(BEGIN(?:\s+(?:DEFERRED|IMMEDIATE|EXCLUSIVE|TRANSACTION))?|COMMIT|ROLLBACK|SAVEPOINT|RELEASE)\b/i)?.[1]?.toUpperCase() ?? null;
198
- }
199
- function classifyMigration(migration) {
200
- const sql = canonicalSql(migration.sql);
201
- const sqlHash = sha256Hex(sql);
202
- const transactionControl = includesTransactionControl(sql);
203
- if (transactionControl) throw new Error(`Migration ${migration.name} contains ${transactionControl}; Void owns the stable D1 transaction boundary.`);
204
- let base;
205
- const warnings = [];
206
- if (hasStatementBreakpointOutsideLiterals(sql)) {
207
- const statements = splitBreakpointFramedSql(sql);
208
- if (statements.length === 0) throw new Error(`Migration ${migration.name} has statement breakpoints but no SQL statements.`);
209
- base = {
210
- classifierVersion: 1,
211
- dialect: "sqlite",
212
- kind: "breakpoint-framed",
213
- name: migration.name,
214
- sqlHash,
215
- stability: "stable",
216
- statements
217
- };
218
- } else if (isSingleStatement(sql)) base = {
219
- classifierVersion: 1,
220
- dialect: "sqlite",
221
- kind: "single-statement",
222
- name: migration.name,
223
- sqlHash,
224
- stability: "stable"
225
- };
226
- else {
227
- const allowLegacy = hasStandalonePragma(sql, UNSPLIT_MULTI_STATEMENT_PRAGMA);
228
- warnings.push(`Migration ${migration.name} contains multiple statements without Drizzle statement breakpoints; it will run through the legacy D1 path.`);
229
- base = {
230
- allowLegacy,
231
- classifierVersion: 1,
232
- dialect: "sqlite",
233
- kind: "legacy-unsplit-multi-statement",
234
- name: migration.name,
235
- sqlHash,
236
- stability: "legacy"
237
- };
238
- }
239
- return {
240
- ...base,
241
- planHash: hashPlan(base),
242
- ...warnings.length > 0 ? { warnings } : {}
243
- };
244
- }
245
- function buildMigrationPlanBundle(migrations) {
246
- const plans = migrations.map((migration) => classifyMigration(migration));
247
- return {
248
- classifierVersion: 1,
249
- destructiveValidation: "passed",
250
- migrationListHash: computeMigrationListHash(plans),
251
- plans,
252
- protocolVersion: 2
253
- };
254
- }
255
- //#endregion
256
- export { classifyMigration as a, isSingleStatement as c, canonicalSql as i, sha256Hex as l, UNSPLIT_MULTI_STATEMENT_PRAGMA as n, computeMigrationListHash as o, buildMigrationPlanBundle as r, hasStandalonePragma as s, DESTRUCTIVE_PRAGMA as t, tokenizeSql as u };
@@ -1,2 +0,0 @@
1
- import { r as buildMigrationPlanBundle } from "./plan-BEZ8VJW0.mjs";
2
- export { buildMigrationPlanBundle };
@@ -1,2 +0,0 @@
1
- import { t as prepareProject } from "./prepare-CRhJbVrG.mjs";
2
- export { prepareProject };
@@ -1,2 +0,0 @@
1
- import { i as validateMigrations } from "./validate-CIUwFpjB.mjs";
2
- export { validateMigrations };