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
@@ -0,0 +1,254 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Handlers and Middleware {#handlers}
6
+
7
+ Imported from `"void"` or `"void/handler"`.
8
+
9
+ ## `defineHandler(handler)` {#definehandler-handler}
10
+
11
+ Wraps a route handler function. The handler receives a [`CloudContext`](./types.md#cloudcontext) and can return a plain value (auto-converted to a Response) or use the Hono `c.json()` / `c.text()` APIs directly.
12
+
13
+ ```ts
14
+ import { defineHandler } from 'void';
15
+
16
+ export const GET = defineHandler((c) => {
17
+ return { message: 'hello' };
18
+ });
19
+ ```
20
+
21
+ **Signature:**
22
+
23
+ ```ts
24
+ function defineHandler<R>(handler: (c: CloudContext) => R): TypedHandler<{}, R>;
25
+ ```
26
+
27
+ ## `defineHandler(middleware..., handler)` {#definehandler-middleware-handler}
28
+
29
+ Composes up to 5 per-route middleware with a final handler. Middleware runs in order before the handler.
30
+
31
+ ```ts
32
+ export const GET = defineHandler(authMiddleware, rateLimiter, (c) => {
33
+ return { ok: true };
34
+ });
35
+ ```
36
+
37
+ ## `defineHandler.withValidator(validators)` {#definehandler-withvalidator-validators}
38
+
39
+ Creates a handler with input validation using any [Standard Schema](https://github.com/standard-schema/standard-schema) compatible library (zod, valibot, arktype, etc.). Returns a curried function that accepts the handler.
40
+
41
+ Validated input is passed as the second argument to the handler.
42
+
43
+ ```ts
44
+ import { defineHandler } from 'void';
45
+ import * as v from 'valibot';
46
+
47
+ export const POST = defineHandler.withValidator({
48
+ body: v.object({
49
+ name: v.pipe(v.string(), v.minLength(1)),
50
+ email: v.pipe(v.string(), v.email()),
51
+ }),
52
+ })((c, { body }) => {
53
+ return { received: body.name };
54
+ });
55
+ ```
56
+
57
+ **Signature:**
58
+
59
+ ```ts
60
+ function withValidator<V extends ValidatorSlots>(
61
+ validators: V,
62
+ ): <R>(handler: (c: CloudContext, input: HandlerInput<V>) => R) => TypedHandler<V, R>;
63
+ ```
64
+
65
+ **Type: `ValidatorSlots`**
66
+
67
+ ```ts
68
+ interface ValidatorSlots {
69
+ body?: StandardSchemaV1;
70
+ query?: StandardSchemaV1;
71
+ params?: StandardSchemaV1;
72
+ }
73
+ ```
74
+
75
+ **Type: `HandlerInput<V>`**
76
+
77
+ The inferred output types of each validator slot. For a `ValidatorSlots` with `body` and `query`, the input object has `{ body: ..., query: ... }` with types inferred from the schema output.
78
+
79
+ ## `defineMiddleware(handler)` {#definemiddleware-handler}
80
+
81
+ Type-safe wrapper for Hono middleware.
82
+
83
+ ```ts
84
+ import { defineMiddleware } from 'void';
85
+
86
+ export default defineMiddleware(async (c, next) => {
87
+ console.log(`${c.req.method} ${c.req.path}`);
88
+ await next();
89
+ });
90
+ ```
91
+
92
+ **Signature:**
93
+
94
+ ```ts
95
+ function defineMiddleware(handler: MiddlewareHandler<CloudEnv>): MiddlewareHandler<CloudEnv>;
96
+ ```
97
+
98
+ ## `basicAuth(options)` {#basicauth-options}
99
+
100
+ Built-in Basic authentication middleware for temporary site gates and pre-launch protection. Use it from `middleware/` with credentials from `void/env` to protect the whole app, or pass it to `defineHandler()` for a single route.
101
+
102
+ Void’s reserved `/__void` endpoints use their own authentication and are excluded from Basic auth.
103
+
104
+ When credentials come from `void/env`, wrap the reads in functions so they are resolved per request after Void has bound the runtime env.
105
+
106
+ For app-specific bypasses such as health checks or public webhooks, compose that logic in your own middleware before calling `basicAuth()`.
107
+
108
+ ```ts
109
+ // env.ts
110
+ import { defineEnv, string } from 'void/env';
111
+
112
+ export default defineEnv({
113
+ BASIC_AUTH_USERNAME: string(),
114
+ BASIC_AUTH_PASSWORD: string(),
115
+ });
116
+ ```
117
+
118
+ ```ts
119
+ // middleware/01.basic-auth.ts
120
+ import { basicAuth } from 'void';
121
+ import { env } from 'void/env';
122
+
123
+ export default basicAuth({
124
+ username: () => env.BASIC_AUTH_USERNAME,
125
+ password: () => env.BASIC_AUTH_PASSWORD,
126
+ realm: 'Preview',
127
+ });
128
+ ```
129
+
130
+ **Signature:**
131
+
132
+ ```ts
133
+ function basicAuth(options: {
134
+ username: string | (() => string);
135
+ password: string | (() => string);
136
+ realm?: string | (() => string);
137
+ message?: string | (() => string);
138
+ }): MiddlewareHandler<CloudEnv>;
139
+ ```
140
+
141
+ ## `defineScheduled(handler)` {#definescheduled-handler}
142
+
143
+ Wraps a Cloudflare [Scheduled handler](https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/) with type inference.
144
+
145
+ ```ts
146
+ import { defineScheduled } from 'void';
147
+
148
+ export default defineScheduled(async (controller, env, ctx) => {
149
+ const { results } = await env.DB.prepare('SELECT * FROM stale').all();
150
+ // ...
151
+ });
152
+ ```
153
+
154
+ **Signature:**
155
+
156
+ ```ts
157
+ function defineScheduled(
158
+ handler: (
159
+ controller: ScheduledController,
160
+ env: CloudEnv['Bindings'],
161
+ ctx: ExecutionContext,
162
+ ) => unknown | Promise<unknown>,
163
+ ): ScheduledFn;
164
+ ```
165
+
166
+ ## `defineQueue<T>(handler)` {#definequeue-t-handler}
167
+
168
+ Wraps a [queue](../../guide/queues.md) consumer handler with typed message bodies. The generic `<T>` defines the message body type, which flows through to the typed `queues` proxy for `send()` calls.
169
+
170
+ ```ts
171
+ import { defineQueue } from 'void';
172
+
173
+ export default defineQueue<{ to: string; subject: string }>(async (batch, env) => {
174
+ for (const msg of batch.messages) {
175
+ console.log(`Send to ${msg.body.to}: ${msg.body.subject}`);
176
+ }
177
+ });
178
+ ```
179
+
180
+ **Signature:**
181
+
182
+ ```ts
183
+ function defineQueue<T>(
184
+ handler: (batch: QueueBatch<T>, env: CloudEnv['Bindings']) => void | Promise<void>,
185
+ ): QueueFn;
186
+ ```
187
+
188
+ ## `defineRender(handler)` {#definerender-handler}
189
+
190
+ Wraps an SSR render entry. The second argument provides pre-built `<head>` and `<body>` asset tags for injecting client scripts and styles.
191
+
192
+ ```ts
193
+ import { defineRender } from "void";
194
+ import { renderToString } from "react-dom/server";
195
+
196
+ export default defineRender((c, assetTags) => {
197
+ const html = renderToString(<App />);
198
+ return c.html(`<!DOCTYPE html>
199
+ <html><head>${assetTags.css}${assetTags.preloads}</head>
200
+ <body><div id="root">${html}</div>${assetTags.body}</body></html>`);
201
+ });
202
+ ```
203
+
204
+ **Signature:**
205
+
206
+ ```ts
207
+ function defineRender(
208
+ handler: (c: CloudContext, assetTags: RenderAssetTags) => Response | Promise<Response>,
209
+ ): RenderFn;
210
+ ```
211
+
212
+ **Type: `RenderAssetTags`**
213
+
214
+ ```ts
215
+ interface RenderAssetTags {
216
+ css: string; // Stylesheet links for <head>
217
+ preloads: string; // Modulepreload and dev client tags for <head>
218
+ body: string; // Script tags for before </body>
219
+ }
220
+ ```
221
+
222
+ ## `defineHead<P>(handler)` {#definehead-p-handler}
223
+
224
+ Type-safe wrapper for the page `head()` export in `.server.ts` files. Provides [`CloudContext`](./types.md#cloudcontext) typing for the first argument and generic props typing for the second.
225
+
226
+ ```ts
227
+ import { defineHandler, defineHead } from 'void';
228
+ import type { InferProps } from 'void';
229
+
230
+ export type Props = InferProps<typeof loader>;
231
+
232
+ export const loader = defineHandler(async (c) => {
233
+ const post = await getPost(c.req.param('slug'));
234
+ return { post };
235
+ });
236
+
237
+ export const head = defineHead<Props>((c, props) => {
238
+ return {
239
+ title: props.post.title,
240
+ meta: [
241
+ { name: 'description', content: props.post.excerpt },
242
+ { property: 'og:title', content: props.post.title },
243
+ ],
244
+ };
245
+ });
246
+ ```
247
+
248
+ **Signature:**
249
+
250
+ ```ts
251
+ function defineHead<P = Record<string, unknown>>(
252
+ handler: (c: CloudContext, props: P) => HeadDescriptor | undefined,
253
+ ): (c: CloudContext, props: P) => HeadDescriptor | undefined;
254
+ ```
@@ -0,0 +1,241 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Pages Adapters {#framework-adaptors}
6
+
7
+ Framework adaptors for [Pages Routing](../../guide/pages-routing/overview). Each adaptor provides a Vite plugin and client-side runtime.
8
+
9
+ ## `@void/vue` {#void-vue}
10
+
11
+ ### `voidVue(options?)` {#voidvue-options}
12
+
13
+ Imported from `"@void/vue/plugin"`. Returns an array of Vite plugins that handle Vue SFC compilation and SSR or hydration entry generation. It already includes `@vitejs/plugin-vue`, so you do not need to install or configure that separately.
14
+
15
+ ```ts
16
+ import { voidVue } from '@void/vue/plugin';
17
+
18
+ export default defineConfig({
19
+ plugins: [voidPlugin(), voidVue()],
20
+ });
21
+ ```
22
+
23
+ **Signature:**
24
+
25
+ ```ts
26
+ function voidVue(options?: VoidVueOptions): Plugin[];
27
+ ```
28
+
29
+ **Options:**
30
+
31
+ ```ts
32
+ interface VoidVueOptions {
33
+ vue?: VuePluginOptions; // passed through to @vitejs/plugin-vue
34
+ viewTransitions?: boolean; // enable View Transitions API for navigations
35
+ }
36
+ ```
37
+
38
+ ### Vue Runtime {#vue-runtime}
39
+
40
+ Imported from `"@void/vue"`.
41
+
42
+ | Export | Description |
43
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
+ | `Link` | Vue component for SPA navigation. Renders `<a>` for GET, `<button>` for non-GET methods. Props: `href`, `method`, `data`, `prefetch`, `cacheFor`, `preserveScroll`, `preserveState`, `replace`, `reloadDocument`, `viewTransition`, `onNavigate`. |
45
+ | `useRouter()` | Returns the Void Router with current route state (`url`, `path`, `query`, `params`) and navigation methods: `visit`, `refresh`, awaitable `prefetch`, `flush`, `flushAll`. |
46
+ | `useParams()` | Returns dynamic route params for the page currently being rendered. |
47
+ | `useNavigation()` | Returns pending navigation state: `{ state, location, method }`, where `state` is `"idle"`, `"loading"`, or `"submitting"` and `location` is the pending destination. |
48
+ | `useForm(url, defaults, options?)` | Typed reactive form helper bound to a page action URL. Returns `{ data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
49
+ | `useIslandForm(defaults)` | Form helper for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
50
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
51
+ | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
52
+
53
+ Vue `Link` GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw. `prefetch` and `reloadDocument` are GET-only and throw for mutation links.
54
+
55
+ Vue GET navigation remounts the page so `useForm()` picks up the destination record's URL and defaults; layouts persist. Mutations and `router.refresh()` preserve page state by default. Set `preserveState` explicitly to override the default for navigation within the same record.
56
+
57
+ ## `@void/react` {#void-react}
58
+
59
+ ### `voidReact(options?)` {#voidreact-options}
60
+
61
+ Imported from `"@void/react/plugin"`. Returns an array of Vite plugins that handle SSR and hydration entry generation. It already includes `@vitejs/plugin-react`, so you do not need to install or configure that separately.
62
+
63
+ ```ts
64
+ import { voidReact } from '@void/react/plugin';
65
+
66
+ export default defineConfig({
67
+ plugins: [voidPlugin(), voidReact()],
68
+ });
69
+ ```
70
+
71
+ **Signature:**
72
+
73
+ ```ts
74
+ function voidReact(options?: VoidReactOptions): Plugin[];
75
+ ```
76
+
77
+ **Options:**
78
+
79
+ ```ts
80
+ interface VoidReactOptions {
81
+ react?: ReactPluginOptions; // passed through to @vitejs/plugin-react
82
+ viewTransitions?: boolean; // enable View Transitions API for navigations
83
+ prefetch?: {
84
+ hoverDelay?: number;
85
+ cacheFor?: number | string | [string, string];
86
+ };
87
+ }
88
+ ```
89
+
90
+ ### React Runtime {#react-runtime}
91
+
92
+ Imported from `"@void/react"`.
93
+
94
+ | Export | Description |
95
+ | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
96
+ | `Link` | React component for SPA navigation. Renders `<a>` for GET, `<button>` for non-GET methods. Props: `href`, `method`, `data`, `prefetch`, `cacheFor`, `preserveScroll`, `preserveState`, `replace`, `reloadDocument`, `viewTransition`, `onNavigate`. |
97
+ | `useRouter()` | Returns the Void Router with current route state (`url`, `path`, `query`, `params`) and navigation methods: `visit`, `refresh`, awaitable `prefetch`, `flush`, `flushAll`. React navigations are scheduled as transitions. |
98
+ | `useParams()` | Returns dynamic route params for the page currently being rendered. |
99
+ | `useNavigation()` | Returns pending navigation state: `{ state, location, method }`, where `state` is `"idle"`, `"loading"`, or `"submitting"` and `location` is the pending destination. |
100
+ | `useForm(url, defaults, options?)` | Form helper hook. Returns `{ data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
101
+ | `useIslandForm(defaults)` | Form helper hook for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
102
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
103
+ | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
104
+ | `Deferred<T>` | React-only prop type for `defer()` results. It is `Promise<T>` and is consumed with React `use()`. |
105
+
106
+ React `Link` GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw. `prefetch` and `reloadDocument` are GET-only and throw for mutation links.
107
+
108
+ React deferred props returned from `defer()` are Suspense resources. Read them
109
+ with React's `use()` inside a `<Suspense>` boundary. React Pages requires React
110
+ 19 and uses streaming SSR for the initial deferred shell. Rejections throw from
111
+ `use()`, so use a normal React error boundary for custom deferred error UI. Vue,
112
+ Svelte, and Solid keep the `{ loading, value, error }` deferred state object.
113
+ When explicitly annotating props, import `Deferred` from the framework adapter
114
+ package (`@void/react`, `@void/vue`, `@void/svelte`, or `@void/solid`) so the
115
+ type matches that adapter's client runtime shape.
116
+
117
+ ## `@void/svelte` {#void-svelte}
118
+
119
+ ### `voidSvelte(options?)` {#voidsvelte-options}
120
+
121
+ Imported from `"@void/svelte/plugin"`. Returns an array of Vite plugins that handle SSR and hydration entry generation for Svelte 5. It already includes `@sveltejs/vite-plugin-svelte`, so you do not need to install or configure that separately.
122
+
123
+ ```ts
124
+ import { voidSvelte } from '@void/svelte/plugin';
125
+
126
+ export default defineConfig({
127
+ plugins: [voidPlugin(), voidSvelte()],
128
+ });
129
+ ```
130
+
131
+ **Signature:**
132
+
133
+ ```ts
134
+ function voidSvelte(options?: VoidSvelteOptions): Plugin[];
135
+ ```
136
+
137
+ **Options:**
138
+
139
+ ```ts
140
+ interface VoidSvelteOptions {
141
+ svelte?: SveltePluginOptions; // passed through to @sveltejs/vite-plugin-svelte
142
+ viewTransitions?: boolean; // enable View Transitions API
143
+ prefetch?: {
144
+ hoverDelay?: number;
145
+ cacheFor?: number | string | [string, string];
146
+ };
147
+ }
148
+ ```
149
+
150
+ ### Svelte Runtime {#svelte-runtime}
151
+
152
+ Imported from `"@void/svelte"`.
153
+
154
+ | Export | Description |
155
+ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
156
+ | `Link` | Svelte component for SPA navigation. Renders `<a>` for GET, `<button>` for non-GET methods. Props: `href`, `method`, `data`, `prefetch`, `cacheFor`, `preserveScroll`, `preserveState`, `replace`, `reloadDocument`, `viewTransition`, `onNavigate`. |
157
+ | `useForm(url, defaults, options?)` | Form helper using Svelte 5 runes. Returns `{ data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
158
+ | `useIslandForm(defaults)` | Form helper for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
159
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
160
+ | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
161
+ | `useRouter()` | Returns the Void Router with current route state (`url`, `path`, `query`, `params`) and navigation methods: `visit`, `refresh`, awaitable `prefetch`, `flush`, `flushAll`. |
162
+ | `useParams()` | Returns dynamic route params for the page currently being rendered. |
163
+ | `useNavigation()` | Returns pending navigation state: `{ state, location, method }`, where `state` is `"idle"`, `"loading"`, or `"submitting"` and `location` is the pending destination. |
164
+
165
+ Svelte `Link` GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw. `prefetch` and `reloadDocument` are GET-only and throw for mutation links.
166
+
167
+ ## `@void/solid` {#void-solid}
168
+
169
+ ### `voidSolid(options?)` {#voidsolid-options}
170
+
171
+ Imported from `"@void/solid/plugin"`. Returns an array of Vite plugins that handle SSR and hydration entry generation for Solid. It already includes `vite-plugin-solid`, so you do not need to install or configure that separately.
172
+
173
+ ```ts
174
+ import { voidSolid } from '@void/solid/plugin';
175
+
176
+ export default defineConfig({
177
+ plugins: [voidPlugin(), voidSolid()],
178
+ });
179
+ ```
180
+
181
+ **Signature:**
182
+
183
+ ```ts
184
+ function voidSolid(options?: VoidSolidOptions): Plugin[];
185
+ ```
186
+
187
+ **Options:**
188
+
189
+ ```ts
190
+ interface VoidSolidOptions {
191
+ solid?: SolidPluginOptions; // passed through to vite-plugin-solid
192
+ viewTransitions?: boolean; // enable View Transitions API
193
+ prefetch?: {
194
+ hoverDelay?: number;
195
+ cacheFor?: number | string | [string, string];
196
+ };
197
+ }
198
+ ```
199
+
200
+ ### Solid Runtime {#solid-runtime}
201
+
202
+ Imported from `"@void/solid"`.
203
+
204
+ | Export | Description |
205
+ | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
206
+ | `Link` | Solid component for SPA navigation. Renders `<a>` for GET, `<button>` for non-GET methods. Props: `href`, `method`, `data`, `prefetch`, `cacheFor`, `preserveScroll`, `preserveState`, `replace`, `reloadDocument`, `viewTransition`, `onNavigate`. |
207
+ | `useForm(url, defaults, options?)` | Form helper using Solid stores. Returns `{ data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
208
+ | `useIslandForm(defaults)` | Form helper for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
209
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
210
+ | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
211
+ | `useRouter()` | Returns the Void Router with current route state (`url`, `path`, `query`, `params`) and navigation methods: `visit`, `refresh`, awaitable `prefetch`, `flush`, `flushAll`. |
212
+ | `useParams()` | Returns dynamic route params for the page currently being rendered. |
213
+ | `useNavigation()` | Returns pending navigation state: `{ state, location, method }`, where `state` is `"idle"`, `"loading"`, or `"submitting"` and `location` is the pending destination. |
214
+
215
+ Solid `Link` GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw. `prefetch` and `reloadDocument` are GET-only and throw for mutation links.
216
+
217
+ ## Markdown Package {#markdown-package}
218
+
219
+ The optional `@void/md` package adds Markdown pages to Pages Routing. Install it alongside a Pages adapter and add `voidMarkdown()` to your Vite plugins.
220
+
221
+ ```ts
222
+ import { voidMarkdown } from '@void/md/plugin';
223
+
224
+ export default defineConfig({
225
+ plugins: [voidPlugin(), voidReact(), voidMarkdown()],
226
+ });
227
+ ```
228
+
229
+ | Import path | Contents |
230
+ | ---------------------------- | ---------------------------------------------------------------------------------------- |
231
+ | `@void/md/plugin` | `voidMarkdown(options?)`, `MarkdownOptions`, `MdPage` |
232
+ | `@void/md` | `useFrontmatter()`, `FrontmatterContext`, `setFrontmatter()`, `MdPage` |
233
+ | `@void/md/pages` | Generated metadata for Markdown pages, used for navigation, sidebars, and search indexes |
234
+ | `@void/md/theme.css` | Full Markdown theme styles |
235
+ | `@void/md/theme-content.css` | Content-only Markdown styles for apps that provide their own shell/layout |
236
+
237
+ See [Markdown Pages](../../guide/pages-routing/markdown.md) for setup and framework-specific examples.
238
+
239
+ ## Form
240
+
241
+ Each Pages adapter exports `Form`. Pass the object returned by `useForm()` as `form`; `method` defaults to `post`. It renders validation and action errors, preserves controlled input, and respects known quota retry deadlines without submitting automatically. `renderError` customizes action-error presentation; Svelte uses a snippet. See [Actions and Forms](../../guide/pages-routing/actions-and-forms.md).
@@ -0,0 +1,39 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Plugin and Configuration {#plugin}
6
+
7
+ ## `voidPlugin(options?)` {#voidplugin-options}
8
+
9
+ Named export from `"void"`. Returns an array of Vite plugins that set up file-based routing, migration support, and the Cloudflare Workers runtime. Application-level configuration is read from [`void.config.ts`](../config.md); the optional `options` object controls Vite/Cloudflare plugin behavior.
10
+
11
+ ```ts
12
+ import { voidPlugin } from 'void';
13
+
14
+ export default defineConfig({
15
+ plugins: [voidPlugin()],
16
+ });
17
+ ```
18
+
19
+ | Option | Type | Description |
20
+ | ------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
21
+ | `persistTo` | `string` | Directory path for persisting local dev state (D1, KV, R2). Defaults to `.void/` in the project root. |
22
+ | `auxiliaryWorkers` | `AuxiliaryWorkerConfig[]` | Additional workers to run inside the same Miniflare instance during dev. Passed through to `@cloudflare/vite-plugin`. Useful for running multiple workers that share bindings (e.g. a separate API worker alongside a dashboard). |
23
+
24
+ ## Project configuration {#project-configuration}
25
+
26
+ ### `defineConfig(config)` {#defineconfig-config}
27
+
28
+ Import from `void/config` in the root `void.config.ts`. It returns the config with editor completion and TypeScript checking. Void validates the result when loading it, including values computed at runtime.
29
+
30
+ ```ts
31
+ import { defineConfig } from 'void/config';
32
+
33
+ export default defineConfig({
34
+ cloudflare: { name: 'my-app' },
35
+ routing: { revalidate: 60 },
36
+ });
37
+ ```
38
+
39
+ See the [config reference](../config.md) for all fields.
@@ -0,0 +1,109 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Resource Clients
6
+
7
+ ## KV {#kv}
8
+
9
+ Imported from `"void/kv"`.
10
+
11
+ ### `kv` {#kv-1}
12
+
13
+ Typed JSON-aware client for the inferred `KV` binding.
14
+
15
+ ```ts
16
+ import { kv } from 'void/kv';
17
+
18
+ await kv.put('settings', { theme: 'dark' });
19
+ const settings = await kv.get<{ theme: string }>('settings');
20
+ ```
21
+
22
+ **Key exports:** `kv`, `createKV(namespace)`, `KVClient`, `KVMap`, `PutOptions`, `ListOptions`.
23
+
24
+ `kv.map(prefix)` creates a typed namespaced view where every key is stored under `prefix:`.
25
+
26
+ ## Storage {#storage}
27
+
28
+ Imported from `"void/storage"`.
29
+
30
+ ### `storage` {#storage-1}
31
+
32
+ Default [R2 bucket](https://developers.cloudflare.com/r2/) proxy for the inferred `STORAGE` binding.
33
+
34
+ ```ts
35
+ import { storage } from 'void/storage';
36
+
37
+ await storage.put('avatars/alice.png', file);
38
+ const object = await storage.get('avatars/alice.png');
39
+ ```
40
+
41
+ **Key exports:** `storage`, `createStorage(bucket)`.
42
+
43
+ ## AI {#ai}
44
+
45
+ Imported from `"void/ai"`.
46
+
47
+ ### `ai` {#ai-1}
48
+
49
+ Typed AI client for Cloudflare AI models and provider-native AI Gateway requests.
50
+
51
+ ```ts
52
+ import { ai } from 'void/ai';
53
+
54
+ const result = await ai
55
+ .run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
56
+ messages: [{ role: 'user', content: 'Summarize this release note.' }],
57
+ })
58
+ .match({ ok: (result) => result, limited: (limit) => limit.response() });
59
+
60
+ const response = await ai
61
+ .provider('openai')
62
+ .fetch('/chat/completions', {
63
+ body: {
64
+ model: 'gpt-4o',
65
+ messages: [{ role: 'user', content: 'Summarize this release note.' }],
66
+ },
67
+ })
68
+ .match({ ok: (result) => result, limited: (limit) => limit.response() });
69
+ ```
70
+
71
+ **Key exports:** `ai`, `VoidAi`, provider request types. See [AI](../../guide/ai.md) for provider setup and streaming examples.
72
+
73
+ ## ISR {#isr}
74
+
75
+ Imported from `"void/isr"`.
76
+
77
+ ### `revalidate(options)` {#revalidate-options}
78
+
79
+ Revalidate ISR-cached pages on demand. In local development this is a no-op because there is no edge ISR cache.
80
+
81
+ ```ts
82
+ import { revalidate } from 'void/isr';
83
+
84
+ await revalidate({ paths: ['/', '/blog/hello'] });
85
+ await revalidate({ all: true });
86
+ ```
87
+
88
+ **Signature:**
89
+
90
+ ```ts
91
+ function revalidate(options: { paths?: string[]; all?: boolean }): Promise<void>;
92
+ ```
93
+
94
+ ## Logging {#logging}
95
+
96
+ Imported from `"void/log"`.
97
+
98
+ ### `logger` {#logger}
99
+
100
+ Structured logger that emits one JSON line per call so deployed logs can be filtered by message and fields.
101
+
102
+ ```ts
103
+ import { logger } from 'void/log';
104
+
105
+ logger.info('checkout completed', { orderId, userId });
106
+ logger.error('webhook failed', { provider: 'stripe', attempt: 3 });
107
+ ```
108
+
109
+ **Methods:** `logger.error(message, fields?)`, `logger.warn(message, fields?)`, `logger.info(message, fields?)`.