void 0.10.12 → 0.20.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 (431) hide show
  1. package/AGENTS_TEMPLATE.md +6 -0
  2. package/{skills/void/docs/node_modules/void/node_modules/pglite-server/LICENSE.md → LICENSE} +1 -1
  3. package/README.md +34 -8
  4. package/dist/{auth-qgMlYp7Z.d.mts → auth-DkcFflXV.d.mts} +10 -11
  5. package/dist/auth-W9WII-mN.mjs +630 -0
  6. package/dist/{auth-cmd-BqsdZJp5.mjs → auth-cmd-CYVhSNFy.mjs} +4 -3
  7. package/dist/{auth-migrations-BTZ-ATvQ.mjs → auth-migrations-9vif1uj8.mjs} +53 -12
  8. package/dist/{better-auth-shared-BQooDxbw.mjs → better-auth-shared-CYw1T3k4.mjs} +7 -10
  9. package/dist/{better-auth-shared-DealXecJ.d.mts → better-auth-shared-DSCeohOK.d.mts} +10 -5
  10. package/dist/{build-cmd-Bujrv5q-.mjs → build-cmd-CkVD1uOh.mjs} +6 -4
  11. package/dist/{cache-C11V8Fxq.mjs → cache-QcUfR-ff.mjs} +9 -5
  12. package/dist/{cancel-deploy-fwFYF04b.mjs → cancel-deploy-DsvWKFTe.mjs} +3 -2
  13. package/dist/cf-access-AJ1ehiFR.mjs +42 -0
  14. package/dist/cf-access-DsSsZUPr.mjs +67 -0
  15. package/dist/cli/cli.d.mts +1 -1
  16. package/dist/cli/cli.mjs +1592 -153
  17. package/dist/cli/env-schema-probe.d.mts +48 -61
  18. package/dist/cli/env-schema-probe.mjs +10 -58
  19. package/dist/{client-Gb71-XkG.mjs → client-CyCHWSO_.mjs} +61 -463
  20. package/dist/cloudflare-auth-DRkGe7-s.mjs +170 -0
  21. package/dist/cloudflare-cmd-D3ME2GAe.mjs +62 -0
  22. package/dist/cloudflare-connect-BivMefMA.mjs +56 -0
  23. package/dist/cloudflare-operations-CPTpRW6d.mjs +566 -0
  24. package/dist/{config-BkTvs43g.mjs → config-BQFq7QvD.mjs} +85 -41
  25. package/dist/{config-CutEMNGJ.mjs → config-NOG_U1aK.mjs} +10 -15
  26. package/dist/connect-D9Yr-T5f.mjs +79 -0
  27. package/dist/{create-project-DsYvl3TB.mjs → create-project-DMV-csEm.mjs} +26 -16
  28. package/dist/database-provider.d.mts +21 -0
  29. package/dist/database-provider.mjs +6 -0
  30. package/dist/{db-DOiJMRt2.mjs → db-BxoUWL0F.mjs} +600 -115
  31. package/dist/{delete-mh6p-zkQ.mjs → delete-iJOqxBz1.mjs} +9 -6
  32. package/dist/{deploy-u7Rv9q_q.mjs → deploy-CcDoeBIf.mjs} +3451 -1986
  33. package/dist/dev-inbox-DkgRWLkW.mjs +307 -0
  34. package/dist/{discover-CJHyvYfR.mjs → discover-xvfrgJeo.mjs} +3 -3
  35. package/dist/{magic-string.es-ZQjdJFFn.mjs → dist-BR1quN_w.mjs} +570 -216
  36. package/dist/{dist-DaKKDf8D.mjs → dist-BrsS7cai.mjs} +17 -2
  37. package/dist/{dist-BuiRJkTd.mjs → dist-m40_XgNh.mjs} +48 -33
  38. package/dist/{domain-DiaNQbrl.mjs → domain-gu_iaHmn.mjs} +41 -4
  39. package/dist/dotenv-VQxupEUv.mjs +181 -0
  40. package/dist/edge.d.mts +2 -0
  41. package/dist/edge.mjs +2 -0
  42. package/dist/email-Ce6SQq-i.mjs +182 -0
  43. package/dist/email-r6DHJyAB.mjs +262 -0
  44. package/dist/{entry-D7yy4xVH.mjs → entry-DU3oDoQ3.mjs} +2 -2
  45. package/dist/env-D4Emu-M_.mjs +95 -0
  46. package/dist/env-DmU2To0C.mjs +73 -0
  47. package/dist/env-helpers-CyKtOBpj.d.mts +22 -0
  48. package/dist/env-public-D_6u46fX.d.mts +135 -0
  49. package/dist/{env-types-QBj-ndax.mjs → env-types-BNPhro-M.mjs} +2 -2
  50. package/dist/{env-validation-Dea3v3ej.mjs → env-validation-ENpMy6Ez.mjs} +68 -122
  51. package/dist/{gen-o_w-8yI8.mjs → gen-BKw6qHIg.mjs} +70 -15
  52. package/dist/{github-cmd-DKcGUNsj.mjs → github-cmd-DJS5Ab-H.mjs} +39 -31
  53. package/dist/{handler-Cjh8uM3Y.d.mts → handler-D1hLsObx.d.mts} +124 -122
  54. package/dist/{head-nmvOgFjd.d.mts → head-Do8P4puT.d.mts} +9 -8
  55. package/dist/{headers-nsHIFixA.mjs → headers-D8QfRX9Y.mjs} +12 -10
  56. package/dist/inbound-BJ70in1n.d.mts +354 -0
  57. package/dist/inbound-CNKxb3FY.mjs +694 -0
  58. package/dist/index.d.mts +61 -34
  59. package/dist/index.mjs +1048 -321
  60. package/dist/{init-3rgHKBVi.mjs → init-Dx5cgKqK.mjs} +329 -271
  61. package/dist/link-D_rm5sRH.mjs +52 -0
  62. package/dist/{list-CPwFDZ_c.mjs → list-M8XShti7.mjs} +37 -5
  63. package/dist/{runner-kapo9aPs.mjs → local-d1-BE8KBbMy.mjs} +116 -6
  64. package/dist/{login-BT3H8PN3.mjs → login-C8-UuLnp.mjs} +17 -15
  65. package/dist/{logs-Bt313ax7.mjs → logs-DwFU7dMW.mjs} +16 -2
  66. package/dist/mime-BJD7d_qL.mjs +1216 -0
  67. package/dist/neon-DHwd2zvC.mjs +54 -0
  68. package/dist/{node-Da0UcsGA.mjs → node-BkaXcpAc.mjs} +29 -8
  69. package/dist/operator-cmd-DYWRbWUA.mjs +348 -0
  70. package/dist/{agents-CtgBYqld.mjs → output-tFQLLj26.mjs} +676 -211
  71. package/dist/{package-json-Cx1osYo6.mjs → package-json-CPoWX79C.mjs} +1 -1
  72. package/dist/pages/client.d.mts +43 -41
  73. package/dist/pages/client.mjs +40 -33
  74. package/dist/pages/head-client.d.mts +10 -12
  75. package/dist/pages/head.d.mts +1 -1
  76. package/dist/pages/index.d.mts +37 -14
  77. package/dist/pages/index.mjs +5 -5
  78. package/dist/pages/islands-plugin.d.mts +25 -27
  79. package/dist/pages/islands-plugin.mjs +6 -4
  80. package/dist/pages/prefetch.d.mts +6 -7
  81. package/dist/pages/protocol.d.mts +2 -2
  82. package/dist/pages/protocol.mjs +2 -1
  83. package/dist/pages/serialize.d.mts +7 -8
  84. package/dist/platform-cmd-BEOVv1PN.mjs +123 -0
  85. package/dist/platform-domain-BszUfiS8.mjs +228 -0
  86. package/dist/platform-lifecycle-CjSr6xf0.mjs +4450 -0
  87. package/dist/platform-management-W30iCaTL.mjs +698 -0
  88. package/dist/platform-recovery-pHHv4ZSg.mjs +99 -0
  89. package/dist/{plugin-inference-DMeavIJ6.mjs → plugin-inference-BDRfZngg.mjs} +35 -19
  90. package/dist/prepare-BfJvFUtJ.mjs +14 -0
  91. package/dist/{prepare-BoKHgMNx.mjs → prepare-CBetXvsN.mjs} +15 -24
  92. package/dist/{preset-BjyR3lzz.mjs → preset-lAy0B0BQ.mjs} +25 -212
  93. package/dist/{project-cmd-D_w-4w5B.mjs → project-cmd-DCpk1cDt.mjs} +25 -12
  94. package/dist/{project-paths-BQd7OmIo.mjs → project-paths-SK8nMHPp.mjs} +3 -1
  95. package/dist/{project-tsconfig-B-QtXjLQ.mjs → project-tsconfig-Ql2XsSQp.mjs} +2 -2
  96. package/dist/{protocol-Bnb0LFp3.d.mts → protocol-C-pqYJjE.d.mts} +3 -4
  97. package/dist/{provision-rShh6MKY.mjs → provision-Blnstcm2.mjs} +78 -45
  98. package/dist/r2-conditions-D1Wk8i7b.mjs +30 -0
  99. package/dist/{requests-B8sZxaFM.mjs → requests-Dn8Vheh1.mjs} +5 -3
  100. package/dist/{resolve-project-BBMtLLV9.mjs → resolve-project--Vxawf7z.mjs} +2 -2
  101. package/dist/rollback-CtlPXEBi.mjs +166 -0
  102. package/dist/{rolldown-runtime-DJK8HYOj.mjs → rolldown-runtime-rQ84J-ij.mjs} +1 -1
  103. package/dist/{route-types-COI2DsZv.mjs → route-types-Da-DpyUp.mjs} +85 -26
  104. package/dist/routes-stub.d.mts +22 -23
  105. package/dist/runner-mysql-CgRFl3s6.mjs +61 -0
  106. package/dist/{runner-pg-CHM76xuC.mjs → runner-pg-DCkWPsWS.mjs} +18 -6
  107. package/dist/runtime/ai.d.mts +21 -14
  108. package/dist/runtime/ai.mjs +5 -4
  109. package/dist/runtime/auth-client-react.d.mts +3 -5
  110. package/dist/runtime/auth-client-solid.d.mts +3 -5
  111. package/dist/runtime/auth-client-svelte.d.mts +3 -5
  112. package/dist/runtime/auth-client-vue.d.mts +3 -5
  113. package/dist/runtime/auth-client.d.mts +3 -5
  114. package/dist/runtime/auth.d.mts +1 -1
  115. package/dist/runtime/better-auth-mysql.d.mts +10 -0
  116. package/dist/runtime/better-auth-mysql.mjs +49 -0
  117. package/dist/runtime/better-auth-pg.d.mts +8 -9
  118. package/dist/runtime/better-auth-pg.mjs +2 -2
  119. package/dist/runtime/better-auth.d.mts +8 -9
  120. package/dist/runtime/better-auth.mjs +2 -2
  121. package/dist/runtime/client-react.d.mts +1 -1
  122. package/dist/runtime/client-solid.d.mts +1 -1
  123. package/dist/runtime/client-svelte.d.mts +1 -1
  124. package/dist/runtime/client-vue.d.mts +1 -1
  125. package/dist/runtime/client.d.mts +1 -1
  126. package/dist/runtime/db-mysql.d.mts +2 -0
  127. package/dist/runtime/db-mysql.mjs +1 -0
  128. package/dist/runtime/db.d.mts +10 -11
  129. package/dist/runtime/durable.d.mts +47 -0
  130. package/dist/runtime/durable.mjs +146 -0
  131. package/dist/runtime/email/testing.d.mts +112 -0
  132. package/dist/runtime/email/testing.mjs +283 -0
  133. package/dist/runtime/email.d.mts +30 -0
  134. package/dist/runtime/email.mjs +573 -0
  135. package/dist/runtime/env-helpers.d.mts +2 -2
  136. package/dist/runtime/env-helpers.mjs +5 -42
  137. package/dist/runtime/env-public-client.d.mts +10 -11
  138. package/dist/runtime/env-public-client.mjs +1 -1
  139. package/dist/runtime/env-public.d.mts +2 -2
  140. package/dist/runtime/env-public.mjs +104 -49
  141. package/dist/runtime/env.d.mts +19 -18
  142. package/dist/runtime/env.mjs +15 -2
  143. package/dist/runtime/fetch-stream.d.mts +20 -21
  144. package/dist/runtime/fetch.d.mts +15 -16
  145. package/dist/runtime/handler.d.mts +1 -1
  146. package/dist/runtime/isr.d.mts +21 -22
  147. package/dist/runtime/isr.mjs +26 -8
  148. package/dist/runtime/kv.d.mts +9 -10
  149. package/dist/runtime/live-client.d.mts +5 -7
  150. package/dist/runtime/live-client.mjs +9 -7
  151. package/dist/runtime/live-server.d.mts +4 -5
  152. package/dist/runtime/live.d.mts +22 -24
  153. package/dist/runtime/live.mjs +1 -1
  154. package/dist/runtime/log.d.mts +16 -17
  155. package/dist/runtime/migration-handler-mysql.d.mts +4 -0
  156. package/dist/runtime/migration-handler-mysql.mjs +81 -0
  157. package/dist/runtime/migration-handler-pg.d.mts +2 -4
  158. package/dist/runtime/migration-handler.d.mts +5 -6
  159. package/dist/runtime/migration-handler.mjs +4 -3
  160. package/dist/runtime/queues.d.mts +3 -4
  161. package/dist/runtime/queues.mjs +2 -1
  162. package/dist/runtime/remote/binding-handler.d.mts +10 -12
  163. package/dist/runtime/remote/binding-handler.mjs +24 -3
  164. package/dist/runtime/remote/index.d.mts +5 -6
  165. package/dist/runtime/remote/index.mjs +21 -18
  166. package/dist/runtime/response.d.mts +10 -11
  167. package/dist/runtime/sandbox.d.mts +56 -55
  168. package/dist/runtime/sandbox.mjs +57 -49
  169. package/dist/runtime/schema-mysql.d.mts +1 -0
  170. package/dist/runtime/schema-mysql.mjs +2 -0
  171. package/dist/runtime/seed.d.mts +14 -9
  172. package/dist/runtime/sse-client.d.mts +6 -7
  173. package/dist/runtime/sse.d.mts +11 -12
  174. package/dist/runtime/storage.d.mts +3 -4
  175. package/dist/runtime/validator.d.mts +1 -1
  176. package/dist/runtime/ws-server.d.mts +12 -12
  177. package/dist/runtime/ws-server.mjs +32 -4
  178. package/dist/runtime/ws.d.mts +19 -21
  179. package/dist/{scan-DYXkrasO.mjs → scan-BMH4rzlv.mjs} +53 -31
  180. package/dist/{scan-DEwlM_Xy.mjs → scan-CpK-57ug.mjs} +9 -5
  181. package/dist/{secret-Dt32J6RI.mjs → secret-BqTxGqki.mjs} +62 -5
  182. package/dist/{skills-CLjN0uUO.mjs → skills-Q46GZMO-.mjs} +6 -4
  183. package/dist/{standard-schema-DJ0HW7QP.d.mts → standard-schema-Fo_vCAZh.d.mts} +6 -6
  184. package/dist/{subcommand-prompt-BzV8iQZo.mjs → subcommand-prompt-WfySCQ7S.mjs} +67 -48
  185. package/dist/sveltekit.d.mts +12 -11
  186. package/dist/sveltekit.mjs +1 -1
  187. package/dist/types-BAp5AEBU.d.mts +79 -0
  188. package/dist/types-CKWnYgfy.d.mts +1 -0
  189. package/dist/{validate-Cw_RLeTj.mjs → validate-Bihr8WBi.mjs} +3 -3
  190. package/dist/wrangler--imS8n0d.mjs +1796 -0
  191. package/dist/{yarn-pnp-DJn3SAHF.mjs → yarn-pnp-DxSInkzL.mjs} +1 -1
  192. package/package.json +79 -65
  193. package/schema.json +35 -3
  194. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +1 -1
  195. package/skills/void/SKILL.md +59 -2
  196. package/skills/void/docs/guide/ai.md +32 -14
  197. package/skills/void/docs/guide/app-types.md +6 -6
  198. package/skills/void/docs/guide/auth.md +14 -16
  199. package/skills/void/docs/guide/database/d1.md +6 -0
  200. package/skills/void/docs/guide/database/mysql.md +60 -0
  201. package/skills/void/docs/guide/database/postgresql.md +14 -9
  202. package/skills/void/docs/guide/database.md +39 -26
  203. package/skills/void/docs/guide/deployment.md +163 -22
  204. package/skills/void/docs/guide/durable-state.md +140 -0
  205. package/skills/void/docs/guide/edge/headers.md +5 -5
  206. package/skills/void/docs/guide/edge/prerendering.md +2 -0
  207. package/skills/void/docs/guide/edge/revalidation.md +21 -6
  208. package/skills/void/docs/guide/edge/rewrites.md +18 -14
  209. package/skills/void/docs/guide/edge/static-assets.md +23 -8
  210. package/skills/void/docs/guide/email.md +609 -0
  211. package/skills/void/docs/guide/env-migration.md +109 -0
  212. package/skills/void/docs/guide/env-vars.md +70 -248
  213. package/skills/void/docs/guide/index.md +15 -17
  214. package/skills/void/docs/guide/jobs.md +8 -5
  215. package/skills/void/docs/guide/live.md +7 -15
  216. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +8 -4
  217. package/skills/void/docs/guide/pages-routing/islands.md +3 -3
  218. package/skills/void/docs/guide/pages-routing/loaders.md +6 -4
  219. package/skills/void/docs/guide/pages-routing/overview.md +7 -7
  220. package/skills/void/docs/guide/platform-administration.md +212 -0
  221. package/skills/void/docs/guide/platform-development.md +235 -0
  222. package/skills/void/docs/guide/queues.md +10 -10
  223. package/skills/void/docs/guide/quickstart.md +46 -67
  224. package/skills/void/docs/guide/remote-dev.md +8 -6
  225. package/skills/void/docs/guide/sandboxes.md +33 -16
  226. package/skills/void/docs/guide/self-hosted-platform.md +553 -0
  227. package/skills/void/docs/guide/server-routing.md +25 -5
  228. package/skills/void/docs/guide/sse.md +4 -4
  229. package/skills/void/docs/guide/ssg.md +5 -3
  230. package/skills/void/docs/guide/storage.md +2 -2
  231. package/skills/void/docs/guide/websockets.md +18 -7
  232. package/skills/void/docs/index.md +3 -3
  233. package/skills/void/docs/integrations/agents.md +6 -64
  234. package/skills/void/docs/integrations/cloudflare.md +165 -146
  235. package/skills/void/docs/integrations/frameworks/analog.md +4 -4
  236. package/skills/void/docs/integrations/frameworks/astro.md +5 -5
  237. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -5
  238. package/skills/void/docs/integrations/frameworks/overview.md +3 -3
  239. package/skills/void/docs/integrations/frameworks/react-router.md +3 -3
  240. package/skills/void/docs/integrations/frameworks/sveltekit.md +3 -3
  241. package/skills/void/docs/integrations/frameworks/tanstack-start.md +2 -2
  242. package/skills/void/docs/integrations/nodejs-bun-deno.md +11 -4
  243. package/skills/void/docs/reference/api.md +42 -6
  244. package/skills/void/docs/reference/cli.md +637 -159
  245. package/skills/void/docs/reference/config.md +80 -25
  246. package/skills/void/docs/reference/resource-inference.md +13 -9
  247. package/skills/void/docs/reference/structure.md +10 -11
  248. package/AGENT_PROMPT.md +0 -19
  249. package/dist/cf-access-Bqw81xAf.mjs +0 -22
  250. package/dist/env-CZy5MorI.mjs +0 -299
  251. package/dist/env-helpers-z4stu8uc.d.mts +0 -52
  252. package/dist/env-mask-Dd47NbR6.mjs +0 -90
  253. package/dist/env-public-BfiLcMBk.d.mts +0 -140
  254. package/dist/link-CdGHSIy-.mjs +0 -45
  255. package/dist/mcp-DoM3_nhd.mjs +0 -377
  256. package/dist/project-paths-GpziKeQQ.d.mts +0 -25
  257. package/dist/providers-BNKRacMr.d.mts +0 -7
  258. package/dist/proxy-D-3_D-Gl.mjs +0 -5
  259. package/dist/rollback-CkvTFXx5.mjs +0 -90
  260. package/dist/runtime/isr-cache.d.mts +0 -207
  261. package/dist/runtime/isr-cache.mjs +0 -523
  262. package/dist/types-lLjNE9Qp.d.mts +0 -51
  263. package/getting-started-prompt.txt +0 -28
  264. package/skills/void/command/void.md +0 -7
  265. package/skills/void/docs/integrations/auth-providers.md +0 -0
  266. package/skills/void/docs/integrations/payment-processors.md +0 -0
  267. package/skills/void/docs/node_modules/@iconify/vue/README.md +0 -408
  268. package/skills/void/docs/node_modules/@iconify/vue/offline/readme.md +0 -5
  269. package/skills/void/docs/node_modules/@voidzero-dev/vitepress-theme/README.md +0 -103
  270. package/skills/void/docs/node_modules/oxc-minify/README.md +0 -78
  271. package/skills/void/docs/node_modules/reka-ui/README.md +0 -80
  272. package/skills/void/docs/node_modules/vitepress/README.md +0 -28
  273. package/skills/void/docs/node_modules/vitepress/template/api-examples.md +0 -49
  274. package/skills/void/docs/node_modules/vitepress/template/index.md +0 -28
  275. package/skills/void/docs/node_modules/vitepress/template/markdown-examples.md +0 -85
  276. package/skills/void/docs/node_modules/vitepress-plugin-group-icons/README.md +0 -101
  277. package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +0 -19
  278. package/skills/void/docs/node_modules/void/CLAUDE.md +0 -219
  279. package/skills/void/docs/node_modules/void/README.md +0 -90
  280. package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/CHANGELOG.md +0 -685
  281. package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/README.md +0 -396
  282. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/sandbox/README.md +0 -219
  283. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/vite-plugin/README.md +0 -37
  284. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/workers-types/README.md +0 -135
  285. package/skills/void/docs/node_modules/void/node_modules/@electric-sql/pglite/README.md +0 -189
  286. package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/CHANGELOG.md +0 -143
  287. package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/README.md +0 -1272
  288. package/skills/void/docs/node_modules/void/node_modules/@napi-rs/keyring/README.md +0 -19
  289. package/skills/void/docs/node_modules/void/node_modules/@types/better-sqlite3/README.md +0 -15
  290. package/skills/void/docs/node_modules/void/node_modules/@types/node/README.md +0 -15
  291. package/skills/void/docs/node_modules/void/node_modules/@types/pg/README.md +0 -15
  292. package/skills/void/docs/node_modules/void/node_modules/@types/proper-lockfile/README.md +0 -51
  293. package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/README.md +0 -22
  294. package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/vendor/vscode-jsonrpc/README.md +0 -69
  295. package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +0 -153
  296. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/engine-javascript/README.md +0 -9
  297. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/transformers/README.md +0 -9
  298. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@types/node/README.md +0 -15
  299. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/CHANGELOG.md +0 -24
  300. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/README.md +0 -565
  301. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-exit/README.md +0 -127
  302. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-anchor/README.md +0 -600
  303. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-attrs/README.md +0 -386
  304. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-container/README.md +0 -95
  305. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-emoji/README.md +0 -101
  306. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-footnote/README.md +0 -135
  307. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathslash/README.md +0 -64
  308. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/shiki/README.md +0 -15
  309. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tinyglobby/README.md +0 -25
  310. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/AGENTS.md +0 -16
  311. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/README.md +0 -220
  312. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/build.md +0 -21
  313. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/check.md +0 -35
  314. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/create.md +0 -70
  315. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/fmt.md +0 -20
  316. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/index.md +0 -35
  317. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/lint.md +0 -26
  318. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/pack.md +0 -17
  319. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/run.md +0 -364
  320. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/staged.md +0 -15
  321. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/test.md +0 -18
  322. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/automatic-data-tracking.md +0 -145
  323. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/build.md +0 -40
  324. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/cache.md +0 -107
  325. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/check.md +0 -60
  326. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/ci.md +0 -62
  327. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/commit-hooks.md +0 -60
  328. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/create.md +0 -341
  329. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/dev.md +0 -24
  330. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/docker.md +0 -175
  331. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/env.md +0 -167
  332. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/fmt.md +0 -41
  333. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/github-actions-cache.md +0 -165
  334. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/ide-integration.md +0 -101
  335. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/implode.md +0 -23
  336. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/index.md +0 -134
  337. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/install.md +0 -199
  338. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/lint.md +0 -50
  339. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/migrate-rules.md +0 -347
  340. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/migrate.md +0 -197
  341. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/monorepo.md +0 -176
  342. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/pack.md +0 -69
  343. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/run.md +0 -356
  344. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/test.md +0 -35
  345. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/troubleshooting.md +0 -108
  346. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/upgrade.md +0 -101
  347. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/vpx.md +0 -66
  348. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/why.md +0 -39
  349. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/index.md +0 -12
  350. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/team.md +0 -35
  351. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/templates/generator/README.md +0 -35
  352. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/templates/monorepo/README.md +0 -29
  353. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vue/README.md +0 -58
  354. package/skills/void/docs/node_modules/void/node_modules/arktype/README.md +0 -165
  355. package/skills/void/docs/node_modules/void/node_modules/better-auth/LICENSE.md +0 -20
  356. package/skills/void/docs/node_modules/void/node_modules/better-auth/README.md +0 -32
  357. package/skills/void/docs/node_modules/void/node_modules/better-sqlite3/README.md +0 -99
  358. package/skills/void/docs/node_modules/void/node_modules/blake3-jit/README.md +0 -108
  359. package/skills/void/docs/node_modules/void/node_modules/drizzle-arktype/README.md +0 -51
  360. package/skills/void/docs/node_modules/void/node_modules/drizzle-kit/README.md +0 -79
  361. package/skills/void/docs/node_modules/void/node_modules/drizzle-orm/README.md +0 -44
  362. package/skills/void/docs/node_modules/void/node_modules/drizzle-valibot/README.md +0 -51
  363. package/skills/void/docs/node_modules/void/node_modules/drizzle-zod/README.md +0 -65
  364. package/skills/void/docs/node_modules/void/node_modules/es-module-lexer/README.md +0 -403
  365. package/skills/void/docs/node_modules/void/node_modules/estree-walker/README.md +0 -48
  366. package/skills/void/docs/node_modules/void/node_modules/hono/README.md +0 -85
  367. package/skills/void/docs/node_modules/void/node_modules/ignore/README.md +0 -452
  368. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/CHANGELOG.md +0 -76
  369. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/LICENSE.md +0 -21
  370. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/README.md +0 -364
  371. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/SECURITY.md +0 -41
  372. package/skills/void/docs/node_modules/void/node_modules/magic-string/README.md +0 -325
  373. package/skills/void/docs/node_modules/void/node_modules/ofetch/README.md +0 -398
  374. package/skills/void/docs/node_modules/void/node_modules/pathslash/README.md +0 -64
  375. package/skills/void/docs/node_modules/void/node_modules/pg/README.md +0 -96
  376. package/skills/void/docs/node_modules/void/node_modules/pglite-server/README.md +0 -135
  377. package/skills/void/docs/node_modules/void/node_modules/picocolors/README.md +0 -21
  378. package/skills/void/docs/node_modules/void/node_modules/proper-lockfile/CHANGELOG.md +0 -108
  379. package/skills/void/docs/node_modules/void/node_modules/proper-lockfile/README.md +0 -183
  380. package/skills/void/docs/node_modules/void/node_modules/tinyglobby/README.md +0 -25
  381. package/skills/void/docs/node_modules/void/node_modules/valibot/LICENSE.md +0 -9
  382. package/skills/void/docs/node_modules/void/node_modules/valibot/README.md +0 -94
  383. package/skills/void/docs/node_modules/void/node_modules/vite-plus/AGENTS.md +0 -16
  384. package/skills/void/docs/node_modules/void/node_modules/vite-plus/README.md +0 -220
  385. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/build.md +0 -21
  386. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/check.md +0 -35
  387. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/create.md +0 -70
  388. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/fmt.md +0 -20
  389. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/index.md +0 -35
  390. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/lint.md +0 -26
  391. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/pack.md +0 -17
  392. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/run.md +0 -364
  393. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/staged.md +0 -15
  394. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/test.md +0 -18
  395. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/automatic-data-tracking.md +0 -145
  396. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/build.md +0 -40
  397. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/cache.md +0 -107
  398. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/check.md +0 -60
  399. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/ci.md +0 -62
  400. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/commit-hooks.md +0 -60
  401. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/create.md +0 -341
  402. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/dev.md +0 -24
  403. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/docker.md +0 -175
  404. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/env.md +0 -167
  405. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/fmt.md +0 -41
  406. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/github-actions-cache.md +0 -165
  407. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/ide-integration.md +0 -101
  408. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/implode.md +0 -23
  409. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/index.md +0 -134
  410. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/install.md +0 -199
  411. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/lint.md +0 -50
  412. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/migrate-rules.md +0 -347
  413. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/migrate.md +0 -197
  414. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/monorepo.md +0 -176
  415. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/pack.md +0 -69
  416. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/run.md +0 -356
  417. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/test.md +0 -35
  418. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/troubleshooting.md +0 -108
  419. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/upgrade.md +0 -101
  420. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/vpx.md +0 -66
  421. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/why.md +0 -39
  422. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/index.md +0 -12
  423. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/team.md +0 -35
  424. package/skills/void/docs/node_modules/void/node_modules/vite-plus/templates/generator/README.md +0 -35
  425. package/skills/void/docs/node_modules/void/node_modules/vite-plus/templates/monorepo/README.md +0 -29
  426. package/skills/void/docs/node_modules/void/node_modules/wrangler/README.md +0 -63
  427. package/skills/void/docs/node_modules/void/node_modules/zod/README.md +0 -191
  428. package/skills/void/docs/node_modules/void/skills/migrate-vite-cloudflare-to-void/SKILL.md +0 -175
  429. package/skills/void/docs/node_modules/void/skills/void/SKILL.md +0 -76
  430. package/skills/void/docs/node_modules/void/skills/void/command/void.md +0 -7
  431. package/skills/void/docs/node_modules/void/test/e2e/README.md +0 -85
