void 0.26.0 → 0.26.1
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/AGENTS_TEMPLATE.md +1 -3
- package/README.md +19 -9
- package/dist/{account-cmd-CDry3B5V.mjs → account-cmd-CfUXh_nU.mjs} +8 -7
- package/dist/{application-analysis-DC2yPvzY.mjs → application-analysis-DKy02UY0.mjs} +21 -32
- package/dist/{application-routing-C9khgLiS.mjs → application-routing-DQyUh_5S.mjs} +1 -1
- package/dist/{auth-D52yG7hl.mjs → auth-B5_tZLxT.mjs} +7 -7
- package/dist/{auth-B60QDbjg.mjs → auth-BgX2qYSY.mjs} +1 -1
- package/dist/{auth-link-DjeOptYi.mjs → auth-link-D5RmKnzh.mjs} +5 -5
- package/dist/{auth-migrations-9vif1uj8.mjs → auth-migrations-BwHgeEsD.mjs} +8 -18
- package/dist/{auth-router-BRxIuqDi.mjs → auth-router-Bap-pvbn.mjs} +4 -17
- package/dist/{better-auth-shared-BVkjZ3vM.d.mts → better-auth-shared-CPvWD3nG.d.mts} +0 -4
- package/dist/{better-auth-shared-hy6RPh9W.mjs → better-auth-shared-DPpj8zxc.mjs} +94 -16
- package/dist/{build-cmd-Ce3C8huo.mjs → build-cmd-B58c8iS8.mjs} +7 -6
- package/dist/{cache-CS8Yxr5a.mjs → cache-Bo52trKF.mjs} +7 -7
- package/dist/{cancel-deploy-mZsD88Xa.mjs → cancel-deploy-BZNz3Q26.mjs} +5 -4
- package/dist/{cf-access-YTlqvAsk.mjs → cf-access-ngGqZpHZ.mjs} +10 -11
- package/dist/{cf-build-output-U8o1Gl6X.mjs → cf-build-output-DjvB_872.mjs} +62 -85
- package/dist/cf-build-output-H9a97vME.mjs +2 -0
- package/dist/cli/cli.mjs +48 -83
- package/dist/cli/cloudflare-operation-process.mjs +71 -77
- package/dist/cli/env-schema-probe.mjs +5 -6
- package/dist/client-By4JjMw_.mjs +2 -0
- package/dist/{client-mC-dFGDD.mjs → client-C2Prx_Bi.mjs} +28 -6
- package/dist/{cloudflare-auth-Qdc7tw8F.mjs → cloudflare-auth-CuxfF6OA.mjs} +9 -17
- package/dist/{cloudflare-cmd-bhwCxAN6.mjs → cloudflare-cmd-lHqNlJGW.mjs} +6 -5
- package/dist/{cloudflare-config-Bktvwtpf.mjs → cloudflare-config-BmhBv3HV.mjs} +1 -1
- package/dist/{cloudflare-connect-CuhRgk3k.mjs → cloudflare-connect-2G3rL2rP.mjs} +4 -4
- package/dist/{cloudflare-operations-DoQrVHAt.mjs → cloudflare-operations-BlYLlowZ.mjs} +1 -1
- package/dist/{cloudflare-operations-DYa3coIk.mjs → cloudflare-operations-CwI1bChl.mjs} +41 -70
- package/dist/{cloudflare-process-B-wekeR6.mjs → cloudflare-process-2-TfIEzB.mjs} +20 -22
- package/dist/{config-CyQ-wVd7.mjs → config-5r-YpMC-.mjs} +1 -1
- package/dist/{config-C_XRIPx2.mjs → config-B_ggY-IO.mjs} +3 -3
- package/dist/config-BtSFvXZx.mjs +2 -0
- package/dist/config-CLYAosnQ.mjs +78 -0
- package/dist/{config-BMHb8RCj.d.mts → config-CSa15FvD.d.mts} +1 -1
- package/dist/{config-Br_JZD6u.mjs → config-DiowPT80.mjs} +24 -30
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config-write-B1f88wJA.mjs → config-write-AHGesphx.mjs} +8 -7
- package/dist/{connect-H6EvP62X.mjs → connect-X0MUA1gk.mjs} +10 -9
- package/dist/{create-project-B2kk9Q0o.mjs → create-project-DxiyW6iX.mjs} +6 -6
- package/dist/{create-project-Dbb4uiN-.mjs → create-project-iwkbqiBU.mjs} +1 -1
- package/dist/{db-DpCKZto0.mjs → db-XnVMHzoV.mjs} +100 -132
- package/dist/{delete-CxlSvsvW.mjs → delete-esYlMiSJ.mjs} +6 -6
- package/dist/{deploy-CeEbnv4b.mjs → deploy-BsEvnlJl.mjs} +2346 -2495
- package/dist/deploy-C1d-YTfp.mjs +2 -0
- package/dist/{dev-inbox-D64ZKUod.mjs → dev-inbox-CK-UuPob.mjs} +7 -16
- package/dist/{discover-BcPPiF1o.mjs → discover-CkCYv9T_.mjs} +1 -2
- package/dist/discover-EDUf6JJw.mjs +2 -0
- package/dist/{prompts-ZAuJlyCj.mjs → dist-Bx1z6Eva.mjs} +1 -1
- package/dist/{dist-AoCzRTJE.mjs → dist-Cegxq8gs.mjs} +8 -8
- package/dist/{prompts-6OSVA7DJ.mjs → dist-D3m88sjf.mjs} +10 -53
- package/dist/{domain-B_9VgOm6.mjs → domain-CbbBWhWE.mjs} +28 -29
- package/dist/{dotenv-VQxupEUv.mjs → dotenv-BfU6eqFt.mjs} +20 -32
- package/dist/{drizzle-Beb2Am5S.mjs → drizzle-CF84FOVM.mjs} +16 -13
- package/dist/{email-BokHgjKj.mjs → email-CpuT42g7.mjs} +23 -18
- package/dist/{email--tEtMoj_.mjs → email-d_Aux1vM.mjs} +1 -1
- package/dist/{entry-CF5wvH4w.mjs → entry-CMAkqBmU.mjs} +6 -6
- package/dist/{env-_v349JBd.mjs → env-BxocywBB.mjs} +25 -6
- package/dist/{env-D5liuQYR.mjs → env-DMA3cXZt.mjs} +1 -1
- package/dist/{env-raw-Cx8ElDdj.mjs → env-raw-jZpP5n47.mjs} +1 -2
- package/dist/{env-types-D5kds_OZ.mjs → env-types-CwXgeMgL.mjs} +1 -1
- package/dist/{env-validation-cZBvGWaP.mjs → env-validation-CrVNjsPm.mjs} +1 -1
- package/dist/{env-validation-vBSQ8gw5.mjs → env-validation-Dxdx_5wo.mjs} +17 -21
- package/dist/{env-BdTc-K2L.mjs → env-w9jOyGZn.mjs} +9 -9
- package/dist/{fetch-_SeGZao9.d.mts → fetch-BPCYVi3H.d.mts} +20 -1
- package/dist/{fetch-BIZJh7vR.mjs → fetch-sAcwjzLO.mjs} +1 -1
- package/dist/{fetch-stream-Nm3hkZbT.mjs → fetch-stream-PGgz4uGz.mjs} +18 -23
- package/dist/{fetch-stream-Bjf0hoZb.d.mts → fetch-stream-obvZ7fvO.d.mts} +1 -16
- package/dist/{gen-BhDlTpwW.mjs → gen-DtkQhvQg.mjs} +40 -57
- package/dist/gen-dA9hW7AV.mjs +2 -0
- package/dist/{github-cmd-hhkTzlGS.mjs → github-cmd-D_FsOFxq.mjs} +64 -163
- package/dist/{handler-DghKr6dU.mjs → handler-BHAn2fZJ.mjs} +1 -0
- package/dist/{handler-BeK3weD4.d.mts → handler-CNAwjRcW.d.mts} +4 -11
- package/dist/{head-Do8P4puT.d.mts → head-C8K_iGe6.d.mts} +1 -1
- package/dist/{head-D_QRR5Yd.mjs → head-D2VF4ApL.mjs} +29 -51
- package/dist/{headers-2rKda9Y6.mjs → headers-DlfR78Nu.mjs} +3 -3
- package/dist/{help-Bv44e2tm.mjs → help-CVFBTmBx.mjs} +13 -32
- package/dist/help-DzKUrQvk.mjs +2 -0
- package/dist/{inbound-fRkqcXaC.mjs → inbound-PfQDLXc5.mjs} +23 -24
- package/dist/index.d.mts +19 -2
- package/dist/index.mjs +617 -530
- package/dist/{info-DhtTKh65.mjs → info-PYWwkWyt.mjs} +4 -4
- package/dist/{init-BMf4T03q.mjs → init-Bw-fRKGp.mjs} +160 -197
- package/dist/{link-BqYsSS_I.mjs → link-DlPG8iX3.mjs} +9 -9
- package/dist/{list-_kBToO-l.mjs → list-2GN7_ueV.mjs} +8 -7
- package/dist/{live-CB1y5IuC.mjs → live-CgQuTpqD.mjs} +15 -16
- package/dist/{live-iAuEH1hd.d.mts → live-Du8jXwOW.d.mts} +4 -2
- package/dist/{local-d1-fGxYrVD6.mjs → local-d1-ga5O_idV.mjs} +2 -2
- package/dist/{login-DFuo-RWO.mjs → login-D-Q4xw3Q.mjs} +7 -7
- package/dist/login-Dc-wuTDq.mjs +2 -0
- package/dist/{logs-DYgnh6dH.mjs → logs-rd8J-OFh.mjs} +27 -10
- package/dist/migrate-BHp07yJE.mjs +2 -0
- package/dist/{migrate-CV1on-yJ.mjs → migrate-NLsjBbuM.mjs} +34 -20
- package/dist/{mime-D5Nmdzf7.mjs → mime-DxCznlJq.mjs} +45 -95
- package/dist/{node-C6Q6e1Es.mjs → node-DJicPvPj.mjs} +5 -5
- package/dist/{operator-args-DdY54Bgb.mjs → operator-args-BNsW5gfp.mjs} +10 -1
- package/dist/{operator-auth-2dsGlTT5.mjs → operator-auth-AzVLbrr3.mjs} +1 -1
- package/dist/{operator-client-BFqpp6z0.mjs → operator-client-BQtzyG-g.mjs} +1 -1
- package/dist/{operator-cmd-CUGHXrQf.mjs → operator-cmd-B6f6Cg9Z.mjs} +24 -11
- package/dist/operator-cmd-Cwn50lOV.mjs +2 -0
- package/dist/{output-BvdaehtE.mjs → output-C50ag2r3.mjs} +20 -2
- package/dist/pages/client.d.mts +19 -51
- package/dist/pages/client.mjs +204 -225
- package/dist/pages/head-client.d.mts +1 -1
- package/dist/pages/head.d.mts +1 -1
- package/dist/pages/head.mjs +1 -1
- package/dist/pages/index.d.mts +2 -2
- package/dist/pages/index.mjs +6 -12
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/islands-plugin.mjs +21 -25
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +2 -2
- package/dist/{plan-CJGEeTEI.mjs → plan-BhLO2p4w.mjs} +2 -1
- package/dist/plan-CH2G51je.mjs +2 -0
- package/dist/{platform-args-DSV2p4nY.mjs → platform-args-BoZkWQnJ.mjs} +1 -1
- package/dist/platform-args-DYgITk0D.mjs +2 -0
- package/dist/{platform-auth-config-Bosx7U1h.mjs → platform-auth-config-n603OANg.mjs} +40 -36
- package/dist/{platform-auth-protection-DcbL_LW_.mjs → platform-auth-protection-zxDr0hWW.mjs} +8 -7
- package/dist/{platform-auth-recovery-WfTZ8K6o.mjs → platform-auth-recovery-tw9lgtgE.mjs} +7 -6
- package/dist/{platform-cmd-DbKtQb_4.mjs → platform-cmd-B8-bCb7t.mjs} +10 -10
- package/dist/{platform-cmd-dyFUof0t.mjs → platform-cmd-C00YM14r.mjs} +1 -1
- package/dist/{platform-domain-Bsq43AJp.mjs → platform-domain-p0kobLV8.mjs} +5 -5
- package/dist/{platform-lifecycle-Cfi0o6xM.mjs → platform-lifecycle-D_QEY32D.mjs} +75 -386
- package/dist/{platform-lifecycle--5gWmDoI.mjs → platform-lifecycle-vFqtNPPa.mjs} +1 -1
- package/dist/{platform-management-BrF9STZp.mjs → platform-management-BdYblvvE.mjs} +6 -6
- package/dist/{platform-management-Bbwf6-Dq.mjs → platform-management-oi-SvI3f.mjs} +1 -1
- package/dist/{platform-plans-config-DU-8nC2Y.mjs → platform-plans-config-CjiFv5J4.mjs} +5 -4
- package/dist/{platform-recovery-DQAqAQYu.mjs → platform-recovery-PvNS9Nl2.mjs} +2 -2
- package/dist/platform-setup-DVe42Ws7.mjs +299 -0
- package/dist/{plugin-inference-CXWnn79A.mjs → plugin-inference-BlQbOL0P.mjs} +43 -42
- package/dist/prepare-DRUV-g3X.mjs +2 -0
- package/dist/{prepare-WoUubFKL.mjs → prepare-Do96654b.mjs} +8 -8
- package/dist/{prepare-BMrRWLwP.mjs → prepare-Dq9hTIbo.mjs} +4 -4
- package/dist/{prerender-render-D9qbLs2f.mjs → prerender-render-Ct20jftc.mjs} +17 -3
- package/dist/prerender-render.mjs +1 -1
- package/dist/{project-cmd-BbH2LptN.mjs → project-cmd-ti8_yTcA.mjs} +18 -18
- package/dist/{project-team-Yiww3-go.mjs → project-team-CDPE1Tsg.mjs} +14 -17
- package/dist/{project-token-BrtT2NkY.mjs → project-token-CkZ1cN0Z.mjs} +13 -16
- package/dist/{project-tsconfig-B8GeM0RM.mjs → project-tsconfig-CVJhNMxs.mjs} +2 -1
- package/dist/{project-zero-trust-nYJ2V2nc.mjs → project-zero-trust-DdjLR61k.mjs} +11 -8
- package/dist/{protocol-BX8t2jiw.d.mts → protocol-BPZaNqBo.d.mts} +4 -2
- package/dist/{protocol-U7bfjHmA.mjs → protocol-CfaUwNs8.mjs} +46 -49
- package/dist/{providers-CJlNS3kT.mjs → providers-BXuhmuub.mjs} +1 -12
- package/dist/{provision-VeqAC77A.mjs → provision-BfaLiWbj.mjs} +38 -41
- package/dist/{provision-DMTPG8Rh.mjs → provision-Wu9ZBk9L.mjs} +2 -3
- package/dist/{requests-TIz_jtSu.mjs → requests-DFAqyYy8.mjs} +4 -4
- package/dist/resolve-project-BIeYs9Cw.mjs +2 -0
- package/dist/{resolve-project-BG5ORGID.mjs → resolve-project-CP8rZs_p.mjs} +6 -1
- package/dist/{rollback-dBqICPzj.mjs → rollback-BKYXBduI.mjs} +29 -36
- package/dist/{route-types-Clm4WD0B.mjs → route-types-CbtsIeFn.mjs} +1 -1
- package/dist/route-url-BgPja1GS.d.mts +5 -0
- package/dist/route-url-BjGv_KKY.mjs +28 -0
- package/dist/runner-9wjsSZx-.mjs +2 -0
- package/dist/{runner--2KF6Kua.mjs → runner-DMBKSrRk.mjs} +2 -2
- package/dist/{runner-mysql-DmWchSWJ.mjs → runner-mysql-CEzKtmFb.mjs} +8 -8
- package/dist/{runner-mysql-CEG5JozK.mjs → runner-mysql-CkFqZ6CE.mjs} +1 -1
- package/dist/{runner-pg-Bh4AgZdj.mjs → runner-pg-BGYRFdRp.mjs} +1 -1
- package/dist/runtime/ai.d.mts +1 -1
- package/dist/runtime/ai.mjs +34 -95
- package/dist/runtime/better-auth-mysql.d.mts +1 -1
- package/dist/runtime/better-auth-mysql.mjs +4 -9
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +5 -10
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +3 -3
- package/dist/runtime/client-react.d.mts +2 -3
- package/dist/runtime/client-react.mjs +2 -2
- package/dist/runtime/client-solid.d.mts +2 -3
- package/dist/runtime/client-solid.mjs +2 -2
- package/dist/runtime/client-svelte.d.mts +2 -3
- package/dist/runtime/client-svelte.mjs +2 -2
- package/dist/runtime/client-vue.d.mts +2 -3
- package/dist/runtime/client-vue.mjs +2 -2
- package/dist/runtime/client.d.mts +2 -3
- package/dist/runtime/client.mjs +2 -2
- package/dist/runtime/db.mjs +1 -1
- package/dist/runtime/durable.mjs +3 -10
- package/dist/runtime/email/testing.mjs +5 -5
- package/dist/runtime/email.d.mts +2 -1
- package/dist/runtime/email.mjs +11 -27
- package/dist/runtime/env-public.mjs +15 -20
- package/dist/runtime/env.mjs +1 -1
- package/dist/runtime/fetch-stream.d.mts +2 -2
- package/dist/runtime/fetch-stream.mjs +1 -1
- package/dist/runtime/fetch.d.mts +2 -3
- package/dist/runtime/fetch.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/handler.mjs +2 -2
- package/dist/runtime/isr.mjs +1 -1
- package/dist/runtime/kv.mjs +10 -11
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-client.mjs +12 -22
- package/dist/runtime/live-server.mjs +27 -35
- package/dist/runtime/live.d.mts +2 -2
- package/dist/runtime/live.mjs +2 -2
- package/dist/runtime/migration-handler.mjs +4 -81
- package/dist/runtime/queues.mjs +1 -1
- package/dist/runtime/remote/binding-handler.d.mts +2 -2
- package/dist/runtime/remote/binding-handler.mjs +8 -9
- package/dist/runtime/remote/index.mjs +27 -77
- package/dist/runtime/route-url.d.mts +2 -4
- package/dist/runtime/route-url.mjs +1 -1
- package/dist/runtime/routing.d.mts +1 -1
- package/dist/runtime/routing.mjs +15 -26
- package/dist/runtime/sandbox.mjs +2 -2
- package/dist/runtime/sse.mjs +1 -1
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +2 -2
- package/dist/runtime/ws-server.mjs +30 -61
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/runtime/ws.mjs +1 -1
- package/dist/{scan-C8dA7iM4.mjs → scan-C3uDzz6J.mjs} +12 -13
- package/dist/{secret-AKnNXNP5.mjs → secret-BAt2KMmO.mjs} +14 -14
- package/dist/{skills-BPQUGClu.mjs → skills-BgVMvQdy.mjs} +2 -2
- package/dist/{sse-CQNaDFFV.mjs → sse-CMvCgjNk.mjs} +1 -1
- package/dist/{subcommand-prompt-B6WS9Aoz.mjs → subcommand-prompt-BSlnD1fI.mjs} +2 -2
- package/dist/sveltekit.d.mts +0 -2
- package/dist/terminal-log-text-D9ACPOuG.mjs +32 -0
- package/dist/validate-BJr9LfXy.mjs +2 -0
- package/dist/{validate-ymhap6M_.mjs → validate-C9qJArv7.mjs} +9 -28
- package/dist/{defer-YsYDUoii.mjs → validation-error-Dg9Recn1.mjs} +11 -11
- package/dist/{wrangler-DhUerFkW.mjs → wrangler-D9KTuqnv.mjs} +89 -194
- package/dist/{ws-C79j4aED.d.mts → ws-CChrrAU-.d.mts} +1 -1
- package/dist/{yarn-pnp-BV4AzNul.mjs → yarn-pnp-CUX_iTPA.mjs} +19 -27
- package/{skills/void/docs → docs}/guide/ai.md +5 -3
- package/{skills/void/docs → docs}/guide/auth.md +37 -1
- package/{skills/void/docs → docs}/guide/database/postgresql.md +2 -2
- package/{skills/void/docs → docs}/guide/edge/revalidation.md +1 -1
- package/{skills/void/docs → docs}/guide/edge/rewrites.md +2 -4
- package/{skills/void/docs → docs}/guide/email/receiving.md +2 -2
- package/{skills/void/docs → docs}/guide/email/sending.md +0 -2
- package/{skills/void/docs → docs}/guide/env-vars.md +4 -0
- package/{skills/void/docs → docs}/guide/jobs.md +2 -2
- package/{skills/void/docs → docs}/guide/live.md +10 -5
- package/{skills/void/docs → docs}/guide/pages-routing/actions-and-forms.md +20 -8
- package/{skills/void/docs → docs}/guide/pages-routing/loaders.md +7 -3
- package/{skills/void/docs → docs}/guide/pages-routing/markdown.md +15 -23
- package/{skills/void/docs → docs}/guide/pages-routing/overview.md +6 -4
- package/{skills/void/docs → docs}/guide/platform/administration/access.md +2 -10
- package/{skills/void/docs → docs}/guide/platform/administration/operations.md +3 -12
- package/{skills/void/docs → docs}/guide/platform/administration/projects.md +1 -1
- package/{skills/void/docs → docs}/guide/platform/development/local.md +4 -2
- package/{skills/void/docs → docs}/guide/platform/development/runtime.md +1 -1
- package/{skills/void/docs → docs}/guide/platform/development/schema-ci.md +1 -1
- package/{skills/void/docs → docs}/guide/platform/installation/domains.md +3 -1
- package/{skills/void/docs → docs}/guide/platform/installation/first-deployment.md +3 -1
- package/{skills/void/docs → docs}/guide/platform/installation/maintenance.md +4 -0
- package/{skills/void/docs → docs}/guide/project-collaboration.md +6 -2
- package/{skills/void/docs → docs}/guide/queues.md +0 -2
- package/{skills/void/docs → docs}/guide/remote-dev.md +5 -5
- package/{skills/void/docs → docs}/guide/sandboxes.md +2 -2
- package/{skills/void/docs → docs}/guide/sse.md +0 -2
- package/{skills/void/docs → docs}/guide/storage.md +7 -2
- package/{skills/void/docs → docs}/guide/websockets.md +4 -0
- package/docs/integrations/agents.md +37 -0
- package/{skills/void/docs → docs}/integrations/frameworks/astro.md +3 -3
- package/{skills/void/docs → docs}/integrations/frameworks/nuxt.md +6 -2
- package/{skills/void/docs → docs}/integrations/hono.md +15 -7
- package/{skills/void/docs → docs}/integrations/nodejs-bun-deno.md +1 -0
- package/{skills/void/docs → docs}/reference/api/auth.md +1 -1
- package/{skills/void/docs → docs}/reference/api/handlers.md +4 -2
- package/{skills/void/docs → docs}/reference/api/pages.md +4 -0
- package/{skills/void/docs → docs}/reference/cli/auth.md +0 -5
- package/{skills/void/docs → docs}/reference/cli/database.md +3 -4
- package/{skills/void/docs → docs}/reference/cli/generate.md +1 -1
- package/{skills/void/docs → docs}/reference/cli/github.md +3 -12
- package/{skills/void/docs → docs}/reference/cli/platform-config.md +1 -1
- package/{skills/void/docs → docs}/reference/cli/platform-email.md +2 -3
- package/{skills/void/docs → docs}/reference/cli/platform-installation.md +1 -1
- package/{skills/void/docs → docs}/reference/cli/platform-operations.md +3 -0
- package/{skills/void/docs → docs}/reference/cli/platform-users.md +2 -2
- package/{skills/void/docs → docs}/reference/cli/project.md +5 -4
- package/{skills/void/docs → docs}/reference/cli/secrets.md +3 -3
- package/{skills/void/docs → docs}/reference/cli/setup.md +9 -11
- package/{skills/void/docs → docs}/reference/cli.md +1 -1
- package/{skills/void/docs → docs}/reference/config.md +13 -13
- package/{skills/void/docs → docs}/reference/resource-inference.md +1 -16
- package/package.json +34 -30
- package/schema.json +1 -1
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +4 -1
- package/skills/void/SKILL.md +6 -3
- package/dist/cf-build-output-ChY6-XWP.mjs +0 -2
- package/dist/client-BxVixJBI.mjs +0 -2
- package/dist/config-0acf1oys.mjs +0 -2
- package/dist/config-D8MOgiQV.mjs +0 -32
- package/dist/deploy-qmiLE1G1.mjs +0 -2
- package/dist/discover-AMCBXivQ.mjs +0 -2
- package/dist/fetch-error-Sp1R4mZv.d.mts +0 -20
- package/dist/gen-qCBwH3fZ.mjs +0 -2
- package/dist/help-Dw5f9Xrg.mjs +0 -2
- package/dist/login-D7meQg_3.mjs +0 -2
- package/dist/migrate-CEu2X5DB.mjs +0 -2
- package/dist/operator-cmd-DRPvhpjM.mjs +0 -2
- package/dist/plan-COtUvdMA.mjs +0 -2
- package/dist/platform-args-Dcy_5b_Y.mjs +0 -2
- package/dist/prepare-BBknoZI1.mjs +0 -2
- package/dist/resolve-project-DtbidV4y.mjs +0 -2
- package/dist/route-url-CG7U-cRN.mjs +0 -15
- package/dist/runner-voIltZrY.mjs +0 -2
- package/dist/validate-pna7R3Pv.mjs +0 -2
- package/skills/void/docs/integrations/agents.md +0 -26
- package/dist/{runner-pg-D4OPlil-.mjs → runner-pg-DV8p_zjA.mjs} +4 -4
- package/{skills/void/docs → docs}/guide/app-types.md +0 -0
- package/{skills/void/docs → docs}/guide/database/d1.md +2 -2
- package/{skills/void/docs → docs}/guide/database/mysql.md +0 -0
- package/{skills/void/docs → docs}/guide/database.md +8 -8
- package/{skills/void/docs → docs}/guide/deployment.md +0 -0
- package/{skills/void/docs → docs}/guide/durable-state.md +0 -0
- package/{skills/void/docs → docs}/guide/edge/headers.md +0 -0
- package/{skills/void/docs → docs}/guide/edge/prerendering.md +0 -0
- package/{skills/void/docs → docs}/guide/edge/redirects.md +0 -0
- package/{skills/void/docs → docs}/guide/edge/static-assets.md +0 -0
- package/{skills/void/docs → docs}/guide/email/domains.md +0 -0
- package/{skills/void/docs → docs}/guide/email.md +0 -0
- package/{skills/void/docs → docs}/guide/index.md +0 -0
- package/{skills/void/docs → docs}/guide/kv.md +0 -0
- package/{skills/void/docs → docs}/guide/pages-routing/head.md +0 -0
- package/{skills/void/docs → docs}/guide/pages-routing/islands.md +2 -2
- package/{skills/void/docs → docs}/guide/pages-routing/layouts.md +0 -0
- package/{skills/void/docs → docs}/guide/pages-routing/view-transitions.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/administration/email.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/administration/plans.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/administration/zero-trust.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/installation/ci.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/installation/credentials.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/installation/prerequisites.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/installation/setup.md +0 -0
- package/{skills/void/docs → docs}/guide/platform/installation/uninstall.md +0 -0
- package/{skills/void/docs → docs}/guide/platform-administration.md +0 -0
- package/{skills/void/docs → docs}/guide/platform-development.md +0 -0
- package/{skills/void/docs → docs}/guide/quickstart.md +0 -0
- package/{skills/void/docs → docs}/guide/self-hosted-platform.md +0 -0
- package/{skills/void/docs → docs}/guide/server-routing.md +3 -3
- package/{skills/void/docs → docs}/guide/ssg.md +0 -0
- package/{skills/void/docs → docs}/guide/ssr.md +0 -0
- package/{skills/void/docs → docs}/guide/type-safety.md +0 -0
- package/{skills/void/docs → docs}/guide/typed-fetch.md +0 -0
- package/{skills/void/docs → docs}/index.md +0 -0
- package/{skills/void/docs → docs}/integrations/cloudflare.md +0 -0
- package/{skills/void/docs → docs}/integrations/frameworks/analog.md +3 -3
- package/{skills/void/docs → docs}/integrations/frameworks/overview.md +0 -0
- package/{skills/void/docs → docs}/integrations/frameworks/react-router.md +3 -3
- package/{skills/void/docs → docs}/integrations/frameworks/sveltekit.md +1 -1
- package/{skills/void/docs → docs}/integrations/frameworks/tanstack-start.md +2 -2
- package/{skills/void/docs → docs}/reference/api/client.md +0 -0
- package/{skills/void/docs → docs}/reference/api/database.md +2 -2
- /package/{skills/void/docs → docs}/reference/api/durable.md +0 -0
- /package/{skills/void/docs → docs}/reference/api/env.md +0 -0
- /package/{skills/void/docs → docs}/reference/api/plugin.md +0 -0
- /package/{skills/void/docs → docs}/reference/api/resources.md +0 -0
- /package/{skills/void/docs → docs}/reference/api/rewrites.md +0 -0
- /package/{skills/void/docs → docs}/reference/api/types.md +0 -0
- /package/{skills/void/docs → docs}/reference/api.md +0 -0
- /package/{skills/void/docs → docs}/reference/cli/deploy.md +0 -0
- /package/{skills/void/docs → docs}/reference/cli/domains.md +0 -0
- /package/{skills/void/docs → docs}/reference/cli/email.md +0 -0
- /package/{skills/void/docs → docs}/reference/cli/platform-zero-trust.md +0 -0
- /package/{skills/void/docs → docs}/reference/cli/platform.md +0 -0
- /package/{skills/void/docs → docs}/reference/structure.md +0 -0
|
@@ -108,7 +108,7 @@ Requests with `Cookie`, `Authorization`, or Cloudflare Access's `Cf-Access-Jwt-A
|
|
|
108
108
|
|
|
109
109
|
For a dispatch rewrite, the cache key includes both the destination and original pathname. A direct request to `/en/docs/foo` therefore uses a different entry from `/docs/foo` rewritten to that destination.
|
|
110
110
|
|
|
111
|
-
Query parameters are excluded by default. Add `routing.revalidateQueryAllowlist` when specific parameters should produce separate cached responses. Middleware `c.rewrite()` runs after the ISR lookup, so it doesn't create an additional cache variant.
|
|
111
|
+
Query parameters are excluded by default. Add `routing.revalidateQueryAllowlist` when specific parameters should produce separate cached responses. Requests with other query parameters get the cached page. If nothing is cached yet, they render live and are not stored, so add every parameter a page reads to `routing.revalidateQueryAllowlist`. Middleware `c.rewrite()` runs after the ISR lookup, so it doesn't create an additional cache variant.
|
|
112
112
|
|
|
113
113
|
Purge the destination pathname with `revalidate({ paths })`. Purging `/en/docs/foo` clears both direct and rewritten variants. Purging only `/docs/foo` won't clear them, because the entries are stored under the destination.
|
|
114
114
|
|
|
@@ -109,15 +109,13 @@ The file can include [3xx redirects](./redirects) too. Rules in `void.config.ts`
|
|
|
109
109
|
|
|
110
110
|
## Client navigation
|
|
111
111
|
|
|
112
|
-
Rewrites run on the server. In Pages mode, a client-side `<Link
|
|
112
|
+
Rewrites run on the server. In Pages mode, a client-side `<Link href="/docs">` navigation may fetch loader data for `/docs` rather than the rewritten route `/en/docs`.
|
|
113
113
|
|
|
114
114
|
Use `<a href="/docs">` to make a full server request when the destination has a different loader. Use a redirect if the URL should change.
|
|
115
115
|
|
|
116
116
|
## ISR cache keys with rewrites
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
Purge the destination with `revalidate({ paths: ['/en/docs/foo'] })` to clear direct and rewritten requests. Purging only `/docs/foo` does not clear that entry. See [Revalidation](./revalidation).
|
|
118
|
+
Purge the destination path, such as `/en/docs/foo`, to clear rewritten cache entries. See [Cache keys and rewrites](./revalidation#cache-keys-and-rewrites).
|
|
121
119
|
|
|
122
120
|
## Debugging with `X-Void-Routing`
|
|
123
121
|
|
|
@@ -100,13 +100,13 @@ There is no local inbound trigger yet — `void dev` serves the outbound dev inb
|
|
|
100
100
|
|
|
101
101
|
## Testing inbound handlers {#testing-inbound-handlers}
|
|
102
102
|
|
|
103
|
-
Use `createInboundTestHarness` to capture replies, forwards, and rejections. For shared platform mail, pass the full address including the project prefix, such as `acme+support+abc-123@acme.dev
|
|
103
|
+
Use `createInboundTestHarness` to capture replies, forwards, and rejections. For shared platform mail, pass the full address including the project prefix, such as [`acme+support+abc-123@acme.dev`](mailto:acme+support+abc-123@acme.dev). For direct Cloudflare mail, set `slug: null` and use [`support+abc-123@mail.acme.com`](mailto:support+abc-123@mail.acme.com).
|
|
104
104
|
|
|
105
105
|
```ts
|
|
106
106
|
import { describe, it, expect } from 'vitest';
|
|
107
107
|
import { createInboundTestHarness } from 'void/email/testing';
|
|
108
|
-
import support from './email/support+[ticket]';
|
|
109
108
|
import defaultHandler from './email/_default';
|
|
109
|
+
import support from './email/support+[ticket]';
|
|
110
110
|
|
|
111
111
|
describe('email handlers', () => {
|
|
112
112
|
it('routes to support+[ticket] and extracts the tag', async () => {
|
|
@@ -59,8 +59,6 @@ Cloudflare emails the recipient with a verification link. Once they click it and
|
|
|
59
59
|
void email destinations
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
The project owner’s email is added automatically, but still needs verification as described in [Setup](#setup).
|
|
63
|
-
|
|
64
62
|
::: warning When this is the right fit
|
|
65
63
|
The shared sender suits team alerts, project notifications, and replies to inbound mail.
|
|
66
64
|
|
|
@@ -39,8 +39,12 @@ STRIPE_KEY=sk_test_example
|
|
|
39
39
|
VITE_API_ORIGIN=http://localhost:5173
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
An unquoted value ends at `#`, which starts a comment. Quote a value that contains `#`, such as `DATABASE_URL="postgres://user:p#ss@localhost/my-app"`.
|
|
43
|
+
|
|
42
44
|
Keep `.env` out of Git. Other dotenv files, including `.env.local`, `.env.production`, `.env.example`, and Wrangler’s `.dev.vars*`, are not supported.
|
|
43
45
|
|
|
46
|
+
Names starting with `__VOID_` are reserved for Void. Void stops with an error if `.env` or `env.ts` defines one.
|
|
47
|
+
|
|
44
48
|
Run the local check at any time:
|
|
45
49
|
|
|
46
50
|
```sh
|
|
@@ -70,10 +70,10 @@ curl -X POST http://localhost:5173/__void/scheduled \
|
|
|
70
70
|
-d '{"cron":"0 * * * *","scheduledTime":'"$(date +%s000)"'}'
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
If you set `__VOID_PROXY_TOKEN` in `.env`, that explicit token takes precedence and the printed curl command uses `x-void-internal: <your-token>` instead.
|
|
74
|
-
|
|
75
73
|
The endpoint works in native Void apps and supported frameworks. Framework jobs run in the adapter's development runtime and use the bindings it provides.
|
|
76
74
|
|
|
77
75
|
## Deployment behavior
|
|
78
76
|
|
|
79
77
|
Native scheduled events do not require a manual HTTP token. For framework deployments, HTTP requests to `/__void/scheduled` require a matching `x-void-internal` token: the managed platform supplies its proxy token, or you can explicitly configure `CRON_SECRET` for manual calls. An absent or mismatched token returns `401` without running a job.
|
|
78
|
+
|
|
79
|
+
On a Void platform, each project can use up to 100 different cron expressions and 1,000 schedules (each expression a job exports counts as one schedule). Jobs that share an expression count once toward the expression limit. When you deploy to your own Cloudflare account, Cloudflare's [Cron Trigger limits](https://developers.cloudflare.com/workers/platform/limits/) apply instead.
|
|
@@ -22,6 +22,8 @@ export const live = defineLiveStream({
|
|
|
22
22
|
});
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
This example accepts visitors who are not signed in. Without `onSubscribe`, any connection can subscribe to any topic, so read [Authorization](#authorization) before you publish private data.
|
|
26
|
+
|
|
25
27
|
Void enables live streams when a [scanned file](../reference/resource-inference.md#scanned-directories) imports `void/live`, so keep this module in `src/` or another scanned directory. To keep it in an unscanned directory such as `lib/`, add that directory to [`inference.scanDirs`](../reference/resource-inference.md#custom-scan-directories) and list the default directories you still use, because `scanDirs` replaces them.
|
|
26
28
|
|
|
27
29
|
Expose it from a normal route:
|
|
@@ -101,6 +103,8 @@ await live.withEnv(env).publish('post:12', { title: 'Updated title' });
|
|
|
101
103
|
|
|
102
104
|
Only a connection's owner can change its subscriptions. The example above allows anonymous connections; authenticated streams use the current Void user by default.
|
|
103
105
|
|
|
106
|
+
The owner decides who can change a connection's subscriptions, not which topics the connection can read.
|
|
107
|
+
|
|
104
108
|
For authenticated streams, pass the same owner key to `connect()` and
|
|
105
109
|
`control()`:
|
|
106
110
|
|
|
@@ -127,16 +131,17 @@ current authenticated user and uses `user:${user.id}` when the user has a string
|
|
|
127
131
|
`id`. If neither path produces an owner and `allowAnonymousControl` is not set,
|
|
128
132
|
the request is rejected with `403`.
|
|
129
133
|
|
|
130
|
-
|
|
134
|
+
Without `onSubscribe`, any connection that passes the owner check (any signed-in user, or any visitor when `allowAnonymousControl` is set) can subscribe to any topic and receives everything published to it. Topic names are easy to guess. Use `onSubscribe` to decide who can read each topic: return a `Response` to reject the subscription, or return nothing to allow it.
|
|
131
135
|
|
|
132
136
|
```ts
|
|
133
137
|
export const live = defineLiveStream({
|
|
134
138
|
id: 'app',
|
|
135
139
|
async onSubscribe(ctx) {
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
+
const post = /^post:(.+)$/.exec(ctx.topic);
|
|
141
|
+
if (post && (await canReadPost(ctx.env, ctx.user, post[1]))) return;
|
|
142
|
+
const inbox = /^user:(.+):inbox$/.exec(ctx.topic);
|
|
143
|
+
if (inbox && ctx.owner === `user:${inbox[1]}`) return;
|
|
144
|
+
return new Response('Forbidden', { status: 403 });
|
|
140
145
|
},
|
|
141
146
|
});
|
|
142
147
|
```
|
|
@@ -11,10 +11,10 @@ Use an action to change server data from a form or button. Define it in the page
|
|
|
11
11
|
Export `action` from a `.server.ts` file. Use `withValidator()` with a [schema-derived validator](../database.md#schema-derived-validators) to validate the request body:
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
+
import { users, insertUserSchema } from '@schema';
|
|
14
15
|
// pages/users/index.server.ts
|
|
15
16
|
import { defineHandler } from 'void';
|
|
16
17
|
import { db } from 'void/db';
|
|
17
|
-
import { users, insertUserSchema } from '@schema';
|
|
18
18
|
|
|
19
19
|
export const action = defineHandler.withValidator({
|
|
20
20
|
body: insertUserSchema,
|
|
@@ -176,10 +176,10 @@ const form = useForm('/users/:id', { name: '' }, { params: { id: '42' } });
|
|
|
176
176
|
When a page needs multiple mutations, such as updating and deleting a user on the same page, export `actions` (plural) instead of `action`:
|
|
177
177
|
|
|
178
178
|
```ts
|
|
179
|
+
import { users, updateUserSchema } from '@schema';
|
|
179
180
|
// pages/users/[id].server.ts
|
|
180
181
|
import { defineHandler } from 'void';
|
|
181
182
|
import { db, eq } from 'void/db';
|
|
182
|
-
import { users, updateUserSchema } from '@schema';
|
|
183
183
|
|
|
184
184
|
export const actions = {
|
|
185
185
|
update: defineHandler.withValidator({
|
|
@@ -355,20 +355,32 @@ On the server, use `c.req.parseBody()` to access the uploaded file:
|
|
|
355
355
|
|
|
356
356
|
```ts
|
|
357
357
|
// pages/photos.server.ts
|
|
358
|
-
import { defineHandler } from 'void';
|
|
358
|
+
import { defineHandler, ValidationError } from 'void/handler';
|
|
359
359
|
import { storage } from 'void/storage';
|
|
360
360
|
|
|
361
|
+
// file.name and file.type come from the browser. Don't use them as the key or trust the type.
|
|
362
|
+
const imageTypes = new Map([
|
|
363
|
+
['image/jpeg', 'jpg'],
|
|
364
|
+
['image/png', 'png'],
|
|
365
|
+
['image/webp', 'webp'],
|
|
366
|
+
]);
|
|
367
|
+
|
|
361
368
|
export const action = defineHandler(async (c) => {
|
|
362
369
|
const body = await c.req.parseBody();
|
|
363
|
-
const file = body['photo']
|
|
364
|
-
if (file
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
});
|
|
370
|
+
const file = body['photo'];
|
|
371
|
+
if (!(file instanceof File) || file.size === 0) return;
|
|
372
|
+
const ext = imageTypes.get(file.type);
|
|
373
|
+
if (!ext) {
|
|
374
|
+
throw new ValidationError({ photo: 'Upload a JPEG, PNG, or WebP image.' });
|
|
368
375
|
}
|
|
376
|
+
await storage.put(`uploads/${crypto.randomUUID()}.${ext}`, file.stream(), {
|
|
377
|
+
httpMetadata: { contentType: file.type },
|
|
378
|
+
});
|
|
369
379
|
});
|
|
370
380
|
```
|
|
371
381
|
|
|
382
|
+
Pick the storage key on the server and allow only the file types you expect. See [Serving Files](../storage.md#serving-files) to send them back safely.
|
|
383
|
+
|
|
372
384
|
## Choosing a Primitive
|
|
373
385
|
|
|
374
386
|
| Primitive | Page update | Form state | Framework-specific |
|
|
@@ -11,11 +11,11 @@ A loader fetches the data a page needs. Define it in a companion `.server.ts` fi
|
|
|
11
11
|
`loader` runs on GET requests and returns an object that becomes the page's props:
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
+
import { users } from '@schema';
|
|
14
15
|
// pages/users/index.server.ts
|
|
15
16
|
import { defineHandler } from 'void';
|
|
16
17
|
import type { InferProps } from 'void';
|
|
17
18
|
import { db } from 'void/db';
|
|
18
|
-
import { users } from '@schema';
|
|
19
19
|
|
|
20
20
|
export type Props = InferProps<typeof loader>; // [!code highlight]
|
|
21
21
|
|
|
@@ -79,9 +79,9 @@ defineProps<Props>();
|
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
```tsx [Solid]
|
|
82
|
+
import { For } from 'solid-js';
|
|
82
83
|
// pages/users/index.tsx
|
|
83
84
|
import type { Props } from './index.server';
|
|
84
|
-
import { For } from 'solid-js';
|
|
85
85
|
|
|
86
86
|
export default function UsersPage(props: Props) {
|
|
87
87
|
return (
|
|
@@ -102,11 +102,11 @@ export default function UsersPage(props: Props) {
|
|
|
102
102
|
Use `defer()` for slow data. The page renders immediately and receives the result when it is ready:
|
|
103
103
|
|
|
104
104
|
```ts
|
|
105
|
+
import { projects } from '@schema';
|
|
105
106
|
// pages/dashboard.server.ts
|
|
106
107
|
import { defineHandler, defer } from 'void';
|
|
107
108
|
import type { InferProps } from 'void';
|
|
108
109
|
import { db } from 'void/db';
|
|
109
|
-
import { projects } from '@schema';
|
|
110
110
|
|
|
111
111
|
export type Props = InferProps<typeof loader>;
|
|
112
112
|
|
|
@@ -157,6 +157,10 @@ around the Suspense boundary when the page should render a custom failure state.
|
|
|
157
157
|
For explicit React prop annotations, import `Deferred` from `@void/react`; the
|
|
158
158
|
adapter export is typed as `Promise<T>`.
|
|
159
159
|
|
|
160
|
+
In production, an unexpected error in a deferred prop reaches the page as
|
|
161
|
+
`Internal Server Error`; throw an
|
|
162
|
+
[`HTTPException`](../../integrations/hono.md#utilities) to show your own message.
|
|
163
|
+
|
|
160
164
|
In Vue, Svelte, and Solid, `Deferred<T>` behaves as a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions) with three states:
|
|
161
165
|
|
|
162
166
|
```ts
|
|
@@ -64,11 +64,11 @@ Add the plugin to your Vite config **after** the framework adapter:
|
|
|
64
64
|
::: code-group
|
|
65
65
|
|
|
66
66
|
```ts [React]
|
|
67
|
+
import { voidMarkdown } from '@void/md/plugin';
|
|
68
|
+
import { voidReact } from '@void/react/plugin';
|
|
67
69
|
// vite.config.ts
|
|
68
70
|
import { defineConfig } from 'vite';
|
|
69
71
|
import { voidPlugin } from 'void';
|
|
70
|
-
import { voidReact } from '@void/react/plugin';
|
|
71
|
-
import { voidMarkdown } from '@void/md/plugin';
|
|
72
72
|
|
|
73
73
|
export default defineConfig({
|
|
74
74
|
plugins: [voidPlugin(), voidReact(), voidMarkdown()],
|
|
@@ -76,11 +76,11 @@ export default defineConfig({
|
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
```ts [Vue]
|
|
79
|
+
import { voidMarkdown } from '@void/md/plugin';
|
|
80
|
+
import { voidVue } from '@void/vue/plugin';
|
|
79
81
|
// vite.config.ts
|
|
80
82
|
import { defineConfig } from 'vite';
|
|
81
83
|
import { voidPlugin } from 'void';
|
|
82
|
-
import { voidVue } from '@void/vue/plugin';
|
|
83
|
-
import { voidMarkdown } from '@void/md/plugin';
|
|
84
84
|
|
|
85
85
|
export default defineConfig({
|
|
86
86
|
plugins: [voidPlugin(), voidVue(), voidMarkdown()],
|
|
@@ -88,11 +88,11 @@ export default defineConfig({
|
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
```ts [Svelte]
|
|
91
|
+
import { voidMarkdown } from '@void/md/plugin';
|
|
92
|
+
import { voidSvelte } from '@void/svelte/plugin';
|
|
91
93
|
// vite.config.ts
|
|
92
94
|
import { defineConfig } from 'vite';
|
|
93
95
|
import { voidPlugin } from 'void';
|
|
94
|
-
import { voidSvelte } from '@void/svelte/plugin';
|
|
95
|
-
import { voidMarkdown } from '@void/md/plugin';
|
|
96
96
|
|
|
97
97
|
export default defineConfig({
|
|
98
98
|
plugins: [voidPlugin(), voidSvelte(), voidMarkdown()],
|
|
@@ -100,11 +100,11 @@ export default defineConfig({
|
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
```ts [Solid]
|
|
103
|
+
import { voidMarkdown } from '@void/md/plugin';
|
|
104
|
+
import { voidSolid } from '@void/solid/plugin';
|
|
103
105
|
// vite.config.ts
|
|
104
106
|
import { defineConfig } from 'vite';
|
|
105
107
|
import { voidPlugin } from 'void';
|
|
106
|
-
import { voidSolid } from '@void/solid/plugin';
|
|
107
|
-
import { voidMarkdown } from '@void/md/plugin';
|
|
108
108
|
|
|
109
109
|
export default defineConfig({
|
|
110
110
|
plugins: [voidPlugin(), voidSolid(), voidMarkdown()],
|
|
@@ -401,7 +401,7 @@ Code blocks include a copy button.
|
|
|
401
401
|
|
|
402
402
|
### Line Numbers
|
|
403
403
|
|
|
404
|
-
Enable per code block with `:line-numbers
|
|
404
|
+
Enable per code block with `:line-numbers`:
|
|
405
405
|
|
|
406
406
|
````md
|
|
407
407
|
```ts :line-numbers
|
|
@@ -412,14 +412,6 @@ const b = 2;
|
|
|
412
412
|
|
|
413
413
|
Start from a specific number with `:line-numbers=5`.
|
|
414
414
|
|
|
415
|
-
### Snippet Imports
|
|
416
|
-
|
|
417
|
-
Import code from external files:
|
|
418
|
-
|
|
419
|
-
```md
|
|
420
|
-
<<< ./path/to/file.ts
|
|
421
|
-
```
|
|
422
|
-
|
|
423
415
|
### Emoji
|
|
424
416
|
|
|
425
417
|
Shortcodes convert to unicode: `:tada:` becomes :tada:, `:rocket:` becomes :rocket:.
|
|
@@ -455,16 +447,16 @@ Headings include permalink anchors. Use `[[toc]]` for a table of contents. Image
|
|
|
455
447
|
```ts
|
|
456
448
|
voidMarkdown({
|
|
457
449
|
shiki: {
|
|
458
|
-
themes: { light: 'github-light', dark: 'github-dark' },
|
|
459
|
-
langs: ['sql', 'graphql'], // additional languages
|
|
450
|
+
themes: { light: 'github-light', dark: 'github-dark' },
|
|
460
451
|
},
|
|
461
452
|
});
|
|
462
453
|
```
|
|
463
454
|
|
|
464
|
-
| Option | Type | Default | Description
|
|
465
|
-
| -------------- | -------------------------------- | ------------------------------------------------ |
|
|
466
|
-
| `shiki.themes` | `{ light: string; dark: string}` | `{ light: "github-light", dark: "github-dark" }` | Shiki color themes
|
|
467
|
-
|
|
455
|
+
| Option | Type | Default | Description |
|
|
456
|
+
| -------------- | -------------------------------- | ------------------------------------------------ | ------------------ |
|
|
457
|
+
| `shiki.themes` | `{ light: string; dark: string}` | `{ light: "github-light", dark: "github-dark" }` | Shiki color themes |
|
|
458
|
+
|
|
459
|
+
Code block languages load on demand from Shiki's bundled languages.
|
|
468
460
|
|
|
469
461
|
## Building a Sidebar
|
|
470
462
|
|
|
@@ -41,10 +41,10 @@ Add both plugins to your Vite config:
|
|
|
41
41
|
::: code-group
|
|
42
42
|
|
|
43
43
|
```ts [React]
|
|
44
|
+
import { voidReact } from '@void/react/plugin';
|
|
44
45
|
// vite.config.ts
|
|
45
46
|
import { defineConfig } from 'vite';
|
|
46
47
|
import { voidPlugin } from 'void';
|
|
47
|
-
import { voidReact } from '@void/react/plugin';
|
|
48
48
|
|
|
49
49
|
export default defineConfig({
|
|
50
50
|
plugins: [voidPlugin(), voidReact()],
|
|
@@ -52,10 +52,10 @@ export default defineConfig({
|
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
```ts [Vue]
|
|
55
|
+
import { voidVue } from '@void/vue/plugin';
|
|
55
56
|
// vite.config.ts
|
|
56
57
|
import { defineConfig } from 'vite';
|
|
57
58
|
import { voidPlugin } from 'void';
|
|
58
|
-
import { voidVue } from '@void/vue/plugin';
|
|
59
59
|
|
|
60
60
|
export default defineConfig({
|
|
61
61
|
plugins: [voidPlugin(), voidVue()],
|
|
@@ -63,10 +63,10 @@ export default defineConfig({
|
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
```ts [Svelte]
|
|
66
|
+
import { voidSvelte } from '@void/svelte/plugin';
|
|
66
67
|
// vite.config.ts
|
|
67
68
|
import { defineConfig } from 'vite';
|
|
68
69
|
import { voidPlugin } from 'void';
|
|
69
|
-
import { voidSvelte } from '@void/svelte/plugin';
|
|
70
70
|
|
|
71
71
|
export default defineConfig({
|
|
72
72
|
plugins: [voidPlugin(), voidSvelte()],
|
|
@@ -74,10 +74,10 @@ export default defineConfig({
|
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
```ts [Solid]
|
|
77
|
+
import { voidSolid } from '@void/solid/plugin';
|
|
77
78
|
// vite.config.ts
|
|
78
79
|
import { defineConfig } from 'vite';
|
|
79
80
|
import { voidPlugin } from 'void';
|
|
80
|
-
import { voidSolid } from '@void/solid/plugin';
|
|
81
81
|
|
|
82
82
|
export default defineConfig({
|
|
83
83
|
plugins: [voidPlugin(), voidSolid()],
|
|
@@ -212,6 +212,8 @@ router.refresh(); // re-fetch current page props
|
|
|
212
212
|
router.visit('/logout', { method: 'POST' }); // non-GET navigation
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
+
`router.visit()` updates the page in place for same-origin URLs. `http(s)` URLs on another origin get a full page load, and other schemes such as `javascript:` are rejected.
|
|
216
|
+
|
|
215
217
|
For dynamic route params, use `useParams()` from the same adapter package:
|
|
216
218
|
|
|
217
219
|
```tsx
|
|
@@ -30,15 +30,7 @@ the company sign-in before Void login. Interactive Access authentication uses a
|
|
|
30
30
|
locally installed `cloudflared` and saves its short-lived credential in your
|
|
31
31
|
system keychain for that platform origin. You do not need to copy browser cookies.
|
|
32
32
|
|
|
33
|
-
For CI, use a [project deploy token](/guide/platform/installation/first-deployment) alongside your Access credentials
|
|
34
|
-
|
|
35
|
-
Store Access credentials in origin-keyed `VOID_ACCESS_CREDENTIALS`. A deploy
|
|
36
|
-
that uses prerendering or remote bindings needs entries for both the exact API
|
|
37
|
-
and proxy HTTPS origins, even when both entries contain the same admitted
|
|
38
|
-
service-token pair. `VOID_ACCESS_ORIGIN` selects only one recipient and therefore
|
|
39
|
-
cannot cover both calls. Keep the JSON value in your secret manager, not in
|
|
40
|
-
application configuration. See [CI deployment setup](/guide/platform/installation/first-deployment)
|
|
41
|
-
for the required shape.
|
|
33
|
+
For CI, use a [project deploy token](/guide/platform/installation/first-deployment) alongside your Access credentials in origin-keyed `VOID_ACCESS_CREDENTIALS`. An Access service token does not authorize a Void deployment. See [CI deployment setup](/guide/platform/installation/first-deployment) for the required origins and shape.
|
|
42
34
|
|
|
43
35
|
## Choosing a Platform
|
|
44
36
|
|
|
@@ -165,4 +157,4 @@ void platform invitation list
|
|
|
165
157
|
Invitation history remains available after an involved account is removed. The stored actor ID
|
|
166
158
|
remains visible when that account's login no longer exists.
|
|
167
159
|
|
|
168
|
-
`void platform signup open` allows anyone to sign up. Use `void platform signup restrict` to require an allowlist match again. Disallowing an entry affects future signup; it does not suspend an existing account.
|
|
160
|
+
`void platform signup open` allows anyone to sign up. Everyone who signs up can deploy apps on your application domain, so check how those apps [share cookies](/guide/platform/installation/domains#adding-a-domain) before opening signup. Use `void platform signup restrict` to require an allowlist match again. Disallowing an entry affects future signup; it does not suspend an existing account.
|
|
@@ -66,18 +66,9 @@ The dashboard’s **System Status** page refreshes health checks every 30 second
|
|
|
66
66
|
|
|
67
67
|
Use `void platform upgrade`, `repair`, `disable`, and `enable` to maintain your platform. See [platform maintenance](/guide/platform/installation/maintenance#resume-repair-recover-and-upgrade).
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
refreshes automatically and shows saved progress and the API's traffic state
|
|
73
|
-
while the API and authentication database remain reachable. If a status refresh
|
|
74
|
-
fails, the last confirmed snapshot is marked as stale. Normal administrator
|
|
75
|
-
changes stay paused during maintenance.
|
|
76
|
-
If the CLI reports an error or a waiting state, follow its recovery instructions
|
|
77
|
-
to resume the operation. See
|
|
78
|
-
[Follow upgrade and rollback progress](/guide/platform/installation/maintenance#follow-upgrade-and-rollback-progress).
|
|
79
|
-
|
|
80
|
-
For disaster recovery, keep a matching PostgreSQL backup, provider data backups, installation identity and complete project-encryption keyring, and immutable runtime artifacts. Keep traffic disabled while restoring data, run `discover` to reconstruct verified local metadata, and review `repair --plan` before recreating missing installer-owned infrastructure. Neither command restores backed-up data. See [Prepare for disaster recovery](/guide/platform/installation/maintenance#prepare-for-disaster-recovery) for the full sequence.
|
|
69
|
+
During an upgrade or rollback, the admin UI shows progress at `/admin/status`. See [Follow upgrade and rollback progress](/guide/platform/installation/maintenance#follow-upgrade-and-rollback-progress).
|
|
70
|
+
|
|
71
|
+
For backups and restores, see [Prepare for disaster recovery](/guide/platform/installation/maintenance#prepare-for-disaster-recovery).
|
|
81
72
|
|
|
82
73
|
## Using Scripts
|
|
83
74
|
|
|
@@ -23,7 +23,7 @@ void platform project show <project-id>
|
|
|
23
23
|
|
|
24
24
|
Project details include resources, domains, and recent builds and deployments. The [command reference](../../../reference/cli/platform.md#operator-commands) also covers suspending and restoring users, deleting projects, and removing accounts.
|
|
25
25
|
|
|
26
|
-
In the admin dashboard, open a project to view its team. Search for a platform user and choose a role to add them immediately; an email address is not required. You can also change or remove existing members. Pending invitations created through other project workflows remain visible until accepted or revoked. If email is unavailable for a pending invitation, share its ID so the user can accept it with `void project team accept <invitation-id>`. The owner cannot be removed from the team; transfer ownership first.
|
|
26
|
+
In the admin dashboard, open a project to view its team. Search for a platform user and choose a role to add them immediately; an email address is not required. You can also change or remove existing members. Pending invitations created through other project workflows remain visible until accepted or revoked. If email is unavailable for a pending invitation, share its ID so the user can accept it with `void project team accept <invitation-id>`. The owner cannot be removed from the team; transfer ownership first. Removing a collaborator or admin, changing one to reader, or suspending or deleting their account [replaces the project's platform credentials](../../project-collaboration.md#change-or-remove-access), the same as the CLI.
|
|
27
27
|
|
|
28
28
|
### Transferring Project Ownership
|
|
29
29
|
|
|
@@ -36,7 +36,7 @@ Use the Node.js version recorded in `.node-version`.
|
|
|
36
36
|
|
|
37
37
|
The `@voidcloud/*` names identify workspace implementation packages. Their `private: true` flags prevent publishing those packages to npm. Deployable core Workers are bundled into the public `@void/platform` package.
|
|
38
38
|
|
|
39
|
-
The core installer creates the API, dispatch, proxy, and
|
|
39
|
+
The core installer creates the API, dispatch, proxy, tail, and email gateway Workers. The dashboard and managed GitHub build services are available in the source tree but are not included in that installation. Adding an optional service requires its infrastructure, bindings, authentication, and capability configuration together.
|
|
40
40
|
|
|
41
41
|
## Running the API Locally
|
|
42
42
|
|
|
@@ -44,7 +44,7 @@ Start a local PostgreSQL server and make `psql` and `pg_isready` available on yo
|
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
46
|
vp run --filter @voidcloud/api setup --admin-email dev@example.com
|
|
47
|
-
vp run --filter @voidcloud/api dev
|
|
47
|
+
vp run --filter @voidcloud/api dev:admin
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
The command disables the optional build containers, so basic API and admin work
|
|
@@ -55,6 +55,8 @@ Open `http://localhost:8787/admin/`. Setup writes the API's local database conne
|
|
|
55
55
|
|
|
56
56
|
The API's development bypass lets you work on the browser admin UI without setting up OAuth. Operator CLI sessions still require administrator authentication; they do not use the browser bypass.
|
|
57
57
|
|
|
58
|
+
`dev:admin` watches source files and automatically reloads the browser after edits. Keep it running while working on the admin dashboard's React components and styles; no platform deployment is needed. The setup includes sample users, projects, and deployments for trying each view locally.
|
|
59
|
+
|
|
58
60
|
## Running the Dashboard Locally
|
|
59
61
|
|
|
60
62
|
The dashboard is a separate source app. After API setup, start it in another terminal:
|
|
@@ -25,7 +25,7 @@ void-dev platform install \
|
|
|
25
25
|
--plan
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Before applying the plan, complete the [installation guides](/guide/self-hosted-platform). Run the command without `--plan` to install. For testing before your domain is ready, replace `--application-domain` and `--zone` with `--workers-dev`; PostgreSQL and the runtime
|
|
28
|
+
Before applying the plan, complete the [installation guides](/guide/self-hosted-platform). Run the command without `--plan` to install. For testing before your domain is ready, replace `--application-domain` and `--zone` with `--workers-dev`; PostgreSQL and the runtime, login-provider, and R2 credentials are still needed. Use `void-dev` in place of `void` and keep `--runtime packages/platform/dist/runtime` on install and resume commands. For an interrupted installation, keep that runtime build available until it completes.
|
|
29
29
|
|
|
30
30
|
Later, run `void-dev platform domain set example.app`. Domain setup uses the existing installed runtime and needs no `--runtime`, rebuild, or app redeploy. It keeps the platform API URL and original workers.dev app URLs available.
|
|
31
31
|
|
|
@@ -20,7 +20,7 @@ Review the generated SQL and migration journal before committing them. Released
|
|
|
20
20
|
|
|
21
21
|
`@void/platform` contains installation manifests, resource naming, discovery contracts, Worker configuration, and deployable bundles under the `./installer` export. Platform source lives in `platform/packages/`.
|
|
22
22
|
|
|
23
|
-
Runtime artifacts include migration SQL, its journal, and a rollback compatibility manifest. Drizzle authoring snapshots remain in the source tree.
|
|
23
|
+
Runtime artifacts include migration SQL, its journal, and a rollback compatibility manifest. Drizzle authoring snapshots remain in the source tree.
|
|
24
24
|
|
|
25
25
|
## CI in a Fork
|
|
26
26
|
|
|
@@ -23,6 +23,8 @@ Choose an application domain whose wildcard leaves existing Worker Custom Domain
|
|
|
23
23
|
|
|
24
24
|
Browser login sessions are specific to each origin. Apps using their own OAuth providers may need to register their new callback URLs. Void's built-in auth uses the request origin automatically unless the app overrides that configuration.
|
|
25
25
|
|
|
26
|
+
Apps on one application domain can set cookies that the other apps there receive. With a nested domain such as `apps.example.com`, apps can also set cookies for `example.com` and its other subdomains. Apps on `workers.dev` testing URLs can set cookies that every Worker on your account's `workers.dev` subdomain receives. If people outside your team can deploy, use a domain that serves only Void apps. A platform that serves thousands of independent developers can also apply to list its application domain on the [Public Suffix List](https://github.com/publicsuffix/list/wiki/Guidelines).
|
|
27
|
+
|
|
26
28
|
### What Changes in Testing Mode?
|
|
27
29
|
|
|
28
30
|
In testing mode, each app gets a `workers.dev` URL. These URLs continue working after you add a domain; new apps then use the domain.
|
|
@@ -91,7 +93,7 @@ New platform resources use deterministic `void-<installation-name>-<role>` names
|
|
|
91
93
|
| Workers | 5, plus one per app using workers.dev | API/control plane, proxy, tail ingestion, dispatch, email gateway, and test-origin forwarders |
|
|
92
94
|
| KV namespaces | 3 | Routing, ISR cache, and static asset storage |
|
|
93
95
|
| R2 buckets | 1 | Static and deployment assets |
|
|
94
|
-
| Queues |
|
|
96
|
+
| Queues | 3 | Usage events, cron firing, and deployments |
|
|
95
97
|
| Workers for Platforms dispatch namespaces | 1 | User application Workers |
|
|
96
98
|
| Hyperdrive configurations | 1 | External platform PostgreSQL |
|
|
97
99
|
| AI Gateways | 1 | Installation-isolated AI routing and metering |
|
|
@@ -4,6 +4,8 @@ outline: deep
|
|
|
4
4
|
|
|
5
5
|
# First Deployment
|
|
6
6
|
|
|
7
|
+
Open your platform's API URL in a browser to see its welcome page, CLI connection instructions, and a link to the administrator dashboard. Share this URL with teammates so they can connect to your platform.
|
|
8
|
+
|
|
7
9
|
First verify the new platform and sign in with the administrator login method selected during setup:
|
|
8
10
|
|
|
9
11
|
```sh
|
|
@@ -83,7 +85,7 @@ void platform signup allow github teammate
|
|
|
83
85
|
|
|
84
86
|
Void shows the proposed access change and asks you to confirm it. Once approved, `teammate` can connect to the platform's API URL and sign in with GitHub.
|
|
85
87
|
|
|
86
|
-
To
|
|
88
|
+
To allow email addresses, domains, or OIDC identities, or to open signup, see [Giving People Access](/guide/platform/administration/access#giving-people-access).
|
|
87
89
|
|
|
88
90
|
Your administrator session lasts for one hour. Use it to inspect users, projects, logs, and platform health. The [Platform Administration guide](/guide/platform-administration) walks through those workflows, previews, and automation. You can also open `<API origin>/admin/login` to use the browser admin UI.
|
|
89
91
|
|
|
@@ -98,6 +98,10 @@ void platform rollback [id] --runtime /path/to/earlier/runtime
|
|
|
98
98
|
|
|
99
99
|
Keep the earlier runtime files if you need rollback. If the installed version is a custom build, also pass its files with `--from-runtime /path/to/current/runtime`. Void checks that the earlier version can run against your current database and refuses incompatible rollbacks. A later `upgrade` can move forward again. See [Platform Development](/guide/platform/development/runtime#deploying-your-runtime) for working with custom builds.
|
|
100
100
|
|
|
101
|
+
Do not roll back to 0.26.0 or earlier after upgrading to a later release. Void does not refuse this rollback, but those releases reject the credentials that later releases give your apps. Every project deployed or rotated since the upgrade loses AI, email, ISR revalidation, remote D1, KV, and R2, and prerendering until you upgrade again. If you have rolled back that far, upgrade again, then run `void platform system rotate-proxy-tokens --all --yes` and check with `--plan` until nothing is pending or failed.
|
|
102
|
+
|
|
103
|
+
Let running rotations finish before you roll back. If an older proxy runs next to a newer API, prerendering and remote D1, KV, and R2 fail until both run the same release. After a rollback to the release just before credential rotation, projects deployed since the upgrade lose prerendering and remote D1, KV, and R2 until they are deployed again or you upgrade again. A rotated project deployed during any rollback stays broken after you upgrade again, and 0.26.0 and earlier also drop rotations that have not finished. After upgrading again from any rollback, run the same `rotate-proxy-tokens` commands.
|
|
104
|
+
|
|
101
105
|
:::
|
|
102
106
|
|
|
103
107
|
### Follow upgrade and rollback progress
|
|
@@ -66,8 +66,8 @@ An invitation is bound to the registered account. Forwarding its ID does not let
|
|
|
66
66
|
These three commands use the active platform connection selected by
|
|
67
67
|
`void connect`, even inside a directory linked to another project or deployed
|
|
68
68
|
directly to Cloudflare. `VOID_API_URL` takes precedence when set. If you use
|
|
69
|
-
`VOID_TOKEN`, set `VOID_API_URL` to the matching platform
|
|
70
|
-
|
|
69
|
+
`VOID_TOKEN`, also set `VOID_API_URL` to the matching platform. Each command
|
|
70
|
+
shows the platform it contacts.
|
|
71
71
|
|
|
72
72
|
Accepting an invitation grants access without linking your current directory.
|
|
73
73
|
Open the invited application's directory and run `void project link` if it is
|
|
@@ -92,3 +92,7 @@ void project team revoke <invitation-id>
|
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
A non-owner member can leave with `void project team leave`. The owner cannot leave; an installation administrator must [transfer ownership](./platform/administration/projects.md#transferring-project-ownership) first.
|
|
95
|
+
|
|
96
|
+
When a collaborator or admin is removed, leaves, or is changed to reader, the platform replaces the credentials the project's Workers use to call platform services such as AI, email, and remote bindings. The old credentials stop working once every Worker of the project has the new ones, usually within about 10 minutes, later while a deploy is running. If the replacement cannot finish, the old credentials keep working until it does, and owners and admins see a warning in `void project status` and `void project team list`. WebSocket connections reconnect once. While a Worker is switched to the new credentials, its calls to platform services can fail for a moment, a scheduled run can be skipped, and queue messages are delivered again a couple of minutes later.
|
|
97
|
+
|
|
98
|
+
Code the removed person deployed keeps running until you replace it. If you no longer trust it, deploy code you trust; the platform replaces the credentials again after that deploy. Earlier deployments of theirs kept for rollback keep the old credentials, so after a rollback to one of them, AI, email, and ISR revalidation fail until you deploy again.
|
|
@@ -137,6 +137,4 @@ curl -X POST http://localhost:5173/__void/queue \
|
|
|
137
137
|
-d '{"queue":"my-queue","messages":[{"id":"1","timestamp":'"$(date +%s000)"',"body":{"hello":"world"},"attempts":1}]}'
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
If you set `__VOID_PROXY_TOKEN` in `.env`, that explicit token takes precedence and the printed curl command uses `x-void-internal: <your-token>` instead.
|
|
141
|
-
|
|
142
140
|
In supported meta-frameworks, use `/__void/queue` to test a consumer manually. It runs inside the framework adapter's development runtime with that adapter's bindings. Sending to a queue binding doesn't automatically invoke the consumer in this mode.
|
|
@@ -49,16 +49,16 @@ AI requests use your platform’s account and allowance in both local and remote
|
|
|
49
49
|
When the dev server starts with remote mode active, it prints:
|
|
50
50
|
|
|
51
51
|
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
[void] Remote bindings active
|
|
53
|
+
DB → remote D1
|
|
54
|
+
KV → remote KV
|
|
55
|
+
STORAGE → remote R2
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## Limitations
|
|
59
59
|
|
|
60
60
|
- **Network latency:** each binding call makes a network request, so responses may be slower than local development.
|
|
61
61
|
- **R2 multipart uploads:** `createMultipartUpload()` and `resumeMultipartUpload()` are not supported in remote mode.
|
|
62
|
-
- **R2 conditional writes:** `put(..., { onlyIf })` requires
|
|
62
|
+
- **R2 conditional writes:** `put(..., { onlyIf })` requires an updated platform and project deployment. Failed preconditions return `null`.
|
|
63
63
|
- **D1 dump:** `db.dump()` is not supported in remote mode.
|
|
64
64
|
- **D1 batches:** `db.batch()` requires an updated platform and project deployment.
|