void 0.1.6 → 0.7.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/AGENT_PROMPT.md +15 -0
- package/README.md +62 -123
- package/dist/auth-BdsJ0Aff.d.mts +43 -0
- package/dist/auth-cmd-Dx8oPKZC.mjs +43 -0
- package/dist/auth-migrations-BAtAck2g.mjs +117 -0
- package/dist/better-auth-shared-C9_GHSkR.d.mts +71 -0
- package/dist/better-auth-shared-CdYmQGry.mjs +163 -0
- package/dist/cache-W82I8ihI.mjs +47 -0
- package/dist/cancel-deploy-BOBTqqh0.mjs +59 -0
- package/dist/cf-access-Dee5cXxL.mjs +22 -0
- package/dist/chunk-DJd-R1mw.mjs +34 -0
- package/dist/cli/cli.d.mts +1 -0
- package/dist/cli/cli.mjs +1807 -0
- package/dist/client-snXOjrp1.mjs +565 -0
- package/dist/collect-CjeZgz5D.mjs +55 -0
- package/dist/config-BIa9HwVX.mjs +573 -0
- package/dist/config-BzM9Dy7T.mjs +37 -0
- package/dist/config-CvHtTM0q.mjs +30 -0
- package/dist/create-project-BIA15W7z.mjs +90 -0
- package/dist/db-DsRoMcfN.mjs +895 -0
- package/dist/defer-DcxEsVH1.mjs +49 -0
- package/dist/delete-DAP6yDc7.mjs +64 -0
- package/dist/deploy-BPKblFx6.mjs +2424 -0
- package/dist/discover-B7FkXBLB.mjs +40 -0
- package/dist/dist-DUyXJLkq.mjs +2667 -0
- package/dist/dist-Dayj3gCK.mjs +1287 -0
- package/dist/domain-BGofcQ6I.mjs +79 -0
- package/dist/dotenv-DwO4ti0Z.mjs +173 -0
- package/dist/drizzle-NnudE_UN.mjs +232 -0
- package/dist/env-CyG3tvU0.mjs +301 -0
- package/dist/env-helpers-Dr9Y7RnE.d.mts +52 -0
- package/dist/env-raw-BDL4TvdN.mjs +32 -0
- package/dist/env-types-DknSA4SO.mjs +64 -0
- package/dist/env-validation-DJKjR_8q.mjs +163 -0
- package/dist/fetch-error-BQ8sZ5Nd.mjs +266 -0
- package/dist/fetch-error-CVZ5CGA-.d.mts +20 -0
- package/dist/gen-U0Ktr4Zd.mjs +761 -0
- package/dist/handler-B0ds0OHJ.d.mts +269 -0
- package/dist/head-P-egrtFE.d.mts +45 -0
- package/dist/headers-DCXc7mDs.mjs +279 -0
- package/dist/index.d.mts +32 -0
- package/dist/index.mjs +4695 -0
- package/dist/init-C7wS5iGP.mjs +2625 -0
- package/dist/link-p2R6NbgN.mjs +49 -0
- package/dist/list-Bfel-QLc.mjs +113 -0
- package/dist/log-DXdqnmhF.mjs +26 -0
- package/dist/login-CkcXUiIu.mjs +72 -0
- package/dist/logs-DmkrRvx6.mjs +98 -0
- package/dist/magic-string.es-D6g9UnIy.mjs +1011 -0
- package/dist/mcp-CaQzfeUi.mjs +373 -0
- package/dist/node-DDfXj10V.mjs +54 -0
- package/dist/output-BwlcIYSR.mjs +139 -0
- package/dist/pages/client.d.mts +198 -0
- package/dist/pages/client.mjs +980 -0
- package/dist/pages/head-client.d.mts +15 -0
- package/dist/pages/head-client.mjs +90 -0
- package/dist/pages/head.d.mts +2 -0
- package/dist/pages/head.mjs +112 -0
- package/dist/pages/index.d.mts +38 -0
- package/dist/pages/index.mjs +76 -0
- package/dist/pages/islands-plugin.d.mts +50 -0
- package/dist/pages/islands-plugin.mjs +195 -0
- package/dist/pages/prefetch.d.mts +31 -0
- package/dist/pages/prefetch.mjs +90 -0
- package/dist/pages/protocol.d.mts +3 -0
- package/dist/pages/protocol.mjs +193 -0
- package/dist/pages/serialize.d.mts +10 -0
- package/dist/pages/serialize.mjs +14 -0
- package/dist/pathe.M-eThtNZ-D-kmWkCS.mjs +150 -0
- package/dist/plugin-inference-oZ6Ybu2_.mjs +2447 -0
- package/dist/prepare-BAtWufvm.mjs +99 -0
- package/dist/preset-D4I73kT4.mjs +221 -0
- package/dist/project-TqORyHn8.mjs +72 -0
- package/dist/project-cmd-B7lQp3F3.mjs +67 -0
- package/dist/project-slug-CKam8lF9.mjs +11 -0
- package/dist/project-tsconfig-DfkESbDL.mjs +63 -0
- package/dist/protocol-BWzXs2A2.d.mts +34 -0
- package/dist/providers-B3aMxWzP.mjs +67 -0
- package/dist/resolve-project-Br5BR03U.mjs +29 -0
- package/dist/rollback-gyC59l7U.mjs +92 -0
- package/dist/route-types-DReF1gUY.mjs +255 -0
- package/dist/routes-stub.d.mts +55 -0
- package/dist/routes-stub.mjs +1 -0
- package/dist/runner-6Ep3fNQu.mjs +123 -0
- package/dist/runner-pg-D0wWHYnr.mjs +57 -0
- package/dist/runtime/ai.d.mts +127 -0
- package/dist/runtime/ai.mjs +348 -0
- package/dist/runtime/auth-client-react.d.mts +8 -0
- package/dist/runtime/auth-client-react.mjs +6 -0
- package/dist/runtime/auth-client-solid.d.mts +8 -0
- package/dist/runtime/auth-client-solid.mjs +6 -0
- package/dist/runtime/auth-client-svelte.d.mts +8 -0
- package/dist/runtime/auth-client-svelte.mjs +6 -0
- package/dist/runtime/auth-client-vue.d.mts +8 -0
- package/dist/runtime/auth-client-vue.mjs +6 -0
- package/dist/runtime/auth-client.d.mts +8 -0
- package/dist/runtime/auth-client.mjs +6 -0
- package/dist/runtime/auth.d.mts +2 -0
- package/dist/runtime/auth.mjs +22 -0
- package/dist/runtime/better-auth-pg.d.mts +11 -0
- package/dist/runtime/better-auth-pg.mjs +51 -0
- package/dist/runtime/better-auth.d.mts +11 -0
- package/dist/runtime/better-auth.mjs +33 -0
- package/dist/runtime/client.d.mts +6 -0
- package/dist/runtime/client.mjs +5 -0
- package/dist/runtime/db-pg.d.mts +2 -0
- package/dist/runtime/db-pg.mjs +1 -0
- package/dist/runtime/db.d.mts +17 -0
- package/dist/runtime/db.mjs +30 -0
- package/dist/runtime/drizzle-arktype.d.mts +1 -0
- package/dist/runtime/drizzle-arktype.mjs +2 -0
- package/dist/runtime/drizzle-valibot.d.mts +1 -0
- package/dist/runtime/drizzle-valibot.mjs +2 -0
- package/dist/runtime/drizzle-zod.d.mts +1 -0
- package/dist/runtime/drizzle-zod.mjs +2 -0
- package/dist/runtime/env-helpers.d.mts +2 -0
- package/dist/runtime/env-helpers.mjs +173 -0
- package/dist/runtime/env-public-client.d.mts +22 -0
- package/dist/runtime/env-public-client.mjs +54 -0
- package/dist/runtime/env-public.d.mts +143 -0
- package/dist/runtime/env-public.mjs +366 -0
- package/dist/runtime/env.d.mts +13 -0
- package/dist/runtime/env.mjs +51 -0
- package/dist/runtime/fetch-stream.d.mts +51 -0
- package/dist/runtime/fetch-stream.mjs +81 -0
- package/dist/runtime/fetch.d.mts +59 -0
- package/dist/runtime/fetch.mjs +18 -0
- package/dist/runtime/handler.d.mts +3 -0
- package/dist/runtime/handler.mjs +85 -0
- package/dist/runtime/isr.d.mts +26 -0
- package/dist/runtime/isr.mjs +43 -0
- package/dist/runtime/kv.d.mts +48 -0
- package/dist/runtime/kv.mjs +106 -0
- package/dist/runtime/log.d.mts +24 -0
- package/dist/runtime/log.mjs +31 -0
- package/dist/runtime/migration-handler-pg.d.mts +6 -0
- package/dist/runtime/migration-handler-pg.mjs +85 -0
- package/dist/runtime/migration-handler.d.mts +19 -0
- package/dist/runtime/migration-handler.mjs +92 -0
- package/dist/runtime/queues.d.mts +7 -0
- package/dist/runtime/queues.mjs +8 -0
- package/dist/runtime/remote/binding-handler.d.mts +15 -0
- package/dist/runtime/remote/binding-handler.mjs +208 -0
- package/dist/runtime/remote/index.d.mts +8 -0
- package/dist/runtime/remote/index.mjs +461 -0
- package/dist/runtime/response.d.mts +14 -0
- package/dist/runtime/response.mjs +30 -0
- package/dist/runtime/sandbox.d.mts +17 -0
- package/dist/runtime/sandbox.mjs +19 -0
- package/dist/runtime/schema-d1.d.mts +1 -0
- package/dist/runtime/schema-d1.mjs +2 -0
- package/dist/runtime/schema-pg.d.mts +1 -0
- package/dist/runtime/schema-pg.mjs +2 -0
- package/dist/runtime/seed.d.mts +30 -0
- package/dist/runtime/seed.mjs +6 -0
- package/dist/runtime/storage.d.mts +7 -0
- package/dist/runtime/storage.mjs +14 -0
- package/dist/runtime/validator.d.mts +2 -0
- package/dist/runtime/validator.mjs +72 -0
- package/dist/runtime/ws-server.d.mts +26 -0
- package/dist/runtime/ws-server.mjs +296 -0
- package/dist/runtime/ws.d.mts +123 -0
- package/dist/runtime/ws.mjs +103 -0
- package/dist/scan-Ba4hFwlH.mjs +324 -0
- package/dist/scan-C6HMEIdW.mjs +318 -0
- package/dist/secret-CeRSukgM.mjs +109 -0
- package/dist/skills-ipldjlKE.mjs +62 -0
- package/dist/standard-schema-9CRjx-uR.d.mts +42 -0
- package/dist/subcommand-prompt-BKjuNAPb.mjs +349 -0
- package/dist/sveltekit.d.mts +20 -0
- package/dist/sveltekit.mjs +61 -0
- package/dist/types-mHOEwpW4.d.mts +57 -0
- package/dist/validate-CaMavMxu.mjs +146 -0
- package/dist/yarn-pnp-BFqMV_bl.mjs +196 -0
- package/getting-started-prompt.txt +26 -0
- package/package.json +322 -30
- package/schema.json +364 -0
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +175 -0
- package/skills/void/SKILL.md +75 -0
- package/skills/void/command/void.md +7 -0
- package/skills/void/docs/guide/ai.md +235 -0
- package/skills/void/docs/guide/app-types.md +103 -0
- package/skills/void/docs/guide/auth.md +257 -0
- package/skills/void/docs/guide/database/d1.md +106 -0
- package/skills/void/docs/guide/database/postgresql.md +106 -0
- package/skills/void/docs/guide/database.md +418 -0
- package/skills/void/docs/guide/deployment.md +98 -0
- package/skills/void/docs/guide/edge/headers.md +79 -0
- package/skills/void/docs/guide/edge/prerendering.md +83 -0
- package/skills/void/docs/guide/edge/redirects.md +116 -0
- package/skills/void/docs/guide/edge/revalidation.md +131 -0
- package/skills/void/docs/guide/edge/rewrites.md +354 -0
- package/skills/void/docs/guide/edge/static-assets.md +72 -0
- package/skills/void/docs/guide/env-vars.md +298 -0
- package/skills/void/docs/guide/index.md +80 -0
- package/skills/void/docs/guide/jobs.md +91 -0
- package/skills/void/docs/guide/kv.md +107 -0
- package/skills/void/docs/guide/pages-routing/actions-and-forms.md +419 -0
- package/skills/void/docs/guide/pages-routing/head.md +130 -0
- package/skills/void/docs/guide/pages-routing/islands.md +405 -0
- package/skills/void/docs/guide/pages-routing/layouts.md +362 -0
- package/skills/void/docs/guide/pages-routing/loaders.md +267 -0
- package/skills/void/docs/guide/pages-routing/markdown.md +625 -0
- package/skills/void/docs/guide/pages-routing/overview.md +236 -0
- package/skills/void/docs/guide/pages-routing/view-transitions.md +140 -0
- package/skills/void/docs/guide/queues.md +140 -0
- package/skills/void/docs/guide/quickstart.md +233 -0
- package/skills/void/docs/guide/remote-dev.md +67 -0
- package/skills/void/docs/guide/sandboxes.md +82 -0
- package/skills/void/docs/guide/server-routing.md +246 -0
- package/skills/void/docs/guide/ssg.md +74 -0
- package/skills/void/docs/guide/ssr.md +105 -0
- package/skills/void/docs/guide/storage.md +67 -0
- package/skills/void/docs/guide/type-safety.md +179 -0
- package/skills/void/docs/guide/typed-fetch.md +113 -0
- package/skills/void/docs/guide/websockets.md +190 -0
- package/skills/void/docs/index.md +48 -0
- package/skills/void/docs/integrations/agents.md +84 -0
- package/skills/void/docs/integrations/cloudflare.md +284 -0
- package/skills/void/docs/integrations/frameworks/analog.md +182 -0
- package/skills/void/docs/integrations/frameworks/astro.md +197 -0
- package/skills/void/docs/integrations/frameworks/nuxt.md +164 -0
- package/skills/void/docs/integrations/frameworks/overview.md +136 -0
- package/skills/void/docs/integrations/frameworks/react-router.md +137 -0
- package/skills/void/docs/integrations/frameworks/sveltekit.md +191 -0
- package/skills/void/docs/integrations/frameworks/tanstack-start.md +140 -0
- package/skills/void/docs/integrations/hono.md +97 -0
- package/skills/void/docs/integrations/nodejs-bun-deno.md +210 -0
- package/skills/void/docs/node_modules/@iconify/vue/README.md +408 -0
- package/skills/void/docs/node_modules/@iconify/vue/offline/readme.md +5 -0
- package/skills/void/docs/node_modules/@voidzero-dev/vitepress-theme/README.md +103 -0
- package/skills/void/docs/node_modules/oxc-minify/README.md +78 -0
- package/skills/void/docs/node_modules/reka-ui/README.md +80 -0
- package/skills/void/docs/node_modules/vitepress/README.md +28 -0
- package/skills/void/docs/node_modules/vitepress/template/api-examples.md +49 -0
- package/skills/void/docs/node_modules/vitepress/template/index.md +28 -0
- package/skills/void/docs/node_modules/vitepress/template/markdown-examples.md +85 -0
- package/skills/void/docs/node_modules/vitepress-plugin-group-icons/README.md +101 -0
- package/skills/void/docs/node_modules/void/AGENTS.md +204 -0
- package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +15 -0
- package/skills/void/docs/node_modules/void/README.md +89 -0
- package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/CHANGELOG.md +591 -0
- package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/README.md +375 -0
- package/skills/void/docs/node_modules/void/node_modules/@cloudflare/sandbox/README.md +174 -0
- package/skills/void/docs/node_modules/void/node_modules/@cloudflare/vite-plugin/README.md +37 -0
- package/skills/void/docs/node_modules/void/node_modules/@cloudflare/workers-types/README.md +135 -0
- package/skills/void/docs/node_modules/void/node_modules/@electric-sql/pglite/README.md +189 -0
- package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/CHANGELOG.md +143 -0
- package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/README.md +1272 -0
- package/skills/void/docs/node_modules/void/node_modules/@napi-rs/keyring/README.md +19 -0
- package/skills/void/docs/node_modules/void/node_modules/@types/better-sqlite3/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@types/node/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@types/pg/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/README.md +22 -0
- package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/vendor/vscode-jsonrpc/README.md +69 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +152 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/engine-javascript/README.md +9 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/transformers/README.md +9 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@types/node/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/CHANGELOG.md +24 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/README.md +565 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-exit/README.md +124 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-anchor/README.md +600 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-attrs/README.md +386 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-container/README.md +95 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-emoji/README.md +101 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathe/README.md +73 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/shiki/README.md +15 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tinyglobby/README.md +25 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tsdown/README.md +55 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite/LICENSE.md +2230 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite/README.md +20 -0
- package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vue/README.md +58 -0
- package/skills/void/docs/node_modules/void/node_modules/arktype/README.md +165 -0
- package/skills/void/docs/node_modules/void/node_modules/better-auth/LICENSE.md +20 -0
- package/skills/void/docs/node_modules/void/node_modules/better-auth/README.md +32 -0
- package/skills/void/docs/node_modules/void/node_modules/better-sqlite3/README.md +99 -0
- package/skills/void/docs/node_modules/void/node_modules/blake3-jit/README.md +108 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-arktype/README.md +51 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-kit/README.md +79 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-orm/README.md +44 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-valibot/README.md +51 -0
- package/skills/void/docs/node_modules/void/node_modules/drizzle-zod/README.md +65 -0
- package/skills/void/docs/node_modules/void/node_modules/es-module-lexer/README.md +390 -0
- package/skills/void/docs/node_modules/void/node_modules/estree-walker/README.md +48 -0
- package/skills/void/docs/node_modules/void/node_modules/hono/README.md +85 -0
- package/skills/void/docs/node_modules/void/node_modules/ignore/README.md +452 -0
- package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/CHANGELOG.md +76 -0
- package/{LICENSE → skills/void/docs/node_modules/void/node_modules/jsonc-parser/LICENSE.md} +21 -21
- package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/README.md +364 -0
- package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/SECURITY.md +41 -0
- package/skills/void/docs/node_modules/void/node_modules/magic-string/README.md +325 -0
- package/skills/void/docs/node_modules/void/node_modules/ofetch/README.md +398 -0
- package/skills/void/docs/node_modules/void/node_modules/pathe/README.md +73 -0
- package/skills/void/docs/node_modules/void/node_modules/pg/README.md +95 -0
- package/skills/void/docs/node_modules/void/node_modules/pglite-server/LICENSE.md +21 -0
- package/skills/void/docs/node_modules/void/node_modules/pglite-server/README.md +135 -0
- package/skills/void/docs/node_modules/void/node_modules/picocolors/README.md +21 -0
- package/skills/void/docs/node_modules/void/node_modules/tinyglobby/README.md +25 -0
- package/skills/void/docs/node_modules/void/node_modules/tsdown/README.md +55 -0
- package/skills/void/docs/node_modules/void/node_modules/valibot/LICENSE.md +9 -0
- package/skills/void/docs/node_modules/void/node_modules/valibot/README.md +94 -0
- package/skills/void/docs/node_modules/void/node_modules/vite/LICENSE.md +2230 -0
- package/skills/void/docs/node_modules/void/node_modules/vite/README.md +20 -0
- package/skills/void/docs/node_modules/void/node_modules/wrangler/README.md +63 -0
- package/skills/void/docs/node_modules/void/node_modules/zod/README.md +191 -0
- package/skills/void/docs/node_modules/void/skills/migrate-vite-cloudflare-to-void/SKILL.md +175 -0
- package/skills/void/docs/node_modules/void/skills/void/SKILL.md +75 -0
- package/skills/void/docs/node_modules/void/skills/void/command/void.md +7 -0
- package/skills/void/docs/reference/api.md +917 -0
- package/skills/void/docs/reference/cli.md +561 -0
- package/skills/void/docs/reference/config.md +408 -0
- package/skills/void/docs/reference/resource-inference.md +149 -0
- package/skills/void/docs/reference/structure.md +176 -0
- package/.npmignore +0 -29
- package/.travis.yml +0 -9
- package/favicon.ico +0 -0
- package/index.js +0 -14
- package/lib/Job.js +0 -150
- package/lib/Void.js +0 -99
- package/lib/scan.js +0 -19
- package/test/credentials.js +0 -20
- package/test/job.js +0 -64
- package/test/static/dir1/test6.html +0 -0
- package/test/static/dir2/test7.html +0 -0
- package/test/static/dir2/test8.html +0 -0
- package/test/static/dir2/test9.html +0 -0
- package/test/static/test1.html +0 -0
- package/test/static/test2.html +0 -0
- package/test/static/test3.html +0 -0
- package/test/void.js +0 -31
- /package/{test/static/dir1/test4.html → skills/void/docs/integrations/auth-providers.md} +0 -0
- /package/{test/static/dir1/test5.html → skills/void/docs/integrations/payment-processors.md} +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# AI
|
|
6
|
+
|
|
7
|
+
Void provides a typed AI client powered by Cloudflare's [AI Gateway](https://developers.cloudflare.com/ai-gateway/). It supports both [Workers AI](https://developers.cloudflare.com/workers-ai/) models and third-party providers such as OpenAI, Anthropic, and Google through bring-your-own-key credentials. Import `ai` from `void/ai` and run inference directly from your route handlers. Usage is metered through Void.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ai } from 'void/ai';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
Call `ai.run()` with a model name and inputs. Model names and input types are fully typed from `@cloudflare/workers-types`.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { defineHandler } from 'void';
|
|
19
|
+
import { ai } from 'void/ai';
|
|
20
|
+
|
|
21
|
+
export const POST = defineHandler(async (c) => {
|
|
22
|
+
const { prompt } = await c.req.json();
|
|
23
|
+
|
|
24
|
+
const result = await ai.run('@cf/meta/llama-3.1-8b-instruct', {
|
|
25
|
+
messages: [{ role: 'user', content: prompt }],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return c.json(result);
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
You can use any model available on [Workers AI](https://developers.cloudflare.com/workers-ai/models/), including text generation, image classification, image-to-text, text-to-image, embeddings, translation, and more. Models that return binary data, such as generated images, are returned as a `Blob` from `ai.run()`.
|
|
33
|
+
|
|
34
|
+
## Streaming
|
|
35
|
+
|
|
36
|
+
Use `ai.stream()` to get a streaming response with SSE headers that you can return directly from a route handler:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { defineHandler } from 'void';
|
|
40
|
+
import { ai } from 'void/ai';
|
|
41
|
+
|
|
42
|
+
export const POST = defineHandler(async (c) => {
|
|
43
|
+
const { prompt } = await c.req.json();
|
|
44
|
+
|
|
45
|
+
return ai.stream('@cf/meta/llama-3.1-8b-instruct', {
|
|
46
|
+
messages: [{ role: 'user', content: prompt }],
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
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
|
+
## Listing Models
|
|
54
|
+
|
|
55
|
+
Use `ai.models()` to list available models:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const models = await ai.models();
|
|
59
|
+
|
|
60
|
+
// Filter by task
|
|
61
|
+
const textModels = await ai.models({ task: 'Text Generation' });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Markdown Conversion
|
|
65
|
+
|
|
66
|
+
Use `ai.toMarkdown()` to convert documents to markdown:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const result = await ai.toMarkdown([{ name: 'document.pdf', blob: pdfBytes }]);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Local Development
|
|
73
|
+
|
|
74
|
+
AI requires Void credentials for local development. Run `void auth login` and `void project link` (or follow the interactive setup during `vite dev`) to connect your project.
|
|
75
|
+
|
|
76
|
+
Once linked, credentials are injected automatically as worker bindings. You do not need to configure them by hand. All inference traffic goes through the Void AI proxy over HTTPS, so usage is tracked and metered the same way it is in production.
|
|
77
|
+
|
|
78
|
+
## Usage Limits
|
|
79
|
+
|
|
80
|
+
Workers AI usage is metered in [**neurons**](https://developers.cloudflare.com/workers-ai/platform/pricing/), which is Cloudflare's unit for inference cost. Usage resets at the start of each billing cycle.
|
|
81
|
+
|
|
82
|
+
| Plan | Included | At limit |
|
|
83
|
+
| ---- | ------------- | ---------------------------------- |
|
|
84
|
+
| Free | 100,000/month | Blocked until billing cycle resets |
|
|
85
|
+
| Solo | 300,000/month | Overage billed |
|
|
86
|
+
| Pro | 500,000/month | Overage billed |
|
|
87
|
+
|
|
88
|
+
On the **free tier**, AI requests return a `429` error once the limit is reached. On **paid tiers**, usage beyond the included allowance is tracked as overage on your monthly bill.
|
|
89
|
+
|
|
90
|
+
## Third-Party Providers (BYOK)
|
|
91
|
+
|
|
92
|
+
You can use models from OpenAI, Anthropic, Google, and other providers by passing a `provider/model` identifier. Bring your own API key, add it as a project secret, and Void handles the rest. Third-party inference is billed directly by the provider, and Void does not mark up API calls. Requests still route through AI Gateway so usage shows up on the dashboard.
|
|
93
|
+
|
|
94
|
+
### Usage
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { defineHandler } from 'void';
|
|
98
|
+
import { ai } from 'void/ai';
|
|
99
|
+
|
|
100
|
+
export const POST = defineHandler(async (c) => {
|
|
101
|
+
const { prompt } = await c.req.json();
|
|
102
|
+
|
|
103
|
+
const result = await ai.run('openai/gpt-4o', {
|
|
104
|
+
messages: [{ role: 'user', content: prompt }],
|
|
105
|
+
max_tokens: 512,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return c.json(result);
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The same `ai.run()` and `ai.stream()` methods work for both Workers AI and third-party models. The framework detects the provider from the model string and routes the request through [AI Gateway](https://developers.cloudflare.com/ai-gateway/) automatically.
|
|
113
|
+
|
|
114
|
+
The options follow each provider's conventions. All third-party providers use the OpenAI-compatible chat completions format, including `messages`, `max_tokens`, and `temperature`. TypeScript narrows the input and return types based on the model string: Workers AI models get per-model typed inputs from `@cloudflare/workers-types`, while third-party models such as `"provider/model"` get `ChatCompletionInputs` and `ChatCompletionResponse`.
|
|
115
|
+
|
|
116
|
+
### Vision
|
|
117
|
+
|
|
118
|
+
Third-party chat models that accept image inputs can receive OpenAI-compatible multimodal message content:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
const result = await ai.run('openai/gpt-4o', {
|
|
122
|
+
messages: [
|
|
123
|
+
{
|
|
124
|
+
role: 'user',
|
|
125
|
+
content: [
|
|
126
|
+
{ type: 'text', text: 'What is in this image?' },
|
|
127
|
+
{
|
|
128
|
+
type: 'image_url',
|
|
129
|
+
image_url: { url: 'data:image/png;base64,...', detail: 'high' },
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Image Generation
|
|
138
|
+
|
|
139
|
+
Use `ai.image()` for image-generation providers or Workers AI image models. It returns a `Response`, so route handlers can return it directly or parse it as JSON depending on the provider:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
export const POST = defineHandler(async (c) => {
|
|
143
|
+
const { prompt } = await c.req.json();
|
|
144
|
+
|
|
145
|
+
return ai.image('openai/gpt-image-1.5', {
|
|
146
|
+
prompt,
|
|
147
|
+
size: '1024x1024',
|
|
148
|
+
response_format: 'b64_json',
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
For Workers AI text-to-image models, pass the model name and input shape from Cloudflare's model docs:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
export const POST = defineHandler(async (c) => {
|
|
157
|
+
const { prompt } = await c.req.json();
|
|
158
|
+
return ai.image('@cf/black-forest-labs/flux-1-schnell', { prompt });
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
For image edits, pass the file-like input and select the edit endpoint. Void serializes the file through the proxy and forwards it to AI Gateway as multipart form data:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
export const POST = defineHandler(async (c) => {
|
|
166
|
+
const body = await c.req.parseBody();
|
|
167
|
+
|
|
168
|
+
return ai.image(
|
|
169
|
+
'openai/gpt-image-1.5',
|
|
170
|
+
{
|
|
171
|
+
prompt: String(body.prompt),
|
|
172
|
+
image: body.image as Blob,
|
|
173
|
+
},
|
|
174
|
+
{ endpoint: 'images/edits' },
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Provider Key Convention
|
|
180
|
+
|
|
181
|
+
Each provider requires an API key set as a project secret. The env var name is automatically derived from the provider prefix:
|
|
182
|
+
|
|
183
|
+
| Provider prefix | Env var |
|
|
184
|
+
| ------------------ | --------------------- |
|
|
185
|
+
| `openai` | `OPENAI_API_KEY` |
|
|
186
|
+
| `anthropic` | `ANTHROPIC_API_KEY` |
|
|
187
|
+
| `google-ai-studio` | `GOOGLE_API_KEY` |
|
|
188
|
+
| `deepseek` | `DEEPSEEK_API_KEY` |
|
|
189
|
+
| `groq` | `GROQ_API_KEY` |
|
|
190
|
+
| `mistral` | `MISTRAL_API_KEY` |
|
|
191
|
+
| `grok` | `GROK_API_KEY` |
|
|
192
|
+
| `openrouter` | `OPENROUTER_API_KEY` |
|
|
193
|
+
| `perplexity` | `PERPLEXITY_API_KEY` |
|
|
194
|
+
| `cohere` | `COHERE_API_KEY` |
|
|
195
|
+
| `cerebras` | `CEREBRAS_API_KEY` |
|
|
196
|
+
| `huggingface` | `HUGGINGFACE_API_KEY` |
|
|
197
|
+
| `replicate` | `REPLICATE_API_KEY` |
|
|
198
|
+
| `baseten` | `BASETEN_API_KEY` |
|
|
199
|
+
| `cartesia` | `CARTESIA_API_KEY` |
|
|
200
|
+
| `deepgram` | `DEEPGRAM_API_KEY` |
|
|
201
|
+
| `elevenlabs` | `ELEVENLABS_API_KEY` |
|
|
202
|
+
| `fal` | `FAL_API_KEY` |
|
|
203
|
+
| `ideogram` | `IDEOGRAM_API_KEY` |
|
|
204
|
+
| `parallel` | `PARALLEL_API_KEY` |
|
|
205
|
+
|
|
206
|
+
All [AI Gateway providers](https://developers.cloudflare.com/ai-gateway/usage/providers/) that accept a Bearer API key are supported. Providers with non-standard auth (Amazon Bedrock, Azure OpenAI, Google Vertex) are not yet supported.
|
|
207
|
+
|
|
208
|
+
For production, add your API key as a project secret:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
void secrets set OPENAI_API_KEY sk-...
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
For local development, add it to `.env.local` in your project root:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
OPENAI_API_KEY=sk-...
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
If the key is missing at runtime, `ai.run()` throws a descriptive error telling you which env var to set.
|
|
221
|
+
|
|
222
|
+
### Streaming with Third-Party Models
|
|
223
|
+
|
|
224
|
+
`ai.stream()` works the same way. The response is always SSE regardless of provider:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
export const POST = defineHandler(async (c) => {
|
|
228
|
+
const { prompt } = await c.req.json();
|
|
229
|
+
|
|
230
|
+
return ai.stream('anthropic/claude-sonnet-4-20250514', {
|
|
231
|
+
messages: [{ role: 'user', content: prompt }],
|
|
232
|
+
max_tokens: 512,
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Supported App Types
|
|
6
|
+
|
|
7
|
+
Void supports three types of apps:
|
|
8
|
+
|
|
9
|
+
1. **Void apps:** Vite apps powered by Void's framework layer, including [API routes](./server-routing.md), [pages mode](./pages-routing/overview.md), [auth](./auth.md), [crons](./jobs.md), and [queues](./queues.md)
|
|
10
|
+
2. **Meta frameworks:** [TanStack Start](https://tanstack.com/start/latest), [React Router](https://reactrouter.com/), [SvelteKit](https://svelte.dev/docs/kit), [Nuxt](https://nuxt.com/), and [Astro](https://astro.build/)
|
|
11
|
+
3. **Static sites:** SPAs, sites built with tools like [VitePress](https://vitepress.dev/), or any directory of static files
|
|
12
|
+
|
|
13
|
+
The type is auto-detected from your project structure, or you can set it explicitly in [`void.json`](../reference/config.md).
|
|
14
|
+
|
|
15
|
+
## Void Apps
|
|
16
|
+
|
|
17
|
+
A Vite app powered by Void's framework layer. In this mode, **Void is both the framework and the platform**. It is opinionated in the backend and deployment story, while still staying frontend-framework-agnostic. You can use it with React, Vue, Svelte, Solid, or any frontend that works with Vite.
|
|
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
|
+
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
|
+
|
|
23
|
+
<VoidAppFileTree annotations />
|
|
24
|
+
|
|
25
|
+
Your worker handles API routes, page rendering, and (optionally) [custom SSR](./ssr.md). Static assets are served from the edge via per-worker assets. Cloudflare bindings (D1, KV, R2) are [inferred from your source code](../reference/resource-inference.md) and provisioned automatically.
|
|
26
|
+
|
|
27
|
+
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
|
+
|
|
29
|
+
**Deploy:** `void deploy` builds via Vite, infers bindings, provisions D1/KV/R2 resources, applies migrations, uploads assets and worker, and makes the site live at `{slug}.void.app`. See [Deployment](./deployment.md) for details.
|
|
30
|
+
|
|
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
|
+
## Meta Frameworks
|
|
41
|
+
|
|
42
|
+
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.
|
|
43
|
+
|
|
44
|
+
| Framework | Detected from package | Setup guide |
|
|
45
|
+
| --------------------------------------------------- | ----------------------- | ----------------------------------------------------- |
|
|
46
|
+
| [TanStack Start](https://tanstack.com/start/latest) | `@tanstack/react-start` | [Guide](../integrations/frameworks/tanstack-start.md) |
|
|
47
|
+
| [React Router v7](https://reactrouter.com/) | `@react-router/dev` | [Guide](../integrations/frameworks/react-router.md) |
|
|
48
|
+
| [SvelteKit](https://svelte.dev/docs/kit) | `@sveltejs/kit` | [Guide](../integrations/frameworks/sveltekit.md) |
|
|
49
|
+
| [Nuxt](https://nuxt.com/) | `nuxt` | [Guide](../integrations/frameworks/nuxt.md) |
|
|
50
|
+
| [Analog](https://analogjs.org/) | `@analogjs/platform` | [Guide](../integrations/frameworks/analog.md) |
|
|
51
|
+
| [Astro](https://astro.build/) | `astro` | [Guide](../integrations/frameworks/astro.md) |
|
|
52
|
+
|
|
53
|
+
Add `voidPlugin()` to the framework's Vite config to get binding inference, typed DB generation, migration management, auth, cron jobs, queues, and caching. See the [Meta Frameworks Integration](../integrations/frameworks/overview.md) for the full feature matrix, deploy pipeline, and per-framework setup guides.
|
|
54
|
+
|
|
55
|
+
**Deploy:** `void deploy` runs the framework build, packages the output, and deploys to Void. The framework still owns routing and SSR, while Void handles resource provisioning, migrations, and edge hosting.
|
|
56
|
+
|
|
57
|
+
**Detected when** any of the above packages is in your dependencies.
|
|
58
|
+
|
|
59
|
+
## Pre-built Static Sites
|
|
60
|
+
|
|
61
|
+
Any project that produces static files, whether that is an SPA, a static site, or a plain directory. Assets are served directly from the edge, and a minimal passthrough worker is generated automatically. You do not need to write worker code yourself.
|
|
62
|
+
|
|
63
|
+
**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
|
+
|
|
65
|
+
**Static sites** (static site generators like VitePress, Docusaurus, or any pre-built directory) produce per-page HTML files. Detected when a known SSG is a dependency, or when using the `--dir` flag.
|
|
66
|
+
|
|
67
|
+
At the edge, the resolution order is:
|
|
68
|
+
|
|
69
|
+
1. Exact file path (`/styles.css` → `styles.css`)
|
|
70
|
+
2. Nested index (`/about` → `about/index.html`)
|
|
71
|
+
3. `404.html` with **status 404** (if the file exists)
|
|
72
|
+
4. Plain 404 response
|
|
73
|
+
|
|
74
|
+
**Deploy:** `void deploy` or `void deploy --dir <path>` uploads static files directly. Assets are served from the edge with automatic caching.
|
|
75
|
+
|
|
76
|
+
## Auto-Detection
|
|
77
|
+
|
|
78
|
+
When running `void deploy` and no `inference.appType` is set in `void.json`, the detection logic runs in this order:
|
|
79
|
+
|
|
80
|
+
| Priority | Condition | Type |
|
|
81
|
+
| -------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
82
|
+
| 1 | `--dir` flag | Static (or SPA with `--spa`) |
|
|
83
|
+
| 2 | Known SSG in dependencies (`vitepress`, `@docusaurus/core`) | Static, builds with SSG CLI |
|
|
84
|
+
| 3 | `@tanstack/react-start`, `@react-router/dev`, `@sveltejs/kit`, `nuxt`, `@analogjs/platform`, or `astro` in deps | Framework |
|
|
85
|
+
| 4 | Backend files exist (`routes/`, `pages/`, `middleware/`, `crons/`, `queues/`, SSR entry) | Void app |
|
|
86
|
+
| 5 | `vite` or `vite-plus` in dependencies, no backend files | SPA, builds with `vite build` or `vp build` |
|
|
87
|
+
| 6 | `dist/index.html` or `./index.html` exists | Static (no build step) |
|
|
88
|
+
|
|
89
|
+
## Explicit Configuration
|
|
90
|
+
|
|
91
|
+
To lock the app type and skip auto-detection, set `inference.appType` in [`void.json`](../reference/config.md):
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"inference": {
|
|
96
|
+
"appType": "static",
|
|
97
|
+
"outputDir": ".vitepress/dist"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- `inference.appType`: `"void"`, `"framework"`, `"spa"`, or `"static"`
|
|
103
|
+
- `inference.outputDir`: output directory for static app types (relative to project root, defaults to `"dist"`)
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Authentication
|
|
6
|
+
|
|
7
|
+
::: warning ⚠️ Void Apps Only
|
|
8
|
+
Void-managed auth currently works only for Void apps. Meta-framework mode is not supported yet.
|
|
9
|
+
:::
|
|
10
|
+
|
|
11
|
+
Void uses [Better Auth](https://www.better-auth.com/) as the auth engine for Void apps. Void owns the conventions and wiring; Better Auth owns the auth behavior.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Enable auth
|
|
16
|
+
|
|
17
|
+
Add a provider to `void.json`. Email/password is the default, so the simplest config is:
|
|
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`.
|
|
28
|
+
|
|
29
|
+
### 2. Sign up and sign in
|
|
30
|
+
|
|
31
|
+
Use the preconfigured auth client from `void/client`:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { auth } from 'void/client';
|
|
35
|
+
|
|
36
|
+
// sign up
|
|
37
|
+
await auth.signUp.email({
|
|
38
|
+
email: 'alice@example.com',
|
|
39
|
+
password: 's3cret',
|
|
40
|
+
name: 'Alice',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// sign in
|
|
44
|
+
await auth.signIn.email({
|
|
45
|
+
email: 'alice@example.com',
|
|
46
|
+
password: 's3cret',
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Protect a server route
|
|
51
|
+
|
|
52
|
+
Use `requireAuth` in an API route handler or a page loader to gate access. It returns the authenticated user or throws a `401`:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// routes/api/profile.ts
|
|
56
|
+
import { defineHandler } from 'void';
|
|
57
|
+
import { requireAuth } from 'void/auth';
|
|
58
|
+
|
|
59
|
+
export const GET = defineHandler((c) => {
|
|
60
|
+
const user = requireAuth(c);
|
|
61
|
+
return { email: user.email };
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
In a pages-mode loader, use `getUser` or `getSession` when you want to allow unauthenticated access:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
// pages/dashboard.server.ts
|
|
69
|
+
import { defineHandler, type InferProps } from 'void';
|
|
70
|
+
import { getUser } from 'void/auth';
|
|
71
|
+
|
|
72
|
+
export type Props = InferProps<typeof loader>;
|
|
73
|
+
|
|
74
|
+
export const loader = defineHandler(() => {
|
|
75
|
+
const user = getUser();
|
|
76
|
+
return { user };
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 4. Sign out
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
await auth.signOut();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The rest of this page covers configuration, server helpers, and advanced customization in detail.
|
|
87
|
+
|
|
88
|
+
## Config
|
|
89
|
+
|
|
90
|
+
Auth turns on automatically when you:
|
|
91
|
+
|
|
92
|
+
- import anything from `void/auth`
|
|
93
|
+
- import `auth` from `void/client`
|
|
94
|
+
- add `auth` to `void.json`
|
|
95
|
+
- add a root-level `auth.ts` file
|
|
96
|
+
|
|
97
|
+
The simplest setup is no config at all. Email/password auth is enabled by default.
|
|
98
|
+
|
|
99
|
+
Example:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"auth": {
|
|
104
|
+
"providers": ["email", "google", "github"]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Use `auth.providers` when you want to enable social providers explicitly. Provider credentials come from `AUTH_<PROVIDER>_CLIENT_ID` and `AUTH_<PROVIDER>_CLIENT_SECRET`.
|
|
110
|
+
|
|
111
|
+
See the full provider list in the [config reference](../reference/config.md#auth).
|
|
112
|
+
|
|
113
|
+
For example, `github` uses:
|
|
114
|
+
|
|
115
|
+
- `AUTH_GITHUB_CLIENT_ID`
|
|
116
|
+
- `AUTH_GITHUB_CLIENT_SECRET`
|
|
117
|
+
|
|
118
|
+
## Client Usage
|
|
119
|
+
|
|
120
|
+
`void/client` exports a preconfigured Better Auth client:
|
|
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 exact client API comes from Better Auth. Void just preconfigures the client with `basePath: "/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`
|
|
150
|
+
|
|
151
|
+
For advanced usage, `void/client` also exports `createAuthClient`.
|
|
152
|
+
|
|
153
|
+
## Server Usage
|
|
154
|
+
|
|
155
|
+
`void/auth` provides the server-side helpers:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import { getSession, getUser, requireAuth } from 'void/auth';
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- `getUser()` returns the current `AuthUser | null`
|
|
162
|
+
- `getSession()` returns `{ user, session } | null`
|
|
163
|
+
- `requireAuth(c)` returns the authenticated user or throws `401`
|
|
164
|
+
|
|
165
|
+
Example:
|
|
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
|
+
```
|
|
209
|
+
|
|
210
|
+
## Behavior
|
|
211
|
+
|
|
212
|
+
When auth is active, Void configures Better Auth with these conventions:
|
|
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. `AUTH_KV` is no longer used.
|
|
222
|
+
|
|
223
|
+
On Void Cloud, Void auto-creates `BETTER_AUTH_SECRET` for auth-enabled apps if you have not set `BETTER_AUTH_SECRET` yourself through project secrets.
|
|
224
|
+
|
|
225
|
+
Localhost dev uses a built-in fallback secret automatically. Outside the managed Void Cloud deploy flow, set `BETTER_AUTH_SECRET` yourself.
|
|
226
|
+
|
|
227
|
+
## Customization
|
|
228
|
+
|
|
229
|
+
For advanced configuration, create `auth.ts` at the project root and export `defineAuth(...)`:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import { defineAuth } from "void/auth";
|
|
233
|
+
|
|
234
|
+
export default defineAuth(({ defaults }) => ({
|
|
235
|
+
...defaults,
|
|
236
|
+
trustedOrigins: ["https://example.com"],
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
`defaults` already includes Void's conventions. Extend it explicitly instead of expecting a deep merge.
|
|
241
|
+
|
|
242
|
+
For the full set of available options, see the official [Better Auth options reference](https://www.better-auth.com/docs/reference/options).
|
|
243
|
+
|
|
244
|
+
## Database and Migrations
|
|
245
|
+
|
|
246
|
+
Void manages Better Auth migrations as part of the normal Void migration flow:
|
|
247
|
+
|
|
248
|
+
- local dev bootstraps auth tables automatically
|
|
249
|
+
- deploy runs auth migrations together with app migrations
|
|
250
|
+
- users do not run a separate Better Auth CLI path
|
|
251
|
+
|
|
252
|
+
## Unsupported Modes
|
|
253
|
+
|
|
254
|
+
Void-managed Better Auth is supported only for Cloudflare Void apps in v1.
|
|
255
|
+
|
|
256
|
+
- meta-framework mode should use Better Auth's official framework integrations directly
|
|
257
|
+
- `target: "node" | "bun" | "deno"` should use Better Auth directly
|