@@ -8,7 +8,7 @@ outline: deep
8
8
 
9
9
  Use this page as the exact reference for `void.json`. If you are still learning how the pieces fit together, start in the guide first and come back here when you need field-by-field details.
10
10
 
11
- Project-level configuration lives in a `void.json` file at the project root. Most fields are optional. Cloudflare-targeted apps must pin a Workers `compatibility_date` in `worker.compatibility_date` or in a supported wrangler fallback file (`wrangler.jsonc` or `wrangler.json`). If no date is configured, Void writes the latest known-good date to `void.json` so future runs stay explicit and stable.
11
+ Project-level configuration lives in a `void.json` file at the project root. Most fields are optional. Cloudflare-targeted apps must pin a Workers `compatibility_date` in `worker.compatibility_date` or in a supported Cloudflare fallback file (`wrangler.jsonc` or `wrangler.json`). If no date is configured, Void writes the latest known-good date to `void.json` so future runs stay explicit and stable.
12
12
 
13
13
  ```json
14
14
  {
@@ -53,7 +53,7 @@ When set, those conventions move under the configured directory:
53
53
  { "sourceDir": "src" }
54
54
  ```
55
55
 
56
- With that config, Void reads `src/pages`, `src/routes`, `src/db/schema.ts`, `src/db/migrations`, `src/auth.ts`, and `src/env.ts`. Project files such as `void.json`, `vite.config.ts`, `package.json`, `tsconfig.json`, `wrangler.json`, `public/`, and `.env*` stay at the project root. Void does not scan both locations; if source conventions exist in both places during dev/build, remove one copy so the active source tree is unambiguous.
56
+ With that config, Void reads `src/pages`, `src/routes`, `src/db/schema.ts`, `src/db/migrations`, `src/auth.ts`, and `src/env.ts`. Project files such as `void.json`, `vite.config.ts`, `package.json`, `tsconfig.json`, `wrangler.json`, `public/`, and the local-only `.env` stay at the project root. Void does not scan both locations; if source conventions exist in both places during dev/build, remove one copy so the active source tree is unambiguous.
57
57
 
