void 0.21.9 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/{account-cmd-DZZGK80W.mjs → account-cmd-C84Ee8cO.mjs} +5 -5
- package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
- package/dist/application-routing-B7QEjqSR.mjs +27 -0
- package/dist/{auth-CZuiVsFh.mjs → auth-CCjt0hcq.mjs} +1 -1
- package/dist/{auth-DLNN0D3Z.mjs → auth-CSkdO2Bb.mjs} +4 -47
- package/dist/{auth-link-B_CeugBw.mjs → auth-link-CioEg6uY.mjs} +5 -5
- package/dist/{auth-router-BgEFRuvZ.mjs → auth-router-BsR981d4.mjs} +5 -5
- package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
- package/dist/{build-cmd-Dpt0jd-x.mjs → build-cmd-LzvNJORH.mjs} +19 -7
- package/dist/{cache-7_UeZdTk.mjs → cache-C4MvnrMH.mjs} +4 -4
- package/dist/{cancel-deploy-D23R1RXT.mjs → cancel-deploy-abUxpP2n.mjs} +4 -4
- package/dist/{cf-build-output-CGT03qCD.mjs → cf-build-output-BPqOT964.mjs} +141 -63
- package/dist/cf-build-output-_0HNWysu.mjs +2 -0
- package/dist/cli/cli.mjs +114 -460
- package/dist/cli/cloudflare-operation-process.mjs +1103 -0
- package/dist/cli/env-schema-probe.d.mts +2 -1
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/client-Cu7jWiF1.mjs +2 -0
- package/dist/{client-QTl6ko_D.mjs → client-RV8NVeB8.mjs} +165 -21
- package/dist/{cloudflare-auth-C4_GPZr0.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -43
- package/dist/{cloudflare-cmd-bSmZ1d5L.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +9 -10
- package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
- package/dist/{cloudflare-connect-jAwacxxP.mjs → cloudflare-connect-B8uPZ4nx.mjs} +4 -4
- package/dist/{cloudflare-operations-BipGMJ5O.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
- package/dist/{cloudflare-operations-sMZXpk_S.mjs → cloudflare-operations-fxHb-byx.mjs} +118 -203
- package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
- package/dist/{config-CF69HgXc.d.mts → config-BMHb8RCj.d.mts} +2 -2
- package/dist/{config-CafTW6Cz.mjs → config-Br_JZD6u.mjs} +2 -7
- package/dist/config-C_XRIPx2.mjs +89 -0
- package/dist/{config-s7Xj7tPb.mjs → config-CyQ-wVd7.mjs} +1 -1
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config-write-BSduPMY8.mjs → config-write-B1f88wJA.mjs} +1 -1
- package/dist/{connect-BsUSRzln.mjs → connect-Bd4kJd9U.mjs} +6 -6
- package/dist/{create-project-BniEV0OW.mjs → create-project-Boczwj5r.mjs} +1 -1
- package/dist/{create-project-DBfFSZKY.mjs → create-project-bMf6ffLZ.mjs} +9 -5
- package/dist/{db-hRrvZaq_.mjs → db-8uG64XLl.mjs} +26 -26
- package/dist/{delete-D6dZ9B6B.mjs → delete-NvbiyeJf.mjs} +4 -4
- package/dist/{deploy-WaAQez1O.mjs → deploy-DzAIwqNU.mjs} +944 -607
- package/dist/{deploy-DDz7c8LK.mjs → deploy-bjXdFCtn.mjs} +1 -1
- package/dist/{dist-BR1quN_w.mjs → dist-AoCzRTJE.mjs} +226 -60
- package/dist/{dist-C5fND3R0.mjs → dist-BuDuKZJv.mjs} +1 -1
- package/dist/{dist-Dn6nn2IU.mjs → dist-CTBk70IR.mjs} +42 -42
- package/dist/{domain-Dmhvb2oU.mjs → domain-y5Tvydvo.mjs} +5 -5
- package/dist/{email-DFi-s2t4.mjs → email-B3umsW75.mjs} +15 -30
- package/dist/{env-Csi-tMbT.mjs → env-BS6qYHDb.mjs} +6 -6
- package/dist/{env-public-D_6u46fX.d.mts → env-public-BX_r8HR6.d.mts} +2 -1
- package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
- package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.mjs} +1 -1
- package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
- package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
- package/dist/{gen-Dz3X1Qab.mjs → gen-B580--vC.mjs} +5 -5
- package/dist/gen-BVaUUumi.mjs +2 -0
- package/dist/{github-cmd-BED3_9JD.mjs → github-cmd-v45BdfKX.mjs} +6 -8
- package/dist/{handler-BXJTXd02.d.mts → handler-CZ4nAylQ.d.mts} +2 -1
- package/dist/{headers-BOg_velo.mjs → headers-DWi2IXWx.mjs} +1 -1
- package/dist/help-DofyZuY7.mjs +2 -0
- package/dist/{help-DC7gdz7L.mjs → help-daGKjXGk.mjs} +268 -666
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +305 -1490
- package/dist/info-B97bTX9N.mjs +113 -0
- package/dist/{init-WO0JlPx8.mjs → init-Bvy7zrBo.mjs} +51 -20
- package/dist/limits-Bq5LG8Id.d.mts +27 -0
- package/dist/limits-Cjuk2VPm.mjs +68 -0
- package/dist/{link-CsHOinF7.mjs → link-CDqqCjFl.mjs} +5 -5
- package/dist/{list-CDb-4bZ1.mjs → list-CZj0dzKY.mjs} +5 -5
- package/dist/{live-CKiJilLr.d.mts → live-Chw1eIMv.d.mts} +1 -1
- package/dist/{local-d1-CC8sKFGu.mjs → local-d1-2CMnpuW_.mjs} +2 -2
- package/dist/login-DYt_An22.mjs +2 -0
- package/dist/{login-DvqXsfGs.mjs → login-UZKFM_u7.mjs} +5 -5
- package/dist/{logs-BdfiOezj.mjs → logs-CUZ6t9t3.mjs} +5 -5
- package/dist/migrate-8_2u55MD.mjs +2 -0
- package/dist/{migrate-B8KuoYsO.mjs → migrate-DHul7PRV.mjs} +5 -4
- package/dist/{node-BM43oz4G.mjs → node-BkyRWRx8.mjs} +2 -2
- package/dist/operator-args-CLgKGlwU.mjs +690 -0
- package/dist/{operator-cmd-03819ATr.mjs → operator-cmd-DBA6dl0m.mjs} +69 -23
- package/dist/output-Dm_A4Tbv.mjs +81 -0
- package/dist/pages/client.d.mts +34 -2
- package/dist/pages/client.mjs +59 -3
- package/dist/pages/index.d.mts +1 -1
- package/dist/pages/index.mjs +3 -3
- package/dist/pages/islands-plugin.d.mts +16 -6
- package/dist/pages/islands-plugin.mjs +2 -2
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +2 -308
- package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
- package/dist/{output-CCH48AMM.mjs → picocolors-BTps1_gs.mjs} +2 -76
- package/dist/plan-D1Q5rf-r.mjs +2 -0
- package/dist/plan-NPpwZ_kc.mjs +58 -0
- package/dist/platform-args-BJdRtlLq.mjs +506 -0
- package/dist/platform-args-D3RXyR6h.mjs +2 -0
- package/dist/{platform-auth-config-z92h63q5.mjs → platform-auth-config-B56E9YP1.mjs} +4 -4
- package/dist/{platform-auth-protection-DeE3yr2R.mjs → platform-auth-protection-BDWO_aER.mjs} +3 -3
- package/dist/{platform-auth-recovery-o_340Ixx.mjs → platform-auth-recovery-1gg4CSRe.mjs} +4 -4
- package/dist/{platform-cmd-C4ZV3Vpy.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
- package/dist/{platform-cmd-DNl8WosH.mjs → platform-cmd-DMcQStSc.mjs} +26 -5
- package/dist/{platform-domain-CU1JtJkW.mjs → platform-domain-BNkcz0OB.mjs} +36 -9
- package/dist/{platform-lifecycle-Bc047IeT.mjs → platform-lifecycle-9OyBALhH.mjs} +850 -276
- package/dist/{platform-lifecycle-Bs2qx1E3.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
- package/dist/{platform-management-CVpGI9Y5.mjs → platform-management-CjwLVQwN.mjs} +59 -11
- package/dist/{platform-management-C8tt6D8h.mjs → platform-management-CnyTdcWX.mjs} +1 -1
- package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
- package/dist/{platform-recovery-dvUaptLr.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
- package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
- package/dist/{prepare-DyZ-Yok5.mjs → prepare-B5Mkic5u.mjs} +3 -3
- package/dist/{prepare-C3kt3Rst.mjs → prepare-DOsL0CC9.mjs} +4 -20
- package/dist/prepare-cgvDMtSb.mjs +2 -0
- package/dist/{project-cmd-B44I8J_W.mjs → project-cmd-CNzrqvBv.mjs} +30 -16
- package/dist/{project-team-BkbYIsXN.mjs → project-team-DQOWPfQT.mjs} +4 -4
- package/dist/{project-token-C8xEEQnB.mjs → project-token-CTDYU0Cc.mjs} +4 -4
- package/dist/project-zero-trust-BNAkW-_0.mjs +63 -0
- package/dist/{protocol-ZH3jP4a7.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
- package/dist/protocol-U7bfjHmA.mjs +331 -0
- package/dist/{provision-DNtrtaVD.mjs → provision-C4ORE7G7.mjs} +1 -1
- package/dist/{provision-BhreDAOS.mjs → provision-CJFgTZY8.mjs} +111 -215
- package/dist/{requests-DFyhBMaf.mjs → requests-MhxYnau8.mjs} +4 -4
- package/dist/resource-name-C7LVpcRm.mjs +11 -0
- package/dist/{rollback-DHHxXZiS.mjs → rollback-CJ6iSDoU.mjs} +5 -5
- package/dist/route-url-CG7U-cRN.mjs +15 -0
- package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
- package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
- package/dist/runtime/ai.d.mts +12 -8
- package/dist/runtime/ai.mjs +84 -17
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/client-react.mjs +2 -2
- package/dist/runtime/client-solid.mjs +2 -2
- package/dist/runtime/client-svelte.mjs +2 -2
- package/dist/runtime/client-vue.mjs +2 -2
- package/dist/runtime/client.mjs +2 -2
- package/dist/runtime/durable.d.mts +3 -1
- package/dist/runtime/durable.mjs +4 -1
- package/dist/runtime/email/testing.mjs +1 -1
- package/dist/runtime/env-public.d.mts +1 -1
- package/dist/runtime/fetch-stream.mjs +1 -1
- package/dist/runtime/fetch.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/kv.mjs +0 -1
- package/dist/runtime/limits.d.mts +2 -0
- package/dist/runtime/limits.mjs +2 -0
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-server.mjs +25 -16
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/migration-handler.mjs +62 -42
- package/dist/runtime/route-url.d.mts +4 -0
- package/dist/runtime/route-url.mjs +2 -0
- package/dist/runtime/routing.d.mts +180 -0
- package/dist/runtime/routing.mjs +1082 -0
- package/dist/runtime/sandbox-container.d.mts +3 -0
- package/dist/runtime/sandbox-container.mjs +2 -0
- package/dist/runtime/sandbox.d.mts +4 -32
- package/dist/runtime/sandbox.mjs +151 -75
- package/dist/runtime/sse.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +4 -2
- package/dist/runtime/ws-server.mjs +27 -2
- package/dist/runtime/ws.d.mts +2 -2
- package/dist/runtime/ws.mjs +8 -6
- package/dist/sandbox-XZAqzFlG.d.mts +52 -0
- package/dist/sandbox-container-Bo0eiFKz.d.mts +73 -0
- package/dist/sandbox-container-C6ItmVuN.mjs +281 -0
- package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
- package/dist/{secret-DN9sSNiV.mjs → secret-Dli5fP0B.mjs} +6 -6
- package/dist/{skills-O6FUaizK.mjs → skills-D1II1Juz.mjs} +1 -1
- package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
- package/dist/{subcommand-prompt-BuGYkAkC.mjs → subcommand-prompt-CY1C4fvl.mjs} +2 -2
- package/dist/validate-Dq_L3s0S.mjs +2 -0
- package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
- package/dist/{wrangler-BymcxrRa.mjs → wrangler-7K-bW_DL.mjs} +14 -235
- package/dist/{ws-BwcqizuH.d.mts → ws-CL1w7GXU.d.mts} +13 -2
- package/package.json +48 -33
- package/sandbox.Dockerfile +4 -0
- package/schema.json +10 -22
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
- package/skills/void/SKILL.md +50 -133
- package/skills/void/docs/guide/ai.md +94 -84
- package/skills/void/docs/guide/app-types.md +3 -32
- package/skills/void/docs/guide/auth.md +12 -116
- package/skills/void/docs/guide/database/d1.md +9 -54
- package/skills/void/docs/guide/database/mysql.md +1 -1
- package/skills/void/docs/guide/database/postgresql.md +5 -26
- package/skills/void/docs/guide/database.md +23 -75
- package/skills/void/docs/guide/deployment.md +27 -113
- package/skills/void/docs/guide/durable-state.md +43 -18
- package/skills/void/docs/guide/edge/headers.md +3 -47
- package/skills/void/docs/guide/edge/prerendering.md +5 -20
- package/skills/void/docs/guide/edge/redirects.md +11 -64
- package/skills/void/docs/guide/edge/revalidation.md +6 -19
- package/skills/void/docs/guide/edge/rewrites.md +56 -284
- package/skills/void/docs/guide/edge/static-assets.md +23 -72
- package/skills/void/docs/guide/email/domains.md +112 -0
- package/skills/void/docs/guide/email/receiving.md +139 -0
- package/skills/void/docs/guide/email/sending.md +231 -0
- package/skills/void/docs/guide/email.md +13 -619
- package/skills/void/docs/guide/env-migration.md +11 -11
- package/skills/void/docs/guide/env-vars.md +9 -29
- package/skills/void/docs/guide/index.md +0 -15
- package/skills/void/docs/guide/jobs.md +3 -18
- package/skills/void/docs/guide/kv.md +5 -11
- package/skills/void/docs/guide/live.md +5 -56
- package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
- package/skills/void/docs/guide/pages-routing/head.md +10 -10
- package/skills/void/docs/guide/pages-routing/islands.md +6 -36
- package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
- package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
- package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
- package/skills/void/docs/guide/pages-routing/overview.md +7 -17
- package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
- package/skills/void/docs/guide/platform/administration/access.md +1 -4
- package/skills/void/docs/guide/platform/administration/email.md +35 -8
- package/skills/void/docs/guide/platform/administration/operations.md +26 -4
- package/skills/void/docs/guide/platform/administration/plans.md +126 -0
- package/skills/void/docs/guide/platform/administration/projects.md +5 -2
- package/skills/void/docs/guide/platform/administration/zero-trust.md +189 -0
- package/skills/void/docs/guide/platform/development/local.md +2 -2
- package/skills/void/docs/guide/platform/development/runtime.md +3 -13
- package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
- package/skills/void/docs/guide/platform/installation/credentials.md +6 -4
- package/skills/void/docs/guide/platform/installation/domains.md +31 -3
- package/skills/void/docs/guide/platform/installation/first-deployment.md +6 -0
- package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
- package/skills/void/docs/guide/platform/installation/prerequisites.md +21 -16
- package/skills/void/docs/guide/platform/installation/setup.md +9 -5
- package/skills/void/docs/guide/platform/installation/uninstall.md +17 -2
- package/skills/void/docs/guide/platform-administration.md +2 -0
- package/skills/void/docs/guide/queues.md +7 -9
- package/skills/void/docs/guide/quickstart.md +38 -37
- package/skills/void/docs/guide/remote-dev.md +4 -9
- package/skills/void/docs/guide/sandboxes.md +78 -41
- package/skills/void/docs/guide/server-routing.md +9 -72
- package/skills/void/docs/guide/sse.md +4 -18
- package/skills/void/docs/guide/ssg.md +3 -15
- package/skills/void/docs/guide/ssr.md +14 -62
- package/skills/void/docs/guide/storage.md +9 -4
- package/skills/void/docs/guide/type-safety.md +3 -14
- package/skills/void/docs/guide/typed-fetch.md +3 -7
- package/skills/void/docs/guide/websockets.md +68 -40
- package/skills/void/docs/integrations/agents.md +3 -3
- package/skills/void/docs/integrations/cloudflare.md +85 -316
- package/skills/void/docs/integrations/frameworks/analog.md +5 -64
- package/skills/void/docs/integrations/frameworks/astro.md +4 -73
- package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
- package/skills/void/docs/integrations/frameworks/overview.md +11 -54
- package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
- package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
- package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
- package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
- package/skills/void/docs/reference/api/auth.md +156 -0
- package/skills/void/docs/reference/api/client.md +87 -0
- package/skills/void/docs/reference/api/database.md +95 -0
- package/skills/void/docs/reference/api/durable.md +46 -0
- package/skills/void/docs/reference/api/env.md +50 -0
- package/skills/void/docs/reference/api/handlers.md +254 -0
- package/skills/void/docs/reference/api/pages.md +241 -0
- package/skills/void/docs/reference/api/plugin.md +39 -0
- package/skills/void/docs/reference/api/resources.md +109 -0
- package/skills/void/docs/reference/api/rewrites.md +76 -0
- package/skills/void/docs/reference/api/types.md +92 -0
- package/skills/void/docs/reference/api.md +56 -1218
- package/skills/void/docs/reference/cli/auth.md +88 -0
- package/skills/void/docs/reference/cli/database.md +128 -0
- package/skills/void/docs/reference/cli/deploy.md +85 -0
- package/skills/void/docs/reference/cli/domains.md +41 -0
- package/skills/void/docs/reference/cli/email.md +129 -0
- package/skills/void/docs/reference/cli/generate.md +116 -0
- package/skills/void/docs/reference/cli/github.md +189 -0
- package/skills/void/docs/reference/cli/platform-config.md +92 -0
- package/skills/void/docs/reference/cli/platform-email.md +81 -0
- package/skills/void/docs/reference/cli/platform-installation.md +127 -0
- package/skills/void/docs/reference/cli/platform-operations.md +90 -0
- package/skills/void/docs/reference/cli/platform-users.md +89 -0
- package/skills/void/docs/reference/cli/platform-zero-trust.md +45 -0
- package/skills/void/docs/reference/cli/platform.md +70 -0
- package/skills/void/docs/reference/cli/project.md +214 -0
- package/skills/void/docs/reference/cli/secrets.md +76 -0
- package/skills/void/docs/reference/cli/setup.md +70 -0
- package/skills/void/docs/reference/cli.md +33 -1621
- package/skills/void/docs/reference/config.md +26 -32
- package/skills/void/docs/reference/resource-inference.md +3 -58
- package/skills/void/docs/reference/structure.md +14 -41
- package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
- package/dist/cli/cf-compat.mjs +0 -968
- package/dist/client-4cDVv7BO.mjs +0 -2
- package/dist/gen-Vnv2f65C.mjs +0 -2
- package/dist/help-DQMfeKMz.mjs +0 -2
- package/dist/login-DFQk7rbW.mjs +0 -2
- package/dist/migrate-TsHGBnDA.mjs +0 -2
- package/dist/plan-BEZ8VJW0.mjs +0 -256
- package/dist/plan-DpuOr14e.mjs +0 -2
- package/dist/prepare-BZXkjdNe.mjs +0 -2
- package/dist/validate-EKmJWxmy.mjs +0 -2
- /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
|
@@ -10,6 +10,14 @@ Void provides a typed AI client for Workers AI and Cloudflare's [AI Gateway](htt
|
|
|
10
10
|
import { ai } from 'void/ai';
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
## Handling usage limits
|
|
14
|
+
|
|
15
|
+
Every AI operation is lazy and must be executed with `.match({ ok, limited })`. Both handlers are required, including for provider-native requests, model listing and document conversion. Return a useful fallback from `limited`, or use `limit.response({ message: 'AI is temporarily unavailable.' })` to send a structured HTTP 429. Limits expose `resource`, `reason`, and an optional `retryAt`. Other failures still reject.
|
|
16
|
+
|
|
17
|
+
Do not await the operation itself; await its `.match()` call. TypeScript checks your handlers and the resulting success/fallback union.
|
|
18
|
+
|
|
19
|
+
Streaming responses end with a `void:error` SSE event if generation is interrupted after the response starts. A recognized quota interruption calls your `limited` handler and emits `void:limit`, preserving the message from `limit.response()`. `fetchStream()` throws on either terminal event so your UI can exit its generating state. This also applies to streaming provider responses and `ai.run()` with `stream: true`.
|
|
20
|
+
|
|
13
21
|
## Basic Usage
|
|
14
22
|
|
|
15
23
|
Call `ai.run()` with a model name and inputs. Model names and input types are fully typed from `@cloudflare/workers-types`.
|
|
@@ -21,9 +29,11 @@ import { ai } from 'void/ai';
|
|
|
21
29
|
export const POST = defineHandler(async (c) => {
|
|
22
30
|
const { prompt } = await c.req.json();
|
|
23
31
|
|
|
24
|
-
const result = await ai
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
const result = await ai
|
|
33
|
+
.run('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
|
|
34
|
+
messages: [{ role: 'user', content: prompt }],
|
|
35
|
+
})
|
|
36
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
27
37
|
|
|
28
38
|
return c.json(result);
|
|
29
39
|
});
|
|
@@ -42,23 +52,27 @@ import { ai } from 'void/ai';
|
|
|
42
52
|
export const POST = defineHandler(async (c) => {
|
|
43
53
|
const { prompt } = await c.req.json();
|
|
44
54
|
|
|
45
|
-
return ai
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
return ai
|
|
56
|
+
.stream('@cf/meta/llama-3.3-70b-instruct-fp8-fast', {
|
|
57
|
+
messages: [{ role: 'user', content: prompt }],
|
|
58
|
+
})
|
|
59
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
48
60
|
});
|
|
49
61
|
```
|
|
50
62
|
|
|
51
|
-
`ai.stream()` calls `ai.run()` with `stream: true` and wraps the result in a `Response` with `content-type: text/event-stream` and `cache-control: no-cache` headers.
|
|
52
|
-
|
|
53
63
|
## Listing Models
|
|
54
64
|
|
|
55
65
|
Use `ai.models()` to list available models:
|
|
56
66
|
|
|
57
67
|
```ts
|
|
58
|
-
const models = await ai
|
|
68
|
+
const models = await ai
|
|
69
|
+
.models()
|
|
70
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
59
71
|
|
|
60
72
|
// Filter by task
|
|
61
|
-
const textModels = await ai
|
|
73
|
+
const textModels = await ai
|
|
74
|
+
.models({ task: 'Text Generation' })
|
|
75
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
62
76
|
```
|
|
63
77
|
|
|
64
78
|
## Markdown Conversion
|
|
@@ -66,7 +80,9 @@ const textModels = await ai.models({ task: 'Text Generation' });
|
|
|
66
80
|
Use `ai.toMarkdown()` to convert documents to markdown:
|
|
67
81
|
|
|
68
82
|
```ts
|
|
69
|
-
const result = await ai
|
|
83
|
+
const result = await ai
|
|
84
|
+
.toMarkdown([{ name: 'document.pdf', blob: pdfBytes }])
|
|
85
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
70
86
|
```
|
|
71
87
|
|
|
72
88
|
## Local Development
|
|
@@ -80,12 +96,11 @@ npm run dev
|
|
|
80
96
|
|
|
81
97
|
When the app imports `void/ai`, Void enables a remote Workers AI binding during
|
|
82
98
|
development and preview. Requests use your Cloudflare account and its allowance;
|
|
83
|
-
Workers AI has no local simulator.
|
|
84
|
-
|
|
99
|
+
Workers AI has no local simulator. Use your Cloudflare login or
|
|
100
|
+
`CLOUDFLARE_API_TOKEN` in an automated environment.
|
|
85
101
|
|
|
86
102
|
For a team platform, use `void connect <platform-url>` and link your project.
|
|
87
|
-
Development requests use that platform's
|
|
88
|
-
Credentials are injected into server bindings automatically.
|
|
103
|
+
Development requests use that platform's account and usage limits.
|
|
89
104
|
|
|
90
105
|
## Usage Limits
|
|
91
106
|
|
|
@@ -93,55 +108,54 @@ Workers AI usage is measured in [neurons](https://developers.cloudflare.com/work
|
|
|
93
108
|
On a direct deployment, usage belongs to your Cloudflare account. Provider-native
|
|
94
109
|
requests also use your provider credentials and their billing terms.
|
|
95
110
|
|
|
96
|
-
A team platform
|
|
97
|
-
Fresh self-hosted installations assign the `custom` profile, which has no
|
|
98
|
-
platform-imposed AI allowance. Administrators can select a quota profile through
|
|
99
|
-
[Platform Administration](./platform-administration.md). These profiles do not
|
|
100
|
-
subscribe users to a commercial plan or charge them automatically; the operator
|
|
101
|
-
remains responsible for its infrastructure and provider accounts.
|
|
111
|
+
A team platform uses its own Cloudflare account and may apply per-user limits. Ask your administrator about the available allowance.
|
|
102
112
|
|
|
103
113
|
## Cloudflare Gateway Models
|
|
104
114
|
|
|
105
115
|
`ai.run()` mirrors Cloudflare's `env.AI.run()` model naming and input schemas. Third-party models use Cloudflare model IDs and Cloudflare-managed credentials.
|
|
106
116
|
|
|
107
117
|
```ts
|
|
108
|
-
const result = await ai
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
118
|
+
const result = await ai
|
|
119
|
+
.run('google/gemini-2.5-flash', {
|
|
120
|
+
contents: [
|
|
121
|
+
{
|
|
122
|
+
role: 'user',
|
|
123
|
+
parts: [{ text: 'Explain Durable Objects in one paragraph.' }],
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
})
|
|
127
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
116
128
|
```
|
|
117
129
|
|
|
118
130
|
OpenAI-compatible models use OpenAI-style `messages`:
|
|
119
131
|
|
|
120
132
|
```ts
|
|
121
|
-
const result = await ai
|
|
122
|
-
|
|
123
|
-
}
|
|
133
|
+
const result = await ai
|
|
134
|
+
.run('openai/gpt-4.1-mini', {
|
|
135
|
+
messages: [{ role: 'user', content: 'Summarize this deploy.' }],
|
|
136
|
+
})
|
|
137
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
124
138
|
```
|
|
125
139
|
|
|
126
140
|
Pass Cloudflare AI Gateway options as the third argument:
|
|
127
141
|
|
|
128
142
|
```ts
|
|
129
|
-
const result = await ai
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
const result = await ai
|
|
144
|
+
.run(
|
|
145
|
+
'openai/gpt-4.1-mini',
|
|
146
|
+
{
|
|
147
|
+
messages: [{ role: 'user', content: 'Summarize this deploy.' }],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
gateway: {
|
|
151
|
+
skipCache: true,
|
|
152
|
+
},
|
|
137
153
|
},
|
|
138
|
-
|
|
139
|
-
);
|
|
154
|
+
)
|
|
155
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
140
156
|
```
|
|
141
157
|
|
|
142
|
-
|
|
143
|
-
requests use your Workers AI binding; provider-native requests require your own
|
|
144
|
-
`ai.gateway` configuration.
|
|
158
|
+
For provider-native requests on a direct deployment, configure [`ai.gateway`](../integrations/cloudflare.md#ai-self-host).
|
|
145
159
|
|
|
146
160
|
## Provider-Native Requests
|
|
147
161
|
|
|
@@ -159,13 +173,16 @@ import { ai } from 'void/ai';
|
|
|
159
173
|
export const POST = defineHandler(async (c) => {
|
|
160
174
|
const { prompt } = await c.req.json();
|
|
161
175
|
|
|
162
|
-
const response = await ai
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
176
|
+
const response = await ai
|
|
177
|
+
.provider('openai')
|
|
178
|
+
.fetch('/chat/completions', {
|
|
179
|
+
body: {
|
|
180
|
+
model: 'gpt-4o',
|
|
181
|
+
messages: [{ role: 'user', content: prompt }],
|
|
182
|
+
max_tokens: 512,
|
|
183
|
+
},
|
|
184
|
+
})
|
|
185
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
169
186
|
|
|
170
187
|
const result = await response.json();
|
|
171
188
|
return c.json(result);
|
|
@@ -186,7 +203,8 @@ const response = await ai
|
|
|
186
203
|
},
|
|
187
204
|
],
|
|
188
205
|
},
|
|
189
|
-
})
|
|
206
|
+
})
|
|
207
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
190
208
|
|
|
191
209
|
const result = await response.json();
|
|
192
210
|
```
|
|
@@ -204,7 +222,8 @@ const response = await ai
|
|
|
204
222
|
})
|
|
205
223
|
.fetch('/v1/respond', {
|
|
206
224
|
body: { prompt: 'Hello' },
|
|
207
|
-
})
|
|
225
|
+
})
|
|
226
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
208
227
|
```
|
|
209
228
|
|
|
210
229
|
### Image Generation
|
|
@@ -214,38 +233,45 @@ Use `ai.run()` or `ai.image()` for Cloudflare-native image models:
|
|
|
214
233
|
```ts
|
|
215
234
|
export const POST = defineHandler(async (c) => {
|
|
216
235
|
const { prompt } = await c.req.json();
|
|
217
|
-
return ai
|
|
236
|
+
return ai
|
|
237
|
+
.image('@cf/black-forest-labs/flux-1-schnell', { prompt })
|
|
238
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
218
239
|
});
|
|
219
240
|
```
|
|
220
241
|
|
|
221
|
-
Use `ai.provider().fetch()` for provider-native image APIs:
|
|
242
|
+
Use `ai.provider().fetch()` for provider-native image APIs. Match the [provider's request schema](https://developers.openai.com/api/reference/resources/images/methods/generate):
|
|
222
243
|
|
|
223
244
|
```ts
|
|
224
245
|
export const POST = defineHandler(async (c) => {
|
|
225
246
|
const { prompt } = await c.req.json();
|
|
226
247
|
|
|
227
|
-
return ai
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
248
|
+
return ai
|
|
249
|
+
.provider('openai')
|
|
250
|
+
.fetch('/images/generations', {
|
|
251
|
+
body: {
|
|
252
|
+
model: 'gpt-image-2.5-sunburst',
|
|
253
|
+
prompt,
|
|
254
|
+
size: '1024x1024',
|
|
255
|
+
},
|
|
256
|
+
})
|
|
257
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
235
258
|
});
|
|
236
259
|
```
|
|
237
260
|
|
|
238
|
-
For multipart provider APIs, pass
|
|
261
|
+
For multipart provider APIs, pass `FormData`:
|
|
239
262
|
|
|
240
263
|
```ts
|
|
241
264
|
export const POST = defineHandler(async (c) => {
|
|
242
265
|
const body = await c.req.parseBody();
|
|
243
266
|
const form = new FormData();
|
|
244
|
-
form.set('model', 'gpt-image-
|
|
267
|
+
form.set('model', 'gpt-image-2.5-sunburst');
|
|
245
268
|
form.set('prompt', String(body.prompt));
|
|
246
269
|
form.set('image', body.image as Blob, 'source.png');
|
|
247
270
|
|
|
248
|
-
return ai
|
|
271
|
+
return ai
|
|
272
|
+
.provider('openai')
|
|
273
|
+
.fetch('/images/edits', { body: form })
|
|
274
|
+
.match({ ok: (result) => result, limited: (limit) => limit.response() });
|
|
249
275
|
});
|
|
250
276
|
```
|
|
251
277
|
|
|
@@ -290,22 +316,6 @@ For local development, add it to `.env` in your project root:
|
|
|
290
316
|
OPENAI_API_KEY=sk-...
|
|
291
317
|
```
|
|
292
318
|
|
|
293
|
-
If the key is missing at runtime, `ai.provider().fetch()` throws a descriptive error telling you which env var to set.
|
|
294
|
-
|
|
295
319
|
### Streaming with Provider-Native APIs
|
|
296
320
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
```ts
|
|
300
|
-
export const POST = defineHandler(async (c) => {
|
|
301
|
-
const { prompt } = await c.req.json();
|
|
302
|
-
|
|
303
|
-
return ai.provider('openai').fetch('/chat/completions', {
|
|
304
|
-
body: {
|
|
305
|
-
model: 'gpt-4o',
|
|
306
|
-
messages: [{ role: 'user', content: prompt }],
|
|
307
|
-
stream: true,
|
|
308
|
-
},
|
|
309
|
-
});
|
|
310
|
-
});
|
|
311
|
-
```
|
|
321
|
+
Return the provider response directly. For example, add `stream: true` to the OpenAI request body shown above.
|
|
@@ -16,27 +16,16 @@ The type is auto-detected from your project structure, or you can set it explici
|
|
|
16
16
|
|
|
17
17
|
In a Void app, Void handles server routing and deployment. Use React, Vue, Svelte, or Solid for server-rendered pages, or build a frontend with any library that works with Vite.
|
|
18
18
|
|
|
19
|
-
All Void features that involve backend logic are available in this mode, including [server routing](./server-routing.md), [pages mode](./pages-routing/overview.md), [authentication](./auth.md), [typed fetch](./typed-fetch.md), [cron jobs](./jobs.md), and [queues](./queues.md).
|
|
20
|
-
|
|
21
19
|
A Void app can be **API-only** (just `routes/`), a **SPA + API** (frontend in `src/` with API routes), or **full-stack with pages mode** (server-rendered pages in `pages/` with co-located data loading):
|
|
22
20
|
|
|
23
21
|
<VoidAppFileTree annotations />
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
Void serves API routes, page rendering, and optional [custom SSR](./ssr.md) alongside static assets. Resources such as D1, KV, and R2 are [inferred from your code](../reference/resource-inference.md) and provisioned when you deploy.
|
|
26
24
|
|
|
27
25
|
Void apps can also use [`output: 'static'`](./ssg.md) to pre-render all pages at build time. That gives you a fully static site that can be deployed anywhere, with no Cloudflare Worker required.
|
|
28
26
|
|
|
29
27
|
**Deploy:** `void deploy` builds the app, provisions resources, applies migrations, and uploads it to your saved Cloudflare or Void target. See [Deployment](./deployment.md) for setup.
|
|
30
28
|
|
|
31
|
-
**Detected when any of these exist:**
|
|
32
|
-
|
|
33
|
-
- `routes/` directory
|
|
34
|
-
- `pages/` directory
|
|
35
|
-
- `middleware/` directory
|
|
36
|
-
- `crons/` directory
|
|
37
|
-
- `queues/` directory
|
|
38
|
-
- Custom SSR entry (`src/main.ssr.ts` or `src/main.ssr.tsx`)
|
|
39
|
-
|
|
40
29
|
## Meta Frameworks
|
|
41
30
|
|
|
42
31
|
Void supports deploying Vite-based meta-framework apps with `void deploy`. The framework owns routing and SSR. Void handles [binding inference](../reference/resource-inference.md), [typed DB queries](./database.md), migrations, and deployment.
|
|
@@ -50,15 +39,11 @@ Void supports deploying Vite-based meta-framework apps with `void deploy`. The f
|
|
|
50
39
|
| [Analog](https://analogjs.org/) | `@analogjs/platform` | [Guide](../integrations/frameworks/analog.md) |
|
|
51
40
|
| [Astro](https://astro.build/) | `astro` | [Guide](../integrations/frameworks/astro.md) |
|
|
52
41
|
|
|
53
|
-
Add `voidPlugin()` to the framework's Vite config to get binding inference, typed DB generation, migration management, cron jobs, queues, and caching. Void-managed auth is not supported in framework mode; use Better Auth's official integration for your framework. See the [Meta Frameworks Integration](../integrations/frameworks/overview.md) for
|
|
54
|
-
|
|
55
|
-
**Deploy:** `void deploy` runs your framework's build, provisions resources, applies migrations, and deploys to the selected target. Your framework continues to handle routing and rendering.
|
|
56
|
-
|
|
57
|
-
**Detected when** any of the above packages is in your dependencies.
|
|
42
|
+
Add `voidPlugin()` to the framework's Vite config to get binding inference, typed DB generation, migration management, cron jobs, queues, and caching. Void-managed auth is not supported in framework mode; use Better Auth's official integration for your framework. See the [Meta Frameworks Integration](../integrations/frameworks/overview.md) for supported features and setup guides.
|
|
58
43
|
|
|
59
44
|
## Pre-built Static Sites
|
|
60
45
|
|
|
61
|
-
Any project that produces static files, whether that is an SPA, a static site, or a plain directory.
|
|
46
|
+
Any project that produces static files, whether that is an SPA, a static site, or a plain directory. Void serves the assets without requiring application code.
|
|
62
47
|
|
|
63
48
|
**SPAs** (client-side single-page apps) fall back all non-file paths to `index.html` with a 200 status, so client-side routing works out of the box. Detected when `vite` is a dependency and no backend files exist.
|
|
64
49
|
|
|
@@ -116,20 +101,6 @@ To deploy only the static output, set:
|
|
|
116
101
|
{ "inference": { "appType": "static" } }
|
|
117
102
|
```
|
|
118
103
|
|
|
119
|
-
## Auto-Detection
|
|
120
|
-
|
|
121
|
-
When running `void deploy` and no `inference.appType` is set in `void.config.ts`, the detection logic runs in this order:
|
|
122
|
-
|
|
123
|
-
| Priority | Condition | Type |
|
|
124
|
-
| -------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
125
|
-
| 1 | `--dir` flag | Static (or SPA with `--spa`) |
|
|
126
|
-
| 2 | Known SSG in dependencies (`vitepress`, `@docusaurus/core`) | Static, builds with SSG CLI |
|
|
127
|
-
| 2a | ...and backend files also exist | Refused — set `inference.appType` yourself |
|
|
128
|
-
| 3 | `@tanstack/react-start`, `@react-router/dev`, `@sveltejs/kit`, `nuxt`, `@analogjs/platform`, or `astro` in deps | Framework |
|
|
129
|
-
| 4 | Backend files exist (`routes/`, `pages/`, `middleware/`, `crons/`, `queues/`, SSR entry) | Void app |
|
|
130
|
-
| 5 | `vite` or `vite-plus` in dependencies, no backend files | SPA, builds with `vite build` or `vp build` |
|
|
131
|
-
| 6 | `dist/index.html` or `./index.html` exists | Static (no build step) |
|
|
132
|
-
|
|
133
104
|
## Explicit Configuration
|
|
134
105
|
|
|
135
106
|
To lock the app type and skip auto-detection, set `inference.appType` in [`void.config.ts`](../reference/config.md):
|
|
@@ -5,7 +5,7 @@ outline: deep
|
|
|
5
5
|
# Authentication
|
|
6
6
|
|
|
7
7
|
::: warning ⚠️ Void Apps Only
|
|
8
|
-
Void-managed auth
|
|
8
|
+
Void-managed auth requires a native Void app on Cloudflare. For meta-frameworks or Node.js, Bun, and Deno, use Better Auth directly.
|
|
9
9
|
:::
|
|
10
10
|
|
|
11
11
|
Void configures [Better Auth](https://www.better-auth.com/) for your app, including its database connection, API routes, and client. Start with email and password, or add a social login provider.
|
|
@@ -14,17 +14,7 @@ Void configures [Better Auth](https://www.better-auth.com/) for your app, includ
|
|
|
14
14
|
|
|
15
15
|
### 1. Enable auth
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"auth": {
|
|
22
|
-
"providers": ["email"]
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
You can also skip this step entirely. Auth activates automatically when you import from `void/auth` or `void/client`.
|
|
17
|
+
Import `auth` from `void/client` to enable email/password auth automatically. Use [configuration](#config) to add social providers.
|
|
28
18
|
|
|
29
19
|
### 2. Sign up and sign in
|
|
30
20
|
|
|
@@ -36,14 +26,14 @@ import { auth } from 'void/client';
|
|
|
36
26
|
// sign up
|
|
37
27
|
await auth.signUp.email({
|
|
38
28
|
email: 'alice@example.com',
|
|
39
|
-
password: '
|
|
29
|
+
password: 'example-password-123',
|
|
40
30
|
name: 'Alice',
|
|
41
31
|
});
|
|
42
32
|
|
|
43
33
|
// sign in
|
|
44
34
|
await auth.signIn.email({
|
|
45
35
|
email: 'alice@example.com',
|
|
46
|
-
password: '
|
|
36
|
+
password: 'example-password-123',
|
|
47
37
|
});
|
|
48
38
|
```
|
|
49
39
|
|
|
@@ -83,8 +73,6 @@ export const loader = defineHandler(() => {
|
|
|
83
73
|
await auth.signOut();
|
|
84
74
|
```
|
|
85
75
|
|
|
86
|
-
The rest of this page covers configuration, server helpers, and advanced customization in detail.
|
|
87
|
-
|
|
88
76
|
## Config
|
|
89
77
|
|
|
90
78
|
Auth turns on automatically when you:
|
|
@@ -94,9 +82,7 @@ Auth turns on automatically when you:
|
|
|
94
82
|
- add `auth` to `void.config.ts`
|
|
95
83
|
- add a root-level `auth.ts` file
|
|
96
84
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Example:
|
|
85
|
+
Email/password is enabled by default. To add social providers:
|
|
100
86
|
|
|
101
87
|
```json
|
|
102
88
|
{
|
|
@@ -117,38 +103,9 @@ For example, `github` uses:
|
|
|
117
103
|
|
|
118
104
|
## Client Usage
|
|
119
105
|
|
|
120
|
-
`
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
import { auth } from 'void/client';
|
|
124
|
-
|
|
125
|
-
await auth.signUp.email({
|
|
126
|
-
email: 'alice@example.com',
|
|
127
|
-
password: 's3cret',
|
|
128
|
-
name: 'Alice',
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
await auth.signIn.email({
|
|
132
|
-
email: 'alice@example.com',
|
|
133
|
-
password: 's3cret',
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
await auth.signOut();
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
The client uses Better Auth's API, configured at `/api/auth`.
|
|
140
|
-
|
|
141
|
-
See the official [Better Auth client docs](https://www.better-auth.com/docs/concepts/client) for the full client API.
|
|
142
|
-
|
|
143
|
-
Framework-specific clients are selected automatically:
|
|
144
|
-
|
|
145
|
-
- React pages apps use `better-auth/react`
|
|
146
|
-
- Vue pages apps use `better-auth/vue`
|
|
147
|
-
- Svelte pages apps use `better-auth/svelte`
|
|
148
|
-
- Solid pages apps use `better-auth/solid`
|
|
149
|
-
- other Void apps use `better-auth/client`
|
|
106
|
+
The `auth` client uses [Better Auth's client API](https://www.better-auth.com/docs/concepts/client) at `/api/auth`. Void selects the client for your framework automatically.
|
|
150
107
|
|
|
151
|
-
For
|
|
108
|
+
For a custom client, import `createAuthClient` from `void/client`.
|
|
152
109
|
|
|
153
110
|
## Server Usage
|
|
154
111
|
|
|
@@ -162,67 +119,13 @@ import { getSession, getUser, requireAuth } from 'void/auth';
|
|
|
162
119
|
- `getSession()` returns `{ user, session } | null`
|
|
163
120
|
- `requireAuth(c)` returns the authenticated user or throws `401`
|
|
164
121
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
```ts
|
|
168
|
-
import { defineHandler } from 'void';
|
|
169
|
-
import { requireAuth } from 'void/auth';
|
|
170
|
-
|
|
171
|
-
export const GET = defineHandler((c) => {
|
|
172
|
-
const user = requireAuth(c);
|
|
173
|
-
return { email: user.email };
|
|
174
|
-
});
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### `AuthUser`
|
|
178
|
-
|
|
179
|
-
`AuthUser` maps to Better Auth's core user type:
|
|
180
|
-
|
|
181
|
-
```ts
|
|
182
|
-
interface AuthUser {
|
|
183
|
-
id: string;
|
|
184
|
-
email: string;
|
|
185
|
-
emailVerified: boolean;
|
|
186
|
-
name: string;
|
|
187
|
-
image?: string | null;
|
|
188
|
-
createdAt: Date;
|
|
189
|
-
updatedAt: Date;
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### `AuthSession`
|
|
194
|
-
|
|
195
|
-
`AuthSession` maps to Better Auth's core session type:
|
|
196
|
-
|
|
197
|
-
```ts
|
|
198
|
-
interface AuthSession {
|
|
199
|
-
id: string;
|
|
200
|
-
token: string;
|
|
201
|
-
userId: string;
|
|
202
|
-
expiresAt: Date;
|
|
203
|
-
createdAt: Date;
|
|
204
|
-
updatedAt: Date;
|
|
205
|
-
ipAddress?: string | null;
|
|
206
|
-
userAgent?: string | null;
|
|
207
|
-
}
|
|
208
|
-
```
|
|
122
|
+
Import `AuthUser` and `AuthSession` from `void/auth` for type annotations. See their fields in the [API reference](../reference/api/auth.md#authuser).
|
|
209
123
|
|
|
210
124
|
## Behavior
|
|
211
125
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
- mount path: `/api/auth/*`
|
|
215
|
-
- email/password enabled by default unless `auth.providers` is set without `"email"`
|
|
216
|
-
- `auth.providers` can enable any built-in Better Auth social provider
|
|
217
|
-
- deployed apps need an auth secret via `BETTER_AUTH_SECRET`
|
|
218
|
-
- D1/SQLite uses the app `DB` binding
|
|
219
|
-
- PostgreSQL apps (`"database": "pg"`) use the app `HYPERDRIVE` binding
|
|
220
|
-
|
|
221
|
-
Auth sessions live in the same database system as the rest of the app.
|
|
222
|
-
|
|
223
|
-
On both deployment targets, Void keeps an existing `BETTER_AUTH_SECRET` or generates one when it's missing. The value is stored as an encrypted Worker secret and reused by later versions.
|
|
126
|
+
Auth sessions use the same database as your app. Void creates `BETTER_AUTH_SECRET` on deploy if it is missing and reuses it on later deploys.
|
|
224
127
|
|
|
225
|
-
|
|
128
|
+
Local development needs no secret setup. To preview a production build locally, provide `BETTER_AUTH_SECRET`.
|
|
226
129
|
|
|
227
130
|
## Customization
|
|
228
131
|
|
|
@@ -245,19 +148,12 @@ For the full set of available options, see the official [Better Auth options ref
|
|
|
245
148
|
|
|
246
149
|
Auth tables live alongside your app's tables. During local development, Void creates them automatically.
|
|
247
150
|
|
|
248
|
-
|
|
151
|
+
Void platforms create auth tables automatically. For a direct Cloudflare deploy, include them in your checked-in migrations:
|
|
249
152
|
|
|
250
153
|
```sh
|
|
251
154
|
void db generate
|
|
252
155
|
```
|
|
253
156
|
|
|
254
|
-
|
|
157
|
+
Review and commit the SQL before deploying. Void includes your auth configuration and plugin tables; you don't need to duplicate them in `db/schema.ts` or run the Better Auth CLI.
|
|
255
158
|
|
|
256
159
|
MySQL stores OAuth access, refresh, and ID tokens as unbounded text. Existing direct-deploy MySQL apps should run `void db generate` once after upgrading to widen earlier `varchar(255)` token columns. Void platform deployments apply the same safe widening automatically.
|
|
257
|
-
|
|
258
|
-
## Unsupported Modes
|
|
259
|
-
|
|
260
|
-
Void-managed Better Auth is supported only for Cloudflare Void apps in v1.
|
|
261
|
-
|
|
262
|
-
- meta-framework mode should use Better Auth's official framework integrations directly
|
|
263
|
-
- `target: "node" | "bun" | "deno"` should use Better Auth directly
|
|
@@ -4,26 +4,11 @@ outline: deep
|
|
|
4
4
|
|
|
5
5
|
# D1 (SQLite)
|
|
6
6
|
|
|
7
|
-
[Cloudflare D1](https://developers.cloudflare.com/d1/) is
|
|
8
|
-
|
|
9
|
-
## When to Use D1
|
|
10
|
-
|
|
11
|
-
D1 is the default database for Void apps and a great choice when you want zero-config database access:
|
|
12
|
-
|
|
13
|
-
- **Prototyping:** start building immediately with no external database to provision
|
|
14
|
-
- **Read-heavy apps:** optimized for read workloads at the edge
|
|
15
|
-
- **Small to medium scale:** a good fit for apps that do not need advanced SQL features such as stored procedures or complex joins
|
|
16
|
-
- **Simplicity:** Void creates, migrates, and manages the D1 instance for you
|
|
17
|
-
|
|
18
|
-
For write-heavy workloads, complex queries, or connecting to existing infrastructure, see [PostgreSQL](./postgresql).
|
|
19
|
-
|
|
20
|
-
## Configuration
|
|
21
|
-
|
|
22
|
-
None. D1 is the default dialect, so you can start by defining your schema and querying.
|
|
7
|
+
[Cloudflare D1](https://developers.cloudflare.com/d1/) is Void's default SQLite database. Start with a [schema](../database.md#schema-definition); Void manages the database locally and when you deploy.
|
|
23
8
|
|
|
24
9
|
## Read replication
|
|
25
10
|
|
|
26
|
-
Void enables [D1 read replication](https://developers.cloudflare.com/d1/best-practices/read-replication/) when it provisions a database.
|
|
11
|
+
Void enables [D1 read replication](https://developers.cloudflare.com/d1/best-practices/read-replication/) when it provisions a database. To enable it on an existing database, run `void deploy --platform cloudflare --provision`. Queries through `db` from `void/db` use a D1 session for each Void request, so reads can run near the request and later queries in that request see at least the same data. Framework handlers without Void's request scope start each database operation on the primary. `createDb` starts a replica-capable session for the binding you pass it.
|
|
27
12
|
|
|
28
13
|
Replicas can lag between requests. Authentication session checks start on the primary so a revoked session is not accepted because of replica lag. If another read must start with the latest primary data, use `env.DB.withSession('first-primary')` from `cloudflare:workers`. Other query libraries and raw D1 calls need their own `withSession()` to use replicas; a bare D1 binding reads from the primary.
|
|
29
14
|
|
|
@@ -35,45 +20,15 @@ To store local data outside `.void`, set `voidPlugin({ persistTo: 'local-state'
|
|
|
35
20
|
|
|
36
21
|
## Migrations & Prototyping
|
|
37
22
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
### Prototyping with `push`
|
|
41
|
-
|
|
42
|
-
During development, use `void db push` to apply your schema directly to the local D1 database. It does not create migration files.
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
void db push
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
This diffs your Drizzle schema against the local database and applies the changes immediately. It's fast and ideal for iterating on your schema before committing to a migration.
|
|
49
|
-
|
|
50
|
-
### Production migrations
|
|
51
|
-
|
|
52
|
-
When you're ready to ship, generate SQL migration files from your schema:
|
|
23
|
+
Use `void db push` to apply schema changes locally without creating migration files. Before deploying, generate and commit migrations:
|
|
53
24
|
|
|
54
|
-
```
|
|
25
|
+
```sh
|
|
55
26
|
void db generate
|
|
27
|
+
void db migrate # apply locally
|
|
28
|
+
void deploy # apply remotely and deploy
|
|
56
29
|
```
|
|
57
30
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
To apply pending migrations locally:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
void db migrate
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Deploy Workflow
|
|
67
|
-
|
|
68
|
-
When you run `void deploy`:
|
|
69
|
-
|
|
70
|
-
1. The app is built
|
|
71
|
-
2. Migration files are collected from `db/migrations/`
|
|
72
|
-
3. If the schema has drifted ahead of the migrations, you're prompted to generate and commit the new migrations
|
|
73
|
-
4. Pending migrations run against the remote D1 database
|
|
74
|
-
5. The new worker goes live
|
|
75
|
-
|
|
76
|
-
Deploys always go through migration files. `push` is only for local development.
|
|
31
|
+
See [Database commands](../../reference/cli/database.md#database) for the full workflow.
|
|
77
32
|
|
|
78
33
|
## Batch Operations
|
|
79
34
|
|
|
@@ -91,7 +46,7 @@ await db.batch([
|
|
|
91
46
|
|
|
92
47
|
## Alternative Query Layers
|
|
93
48
|
|
|
94
|
-
|
|
49
|
+
Use `env.DB` from `cloudflare:workers` with another query library or the raw D1 API:
|
|
95
50
|
|
|
96
51
|
### Kysely
|
|
97
52
|
|
|
@@ -114,5 +69,5 @@ const { results } = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bin
|
|
|
114
69
|
Void still handles binding inference and deployment regardless of which query layer you use.
|
|
115
70
|
|
|
116
71
|
::: warning ⚠️ Meta framework limitation
|
|
117
|
-
|
|
72
|
+
Nuxt and SvelteKit do not support `cloudflare:workers` imports during local development. Use `void/db` or your framework's binding access API.
|
|
118
73
|
:::
|