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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as join, n as dirname, o as normalize, t as basename } from "./dist-BVqXeR_h.mjs";
|
|
2
2
|
import "./project-paths-GgcMozYz.mjs";
|
|
3
|
-
import { m as readConfig } from "./config-
|
|
4
|
-
import { a as hasSandboxSqliteMigration, c as resolveSandboxConfig, i as assertSandboxNamespaceConfig, l as sandboxContainerConfig, r as SANDBOX_MIGRATION_TAG } from "./config-
|
|
5
|
-
import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-
|
|
3
|
+
import { m as readConfig } from "./config-DiowPT80.mjs";
|
|
4
|
+
import { a as hasSandboxSqliteMigration, c as resolveSandboxConfig, i as assertSandboxNamespaceConfig, l as sandboxContainerConfig, r as SANDBOX_MIGRATION_TAG } from "./config-B_ggY-IO.mjs";
|
|
5
|
+
import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-BmhBv3HV.mjs";
|
|
6
6
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { appendSqliteClassMigration, isRecord } from "@void/deploy-core";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
@@ -18,9 +18,39 @@ function projectWranglerPaths(root) {
|
|
|
18
18
|
if (existsSync(join(root, "void.config.ts"))) return [materializeCloudflareConfig(root)];
|
|
19
19
|
return ["wrangler.jsonc", "wrangler.json"].map((name) => join(root, name));
|
|
20
20
|
}
|
|
21
|
+
/** Record a change to the generated Cloudflare config in `void.lock.json`. */
|
|
22
|
+
function persistMaterializedWranglerConfig(configPath) {
|
|
23
|
+
if (basename(configPath) === ".void-wrangler.jsonc") persistCloudflareConfig(dirname(configPath));
|
|
24
|
+
}
|
|
21
25
|
function writeProjectWranglerFile(configPath, text) {
|
|
22
26
|
writeFileSync(configPath, text);
|
|
23
|
-
|
|
27
|
+
persistMaterializedWranglerConfig(configPath);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read the first existing project Wrangler config. A missing or unparseable one is
|
|
31
|
+
* replaced by the generated config, starting from an empty object.
|
|
32
|
+
*/
|
|
33
|
+
function readOrCreateProjectWranglerConfig(root) {
|
|
34
|
+
const configPath = projectWranglerPaths(root).find((path) => existsSync(path));
|
|
35
|
+
if (configPath) {
|
|
36
|
+
let parsed;
|
|
37
|
+
try {
|
|
38
|
+
parsed = parseJsonc(readFileSync(configPath, "utf-8"));
|
|
39
|
+
} catch {}
|
|
40
|
+
if (parsed) return {
|
|
41
|
+
configPath,
|
|
42
|
+
parsed,
|
|
43
|
+
created: false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
configPath: materializeCloudflareConfig(root),
|
|
48
|
+
parsed: {},
|
|
49
|
+
created: true
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function durableObjectBindingsOf(config) {
|
|
53
|
+
return config.durable_objects?.bindings ?? [];
|
|
24
54
|
}
|
|
25
55
|
const MANAGED_QUEUES_MARKER = /^\s*\/\/ void:managed-queues:v1:([A-Za-z0-9_-]+)\s*$/m;
|
|
26
56
|
const PUBLISHED_TRAFFIC_MARKER = /^\s*\/\/ void:published-traffic:v1:([A-Za-z0-9_-]+)\s*$/m;
|
|
@@ -241,21 +271,7 @@ function ensureVoidCompatibilityDate(root, config) {
|
|
|
241
271
|
* Returns true if the file was modified.
|
|
242
272
|
*/
|
|
243
273
|
function syncWranglerBindings(root, bindings, options) {
|
|
244
|
-
|
|
245
|
-
let parsed;
|
|
246
|
-
let created = false;
|
|
247
|
-
for (const p of projectWranglerPaths(root)) if (existsSync(p)) {
|
|
248
|
-
configPath = p;
|
|
249
|
-
try {
|
|
250
|
-
parsed = parseJsonc(readFileSync(p, "utf-8"));
|
|
251
|
-
} catch {}
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
if (!configPath || !parsed) {
|
|
255
|
-
configPath = materializeCloudflareConfig(root);
|
|
256
|
-
parsed = {};
|
|
257
|
-
created = true;
|
|
258
|
-
}
|
|
274
|
+
const { configPath, parsed, created } = readOrCreateProjectWranglerConfig(root);
|
|
259
275
|
let modified = false;
|
|
260
276
|
const d1Name = options?.bindingNames?.d1 ?? "DB";
|
|
261
277
|
if (bindings.needsD1) {
|
|
@@ -317,18 +333,17 @@ function syncWranglerBindings(root, bindings, options) {
|
|
|
317
333
|
}
|
|
318
334
|
}
|
|
319
335
|
if (options?.websockets) {
|
|
320
|
-
const existing = parsed
|
|
336
|
+
const existing = durableObjectBindingsOf(parsed);
|
|
321
337
|
const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
|
|
322
|
-
const retained = existing;
|
|
323
338
|
for (const route of options.websockets) {
|
|
324
|
-
const conflict =
|
|
339
|
+
const conflict = existing.find((binding) => binding.name === route.bindingName && binding.class_name !== route.className);
|
|
325
340
|
if (conflict) throw new Error(`websocket: binding '${route.bindingName}' is already configured for class '${conflict.class_name}', but '${route.filePath}' requires '${route.className}'.`);
|
|
326
341
|
}
|
|
327
|
-
const additions = options.websockets.filter((route) => !
|
|
342
|
+
const additions = options.websockets.filter((route) => !existing.some((binding) => binding.name === route.bindingName)).map((route) => ({
|
|
328
343
|
name: route.bindingName,
|
|
329
344
|
class_name: route.className
|
|
330
345
|
}));
|
|
331
|
-
const nextBindings = [...
|
|
346
|
+
const nextBindings = [...existing, ...additions];
|
|
332
347
|
if (nextBindings.length !== existing.length || nextBindings.some((binding, index) => binding.name !== existing[index]?.name || binding.class_name !== existing[index]?.class_name)) {
|
|
333
348
|
parsed.durable_objects = {
|
|
334
349
|
...parsed.durable_objects ?? {},
|
|
@@ -336,14 +351,14 @@ function syncWranglerBindings(root, bindings, options) {
|
|
|
336
351
|
};
|
|
337
352
|
modified = true;
|
|
338
353
|
}
|
|
339
|
-
const planned = appendSqliteClassMigration(migrations, options.websockets.map((route) => route.className), "void-ws-v1",
|
|
354
|
+
const planned = appendSqliteClassMigration(migrations, options.websockets.map((route) => route.className), "void-ws-v1", existing.map((binding) => binding.class_name));
|
|
340
355
|
if (planned.added) {
|
|
341
356
|
parsed.migrations = planned.migrations;
|
|
342
357
|
modified = true;
|
|
343
358
|
}
|
|
344
359
|
}
|
|
345
360
|
if (options?.durableObjects && options.durableObjects.length > 0) {
|
|
346
|
-
const existingBindings = parsed
|
|
361
|
+
const existingBindings = durableObjectBindingsOf(parsed);
|
|
347
362
|
for (const module of options.durableObjects) {
|
|
348
363
|
const conflict = existingBindings.find((binding) => binding.name === module.bindingName && binding.class_name !== module.className);
|
|
349
364
|
if (conflict) throw new Error(`durable: binding '${module.bindingName}' is already configured for class '${conflict.class_name}', but durable-objects/ requires '${module.className}'.`);
|
|
@@ -374,7 +389,7 @@ function syncWranglerBindings(root, bindings, options) {
|
|
|
374
389
|
const bindingName = options?.bindingNames?.sandbox ?? sandbox?.binding ?? "SANDBOX";
|
|
375
390
|
const className = sandbox.className;
|
|
376
391
|
assertSandboxNamespaceConfig(parsed, sandbox);
|
|
377
|
-
const existingDurableObjectBindings = parsed
|
|
392
|
+
const existingDurableObjectBindings = durableObjectBindingsOf(parsed);
|
|
378
393
|
if (!existingDurableObjectBindings.some((binding) => binding.name === bindingName)) {
|
|
379
394
|
parsed.durable_objects = { bindings: [...existingDurableObjectBindings, {
|
|
380
395
|
name: bindingName,
|
|
@@ -398,7 +413,7 @@ function syncWranglerBindings(root, bindings, options) {
|
|
|
398
413
|
}
|
|
399
414
|
}
|
|
400
415
|
if (bindings.needsLive || options?.live) {
|
|
401
|
-
const existingDurableObjectBindings = parsed
|
|
416
|
+
const existingDurableObjectBindings = durableObjectBindingsOf(parsed);
|
|
402
417
|
const liveConfig = typeof options?.live === "object" ? options.live : resolveLiveBindingConfig(root, {
|
|
403
418
|
existingBindings: existingDurableObjectBindings,
|
|
404
419
|
reservedBindings: options?.websockets?.map((route) => route.bindingName),
|
|
@@ -466,19 +481,7 @@ function readWranglerWebSocketTombstones(root, websockets) {
|
|
|
466
481
|
*/
|
|
467
482
|
function ensureWranglerCompatibilityDate(root, compatibilityDate) {
|
|
468
483
|
validateCompatDate(compatibilityDate, "void.json worker config");
|
|
469
|
-
|
|
470
|
-
let parsed;
|
|
471
|
-
for (const p of projectWranglerPaths(root)) if (existsSync(p)) {
|
|
472
|
-
configPath = p;
|
|
473
|
-
try {
|
|
474
|
-
parsed = parseJsonc(readFileSync(p, "utf-8"));
|
|
475
|
-
} catch {}
|
|
476
|
-
break;
|
|
477
|
-
}
|
|
478
|
-
if (!configPath || !parsed) {
|
|
479
|
-
configPath = materializeCloudflareConfig(root);
|
|
480
|
-
parsed = {};
|
|
481
|
-
}
|
|
484
|
+
const { configPath, parsed } = readOrCreateProjectWranglerConfig(root);
|
|
482
485
|
if (parsed.compatibility_date === compatibilityDate) return false;
|
|
483
486
|
parsed.compatibility_date = compatibilityDate;
|
|
484
487
|
writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
|
|
@@ -489,19 +492,7 @@ function ensureWranglerCompatibilityDate(root, compatibilityDate) {
|
|
|
489
492
|
* Returns true if the config file was modified.
|
|
490
493
|
*/
|
|
491
494
|
function ensureWranglerNodejsAlsFlag(root) {
|
|
492
|
-
|
|
493
|
-
let parsed;
|
|
494
|
-
for (const p of projectWranglerPaths(root)) if (existsSync(p)) {
|
|
495
|
-
configPath = p;
|
|
496
|
-
try {
|
|
497
|
-
parsed = parseJsonc(readFileSync(p, "utf-8"));
|
|
498
|
-
} catch {}
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
if (!configPath || !parsed) {
|
|
502
|
-
configPath = materializeCloudflareConfig(root);
|
|
503
|
-
parsed = {};
|
|
504
|
-
}
|
|
495
|
+
const { configPath, parsed } = readOrCreateProjectWranglerConfig(root);
|
|
505
496
|
const compatibilityFlags = Array.isArray(parsed.compatibility_flags) ? parsed.compatibility_flags : [];
|
|
506
497
|
if (compatibilityFlags.includes(NODEJS_ALS_FLAG)) return false;
|
|
507
498
|
parsed.compatibility_flags = [...compatibilityFlags, NODEJS_ALS_FLAG];
|
|
@@ -509,30 +500,24 @@ function ensureWranglerNodejsAlsFlag(root) {
|
|
|
509
500
|
return true;
|
|
510
501
|
}
|
|
511
502
|
function readManagedQueueProvenance(text) {
|
|
512
|
-
const
|
|
513
|
-
if (!encoded) return {
|
|
503
|
+
const none = {
|
|
514
504
|
producerBindings: [],
|
|
515
505
|
consumerQueues: [],
|
|
516
506
|
pendingConsumerRemovals: []
|
|
517
507
|
};
|
|
508
|
+
const encoded = MANAGED_QUEUES_MARKER.exec(text)?.[1];
|
|
509
|
+
if (!encoded) return none;
|
|
510
|
+
const strings = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
518
511
|
try {
|
|
519
512
|
const parsed = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
520
|
-
if (!isRecord(parsed)) return
|
|
521
|
-
producerBindings: [],
|
|
522
|
-
consumerQueues: [],
|
|
523
|
-
pendingConsumerRemovals: []
|
|
524
|
-
};
|
|
513
|
+
if (!isRecord(parsed)) return none;
|
|
525
514
|
return {
|
|
526
|
-
producerBindings:
|
|
527
|
-
consumerQueues:
|
|
528
|
-
pendingConsumerRemovals:
|
|
515
|
+
producerBindings: strings(parsed.producerBindings),
|
|
516
|
+
consumerQueues: strings(parsed.consumerQueues),
|
|
517
|
+
pendingConsumerRemovals: strings(parsed.pendingConsumerRemovals)
|
|
529
518
|
};
|
|
530
519
|
} catch {
|
|
531
|
-
return
|
|
532
|
-
producerBindings: [],
|
|
533
|
-
consumerQueues: [],
|
|
534
|
-
pendingConsumerRemovals: []
|
|
535
|
-
};
|
|
520
|
+
return none;
|
|
536
521
|
}
|
|
537
522
|
}
|
|
538
523
|
function writeManagedQueueProvenance(text, provenance) {
|
|
@@ -592,14 +577,7 @@ function acknowledgeWranglerManagedQueueRemovals(configPath, removedQueues) {
|
|
|
592
577
|
* idempotent upsert — running twice produces byte-identical output.
|
|
593
578
|
*/
|
|
594
579
|
function writeProvisionedWranglerConfig(root, patch, options) {
|
|
595
|
-
|
|
596
|
-
if (configPath === void 0) {
|
|
597
|
-
for (const p of projectWranglerPaths(root)) if (existsSync(p)) {
|
|
598
|
-
configPath = p;
|
|
599
|
-
break;
|
|
600
|
-
}
|
|
601
|
-
configPath ??= materializeCloudflareConfig(root);
|
|
602
|
-
}
|
|
580
|
+
const configPath = options?.configPath ?? discoverWranglerConfigPath(root);
|
|
603
581
|
const rawContent = existsSync(configPath) ? readFileSync(configPath, "utf-8") : "{}";
|
|
604
582
|
const hasBom = rawContent.startsWith(UTF8_BOM);
|
|
605
583
|
const original = hasBom ? rawContent.slice(1) : rawContent;
|
|
@@ -1427,7 +1405,7 @@ function findBindingNameOwner(config, field, name) {
|
|
|
1427
1405
|
* 2. MORE THAN ONE entry in the target field sharing `binding` (ambiguous identity —
|
|
1428
1406
|
* wrangler also rejects duplicate binding names);
|
|
1429
1407
|
* 3. a worker-wide CROSS-TYPE collision — `binding` is ALSO owned by any OTHER binding
|
|
1430
|
-
* type (reuses the {@link collectWorkerBindingNames}
|
|
1408
|
+
* type (reuses the {@link collectWorkerBindingNames} collector, EXCLUDING the
|
|
1431
1409
|
* target field so the entry never self-collides, and INCLUDING `queues.producers`).
|
|
1432
1410
|
* Returns the single matching entry, or `undefined` when the binding is absent.
|
|
1433
1411
|
*/
|
|
@@ -1513,15 +1491,8 @@ const BINDING_FIELD_SHAPES = {
|
|
|
1513
1491
|
* `ratelimits` name-keying and `logfwdr`'s nested `.bindings`, among others).
|
|
1514
1492
|
*/
|
|
1515
1493
|
function bindingNamesForField(field, value) {
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
case "key-map": return keyMapBindingNames(field, value);
|
|
1519
|
-
case "name-keyed-array": return nameKeyedBindingNames(field, value);
|
|
1520
|
-
case "namespace-array": return namespaceArrayBindingNames(field, value);
|
|
1521
|
-
case "singleton": return singletonBindingName(field, value, shape.bindingRequired);
|
|
1522
|
-
case "binding-list": return bindingListNames(field, value, shape.bindingsRequired);
|
|
1523
|
-
case "whole-object": return [];
|
|
1524
|
-
}
|
|
1494
|
+
if (BINDING_FIELD_SHAPES[field]?.kind === "key-map") return keyMapBindingNames(field, value);
|
|
1495
|
+
return bindingEntriesForField(field, value).map((entry) => entry.name);
|
|
1525
1496
|
}
|
|
1526
1497
|
/**
|
|
1527
1498
|
* The entry-shaped sibling of {@link bindingNamesForField}: routes each field to its KNOWN
|
|
@@ -1529,8 +1500,8 @@ function bindingNamesForField(field, value) {
|
|
|
1529
1500
|
* caller can compare not just WHICH bindings a field declares but the TARGET each one points
|
|
1530
1501
|
* at (a `services` binding's `service`, an `unsafe` binding's `type`, …). Same fail-closed
|
|
1531
1502
|
* philosophy as {@link bindingNamesForField} — a malformed/missing REQUIRED identity or wrong
|
|
1532
|
-
* outer shape THROWS.
|
|
1533
|
-
*
|
|
1503
|
+
* outer shape THROWS. {@link bindingNamesForField} is this reader's `.name` projection for every
|
|
1504
|
+
* non-key-map field.
|
|
1534
1505
|
*
|
|
1535
1506
|
* Exported so the deploy orchestrator's pass-through assert-set check can pin a legitimately
|
|
1536
1507
|
* hand-declared binding's ENTRY pre-build and reject a build that KEEPS the name but REWRITES
|
|
@@ -1559,9 +1530,10 @@ function keyMapBindingEntries(field) {
|
|
|
1559
1530
|
throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object mapping names to values. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1560
1531
|
}
|
|
1561
1532
|
/**
|
|
1562
|
-
* Entry-shaped reader for a NAMESPACE-array field (
|
|
1563
|
-
*
|
|
1564
|
-
*
|
|
1533
|
+
* Entry-shaped reader for a NAMESPACE-array field (`[{ binding }]`: kv_namespaces, d1_databases,
|
|
1534
|
+
* r2_buckets, hyperdrive, services, vectorize, …). A PRESENT value that is not an array THROWS
|
|
1535
|
+
* rather than being re-read as a key-map (which could under-collect and hide a real collision);
|
|
1536
|
+
* every member is strictly validated for a non-empty string `.binding`.
|
|
1565
1537
|
*/
|
|
1566
1538
|
function namespaceArrayBindingEntries(field, value) {
|
|
1567
1539
|
if (value === void 0) return [];
|
|
@@ -1569,8 +1541,15 @@ function namespaceArrayBindingEntries(field, value) {
|
|
|
1569
1541
|
return strictBindingEntries(value, "binding", field);
|
|
1570
1542
|
}
|
|
1571
1543
|
/**
|
|
1572
|
-
* Entry-shaped reader for a NAME-keyed array field (
|
|
1573
|
-
*
|
|
1544
|
+
* Entry-shaped reader for a NAME-keyed array field (`send_email` / `ratelimits`: an array of
|
|
1545
|
+
* `{ name }`). A PRESENT non-array THROWS; every member is strictly validated.
|
|
1546
|
+
*
|
|
1547
|
+
* Identity is the `.name` ONLY. Verified against wrangler 4.131's bundle +
|
|
1548
|
+
* `config-schema.json`: NEITHER `send_email` NOR `ratelimits` has a `.binding` property in
|
|
1549
|
+
* the schema, and on UPLOAD wrangler keys them by `.name`. An optional `.binding` that happens
|
|
1550
|
+
* to sit on such an entry is NOT a binding identity wrangler recognizes, so unioning it would
|
|
1551
|
+
* invent a PHANTOM collision (e.g. `send_email:[{name:"EMAIL_A",binding:"QUEUE_JOBS"}]` would
|
|
1552
|
+
* falsely block a legitimate `QUEUE_JOBS` queue producer).
|
|
1574
1553
|
*/
|
|
1575
1554
|
function nameKeyedBindingEntries(field, value) {
|
|
1576
1555
|
if (value === void 0) return [];
|
|
@@ -1578,10 +1557,10 @@ function nameKeyedBindingEntries(field, value) {
|
|
|
1578
1557
|
return strictBindingEntries(value, "name", field);
|
|
1579
1558
|
}
|
|
1580
1559
|
/**
|
|
1581
|
-
* Entry-shaped reader for a binding-LIST field (
|
|
1582
|
-
* of each member is the member itself
|
|
1583
|
-
*
|
|
1584
|
-
* `bindings`-less `unsafe` (optional) contributes nothing.
|
|
1560
|
+
* Entry-shaped reader for a binding-LIST field (`{ bindings: [{ name }] }`: durable_objects /
|
|
1561
|
+
* logfwdr / unsafe): the entry of each member is the member itself, keyed on `.name`. A wrong
|
|
1562
|
+
* outer shape, or a missing `bindings` when required (durable_objects / logfwdr per schema),
|
|
1563
|
+
* THROWS; a `bindings`-less `unsafe` (optional) contributes nothing.
|
|
1585
1564
|
*/
|
|
1586
1565
|
function bindingListEntries(field, value, bindingsRequired) {
|
|
1587
1566
|
if (value === void 0) return [];
|
|
@@ -1594,10 +1573,11 @@ function bindingListEntries(field, value, bindingsRequired) {
|
|
|
1594
1573
|
return strictBindingEntries(value.bindings, "name", `${field}.bindings`);
|
|
1595
1574
|
}
|
|
1596
1575
|
/**
|
|
1597
|
-
* Entry-shaped reader for a SINGLETON field (
|
|
1598
|
-
* is the singleton value itself. A
|
|
1599
|
-
* THROWS; a
|
|
1600
|
-
*
|
|
1576
|
+
* Entry-shaped reader for a SINGLETON field (`{ binding }`: ai / browser / images / stream /
|
|
1577
|
+
* media / websearch / version_metadata / assets): the entry is the singleton value itself. A
|
|
1578
|
+
* PRESENT non-object THROWS; a present-but-malformed `binding` THROWS; a required-but-absent
|
|
1579
|
+
* `binding` THROWS (never a fall-through that would mis-collect the object's OTHER keys); a
|
|
1580
|
+
* binding-optional `assets` with no binding contributes nothing.
|
|
1601
1581
|
*/
|
|
1602
1582
|
function singletonBindingEntry(field, value, bindingRequired) {
|
|
1603
1583
|
if (value === void 0) return [];
|
|
@@ -1614,8 +1594,7 @@ function singletonBindingEntry(field, value, bindingRequired) {
|
|
|
1614
1594
|
* Read binding names from a KEY-MAP field (`vars`/`wasm_modules`/`text_blobs`/
|
|
1615
1595
|
* `data_blobs`): the object's KEYS are the binding names. Reads ONLY the keys — never
|
|
1616
1596
|
* the values — so a value that happens to look like a binding list (`{bindings:[…]}`)
|
|
1617
|
-
* or a singleton (`{binding:'x'}`) is NOT misread
|
|
1618
|
-
* VALUE, or a nested `name`, instead of the real KEY). A PRESENT value that is not a
|
|
1597
|
+
* or a singleton (`{binding:'x'}`) is NOT misread. A PRESENT value that is not a
|
|
1619
1598
|
* plain object is the wrong outer shape and THROWS (fail closed). An explicitly
|
|
1620
1599
|
* `undefined`-valued key is not a real binding and is skipped.
|
|
1621
1600
|
*/
|
|
@@ -1625,95 +1604,11 @@ function keyMapBindingNames(field, value) {
|
|
|
1625
1604
|
return Object.keys(value).filter((key) => value[key] !== void 0);
|
|
1626
1605
|
}
|
|
1627
1606
|
/**
|
|
1628
|
-
*
|
|
1629
|
-
*
|
|
1630
|
-
*
|
|
1631
|
-
*
|
|
1632
|
-
*
|
|
1633
|
-
*/
|
|
1634
|
-
function namespaceArrayBindingNames(field, value) {
|
|
1635
|
-
if (value === void 0) return [];
|
|
1636
|
-
if (!Array.isArray(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an array of binding entries. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1637
|
-
return strictBindingArray(value, "binding", field);
|
|
1638
|
-
}
|
|
1639
|
-
/**
|
|
1640
|
-
* Read binding names from a NAME-keyed array field (`send_email` / `ratelimits`:
|
|
1641
|
-
* an array of `{ name }`). Encodes the field's REQUIRED outer shape: a PRESENT value that
|
|
1642
|
-
* is not an array THROWS (fail closed) rather than falling back to generic key collection —
|
|
1643
|
-
* wrangler validates these via `validateBindingArray`, so a non-array is malformed and
|
|
1644
|
-
* could hide a real collision if silently re-read as a key-map. An ABSENT value contributes
|
|
1645
|
-
* nothing. Every array member is strictly validated (a malformed one rejects the whole
|
|
1646
|
-
* config).
|
|
1647
|
-
*
|
|
1648
|
-
* Identity is the `.name` ONLY. Verified against wrangler 4.131's bundle +
|
|
1649
|
-
* `config-schema.json`: NEITHER `send_email` NOR `ratelimits` has a `.binding` property in
|
|
1650
|
-
* the schema, and on UPLOAD wrangler keys them by `.name` (send_email:
|
|
1651
|
-
* `output[name] = { type: "send_email", ...}`; ratelimits push `{ name: binding.name, … }`).
|
|
1652
|
-
* An optional `.binding` that happens to sit on such an entry is NOT a binding identity
|
|
1653
|
-
* wrangler recognizes, so unioning it invents a PHANTOM collision — e.g. a
|
|
1654
|
-
* `send_email:[{name:"EMAIL_A",binding:"QUEUE_JOBS"}]` would falsely block a legitimate
|
|
1655
|
-
* `QUEUE_JOBS` queue producer / adopt / read-first. We therefore collect ONLY the `.name`
|
|
1656
|
-
* of every member (a genuine same-`name` collision is still caught).
|
|
1657
|
-
*/
|
|
1658
|
-
function nameKeyedBindingNames(field, value) {
|
|
1659
|
-
if (value === void 0) return [];
|
|
1660
|
-
if (!Array.isArray(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an array of binding entries. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1661
|
-
return strictBindingArray(value, "name", field);
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* Read the binding names from a binding-LIST field (`{ bindings: [{ name }] }`:
|
|
1665
|
-
* durable_objects / logfwdr / unsafe). A PRESENT value that is not an object is the
|
|
1666
|
-
* wrong outer shape and THROWS. When `bindingsRequired` (durable_objects / logfwdr per
|
|
1667
|
-
* schema), a MISSING `bindings` array THROWS (never a silent empty read); `unsafe` is
|
|
1668
|
-
* optional, so a `bindings`-less `{ metadata }` contributes nothing. A PRESENT
|
|
1669
|
-
* `bindings` array has EVERY member strictly validated for a non-empty string `name`.
|
|
1670
|
-
*/
|
|
1671
|
-
function bindingListNames(field, value, bindingsRequired) {
|
|
1672
|
-
if (value === void 0) return [];
|
|
1673
|
-
if (!isRecord(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object with a "bindings" array. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1674
|
-
if (value.bindings === void 0) {
|
|
1675
|
-
if (bindingsRequired) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" requires a "bindings" array. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1676
|
-
return [];
|
|
1677
|
-
}
|
|
1678
|
-
if (!Array.isArray(value.bindings)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}.bindings" must be an array. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1679
|
-
return strictBindingArray(value.bindings, "name", `${field}.bindings`);
|
|
1680
|
-
}
|
|
1681
|
-
/**
|
|
1682
|
-
* Read the binding name from a SINGLETON field (`{ binding }`: ai / browser /
|
|
1683
|
-
* images / stream / media / websearch / version_metadata / assets). A PRESENT value
|
|
1684
|
-
* that is not an object is the wrong outer shape and THROWS. A PRESENT-but-malformed
|
|
1685
|
-
* `binding` (non-string / empty) THROWS. When `bindingRequired` (every singleton except
|
|
1686
|
-
* `assets`, per schema), an ABSENT `binding` also THROWS — never a silent empty read,
|
|
1687
|
-
* and never a fall-through that would mis-collect the object's OTHER keys (e.g.
|
|
1688
|
-
* `{ staging: true }`) as bogus binding names. `assets` is binding-optional, so an
|
|
1689
|
-
* absent binding (e.g. `{ directory }`) contributes nothing.
|
|
1690
|
-
*/
|
|
1691
|
-
function singletonBindingName(field, value, bindingRequired) {
|
|
1692
|
-
if (value === void 0) return [];
|
|
1693
|
-
if (!isRecord(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object with a "binding". Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
|
|
1694
|
-
if (typeof value.binding === "string" && value.binding.length > 0) return [value.binding];
|
|
1695
|
-
if (value.binding !== void 0) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" has a malformed "binding" (expected a non-empty string). Refusing to proceed on a partially-readable binding set (a dropped binding could hide a real collision). Fix the wrangler config and retry.`);
|
|
1696
|
-
if (bindingRequired) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" requires a "binding" (a non-empty string). Refusing to proceed on a partially-readable binding set (a dropped binding could hide a real collision). Fix the wrangler config and retry.`);
|
|
1697
|
-
return [];
|
|
1698
|
-
}
|
|
1699
|
-
/**
|
|
1700
|
-
* Strictly read `keyField` (a non-empty string) from EVERY member of a
|
|
1701
|
-
* binding-bearing array. THROWS (fail closed) on ANY malformed member — never
|
|
1702
|
-
* silently drops one. Dropping a malformed member could convert a mixed-validity
|
|
1703
|
-
* array (e.g. `[null, { binding: 'DB', id: '…' }]`) into an empty/partial binding
|
|
1704
|
-
* set, so the worker-wide uniqueness guard would MISS the existing `DB` and commit
|
|
1705
|
-
* a conflicting binding — a fail-open in a documented invariant. Mirrors the
|
|
1706
|
-
* writer's existing fail-closed-on-malformed-config philosophy.
|
|
1707
|
-
*/
|
|
1708
|
-
function strictBindingArray(members, keyField, field) {
|
|
1709
|
-
return strictBindingEntries(members, keyField, field).map((e) => e.name);
|
|
1710
|
-
}
|
|
1711
|
-
/**
|
|
1712
|
-
* The entry-shaped sibling of {@link strictBindingArray}: reads `keyField` (a non-empty string)
|
|
1713
|
-
* from EVERY member and returns it PAIRED with the member's full entry object. Same fail-closed
|
|
1714
|
-
* validation — a non-record member, or one missing a non-empty string `keyField`, THROWS (never
|
|
1715
|
-
* silently dropped). {@link strictBindingArray} is defined in terms of this, so the two agree on
|
|
1716
|
-
* names and error messages for every field.
|
|
1607
|
+
* Strictly read `keyField` (a non-empty string) from EVERY member of a binding-bearing array and
|
|
1608
|
+
* return it PAIRED with the member's full entry object. THROWS (fail closed) on ANY malformed
|
|
1609
|
+
* member — never silently drops one. Dropping a malformed member could convert a mixed-validity
|
|
1610
|
+
* array (e.g. `[null, { binding: 'DB', id: '…' }]`) into an empty/partial binding set, so the
|
|
1611
|
+
* worker-wide uniqueness guard would MISS the existing `DB` and commit a conflicting binding.
|
|
1717
1612
|
*/
|
|
1718
1613
|
function strictBindingEntries(members, keyField, field) {
|
|
1719
1614
|
return members.map((member, index) => {
|
|
@@ -1755,4 +1650,4 @@ function canonicalize(value) {
|
|
|
1755
1650
|
return value;
|
|
1756
1651
|
}
|
|
1757
1652
|
//#endregion
|
|
1758
|
-
export {
|
|
1653
|
+
export { updateWranglerCustomDomain as A, readWranglerManagedQueueCleanupCandidates as C, syncWranglerBindings as D, resolveLiveBindingConfig as E, writeWranglerPublishedTrafficSnapshot as M, syncWranglerDurableObjects as O, readWranglerCustomDomains as S, readWranglerWebSocketTombstones as T, persistMaterializedWranglerConfig as _, LIVE_MIGRATION_TAG as a, readRootWranglerConfig as b, bindingEntriesForField as c, ensureWranglerCompatibilityDate as d, ensureWranglerNodejsAlsFlag as f, normalizeWranglerCompatibilityFlags as g, nextDurableObjectMigrationTag as h, LATEST_KNOWN_COMPAT_DATE as i, writeProvisionedWranglerConfig as j, syncWranglerWebSockets as k, bindingNamesForField as l, hasDurableObjectSqliteMigration as m, DEFAULT_LIVE_CLASS as n, acknowledgeWranglerManagedQueueRemovals as o, findBindingNameOwner as p, FRIENDLY_BINDING_NAMES as r, assertNoDuplicateMembers as s, DEFAULT_LIVE_BINDING as t, ensureWranglerCompat as u, readExistingLiveBindingConfig as v, readWranglerPublishedTrafficSnapshot as w, readWranglerCompat as x, readProvisionedBindingEntry as y };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as StandardSchemaV1 } from "./standard-schema-Fo_vCAZh.mjs";
|
|
2
2
|
import { r as AuthUser } from "./auth-DkcFflXV.mjs";
|
|
3
|
-
import { a as CloudEnv } from "./handler-
|
|
3
|
+
import { a as CloudEnv } from "./handler-CNAwjRcW.mjs";
|
|
4
4
|
import { WebSocketRouteMap } from "void/routes";
|
|
5
5
|
//#region src/runtime/ws.d.ts
|
|
6
6
|
type MaybePromise<T> = T | Promise<T>;
|
|
@@ -69,26 +69,28 @@ function hasLocalLockfile(dir) {
|
|
|
69
69
|
* PnP monorepo, `.pnp.cjs` lives at the workspace root, not in each
|
|
70
70
|
* subpackage. Checking only `start` would miss the common shape.
|
|
71
71
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* Internal: only `buildDrizzleKitSpawnEnv` below consumes this. The
|
|
80
|
-
* stricter `findInstalledYarnPnpRuntime` is the public variant callers
|
|
81
|
-
* outside this module reach for.
|
|
72
|
+
* Local PnP files at `start` are always authoritative and take
|
|
73
|
+
* precedence over the leaf-managed guard below. When `start` has no
|
|
74
|
+
* local PnP files but DOES have a local lockfile, stop here — ancestor
|
|
75
|
+
* PnP data belongs to a different install graph and injecting it will
|
|
76
|
+
* break resolution for the local one. Only walk past `start` when
|
|
77
|
+
* neither condition holds.
|
|
82
78
|
*/
|
|
83
79
|
function findYarnPnpRuntime(start) {
|
|
84
80
|
const local = readPnpRuntimeAt(start);
|
|
85
|
-
if (local !== void 0) return
|
|
81
|
+
if (local !== void 0) return {
|
|
82
|
+
dir: start,
|
|
83
|
+
runtime: local
|
|
84
|
+
};
|
|
86
85
|
if (hasLocalLockfile(start)) return;
|
|
87
86
|
let dir = dirname(start);
|
|
88
87
|
if (dir === start) return;
|
|
89
88
|
while (true) {
|
|
90
89
|
const found = readPnpRuntimeAt(dir);
|
|
91
|
-
if (found !== void 0) return
|
|
90
|
+
if (found !== void 0) return {
|
|
91
|
+
dir,
|
|
92
|
+
runtime: found
|
|
93
|
+
};
|
|
92
94
|
const parent = dirname(dir);
|
|
93
95
|
if (parent === dir) return;
|
|
94
96
|
dir = parent;
|
|
@@ -99,7 +101,7 @@ function findYarnPnpRuntime(start) {
|
|
|
99
101
|
* when the PnP runtime files AND a post-install marker live in the
|
|
100
102
|
* SAME ancestor directory.
|
|
101
103
|
*
|
|
102
|
-
*
|
|
104
|
+
* Yarn Berry repos commonly commit `.pnp.cjs` to
|
|
103
105
|
* version control but NOT `.yarn/cache/*.zip` (zero-install is an
|
|
104
106
|
* opt-in, not the default). A fresh `git clone` before `yarn install`
|
|
105
107
|
* therefore has `.pnp.cjs` on disk while the PnP data points at ZIP
|
|
@@ -108,7 +110,7 @@ function findYarnPnpRuntime(start) {
|
|
|
108
110
|
* install step, and the subsequent `drizzle-kit generate` spawn crashes
|
|
109
111
|
* because PnP tries to load `void/schema-d1` from a missing ZIP.
|
|
110
112
|
*
|
|
111
|
-
*
|
|
113
|
+
* Accept EITHER of two markers, to cover both non-zero-install
|
|
112
114
|
* and zero-install shapes:
|
|
113
115
|
*
|
|
114
116
|
* 1. `.yarn/install-state.gz` in the same dir. Yarn Berry (3.x and
|
|
@@ -135,18 +137,8 @@ function findYarnPnpRuntime(start) {
|
|
|
135
137
|
* a spawn, the env needs to be prepared.
|
|
136
138
|
*/
|
|
137
139
|
function findInstalledYarnPnpRuntime(start) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
if (hasLocalLockfile(start)) return;
|
|
141
|
-
let dir = dirname(start);
|
|
142
|
-
if (dir === start) return;
|
|
143
|
-
while (true) {
|
|
144
|
-
const found = readPnpRuntimeAt(dir);
|
|
145
|
-
if (found !== void 0) return isYarnPnpInstalled(dir) ? found : void 0;
|
|
146
|
-
const parent = dirname(dir);
|
|
147
|
-
if (parent === dir) return;
|
|
148
|
-
dir = parent;
|
|
149
|
-
}
|
|
140
|
+
const found = findYarnPnpRuntime(start);
|
|
141
|
+
return found && isYarnPnpInstalled(found.dir) ? found.runtime : void 0;
|
|
150
142
|
}
|
|
151
143
|
/**
|
|
152
144
|
* Return true when `dir` looks like a post-install Yarn Berry PnP
|
|
@@ -183,7 +175,7 @@ function isYarnPnpInstalled(dir) {
|
|
|
183
175
|
*/
|
|
184
176
|
function buildDrizzleKitSpawnEnv(root) {
|
|
185
177
|
const env = { ...process.env };
|
|
186
|
-
const pnp = findYarnPnpRuntime(root);
|
|
178
|
+
const pnp = findYarnPnpRuntime(root)?.runtime;
|
|
187
179
|
if (!pnp) return env;
|
|
188
180
|
const flags = [];
|
|
189
181
|
if (pnp.pnpCjs) flags.push(`--require ${JSON.stringify(pnp.pnpCjs)}`);
|
|
@@ -41,7 +41,7 @@ export const POST = defineHandler(async (c) => {
|
|
|
41
41
|
});
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
AI methods return promises. Await them to receive the result, or return the promise directly from a handler. Usage
|
|
44
|
+
AI methods return promises. Await them to receive the result, or return the promise directly from a handler. See [Usage Limits](#usage-limits) for limit errors.
|
|
45
45
|
|
|
46
46
|
You can use any model available through Cloudflare's AI binding, including Workers AI models such as `@cf/meta/llama-3.3-70b-instruct-fp8-fast` and Cloudflare Gateway models such as `google/gemini-2.5-flash` or `openai/gpt-4.1-mini`. The input object must match the selected Cloudflare model's schema. Models that return binary data, such as generated images, are returned as a `Blob` from `ai.run()`.
|
|
47
47
|
|
|
@@ -133,7 +133,7 @@ const result = await ai.run('google/gemini-2.5-flash', {
|
|
|
133
133
|
});
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
Pass AI Gateway options as the third argument: `ai.run(model, inputs, { gateway: { skipCache: true } })`.
|
|
136
|
+
Pass AI Gateway options as the third argument: `ai.run(model, inputs, { gateway: { skipCache: true } })`. On a team platform, the platform chooses the gateway and sets its metadata and logging; options such as `skipCache` and `cacheTtl` still apply.
|
|
137
137
|
|
|
138
138
|
For provider-native requests on a direct deployment, configure [`ai.gateway`](../integrations/cloudflare.md#ai-self-host).
|
|
139
139
|
|
|
@@ -142,7 +142,9 @@ For provider-native requests on a direct deployment, configure [`ai.gateway`](..
|
|
|
142
142
|
Use `ai.provider(provider).fetch(path, init)` for a provider-native API with your
|
|
143
143
|
own provider key. The request goes through the configured Cloudflare AI Gateway
|
|
144
144
|
and retains the provider's native HTTP shape. On a team platform, it also passes
|
|
145
|
-
through that installation's proxy.
|
|
145
|
+
through that installation's proxy. AI Gateway cache, timeout and retry headers,
|
|
146
|
+
such as `cf-aig-cache-ttl` and `cf-aig-max-attempts`, still apply there; the
|
|
147
|
+
platform ignores logging, metadata and cost headers.
|
|
146
148
|
|
|
147
149
|
### OpenAI
|
|
148
150
|
|
|
@@ -92,7 +92,7 @@ Email/password is enabled by default. To add social providers:
|
|
|
92
92
|
}
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
Provider credentials come from `AUTH_<PROVIDER>_CLIENT_ID` and `AUTH_<PROVIDER>_CLIENT_SECRET`.
|
|
96
96
|
|
|
97
97
|
See the full provider list in the [config reference](../reference/config.md#auth).
|
|
98
98
|
|
|
@@ -127,6 +127,42 @@ Auth sessions use the same database as your app. Void creates `BETTER_AUTH_SECRE
|
|
|
127
127
|
|
|
128
128
|
Local development needs no secret setup. To preview a production build locally, provide `BETTER_AUTH_SECRET`.
|
|
129
129
|
|
|
130
|
+
`POST`, `PUT`, `PATCH` and `DELETE` requests and WebSocket connections from another origin don't use the signed-in session unless that origin is in `trustedOrigins`. If a separate frontend calls your app, add its origin there (see [Customization](#customization)). If your routes use their own cookies, check the request `Origin` yourself, for example with Hono's [`csrf()`](https://hono.dev/docs/middleware/builtin/csrf) middleware.
|
|
131
|
+
|
|
132
|
+
Deployed apps on Cloudflare limit auth requests per client IP with Better Auth's defaults, for example 3 sign-in attempts per 10 seconds. Each Worker instance keeps its own count. Change or turn off the limits with `rateLimit` in `auth.ts`. To share one count across instances, set `rateLimit: { storage: 'database' }`, then run `void db generate` for a direct Cloudflare deploy.
|
|
133
|
+
|
|
134
|
+
### Proxies and end-to-end tests
|
|
135
|
+
|
|
136
|
+
All requests from one IP share one count. Two common setups reach the limits:
|
|
137
|
+
|
|
138
|
+
- A server calls your auth endpoints for your users, such as a backend-for-frontend, a rewrite from Vercel or nginx, or another Worker's `fetch`. All of those users share that server's IP.
|
|
139
|
+
- End-to-end tests sign up or sign in many times against a deployed app.
|
|
140
|
+
|
|
141
|
+
Don't read the client IP from `x-forwarded-for` instead: any client can send that header. Give the trusted caller a secret header, and skip the limits only for requests that carry it:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { defineAuth } from 'void/auth';
|
|
145
|
+
|
|
146
|
+
export default defineAuth(({ defaults, env }) => ({
|
|
147
|
+
...defaults,
|
|
148
|
+
rateLimit: {
|
|
149
|
+
customRules: {
|
|
150
|
+
'/**': (request, rule) =>
|
|
151
|
+
env.AUTH_TRUSTED_KEY && request.headers.get('x-auth-trusted-key') === env.AUTH_TRUSTED_KEY
|
|
152
|
+
? false
|
|
153
|
+
: rule,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
}));
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`'/**'` matches every auth endpoint. Returning `false` skips the limit, and returning `rule` keeps the default limit for everyone else. Declare `AUTH_TRUSTED_KEY: string().optional()` in `env.ts` and set it with `void secret put AUTH_TRUSTED_KEY` (see [Environment variables](./env-vars.md#production-server-values)).
|
|
160
|
+
|
|
161
|
+
Your app no longer limits requests that carry the key, so:
|
|
162
|
+
|
|
163
|
+
- A proxy that sends it must limit every auth request it forwards for each of its users, including sign-up, password reset and verification emails.
|
|
164
|
+
- A test runner should send it only to your app. Never put the key in code that runs in your users' browsers.
|
|
165
|
+
|
|
130
166
|
## Customization
|
|
131
167
|
|
|
132
168
|
For advanced configuration, create `auth.ts` at the project root and export `defineAuth(...)`:
|
|
@@ -59,7 +59,7 @@ export const users = pgTable('users', {
|
|
|
59
59
|
});
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
`void gen model` generates PostgreSQL-appropriate code when
|
|
62
|
+
`void gen model` generates PostgreSQL-appropriate code when `database` is set to `"pg"`.
|
|
63
63
|
|
|
64
64
|
## Migrations
|
|
65
65
|
|
|
@@ -88,4 +88,4 @@ To update a linked Void project's connection, for example after moving the datab
|
|
|
88
88
|
void db set-url
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
This prompts for the new connection string and updates the Hyperdrive configuration.
|
|
91
|
+
This prompts for the new connection string and updates the Hyperdrive configuration.
|