58
58
  ### `auth`
59
59
 
@@ -111,7 +111,7 @@ Supported values for `auth.providers`:
111
111
 
112
112
  ### `database`
113
113
 
114
- Database backend. Omit for D1/SQLite (default). Set to `"pg"` for PostgreSQL via Hyperdrive.
114
+ Database backend. Omit for D1/SQLite (default). Set to `"pg"` or `"mysql"` for an external database through Hyperdrive.
115
115
 
116
116
  ```json
117
117
  {
@@ -123,13 +123,36 @@ Database backend. Omit for D1/SQLite (default). Set to `"pg"` for PostgreSQL via
123
123
  | ----------- | ------------------------------------------------------- |
124
124
  | _(omitted)_ | D1 (SQLite), fully managed by Void with no extra config |
125
125
  | `"pg"` | PostgreSQL via Hyperdrive; bring your own database |
126
+ | `"mysql"` | MySQL via Hyperdrive; bring your own database |
126
127
 
127
- When using `"pg"`:
128
+ When using an external database:
128
129
 
129
- - Add `DATABASE_URL` to `.env.local` for local development
130
- - Import schema helpers from `void/schema-pg` instead of `void/schema-d1`
130
+ - Add `DATABASE_URL` to `.env` for local development
131
+ - Import schema helpers from `void/schema-pg` or `void/schema-mysql`
131
132
  - `void/db` connects via Hyperdrive in production, direct connection locally
132
- - `void gen model` generates `pgTable` with `serial`, `timestamp`, etc.
133
+ - `void gen model` generates dialect-appropriate table and column builders
134
+
135
+ ### `email`
136
+
137
+ Configuration for the [email integration](../guide/email.md).
138
+
139
+ ```json
140
+ {
141
+ "email": {
142
+ "from": "Acme <noreply@mail.acme.com>"
143
+ }
144
+ }
145
+ ```
146
+
147
+ | Field | Type | Description |
148
+ | ------ | -------- | -------------------------------------------------------------------------------------------------------------- |
149
+ | `from` | `string` | Default sender for `sendEmail()`: one address, optionally with a display name (`Acme <noreply@mail.acme.com>`) |
150
+
151
+ What `from` does depends on where the app runs:
152
+
153
+ - **`void dev`** — becomes the default `from` of every `sendEmail()` call, captured in the dev inbox; no mail leaves the machine.
154
+ - **`void deploy`** (managed platform) — not used: the sender is pinned to your project's own platform address, which Void fills in for you.
155
+ - **`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.json` for you. See [Your own Cloudflare account](../guide/email.md#your-own-cloudflare-account).
133
156
 
134
157
  ### `head`
135
158
 
@@ -168,9 +191,9 @@ Output mode. Controls the default rendering strategy for pages.
168
191
  | Value | Default prerender | Per-page override | Prerender timing |
169
192
  | -------------------- | ----------------- | -------------------------------- | -------------------------- |
170
193
  | `"server"` (default) | `false` | `export const prerender = true` | Deploy-time (platform ISR) |
171
- | `"static"` | `true` | `export const prerender = false` | Build-time (`vite build`) |
194
+ | `"static"` | `true` | `export const prerender = false` | Build or deploy post-build |
172
195
 
173
- When set to `"static"`, all pages are prerendered at build time as static HTML files written to `dist/client/`. Individual pages can opt out with `export const prerender = false`. Dynamic pages (with route params) without a `getPrerenderPaths()` export are implicitly not prerendered.
196
+ 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.
174
197
 
175
198
  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`.
176
199
 
@@ -213,18 +236,18 @@ Enable and configure Cloudflare Sandboxes for Void apps. Importing from `void/sa
213
236
  }
214
237
  ```
215
238
 
216
- | Field | Type | Default |
217
- | ------------------- | -------- | ---------------------------------------- |
218
- | `binding` | `string` | `SANDBOX` |
219
- | `className` | `string` | `Sandbox` |
220
- | `containerName` | `string` | `void-sandbox` |
221
- | `image` | `string` | Bundled `@cloudflare/sandbox` Dockerfile |
222
- | `imageBuildContext` | `string` | Directory of `image` |
223
- | `platformImage` | `string` | Matching sandbox SDK registry image |
224
- | `instanceType` | `string` | `lite` on Void deploy |
225
- | `maxInstances` | `number` | `20` on Void deploy |
239
+ | Field | Type | Default |
240
+ | ------------------- | -------- | ------------------------------------ |
241
+ | `binding` | `string` | `SANDBOX` |
242
+ | `className` | `string` | `Sandbox` |
243
+ | `containerName` | `string` | `void-sandbox` |
244
+ | `image` | `string` | Matching published sandbox SDK image |
245
+ | `imageBuildContext` | `string` | Directory of `image` |
246
+ | `platformImage` | `string` | Matching sandbox SDK registry image |
247
+ | `instanceType` | `string` | `lite` on Void deploy |
248
+ | `maxInstances` | `number` | `20` on Void deploy |
226
249
 
227
- Sandbox support currently applies to Void apps on the Cloudflare target. `void deploy` supports registry images. If `sandbox.image` is a custom local Dockerfile path, set `sandbox.platformImage` to the pushed image that the platform should run.
250
+ Sandbox support currently applies to Void apps on the Cloudflare target. Native deployment requires [Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans) because Cloudflare Containers are unavailable on Workers Free. `void deploy --platform cloudflare` verifies Containers access before provisioning resources or building the app and explains how to fix a missing plan or API-token permission. Apps that do not import `void/sandbox` or configure `sandbox` emit no Container and perform no entitlement check. The default registry image is pinned to the installed `@cloudflare/sandbox` version, so local and native Cloudflare deploys run the same container as Void Platform. If `sandbox.image` is a custom local Dockerfile path, set `sandbox.platformImage` to the pushed image that the platform should run.
228
251
 
229
252
  ### `target`
230
253
 
@@ -247,13 +270,14 @@ Void-managed WebSocket route files (`*.ws.ts`) are Cloudflare-only because they
247
270
 
248
271
  ### `worker`
249
272
 
250
- Curated Cloudflare Workers configuration. Cloudflare-targeted apps require an explicit `compatibility_date` here unless it is provided by a supported wrangler fallback file. If no date is configured, Void writes the latest known-good date here. Binding arrays such as `d1_databases`, `kv_namespaces`, and `r2_buckets` are not allowed here because Void manages bindings through inference and `inference.bindings`. If you need custom bindings with real IDs, use a `wrangler.json` and `wrangler deploy`.
273
+ Curated Cloudflare Workers configuration. Cloudflare-targeted apps require an explicit `compatibility_date` here unless it is provided by a supported Cloudflare fallback file. If no date is configured, Void writes the latest known-good date here. Binding arrays such as `d1_databases`, `kv_namespaces`, and `r2_buckets` are not allowed here because Void manages bindings through inference and `inference.bindings`. If you need custom bindings with real IDs, add them to `wrangler.jsonc`; Void preserves them during deployment.
251
274
 
252
275
  | Field | Type | Description |
253
276
  | --------------------- | ---------- | -------------------------------------- |
254
277
  | `compatibility_date` | `string` | Cloudflare Workers compatibility date |
255
278
  | `compatibility_flags` | `string[]` | Cloudflare Workers compatibility flags |
256
279
  | `vars` | `object` | Plain-text worker variables |
280
+ | `limits` | `object` | Worker resource limit overrides |
257
281
 
258
282
  ```json
259
283
  {
@@ -267,7 +291,19 @@ Curated Cloudflare Workers configuration. Cloudflare-targeted apps require an ex
267
291
  }
268
292
  ```
269
293
 
270
- `worker.vars` values must be strings. They are merged into Worker bindings before `.env` files are loaded, so project `.env` values override `worker.vars` for local dev/build. Do not put secrets here; use `env.ts` plus `void secret put` for production secrets.
294
+ `worker.vars` values must be strings. Root `.env` values override them during local development only. Production builds do not load `.env`, and reject any `worker.vars` name declared as a server key in `env.ts`. Use `void secret put` for production server values.
295
+
296
+ `worker.limits.cpu_ms` caps Workers CPU time per request, in milliseconds. It must be an integer between 1 and 300000 (Cloudflare's hard maximum, 5 minutes). A deploy that requests more than your account plan's ceiling fails with an error naming both the requested value and the plan maximum. Only a rollback clamps: rolling back to a deployment whose configured limit now exceeds your plan applies the plan ceiling instead of failing. If your plan changes so that a previously valid value now exceeds the ceiling, deploys keep failing until you lower `cpu_ms` in `void.json`. On the direct Cloudflare path, the value is written into the generated `dist/ssr/wrangler.json` as `limits.cpu_ms` and enforced by Cloudflare directly. The Void plan ceiling does not apply there, but your Cloudflare account's own CPU-time allowance still does: the Workers Free plan caps CPU at 10 ms per request, and the Workers Paid plan allows up to 300000 ms. A value above what your Cloudflare account permits is constrained or rejected by Cloudflare, not by Void.
297
+
298
+ ```json
299
+ {
300
+ "worker": {
301
+ "limits": {
302
+ "cpu_ms": 30000
303
+ }
304
+ }
305
+ }
306
+ ```
271
307
 
272
308
  ### `routing`
273
309
 
@@ -334,6 +370,20 @@ Fallback rewrites. Same shape as `rewrites`, but rules only fire when no static
334
370
  }
335
371
  ```
336
372
 
373
+ #### `routing.isr`
374
+
375
+ Boolean switch for Void's ISR caching. When omitted or `true`, Void infers caching from your revalidate and prerender settings. Setting it to `false` disables ISR and edge prerendering for the whole app, including per-page exports:
376
+
377
+ ```json
378
+ {
379
+ "routing": {
380
+ "isr": false
381
+ }
382
+ }
383
+ ```
384
+
385
+ 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.
386
+
337
387
  #### `routing.revalidate`
338
388
 
339
389
  ISR revalidation TTL in seconds, either globally or per path. See [Revalidation](../guide/edge/revalidation.md) for details.
@@ -396,6 +446,8 @@ Set `"404-page"` when your assets come from a static site generator (VitePress,
396
446
 
397
447
  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.
398
448
 
449
+ 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.
450
+
399
451
  ### `inference`
400
452
 
401
453
  Configuration for build-time inference, including how Void detects your app type, bindings, and build process.
@@ -407,7 +459,7 @@ Explicitly control inferred Cloudflare bindings. If omitted, bindings are [autom
407
459
  Each binding accepts `true` (use default name), `false` (disable), or a string (custom binding name):
408
460
 
409
461
  ```json
410
- { "inference": { "bindings": { "db": true, "kv": false, "storage": "MY_BUCKET" } } }
462
+ { "inference": { "bindings": { "db": true, "kv": false, "storage": "MY_BUCKET", "ai": "MY_AI" } } }
411
463
  ```
412
464
 
413
465
  | Key | Default Binding | Type | Custom Name |
@@ -415,9 +467,12 @@ Each binding accepts `true` (use default name), `false` (disable), or a string (
415
467
  | `db` | `DB` | `D1Database` | `"db": "MY_DB"` |
416
468
  | `kv` | `KV` | `KVNamespace` | `"kv": "MY_KV"` |
417
469
  | `storage` | `STORAGE` | `R2Bucket` | `"storage": "MY_BUCKET"` |
418
- | `ai` | `AI` | `Ai` | Boolean only |
470
+ | `ai` | `AI` | `Ai` | `"ai": "MY_AI"` |
471
+ | `email` | — | — | Boolean only |
472
+
473
+ Custom resource binding names flow through deploy manifests, Cloudflare config generation, remote binding proxying, internal migrations, and generated runtime helpers such as `void/db`, `void/kv`, and `void/storage`. Custom AI names apply to generated Cloudflare configuration and `void/ai` runtime resolution for direct Cloudflare builds; managed Workers AI continues to use Void's service proxy.
419
474
 
420
- Custom names are used in the deploy manifest, Wrangler config generation/sync, remote binding proxying, internal migrations, and generated runtime helpers such as `void/db`, `void/kv`, and `void/storage`.
475
+ `email` is a feature switch rather than a Cloudflare binding, so it has no binding name or type. On the platform, outbound mail is sent through the Void proxy, which owns the `send_email` binding — none is written into your worker; on your own Cloudflare account, `void deploy --platform cloudflare` writes a `send_email` binding named `SEND_EMAIL` into `wrangler.jsonc` itself once email is set up (see [`email.from`](#email)). Set it to `true` to turn the [email integration](../guide/email.md) on — which registers the `void dev` inbox — even when no scanned file imports `void/email`, or `false` to turn it off.
421
476
 
422
477
  #### `inference.build`
423
478
 
@@ -18,18 +18,21 @@ This runs once before plugins initialize, so the results are available to config
18
18
 
19
19
  ## Detected Bindings
20
20
 
21
- | Binding | Type | Detected by import | Detected by env access |
22
- | --------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
23
- | `DB` | `D1Database` | `import { db } from "void/db"` | `env.DB` or `c.env.DB` |
24
- | `KV` | `KVNamespace` | `import { kv } from "void/kv"` | `env.KV` or `c.env.KV` |
25
- | `STORAGE` | `R2Bucket` | `import { storage } from "void/storage"` | `env.STORAGE` or `c.env.STORAGE` |
26
- | `AI` | `Ai` | `import { ai } from "void/ai"` | `env.AI` or `c.env.AI` |
27
- | `SANDBOX` | `DurableObjectNamespace<Sandbox>` | `import { getSandbox } from "void/sandbox"` | `env.SANDBOX` or `c.env.SANDBOX` |
28
- | Auth | none | `import { ... } from "void/auth"` or `import { auth } from "void/client"` / `void/client/react` / `void/client/vue` / `void/client/svelte` / `void/client/solid` | none |
29
- | `QUEUE_*` | `Queue` | `import { queues } from "void/queues"` | `env.QUEUE_*` |
21
+ | Binding | Type | Detected by import | Detected by env access |
22
+ | ---------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
23
+ | `DB` | `D1Database` | `import { db } from "void/db"` | `env.DB` or `c.env.DB` |
24
+ | `KV` | `KVNamespace` | `import { kv } from "void/kv"` | `env.KV` or `c.env.KV` |
25
+ | `STORAGE` | `R2Bucket` | `import { storage } from "void/storage"` | `env.STORAGE` or `c.env.STORAGE` |
26
+ | `AI` | `Ai` | `import { ai } from "void/ai"` | `env.AI` or `c.env.AI` |
27
+ | `SANDBOX` | `DurableObjectNamespace<Sandbox>` | `import { getSandbox } from "void/sandbox"` | `env.SANDBOX` or `c.env.SANDBOX` |
28
+ | Auth | none | `import { ... } from "void/auth"` or `import { auth } from "void/client"` / `void/client/react` / `void/client/vue` / `void/client/svelte` / `void/client/solid` | none |
29
+ | `QUEUE_*` | `Queue` | `import { queues } from "void/queues"` | `env.QUEUE_*` |
30
+ | filename-derived | `DurableObjectNamespace` | A default-exported `defineDurableState()` module in `durable-objects/` | n/a |
30
31
 
31
32
  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`).
32
33
 
34
+ Durable state uses a filesystem convention rather than the import scanner. 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).
35
+
33
36
  ## Scanned Directories
34
37
 
35
38
  ### Standard mode
@@ -65,6 +68,7 @@ Regardless of mode, these are always checked:
65
68
 
66
69
  - **SSR entry** such as `src/main.ssr.ts`, for SSR apps that access bindings during rendering
67
70
  - **`src/`**, which is always scanned for auth imports unless it is already in the scan list for framework mode
71
+ - **`durable-objects/`**, which is scanned for typed Durable Object state modules in native Void apps
68
72
 
69
73
  ## Custom Scan Directories
70
74
 
@@ -80,6 +80,7 @@ File-based HTTP API endpoints built on [Hono](https://hono.dev). Each file expor
80
80
  - **Catch-all**: `[...slug]` matches the remaining path
81
81
  - **Route groups**: `(admin)/` organizes files without affecting URL paths
82
82
  - **Files starting with `_`** are ignored
83
+ - **Environment suffix**: `debug.dev.ts` builds in development only, `metrics.prod.ts` in production only
83
84
 
84
85
  See [Server Routing](/guide/server-routing) for the full guide.
85
86
 
@@ -163,14 +164,12 @@ Generate or refresh it with `void prepare`, or let `vite dev` / `vite build` pop
163
164
 
164
165
  ## Config Files
165
166
 
166
- | File | Purpose |
167
- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
168
- | `vite.config.ts` | Vite configuration. Must include `voidPlugin()`. |
169
- | `void.json` | Optional Void config for [routing](/reference/config#routing), [inference](/reference/config#inference), and [worker settings](/reference/config#worker) |
170
- | `tsconfig.json` | TypeScript config. Extend `.void/tsconfig.json` for auto-generated types; run `void init --tsconfig` when an existing config already uses `extends`. |
171
- | `.env` | Public environment variables (committed) |
172
- | `.env.local` | Secret variables for local dev (gitignored) |
173
- | `.env.production` | Public production variables (committed) |
174
- | `.env.production.local` | Production secrets for local testing (gitignored) |
175
-
176
- See [Environment Variables](/guide/env-vars) for the full env file loading order.
167
+ | File | Purpose |
168
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
169
+ | `vite.config.ts` | Vite configuration. Must include `voidPlugin()`. |
170
+ | `void.json` | Optional Void config for [routing](/reference/config#routing), [inference](/reference/config#inference), and [worker settings](/reference/config#worker) |
171
+ | `tsconfig.json` | TypeScript config. Extend `.void/tsconfig.json` for auto-generated types; run `void init --tsconfig` when an existing config already uses `extends`. |
172
+ | `.env` | Local development values only (gitignored; never deployed) |
173
+ | `env.ts` | Checked-in env names, types, defaults, and requiredness |
174
+
175
+ See [Environment Variables](/guide/env-vars) for local, production-secret, and client build behavior.
package/AGENT_PROMPT.md DELETED
@@ -1,19 +0,0 @@
1
- ## Void
2
-
3
- This project uses [Void](https://void.cloud) — a fullstack Vite plugin + deployment platform for Cloudflare. `voidPlugin()` in `vite.config.ts` gives you file-based API routing on Hono (`routes/`), Inertia-inspired server-rendered pages with co-located loaders/actions (`pages/` + `@void/vue` or `@void/react`), auto-provisioned D1/KV/R2 bindings, first-class Drizzle ORM integration (schema in `db/schema.ts` -> `void/db` Drizzle instance -> typed routes -> typed fetch client), built-in auth, queues, cron jobs, edge caching (ISR), and one-command deploys via `npx void deploy`. For first-time setup, prefer `npx void init`; in an empty directory, install `void` first and let the interactive flow scaffold the starter with Vite+ by default, add the matching framework adapter, configure project files, handle auth, and link or create the deploy project before the first deploy. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. Use `void` and `@void/*` package names in source code and package manifests.
4
-
5
- Database: define Drizzle tables in `db/schema.ts`, import `db` from `void/db` and tables from `@schema`. Use `void db push` for prototyping, `void db generate` for production migrations. `drizzle-orm` and `drizzle-kit` ship with void (no extra install). Migrations live in `db/migrations/`.
6
-
7
- Env: declare every env key in `env.ts` at the project root via `defineEnv({ KEY: string(), ... })` from `void/env`. Read values via `import { env } from "void/env"`. Schema validation runs at dev start (warns) and on `void deploy` (hard error on missing prod secrets). Use `VITE_*` prefix for keys that should be exposed to client code.
8
-
9
- CI/editor prep: run `void prepare` to generate `.void/routes.d.ts`, `.void/db.d.ts`, `.void/queues.d.ts`, `.void/env.d.ts`, and `.void/tsconfig.json` without booting Vite. Run it after `npm install` in CI or a fresh clone before typechecking; `vite dev` and `vite build` regenerate these during normal workflows.
10
-
11
- Rewrites and redirects: declare static rules in `void.json` under `routing.redirects` / `routing.rewrites` / `routing.fallbacks`, or in a `public/_redirects` file. For dynamic rewrites, call `c.rewrite(path)` in a `defineMiddleware`.
12
-
13
- Logs: surface app-level errors that should show up under `void project logs --level error` via `import { logger } from "void/log"` and `logger.error(msg, fields?)` (also `.warn` / `.info`). Anything caught and only persisted to your own DB is invisible to Cloudflare Tail; route it through `logger.*` or `console.*` so the platform can see it.
14
-
15
- Requests: `void project logs` only has rows when a worker actually ran. 5xx generated by the edge router, and every request to a static/SPA project, produce no log line at all. Use `void project requests --status 5xx --range 12h` to see those — it lists status, method, and duration for every request the edge served, whether or not a worker was invoked.
16
-
17
- Self-host deploy: `void deploy` targets the Void platform; to deploy to the user's OWN Cloudflare account instead, use `void deploy --backend cloudflare` (add `--provision` on the first deploy to create the D1/KV/R2/Queues/Hyperdrive resources the source needs). It uses local wrangler auth, so pin an account (`account_id` in `wrangler.jsonc` or `CLOUDFLARE_ACCOUNT_ID`) and keep real secrets in `wrangler secret put` — every `.env*` file this backend loads (`.env`, `.env.local`, `.env.production`, `.env.production.local`) ships as plaintext worker vars, `.local` included. Provisioning a Hyperdrive config reads `DATABASE_URL` from the shell, not from `.env*`. v1 supports full Void apps on the Cloudflare Workers target only (D1/KV/R2/Queues/Hyperdrive; auth and ISR on D1/SQLite); framework SSR of every kind (TanStack Start, React Router, vinext, SvelteKit, Nuxt, Analog, Astro), static/SPA/SSG apps (including `output: "static"`), WebSocket/Durable Object apps (`*.ws.ts`), a custom `migrations_pattern`, node/bun/deno targets, and PostgreSQL apps with auth all fail closed with guidance. Auth apps must ship checked-in migrations that produce the Better Auth schema. `--provision` is a single-operator, dev-machine step and is disabled in CI.
18
-
19
- Full docs are in `node_modules/void/docs/`. If you have the `void` skill available, use it for a complete API reference covering project structure, routing, pages mode, database, auth, typed fetch, KV, storage, queues, cron jobs, CLI, configuration, and deployment.
@@ -1,22 +0,0 @@
1
- //#region src/shared/cf-access.ts
2
- /**
3
- * Resolve Cloudflare Access headers from an env-like object.
4
- *
5
- * Priority:
6
- * 1. Service token pair (`CF_ACCESS_CLIENT_ID` + `CF_ACCESS_CLIENT_SECRET`) — CI path
7
- * 2. User JWT (`CF_ACCESS_TOKEN`) — dev path, typically populated via `cloudflared access token`
8
- * 3. No headers — prod, or unprotected hostnames
9
- */
10
- function cfAccessHeaders(env) {
11
- const id = env.CF_ACCESS_CLIENT_ID;
12
- const secret = env.CF_ACCESS_CLIENT_SECRET;
13
- if (typeof id === "string" && typeof secret === "string" && id.length > 0 && secret.length > 0) return {
14
- "CF-Access-Client-Id": id,
15
- "CF-Access-Client-Secret": secret
16
- };
17
- const token = env.CF_ACCESS_TOKEN;
18
- if (typeof token === "string" && token.length > 0) return { "cf-access-token": token };
19
- return {};
20
- }
21
- //#endregion
22
- export { cfAccessHeaders as t };
@@ -1,299 +0,0 @@
1
- import { a as join } from "./dist-DaKKDf8D.mjs";
2
- import { D as outro, E as note, T as log, a as cliTitle, w as intro } from "./agents-CtgBYqld.mjs";
3
- import { b as readProjectConfig, f as getToken, n as PlatformClient } from "./client-Gb71-XkG.mjs";
4
- import { r as generateEnvTypes, t as findEnvFile } from "./env-types-QBj-ndax.mjs";
5
- import { h as loadUserEnvFile, l as fetchRemoteSecretNames, m as validateProdEnv, u as formatEnvReport } from "./env-validation-Dea3v3ej.mjs";
6
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
- //#region src/cli/env-example.ts
8
- /**
9
- * `void env example` — generate a `.env.example` block from the registered
10
- * env schema, managed as a marker-delimited section so any user-managed
11
- * entries (CI tokens, build flags, etc.) above or below the block survive
12
- * a refresh.
13
- *
14
- * Marker convention mirrors the one used by `init.ts` for CLAUDE.md /
15
- * AGENTS.md instructions: a literal start marker, a body, and a literal
16
- * end marker. The markers are hash-prefixed so they remain valid dotenv
17
- * comments and don't trip up tools that parse `.env` files.
18
- *
19
- * Schema introspection strategy:
20
- * - Call `schema['~standard'].validate(undefined)`:
21
- * • `{ value: undefined }` → optional (no default)
22
- * • `{ value: <x> }` → has a default (value is `<x>`)
23
- * • `{ issues: [...] }` → required
24
- * - For enum hints, probe with a sentinel that is unlikely to match and
25
- * parse the built-in `oneOf` error message ("Expected one of A, B, got ..."),
26
- * yielding the valid values. This only works for Void's built-in
27
- * `oneOf()` helper — third-party validators silently degrade to no hint,
28
- * which is fine because `.env.example` is purely informational.
29
- *
30
- * This keeps the introspection layer Standard Schema-friendly (no private
31
- * fields, no type-widening) while still giving a good DX for the common
32
- * Void helpers.
33
- */
34
- /** Load the user's env.ts so `defineEnv` registers the schema. */
35
- async function loadRegisteredSchema(envFile) {
36
- await loadUserEnvFile(envFile);
37
- return (await import("./runtime/env-public.mjs"))._getRegisteredSchema();
38
- }
39
- /**
40
- * Introspect a single schema into an {@link EntryKind}.
41
- *
42
- * The probing logic is pure: it only calls the public `~standard.validate`
43
- * contract, so it works for any Standard Schema-compliant validator.
44
- */
45
- function classifySchema(schema) {
46
- const enumValues = tryExtractEnumValues(schema);
47
- const probe = schema["~standard"].validate(void 0);
48
- if (probe instanceof Promise) return {
49
- kind: "required",
50
- enumValues
51
- };
52
- if ("issues" in probe && probe.issues) return {
53
- kind: "required",
54
- enumValues
55
- };
56
- if (probe.value === void 0) return {
57
- kind: "optional",
58
- enumValues
59
- };
60
- return {
61
- kind: "default",
62
- defaultValue: probe.value,
63
- enumValues
64
- };
65
- }
66
- /**
67
- * Attempt to pull enum values out of a Void `oneOf()` schema by probing with
68
- * an invalid sentinel and parsing the error message. Returns undefined for
69
- * any schema that isn't a built-in `oneOf`.
70
- */
71
- function tryExtractEnumValues(schema) {
72
- const result = schema["~standard"].validate("__void_env_example_probe__");
73
- if (result instanceof Promise) return;
74
- if (!("issues" in result) || !result.issues || result.issues.length === 0) return;
75
- const message = result.issues[0].message;
76
- const match = /^Expected one of (.+), got "/.exec(message);
77
- if (!match) return;
78
- return match[1].split(",").map((s) => s.trim());
79
- }
80
- /** Serialize a default value into a dotenv-friendly string. */
81
- function serializeDefault(value) {
82
- if (typeof value === "string") return value;
83
- if (typeof value === "number" || typeof value === "boolean") return String(value);
84
- try {
85
- return JSON.stringify(value);
86
- } catch {
87
- return "";
88
- }
89
- }
90
- /**
91
- * Build the body of the managed env block (no markers) from a registered
92
- * schema map.
93
- *
94
- * Grouped by:
95
- * 1. required (no default, not optional)
96
- * 2. required with default (prefilled value)
97
- * 3. optional (empty value)
98
- *
99
- * Enum-valued keys get a leading `# enum: A | B | C` comment.
100
- */
101
- function formatEnvExample(schema) {
102
- const entries = Object.entries(schema).map(([key, s]) => ({
103
- key,
104
- classification: classifySchema(s)
105
- }));
106
- const required = entries.filter((e) => e.classification.kind === "required");
107
- const withDefault = entries.filter((e) => e.classification.kind === "default");
108
- const optional = entries.filter((e) => e.classification.kind === "optional");
109
- const lines = [];
110
- const writeGroup = (label, group) => {
111
- if (group.length === 0) return;
112
- if (lines.length > 0) lines.push("");
113
- lines.push(`# ${label}`);
114
- for (const entry of group) {
115
- const enumValues = entry.classification.enumValues;
116
- if (enumValues && enumValues.length > 0) lines.push(`# enum: ${enumValues.join(" | ")}`);
117
- if (entry.classification.kind === "default") lines.push(`${entry.key}=${serializeDefault(entry.classification.defaultValue)}`);
118
- else lines.push(`${entry.key}=`);
119
- }
120
- };
121
- writeGroup("required", required);
122
- writeGroup("with defaults", withDefault);
123
- writeGroup("optional", optional);
124
- return lines.join("\n") + (lines.length > 0 ? "\n" : "");
125
- }
126
- /**
127
- * Literal start/end markers for the void-managed block. They are valid
128
- * dotenv comments (hash-prefixed) so any tool that parses `.env.example`
129
- * silently ignores them, and they are matched as whole lines (with
130
- * defensive trailing-whitespace tolerance) when locating the block.
131
- */
132
- const ENV_EXAMPLE_START_MARKER = "# >>> void env: managed block — do not edit between markers <<<";
133
- const ENV_EXAMPLE_END_MARKER = "# >>> end void env <<<";
134
- const ENV_EXAMPLE_MARKER_HINT = "# Run `void env example` to refresh.";
135
- /** Regex matchers for the markers — full line, ignore trailing whitespace. */
136
- const START_MARKER_RE = new RegExp(`^${ENV_EXAMPLE_START_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`);
137
- const END_MARKER_RE = new RegExp(`^${ENV_EXAMPLE_END_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`);
138
- function buildMarkerBlock(body) {
139
- const trimmedBody = body.endsWith("\n") ? body.slice(0, -1) : body;
140
- const parts = [ENV_EXAMPLE_START_MARKER, ENV_EXAMPLE_MARKER_HINT];
141
- if (trimmedBody.length > 0) parts.push(trimmedBody);
142
- parts.push(ENV_EXAMPLE_END_MARKER);
143
- return parts.join("\n") + "\n";
144
- }
145
- /**
146
- * Pure helper that produces the new `.env.example` content given the
147
- * existing file contents (or `null` when the file does not exist) and the
148
- * formatted env body (without marker lines).
149
- *
150
- * Behavior matrix:
151
- * - existing == null → `create` a fresh marker-only file
152
- * - both markers present → `replace` the lines between them
153
- * - no markers present → `append` the block at the end
154
- * - exactly one marker present → `error` (mismatched markers)
155
- */
156
- function applyMarkerBlock(existing, body) {
157
- const block = buildMarkerBlock(body);
158
- if (existing === null) return {
159
- content: block,
160
- action: "create"
161
- };
162
- const lines = existing.split("\n");
163
- let startIdx = -1;
164
- let endIdx = -1;
165
- for (let i = 0; i < lines.length; i++) {
166
- if (startIdx === -1 && START_MARKER_RE.test(lines[i])) {
167
- startIdx = i;
168
- continue;
169
- }
170
- if (startIdx !== -1 && END_MARKER_RE.test(lines[i])) {
171
- endIdx = i;
172
- break;
173
- }
174
- }
175
- const hasStart = lines.some((l) => START_MARKER_RE.test(l));
176
- const hasEnd = lines.some((l) => END_MARKER_RE.test(l));
177
- if (hasStart && !hasEnd) return {
178
- content: existing,
179
- action: "error",
180
- reason: "Found start marker but no matching end marker in .env.example. Restore `# >>> end void env <<<` or delete the file and re-run `void env example`."
181
- };
182
- if (!hasStart && hasEnd) return {
183
- content: existing,
184
- action: "error",
185
- reason: "Found end marker but no matching start marker in .env.example. Restore `# >>> void env: ... <<<` or delete the file and re-run `void env example`."
186
- };
187
- if (startIdx !== -1 && endIdx !== -1) {
188
- const before = lines.slice(0, startIdx);
189
- const after = lines.slice(endIdx + 1);
190
- const beforeText = before.length > 0 ? before.join("\n") + "\n" : "";
191
- const afterText = after.join("\n");
192
- return {
193
- content: beforeText + block + afterText,
194
- action: "replace"
195
- };
196
- }
197
- const trimmed = existing.replace(/\s+$/, "");
198
- return {
199
- content: trimmed + (trimmed.length > 0 ? "\n\n" : "") + block,
200
- action: "append"
201
- };
202
- }
203
- /** CLI entrypoint: load schema, manage marker block, write `.env.example`. */
204
- async function runEnvExample(root, options) {
205
- const envFile = findEnvFile(root);
206
- if (!envFile) {
207
- outro("No env.ts found at project root — nothing to generate.");
208
- return;
209
- }
210
- const schema = await loadRegisteredSchema(envFile);
211
- if (!schema || Object.keys(schema).length === 0) {
212
- outro("env.ts registered no keys — nothing to generate.");
213
- return;
214
- }
215
- const outPath = join(root, ".env.example");
216
- const existing = existsSync(outPath) ? readFileSync(outPath, "utf-8") : null;
217
- const result = applyMarkerBlock(existing, formatEnvExample(schema));
218
- if (result.action === "error") {
219
- log.error(result.reason ?? "Failed to update .env.example.");
220
- process.exit(1);
221
- }
222
- if (existing !== null && existing === result.content) {
223
- outro(".env.example is already up to date.");
224
- return;
225
- }
226
- writeFileSync(outPath, result.content);
227
- const count = Object.keys(schema).length;
228
- const keyCount = `${count} key${count === 1 ? "" : "s"}`;
229
- if (result.action === "create") log.success(`Wrote .env.example (${keyCount}).`);
230
- else if (result.action === "replace") log.success(`Refreshed void env block in .env.example (${keyCount}).`);
231
- else if (result.action === "append") {
232
- log.success(`Refreshed void env block in .env.example (${keyCount}).`);
233
- if (!options.force) log.info("appended void env block to existing .env.example");
234
- }
235
- outro("Done.");
236
- }
237
- //#endregion
238
- //#region src/cli/env.ts
239
- async function runEnvCommand(root, args) {
240
- console.log();
241
- intro(cliTitle(`env ${args.subcommand}`));
242
- if (args.subcommand === "check") {
243
- await runCheck(root, args.useRemoteSecrets);
244
- return;
245
- }
246
- if (args.subcommand === "types") {
247
- runTypes(root);
248
- return;
249
- }
250
- if (args.subcommand === "example") {
251
- await runEnvExample(root, { force: args.force });
252
- return;
253
- }
254
- }
255
- async function runCheck(root, useRemoteSecrets) {
256
- let remoteSecrets;
257
- if (useRemoteSecrets) {
258
- const token = getToken(root);
259
- if (!token) {
260
- log.error("--remote requires authentication. Run `void auth login` first.");
261
- process.exit(1);
262
- }
263
- const config = readProjectConfig(root);
264
- if (!config) {
265
- log.error("--remote requires a linked project. Run `void project link` first.");
266
- process.exit(1);
267
- }
268
- remoteSecrets = await fetchRemoteSecretNames(new PlatformClient(token, { root }), config.projectId);
269
- }
270
- const { hasSchema, report } = await validateProdEnv(root, {
271
- productionOnly: true,
272
- remoteSecrets
273
- });
274
- if (!hasSchema) {
275
- outro("No env.ts found — nothing to validate.");
276
- return;
277
- }
278
- if (report.valid) {
279
- outro("All required env vars are present and valid.");
280
- return;
281
- }
282
- note(formatEnvReport(report), "Env validation failed");
283
- if (report.missing.length > 0) log.info(`Set missing values via .env / .env.production, or upload as secrets with \`void secret put <NAME>\`.`);
284
- process.exit(1);
285
- }
286
- function runTypes(root) {
287
- const envFile = findEnvFile(root);
288
- if (!envFile) {
289
- outro("No env.ts found at project root — nothing to generate.");
290
- return;
291
- }
292
- const outDir = join(root, ".void");
293
- mkdirSync(outDir, { recursive: true });
294
- const { dts } = generateEnvTypes(envFile, outDir);
295
- writeFileSync(join(outDir, "env.d.ts"), dts);
296
- outro(`Wrote ${join(".void", "env.d.ts")}.`);
297
- }
298
- //#endregion
299
- export { runEnvCommand };