void 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_TEMPLATE.md +1 -1
- package/README.md +5 -1
- package/dist/{account-cmd-CjyxcGkM.mjs → account-cmd-vJhh5lrb.mjs} +5 -5
- package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
- package/dist/application-routing-B7QEjqSR.mjs +27 -0
- package/dist/{auth-DLNN0D3Z.mjs → auth-CQkSDS50.mjs} +26 -96
- package/dist/auth-DX3JURcX.mjs +2 -0
- package/dist/{auth-link-BLO4ptzo.mjs → auth-link-D75t9wO2.mjs} +5 -5
- package/dist/{auth-router-ZUg9MF_U.mjs → auth-router-ClfhL1J7.mjs} +7 -7
- package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
- package/dist/{build-cmd-BxR5FROK.mjs → build-cmd-zMi1iFnS.mjs} +21 -9
- package/dist/{cache-D0sWhgKI.mjs → cache-ZtQmyxVV.mjs} +5 -5
- package/dist/{cancel-deploy-D4NUqFbi.mjs → cancel-deploy-Box0kkEV.mjs} +5 -5
- package/dist/{cf-access-P0iZnu0q.mjs → cf-access-BGe5sWXF.mjs} +4 -48
- package/dist/{cf-access-DRsQRe6k.mjs → cf-access-TWNzXltp.mjs} +3 -11
- package/dist/{cf-build-output-BJ6yGEIS.mjs → cf-build-output-BPqOT964.mjs} +2 -1
- package/dist/cf-build-output-_0HNWysu.mjs +2 -0
- package/dist/cli/cli.mjs +89 -461
- package/dist/cli/{cf-compat.mjs → cloudflare-operation-process.mjs} +454 -424
- package/dist/cli/env-schema-probe.d.mts +2 -1
- package/dist/cli/env-schema-probe.mjs +4 -4
- package/dist/client-B9UBI03V.mjs +2 -0
- package/dist/{client-BTZ3XkrB.mjs → client-DKAsFA4X.mjs} +161 -24
- package/dist/{cloudflare-auth-DQkqoMYa.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -38
- package/dist/{cloudflare-cmd-BKlfGHAy.mjs → cloudflare-cmd-CmY8dGkd.mjs} +6 -6
- package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
- package/dist/{cloudflare-connect-Ctmrw579.mjs → cloudflare-connect-IiR3ZieC.mjs} +4 -4
- package/dist/{cloudflare-operations-BT6OWFBk.mjs → cloudflare-operations-BCdXSsmo.mjs} +1 -1
- package/dist/{cloudflare-operations-B9tzgjmf.mjs → cloudflare-operations-DzH-A966.mjs} +116 -172
- package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
- package/dist/{config-VavjpDnp.d.mts → config-BMHb8RCj.d.mts} +1 -0
- package/dist/config-C_XRIPx2.mjs +89 -0
- package/dist/config-entry.d.mts +1 -1
- package/dist/{connect-Dg-WkW-C.mjs → connect-B-usTnlF.mjs} +9 -9
- package/dist/{create-project-l9J7pbtm.mjs → create-project-CYOOAYcn.mjs} +12 -12
- package/dist/{create-project-DdoqwFLF.mjs → create-project-FWbf5Olo.mjs} +1 -1
- package/dist/{db-gp2sCXyN.mjs → db-Ck2eZ2iB.mjs} +26 -26
- package/dist/{delete-TTedbH6B.mjs → delete-sK56qtzZ.mjs} +5 -5
- package/dist/{deploy-CH-o2CaZ.mjs → deploy-gCVaiJbS.mjs} +984 -616
- package/dist/{deploy-B19L2Bra.mjs → deploy-irP5q0-x.mjs} +1 -1
- package/dist/{domain-JRF59P_r.mjs → domain-DFfQE8jg.mjs} +6 -6
- package/dist/{email-Bo6G9LOZ.mjs → email-CdnhUHvJ.mjs} +15 -30
- package/dist/{env-BYOrWQnv.mjs → env-DmGdHi5i.mjs} +8 -8
- package/dist/{env-public-BxU_0yTL.d.mts → env-public-BX_r8HR6.d.mts} +1 -1
- package/dist/{env-types-C2_bIk_b.mjs → env-types-D5kds_OZ.mjs} +1 -1
- package/dist/{env-validation-BB4GkLxn.mjs → env-validation-C_8tPdhs.mjs} +20 -73
- package/dist/{env-validation-BXge7uyK.mjs → env-validation-zZOCcQVZ.mjs} +1 -1
- package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
- package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
- package/dist/{gen-sCtlCOdA.mjs → gen-CshAkukR.mjs} +4 -4
- package/dist/gen-DvQTWzDU.mjs +2 -0
- package/dist/{github-cmd-0-7PexDq.mjs → github-cmd-DftuEvIt.mjs} +13 -13
- package/dist/{handler-HEcZsaij.d.mts → handler-CZ4nAylQ.d.mts} +1 -1
- package/dist/{headers-DWi2IXWx.mjs → headers-2rKda9Y6.mjs} +1 -1
- package/dist/{help-GKtwl07I.mjs → help-Dotbf6iz.mjs} +236 -750
- package/dist/help-mabuIV98.mjs +2 -0
- package/dist/{inbound-aVHEUhKo.mjs → inbound-fRkqcXaC.mjs} +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +299 -1517
- package/dist/info-B97bTX9N.mjs +113 -0
- package/dist/{init-FZx3Elvz.mjs → init-BTQEZZGJ.mjs} +61 -27
- package/dist/limits-Bq5LG8Id.d.mts +27 -0
- package/dist/limits-Cjuk2VPm.mjs +68 -0
- package/dist/{link-BrQfb_CU.mjs → link-B46sYH0K.mjs} +6 -6
- package/dist/{list-D44jmIAM.mjs → list-BnPrIsU_.mjs} +6 -6
- package/dist/{live-CKJlvlNp.d.mts → live-Chw1eIMv.d.mts} +1 -1
- package/dist/{local-d1-Bg9OzEEO.mjs → local-d1-2CMnpuW_.mjs} +2 -2
- package/dist/log-vqY3pqwI.mjs +29 -0
- package/dist/{login-CAsAsQ-_.mjs → login-BuiMyUrx.mjs} +8 -8
- package/dist/login-DIy9Sb-U.mjs +2 -0
- package/dist/{logs-BjKvFnVM.mjs → logs-CZG9d-ic.mjs} +10 -11
- package/dist/migrate-BCiJ8w0f.mjs +2 -0
- package/dist/{migrate-BPITvDJN.mjs → migrate-q4_njtaW.mjs} +4 -3
- package/dist/{node-Dt7z256D.mjs → node-BkyRWRx8.mjs} +1 -1
- package/dist/operator-args-B3BTmSoi.mjs +697 -0
- package/dist/{operator-auth-8KnOVXVd.mjs → operator-auth-7erYc6Lt.mjs} +2 -2
- package/dist/{operator-client-DUwumHpQ.mjs → operator-client-CpHjTd0t.mjs} +3 -3
- package/dist/{operator-cmd-BK5CCiT9.mjs → operator-cmd-DGqPJUD3.mjs} +70 -24
- package/dist/{output-Dm_A4Tbv.mjs → output-CbM85T4k.mjs} +18 -10
- package/dist/pages/client.d.mts +34 -2
- package/dist/pages/client.mjs +59 -3
- package/dist/pages/index.d.mts +1 -1
- package/dist/pages/index.mjs +2 -2
- package/dist/pages/islands-plugin.mjs +1 -1
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +2 -308
- package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
- package/dist/plan-D1Q5rf-r.mjs +2 -0
- package/dist/plan-NPpwZ_kc.mjs +58 -0
- package/dist/platform-args-3k8X9-H_.mjs +514 -0
- package/dist/platform-args-DdnM6WIf.mjs +2 -0
- package/dist/{platform-auth-config-BlN8xTdD.mjs → platform-auth-config-DDrxUy4m.mjs} +6 -6
- package/dist/{platform-auth-protection-7d5aV2Jg.mjs → platform-auth-protection-BLadnnct.mjs} +8 -8
- package/dist/{platform-auth-recovery-Dxij8ZbR.mjs → platform-auth-recovery-CmCzX2Fl.mjs} +6 -6
- package/dist/{platform-cmd-B3hwKrFK.mjs → platform-cmd-DMDEc9uS.mjs} +29 -8
- package/dist/{platform-cmd-E0FuL212.mjs → platform-cmd-pMTRhvYs.mjs} +1 -1
- package/dist/{platform-domain-D6Xcy9ZX.mjs → platform-domain-Di6EYrQl.mjs} +5 -5
- package/dist/{platform-lifecycle-k0E0xoxx.mjs → platform-lifecycle-BBoNzojY.mjs} +1541 -572
- package/dist/{platform-lifecycle-DMh_qrry.mjs → platform-lifecycle-BFdSi9Qt.mjs} +1 -1
- package/dist/{platform-management-Brz_BDiT.mjs → platform-management-CWOQOWXm.mjs} +10 -7
- package/dist/{platform-management-DOtss0BN.mjs → platform-management-DG47jys8.mjs} +1 -1
- package/dist/platform-plans-config-Vl9BP3H4.mjs +359 -0
- package/dist/{platform-recovery-BvtcXON5.mjs → platform-recovery-BJnQJEtQ.mjs} +4 -4
- package/dist/{platform-registry-QBa4DK32.mjs → platform-registry-DkPPXfp_.mjs} +2 -2
- package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
- package/dist/{prepare-C-6YZyyg.mjs → prepare-CBLT3CHH.mjs} +3 -3
- package/dist/prepare-CnjcTV2s.mjs +2 -0
- package/dist/{prepare-CRhJbVrG.mjs → prepare-DnaKBi--.mjs} +5 -21
- package/dist/{project-C0Fqu05O.mjs → project-DKG5Ra8p.mjs} +15 -82
- package/dist/project-DsblYifa.mjs +2 -0
- package/dist/{project-cmd-BZLCqOqw.mjs → project-cmd-DxnXstAq.mjs} +19 -19
- package/dist/{project-team-BvgM0WoX.mjs → project-team-BmHcaALJ.mjs} +5 -5
- package/dist/{project-token-l5DqK6Az.mjs → project-token-GionZlBI.mjs} +5 -5
- package/dist/{project-zero-trust-v6Mvpp8y.mjs → project-zero-trust-JLCjVQA7.mjs} +5 -5
- package/dist/prompts-2TGE6oXx.mjs +2 -0
- package/dist/prompts-BNUoTiaf.mjs +2044 -0
- package/dist/{protocol-BBa6cstI.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
- package/dist/protocol-U7bfjHmA.mjs +331 -0
- package/dist/{provision-Fr9pRqce.mjs → provision-CVku1JFU.mjs} +1 -1
- package/dist/{provision-C4IGqkBf.mjs → provision-CaoxO_U7.mjs} +90 -199
- package/dist/{requests-DN-BbNiM.mjs → requests-BOjIVAeF.mjs} +5 -5
- package/dist/resource-name-C7LVpcRm.mjs +11 -0
- package/dist/{rollback-D7rzSaZM.mjs → rollback-CwR3pLj3.mjs} +6 -6
- package/dist/route-url-CG7U-cRN.mjs +15 -0
- package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
- package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
- package/dist/runtime/ai.d.mts +12 -8
- package/dist/runtime/ai.mjs +87 -22
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/client-react.mjs +2 -2
- package/dist/runtime/client-solid.mjs +2 -2
- package/dist/runtime/client-svelte.mjs +2 -2
- package/dist/runtime/client-vue.mjs +2 -2
- package/dist/runtime/client.mjs +2 -2
- package/dist/runtime/durable.d.mts +3 -1
- package/dist/runtime/durable.mjs +4 -1
- package/dist/runtime/email/testing.mjs +2 -2
- package/dist/runtime/email.mjs +1 -1
- package/dist/runtime/env-public.d.mts +1 -1
- package/dist/runtime/fetch-stream.mjs +1 -1
- package/dist/runtime/fetch.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/kv.mjs +0 -1
- package/dist/runtime/limits.d.mts +2 -0
- package/dist/runtime/limits.mjs +2 -0
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-server.mjs +25 -16
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/migration-handler.mjs +62 -42
- package/dist/runtime/remote/index.mjs +2 -2
- package/dist/runtime/route-url.d.mts +4 -0
- package/dist/runtime/route-url.mjs +2 -0
- package/dist/runtime/routing.d.mts +180 -0
- package/dist/runtime/routing.mjs +1082 -0
- package/dist/runtime/sandbox-container.d.mts +1 -1
- package/dist/runtime/sandbox-container.mjs +1 -1
- package/dist/runtime/sandbox.d.mts +3 -3
- package/dist/runtime/sandbox.mjs +75 -45
- package/dist/runtime/sse.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +4 -2
- package/dist/runtime/ws-server.mjs +27 -2
- package/dist/runtime/ws.d.mts +2 -2
- package/dist/runtime/ws.mjs +8 -6
- package/dist/{sandbox-qpNBT8a3.d.mts → sandbox-XZAqzFlG.d.mts} +11 -8
- package/dist/{sandbox-container-DdNEBfCc.d.mts → sandbox-container-Bo0eiFKz.d.mts} +2 -1
- package/dist/{sandbox-container-4fdqLnyb.mjs → sandbox-container-C6ItmVuN.mjs} +4 -2
- package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
- package/dist/{secret-BOtOl_cb.mjs → secret-ByWJWBUG.mjs} +7 -7
- package/dist/{skills-D1II1Juz.mjs → skills-C1PlclPt.mjs} +1 -1
- package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
- package/dist/{subcommand-prompt-CY1C4fvl.mjs → subcommand-prompt-klFCfcor.mjs} +40 -32
- package/dist/validate-Dq_L3s0S.mjs +2 -0
- package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
- package/dist/{wrangler-DQF1vKyf.mjs → wrangler-7K-bW_DL.mjs} +8 -239
- package/dist/{ws-BoY7vQML.d.mts → ws-CL1w7GXU.d.mts} +13 -2
- package/package.json +16 -10
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
- package/skills/void/SKILL.md +55 -135
- package/skills/void/docs/guide/ai.md +94 -84
- package/skills/void/docs/guide/app-types.md +3 -32
- package/skills/void/docs/guide/auth.md +12 -116
- package/skills/void/docs/guide/database/d1.md +9 -54
- package/skills/void/docs/guide/database/mysql.md +1 -1
- package/skills/void/docs/guide/database/postgresql.md +5 -26
- package/skills/void/docs/guide/database.md +23 -75
- package/skills/void/docs/guide/deployment.md +48 -112
- package/skills/void/docs/guide/durable-state.md +43 -18
- package/skills/void/docs/guide/edge/headers.md +4 -48
- package/skills/void/docs/guide/edge/prerendering.md +5 -20
- package/skills/void/docs/guide/edge/redirects.md +11 -64
- package/skills/void/docs/guide/edge/revalidation.md +5 -18
- package/skills/void/docs/guide/edge/rewrites.md +56 -284
- package/skills/void/docs/guide/edge/static-assets.md +22 -72
- package/skills/void/docs/guide/email/domains.md +116 -0
- package/skills/void/docs/guide/email/receiving.md +139 -0
- package/skills/void/docs/guide/email/sending.md +231 -0
- package/skills/void/docs/guide/email.md +13 -619
- package/skills/void/docs/guide/env-migration.md +11 -11
- package/skills/void/docs/guide/env-vars.md +9 -29
- package/skills/void/docs/guide/index.md +0 -15
- package/skills/void/docs/guide/jobs.md +3 -18
- package/skills/void/docs/guide/kv.md +5 -11
- package/skills/void/docs/guide/live.md +5 -56
- package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
- package/skills/void/docs/guide/pages-routing/head.md +10 -10
- package/skills/void/docs/guide/pages-routing/islands.md +6 -36
- package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
- package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
- package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
- package/skills/void/docs/guide/pages-routing/overview.md +7 -17
- package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
- package/skills/void/docs/guide/platform/administration/access.md +1 -4
- package/skills/void/docs/guide/platform/administration/email.md +35 -8
- package/skills/void/docs/guide/platform/administration/operations.md +26 -4
- package/skills/void/docs/guide/platform/administration/plans.md +126 -0
- package/skills/void/docs/guide/platform/administration/projects.md +5 -2
- package/skills/void/docs/guide/platform/administration/zero-trust.md +49 -160
- package/skills/void/docs/guide/platform/development/runtime.md +3 -13
- package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
- package/skills/void/docs/guide/platform/installation/ci.md +1 -1
- package/skills/void/docs/guide/platform/installation/credentials.md +15 -6
- package/skills/void/docs/guide/platform/installation/domains.md +35 -2
- package/skills/void/docs/guide/platform/installation/first-deployment.md +4 -2
- package/skills/void/docs/guide/platform/installation/maintenance.md +15 -1
- package/skills/void/docs/guide/platform/installation/prerequisites.md +24 -18
- package/skills/void/docs/guide/platform/installation/setup.md +88 -14
- package/skills/void/docs/guide/platform-administration.md +1 -0
- package/skills/void/docs/guide/queues.md +7 -9
- package/skills/void/docs/guide/quickstart.md +38 -37
- package/skills/void/docs/guide/remote-dev.md +5 -10
- package/skills/void/docs/guide/sandboxes.md +29 -21
- package/skills/void/docs/guide/server-routing.md +9 -72
- package/skills/void/docs/guide/sse.md +4 -18
- package/skills/void/docs/guide/ssg.md +3 -15
- package/skills/void/docs/guide/ssr.md +14 -62
- package/skills/void/docs/guide/storage.md +9 -4
- package/skills/void/docs/guide/type-safety.md +3 -14
- package/skills/void/docs/guide/typed-fetch.md +3 -7
- package/skills/void/docs/guide/websockets.md +68 -40
- package/skills/void/docs/integrations/agents.md +3 -3
- package/skills/void/docs/integrations/cloudflare.md +85 -316
- package/skills/void/docs/integrations/frameworks/analog.md +5 -64
- package/skills/void/docs/integrations/frameworks/astro.md +4 -73
- package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
- package/skills/void/docs/integrations/frameworks/overview.md +11 -54
- package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
- package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
- package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
- package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
- package/skills/void/docs/reference/api/auth.md +156 -0
- package/skills/void/docs/reference/api/client.md +87 -0
- package/skills/void/docs/reference/api/database.md +95 -0
- package/skills/void/docs/reference/api/durable.md +46 -0
- package/skills/void/docs/reference/api/env.md +50 -0
- package/skills/void/docs/reference/api/handlers.md +254 -0
- package/skills/void/docs/reference/api/pages.md +241 -0
- package/skills/void/docs/reference/api/plugin.md +39 -0
- package/skills/void/docs/reference/api/resources.md +109 -0
- package/skills/void/docs/reference/api/rewrites.md +76 -0
- package/skills/void/docs/reference/api/types.md +92 -0
- package/skills/void/docs/reference/api.md +56 -1218
- package/skills/void/docs/reference/cli/auth.md +89 -0
- package/skills/void/docs/reference/cli/database.md +128 -0
- package/skills/void/docs/reference/cli/deploy.md +105 -0
- package/skills/void/docs/reference/cli/domains.md +41 -0
- package/skills/void/docs/reference/cli/email.md +129 -0
- package/skills/void/docs/reference/cli/generate.md +116 -0
- package/skills/void/docs/reference/cli/github.md +189 -0
- package/skills/void/docs/reference/cli/platform-config.md +92 -0
- package/skills/void/docs/reference/cli/platform-email.md +81 -0
- package/skills/void/docs/reference/cli/platform-installation.md +142 -0
- package/skills/void/docs/reference/cli/platform-operations.md +90 -0
- package/skills/void/docs/reference/cli/platform-users.md +89 -0
- package/skills/void/docs/reference/cli/platform-zero-trust.md +59 -0
- package/skills/void/docs/reference/cli/platform.md +70 -0
- package/skills/void/docs/reference/cli/project.md +214 -0
- package/skills/void/docs/reference/cli/secrets.md +76 -0
- package/skills/void/docs/reference/cli/setup.md +70 -0
- package/skills/void/docs/reference/cli.md +32 -1682
- package/skills/void/docs/reference/config.md +12 -18
- package/skills/void/docs/reference/resource-inference.md +3 -58
- package/skills/void/docs/reference/structure.md +14 -41
- package/dist/auth-CZuiVsFh.mjs +0 -2
- package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
- package/dist/client-Czz8o5jP.mjs +0 -2
- package/dist/dist-BuDuKZJv.mjs +0 -2
- package/dist/dist-CTBk70IR.mjs +0 -1310
- package/dist/gen-CNJ62MM7.mjs +0 -2
- package/dist/help-CmZzxUba.mjs +0 -2
- package/dist/log-ChfPKsVd.mjs +0 -26
- package/dist/login-CGcRKEoi.mjs +0 -2
- package/dist/migrate-CYfbKkXh.mjs +0 -2
- package/dist/plan-BEZ8VJW0.mjs +0 -256
- package/dist/plan-DpuOr14e.mjs +0 -2
- package/dist/prepare-Bm3iq-u4.mjs +0 -2
- package/dist/project-BuUwfj6f.mjs +0 -2
- package/dist/validate-EKmJWxmy.mjs +0 -2
- /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
package/AGENTS_TEMPLATE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Void
|
|
2
2
|
|
|
3
3
|
- This project uses [Void](https://void.cloud), a full-stack Vite framework for Cloudflare Workers with file-based API routing, server-rendered pages, and typed backend services.
|
|
4
|
-
- Deploy to your Cloudflare account with `void deploy --platform cloudflare`, or connect to
|
|
4
|
+
- Deploy to your Cloudflare account with `void deploy --platform cloudflare`, or explicitly connect to your team’s Void platform with `void connect <url>` before deploying with `void deploy --platform void`. `void deploy` uses the saved destination.
|
|
5
5
|
- Use Void's CLI and typed APIs for development and infrastructure. Void infers Cloudflare bindings from your imports; use Void commands to manage them.
|
|
6
6
|
- Before working with Void, read the relevant Markdown docs in `node_modules/void/skills/void/docs/`. Start with `guide/quickstart.md` for setup and `reference/cli.md` for commands; consult the other guides and references for any Void feature.
|
package/README.md
CHANGED
|
@@ -6,10 +6,11 @@ You can also administer a team platform with the same CLI. Sign in with
|
|
|
6
6
|
`void platform auth login`, then manage users, signup access, projects, and logs.
|
|
7
7
|
Commands show a preview before applying changes and support `--json` for scripts.
|
|
8
8
|
See [Platform Administration](../../docs/guide/platform-administration.md) for a
|
|
9
|
-
walkthrough and the [CLI reference](../../docs/reference/cli.md#operator-commands)
|
|
9
|
+
walkthrough and the [CLI reference](../../docs/reference/cli/platform.md#operator-commands)
|
|
10
10
|
for every command.
|
|
11
11
|
|
|
12
12
|
Use `void platform config auth` to manage login methods and company signup.
|
|
13
|
+
Use `void platform config plans` to manage account plans, enforced limits, and the default for new accounts. See [Plans and Limits](../../docs/guide/platform/administration/plans.md).
|
|
13
14
|
Cloudflare Access protection has separate create/connect controls. Users can
|
|
14
15
|
link another enabled login to their account with `void account link`.
|
|
15
16
|
|
|
@@ -57,6 +58,7 @@ export default defineConfig({
|
|
|
57
58
|
|
|
58
59
|
- `voidPlugin()` — Vite integration, routing, pages mode, codegen, migrations, packaging
|
|
59
60
|
- `void prepare` — generate `.void` artifacts for CI, editors, and fresh clones
|
|
61
|
+
- `void info [--json]` — discover persistent resource names before moving definitions
|
|
60
62
|
- `void auth login` — sign in to the project's saved Cloudflare or Void destination
|
|
61
63
|
- `void account login` — platform auth
|
|
62
64
|
- `void connect [url]` — choose Cloudflare or a Void platform, sign in, and save the deployment destination
|
|
@@ -98,6 +100,8 @@ Runtime helpers include:
|
|
|
98
100
|
|
|
99
101
|
Direct Cloudflare deployments also support D1, KV, R2, Queues, Hyperdrive, auth, cron jobs, AI, ISR, typed SQLite Durable Objects, and WebSocket rooms. They upload an immutable Worker Version, probe it before activation (using a 0%-traffic version override when Durable Objects disable preview URLs), and retain version metadata for migration-aware rollback.
|
|
100
102
|
|
|
103
|
+
Durable State and WebSocket definitions accept optional `name` to preserve their resource identity when files move. Run `void info` and pin the displayed name before moving deployed code. See [Durable State](../../docs/guide/durable-state.md#rename-a-file-while-keeping-its-state) and [WebSockets](../../docs/guide/websockets.md#move-a-route-while-keeping-its-state), including how to preserve room instances when renaming route parameters.
|
|
104
|
+
|
|
101
105
|
Self-hosted platform upgrades verify every packaged PostgreSQL migration and require the live Drizzle history to be an exact prefix. Pending SQL is allowed only for an explicitly attested old-version/schema compatibility edge, runs in one transaction, and leaves the old Worker version authoritative until the target runtime passes discovery and health checks.
|
|
102
106
|
|
|
103
107
|
An upgrade that changes the authenticated usage protocol briefly gates application traffic while it verifies the complete Worker set. An interruption leaves the gate closed for the next resumable upgrade instead of enabling an unsigned compatibility path.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { c as getToken,
|
|
2
|
-
import {
|
|
3
|
-
import { n as PlatformClient } from "./client-
|
|
4
|
-
import { n as runLoginCommand } from "./login-
|
|
1
|
+
import { c as getToken, f as removeToken } from "./auth-CQkSDS50.mjs";
|
|
2
|
+
import { L as log } from "./prompts-BNUoTiaf.mjs";
|
|
3
|
+
import { n as PlatformClient } from "./client-DKAsFA4X.mjs";
|
|
4
|
+
import { n as runLoginCommand } from "./login-BuiMyUrx.mjs";
|
|
5
5
|
import { execSync } from "node:child_process";
|
|
6
6
|
//#region src/cli/account-cmd.ts
|
|
7
7
|
async function runAccountCommand(root, args) {
|
|
8
8
|
switch (args.subcommand) {
|
|
9
9
|
case "login": return runLoginCommand(root);
|
|
10
|
-
case "link": return import("./auth-link-
|
|
10
|
+
case "link": return import("./auth-link-D75t9wO2.mjs").then(({ runAuthLink }) => runAuthLink(root, args.connectionId));
|
|
11
11
|
case "logout":
|
|
12
12
|
if (removeToken(root)) log.success("Logged out.");
|
|
13
13
|
else log.info("Not logged in.");
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { a as join, i as isAbsolute, t as basename } from "./dist-BVqXeR_h.mjs";
|
|
2
|
-
import { n as
|
|
2
|
+
import { c as scanWebSocketRoutes, f as readResourceDefinition, i as inferProjectBindings, l as scanWebSocketRoutesSync, m as needsApplicationDatabase, n as FRAMEWORK_SCAN_DIRS, r as detectFramework, s as isWebSocketPatternFile } from "./plugin-inference-CXWnn79A.mjs";
|
|
3
|
+
import { i as resolveProjectPaths, n as readProjectPaths } from "./project-paths-GgcMozYz.mjs";
|
|
4
|
+
import { t as findVoidAuthConfig } from "./config-DPByhVck.mjs";
|
|
5
|
+
import { h as resolveBindingNames, u as getDatabaseDialect } from "./config-Br_JZD6u.mjs";
|
|
3
6
|
import { n as globSync, t as glob } from "./dist-Bn8Kodjp.mjs";
|
|
4
7
|
import { n as isIdentifier } from "./ast-CPGPjb0V.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { i as scanEmailHandlers } from "./email--tEtMoj_.mjs";
|
|
9
|
-
import {
|
|
8
|
+
import { a as staticLiteral, i as staticExportInitializers, n as parseRouteFilename, o as unwrapStaticExpression, t as isRouteEnabledForEnvironment } from "./parse-filename-CUbj-1MP.mjs";
|
|
9
|
+
import { n as resourceNameWords } from "./resource-name-C7LVpcRm.mjs";
|
|
10
|
+
import { t as collectMigrations } from "./collect-DiTn9yr6.mjs";
|
|
11
|
+
import { a as scanEmailHandlersSync, i as scanEmailHandlers, r as hasEmailHandlers } from "./email--tEtMoj_.mjs";
|
|
12
|
+
import { t as scanPages } from "./scan-C7okrLyM.mjs";
|
|
13
|
+
import { o as isSandboxEnabled } from "./config-C_XRIPx2.mjs";
|
|
14
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
10
15
|
import { parseSync } from "vite";
|
|
11
16
|
//#region src/crons/scan.ts
|
|
12
17
|
const JOB_EXTENSIONS = [
|
|
@@ -65,6 +70,44 @@ function scanJobsSync(root, jobsDir = "crons") {
|
|
|
65
70
|
return parseJobFiles(root, jobsDir, files);
|
|
66
71
|
}
|
|
67
72
|
//#endregion
|
|
73
|
+
//#region src/durable/scan.ts
|
|
74
|
+
const MODULE_PATTERN = /\.(?:[cm]?[jt]s)$/;
|
|
75
|
+
function inferDurableResourceName(filePath) {
|
|
76
|
+
return filePath.replace(/\\/g, "/").split("/").pop().replace(MODULE_PATTERN, "");
|
|
77
|
+
}
|
|
78
|
+
const DURABLE_HELPERS = /* @__PURE__ */ new Set(["defineDurableState"]);
|
|
79
|
+
function deriveDurableResourceIdentity(name) {
|
|
80
|
+
const parts = resourceNameWords(name);
|
|
81
|
+
const classBase = parts.map((part) => part[0].toUpperCase() + part.slice(1)).join("");
|
|
82
|
+
return {
|
|
83
|
+
bindingName: parts.join("_").toUpperCase(),
|
|
84
|
+
className: `${classBase}DurableObject`,
|
|
85
|
+
migrationTag: `void-durable-${parts.join("-").toLowerCase()}-v1`
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function scanDurableObjectModules(root) {
|
|
89
|
+
const directory = join(root, "durable-objects");
|
|
90
|
+
if (!existsSync(directory)) return [];
|
|
91
|
+
const modules = readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && MODULE_PATTERN.test(entry.name) && !entry.name.endsWith(".d.ts")).sort((a, b) => a.name.localeCompare(b.name)).map((entry) => {
|
|
92
|
+
const filePath = join(directory, entry.name);
|
|
93
|
+
const name = readResourceDefinition(filePath, readFileSync(filePath, "utf-8"), DURABLE_HELPERS)?.name;
|
|
94
|
+
if (resourceNameWords(name ?? inferDurableResourceName(entry.name)).length === 0) throw new Error(`durable: cannot derive a name from durable-objects/${entry.name}.`);
|
|
95
|
+
return {
|
|
96
|
+
filePath,
|
|
97
|
+
...deriveDurableResourceIdentity(name ?? inferDurableResourceName(entry.name)),
|
|
98
|
+
...name === void 0 ? {} : { name }
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
102
|
+
const classes = /* @__PURE__ */ new Set();
|
|
103
|
+
for (const module of modules) {
|
|
104
|
+
if (bindings.has(module.bindingName) || classes.has(module.className)) throw new Error(`durable: duplicate generated name for '${module.filePath}'. Choose a different resource name or rename one of the durable-objects files.`);
|
|
105
|
+
bindings.add(module.bindingName);
|
|
106
|
+
classes.add(module.className);
|
|
107
|
+
}
|
|
108
|
+
return modules;
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
68
111
|
//#region src/queues/scan.ts
|
|
69
112
|
const QUEUE_EXTENSIONS = [
|
|
70
113
|
"ts",
|
|
@@ -226,31 +269,31 @@ function compareRouteSpecificity(a, b) {
|
|
|
226
269
|
async function scanRoutes(root, options) {
|
|
227
270
|
const paths = options?.paths ?? readProjectPaths(root);
|
|
228
271
|
const [routeFiles, websockets, middlewareFiles, jobs, queues, pages, email] = await Promise.all([
|
|
229
|
-
glob(ROUTE_PATTERN, {
|
|
272
|
+
options?.inventory ? [] : glob(ROUTE_PATTERN, {
|
|
230
273
|
cwd: paths.routesDir,
|
|
231
274
|
absolute: false
|
|
232
275
|
}),
|
|
233
|
-
scanWebSocketRoutes(root, paths, options?.environment),
|
|
234
|
-
glob(ROUTE_PATTERN, {
|
|
276
|
+
options?.inventory?.websockets ?? scanWebSocketRoutes(root, paths, options?.environment),
|
|
277
|
+
options?.inventory ? [] : glob(ROUTE_PATTERN, {
|
|
235
278
|
cwd: paths.middlewareDir,
|
|
236
279
|
absolute: false
|
|
237
280
|
}).catch(() => []),
|
|
238
|
-
scanJobs(root, paths.cronsDir),
|
|
239
|
-
scanQueues(root, paths.queuesDir),
|
|
281
|
+
options?.inventory?.jobs ?? scanJobs(root, paths.cronsDir),
|
|
282
|
+
options?.inventory?.queues ?? scanQueues(root, paths.queuesDir),
|
|
240
283
|
scanPages(root, {
|
|
241
284
|
output: options?.output,
|
|
242
285
|
paths
|
|
243
286
|
}),
|
|
244
|
-
scanEmailHandlers(paths.sourceRoot)
|
|
287
|
+
options?.inventory?.email ?? scanEmailHandlers(paths.sourceRoot)
|
|
245
288
|
]);
|
|
246
289
|
const routesDir = paths.routesDir;
|
|
247
290
|
return {
|
|
248
|
-
routes: routeFiles.filter((f) => !isWebSocketPatternFile(f)).filter((f) => !f.split("/").some((s) => s.startsWith("_"))).map((file) => parseRouteFilename(file)).filter((route) => isRouteEnabledForEnvironment(route, options?.environment)).map((route) => {
|
|
249
|
-
route
|
|
250
|
-
|
|
251
|
-
}).sort(compareRouteSpecificity),
|
|
291
|
+
routes: (options?.inventory?.routes ?? routeFiles.filter((f) => !isWebSocketPatternFile(f)).filter((f) => !f.split("/").some((s) => s.startsWith("_"))).map((file) => parseRouteFilename(file)).filter((route) => isRouteEnabledForEnvironment(route, options?.environment))).map((route) => ({
|
|
292
|
+
...route,
|
|
293
|
+
methods: detectHttpExports(join(routesDir, route.filePath))
|
|
294
|
+
})).sort(compareRouteSpecificity),
|
|
252
295
|
websockets,
|
|
253
|
-
middleware: parseMiddlewareDefinitions(middlewareFiles),
|
|
296
|
+
middleware: options?.inventory?.middleware ?? parseMiddlewareDefinitions(middlewareFiles),
|
|
254
297
|
jobs,
|
|
255
298
|
queues,
|
|
256
299
|
pages,
|
|
@@ -282,4 +325,78 @@ function scanRoutePatternsSync(root, paths = readProjectPaths(root), environment
|
|
|
282
325
|
return routeFiles.filter((f) => !isWebSocketPatternFile(f)).filter((f) => !f.split("/").some((s) => s.startsWith("_"))).map((f) => parseRouteFilename(f)).filter((route) => isRouteEnabledForEnvironment(route, environment)).sort(compareRouteSpecificity);
|
|
283
326
|
}
|
|
284
327
|
//#endregion
|
|
285
|
-
|
|
328
|
+
//#region src/application-analysis.ts
|
|
329
|
+
/**
|
|
330
|
+
* Discover application source features once for a consumer's environment.
|
|
331
|
+
* Resource ids, generated provider configuration and migration history remain
|
|
332
|
+
* the responsibility of the target consuming this analysis.
|
|
333
|
+
*/
|
|
334
|
+
function analyzeApplicationSync(root, options) {
|
|
335
|
+
const { config, environment } = options;
|
|
336
|
+
const paths = resolveProjectPaths(root, config);
|
|
337
|
+
const framework = detectFramework(root);
|
|
338
|
+
const scanDirs = config.inference?.scanDirs ?? (framework ? FRAMEWORK_SCAN_DIRS : void 0);
|
|
339
|
+
const inferred = inferProjectBindings(root, {
|
|
340
|
+
paths,
|
|
341
|
+
environment,
|
|
342
|
+
bindings: config.inference?.bindings
|
|
343
|
+
}, scanDirs);
|
|
344
|
+
const authConfigPath = findVoidAuthConfig(root, paths);
|
|
345
|
+
const authEnabled = inferred.needsAuth || authConfigPath !== null || config.auth !== void 0;
|
|
346
|
+
const bindings = {
|
|
347
|
+
...inferred,
|
|
348
|
+
needsAuth: authEnabled,
|
|
349
|
+
needsSandbox: inferred.needsSandbox || isSandboxEnabled(config)
|
|
350
|
+
};
|
|
351
|
+
const dialect = getDatabaseDialect(config);
|
|
352
|
+
const migrations = collectMigrations(paths.migrationsDir);
|
|
353
|
+
const jobs = scanJobsSync(root, paths.cronsDir);
|
|
354
|
+
const queues = scanQueuesSync(root, paths.queuesDir);
|
|
355
|
+
const allWebsockets = scanWebSocketRoutesSync(root, paths);
|
|
356
|
+
const websockets = allWebsockets.filter((route) => isRouteEnabledForEnvironment(route, environment));
|
|
357
|
+
const durableObjects = scanDurableObjectModules(root);
|
|
358
|
+
const email = scanEmailHandlersSync(paths.sourceRoot);
|
|
359
|
+
const overrides = config.inference?.bindings;
|
|
360
|
+
const bindingReason = (key, label, inferredReason) => overrides?.[key] ? `inference.bindings.${key} enables ${label}` : inferredReason;
|
|
361
|
+
const reasons = {
|
|
362
|
+
database: [],
|
|
363
|
+
kv: bindings.needsKV ? [bindingReason("kv", "KV", "app uses env.KV")] : [],
|
|
364
|
+
r2: bindings.needsR2 ? [bindingReason("storage", "R2", "app uses env.STORAGE (R2)")] : [],
|
|
365
|
+
ai: bindings.needsAI ? [bindingReason("ai", "Workers AI", "app uses Workers AI")] : [],
|
|
366
|
+
sandbox: bindings.needsSandbox ? [isSandboxEnabled(config) ? "void.config.ts enables Sandbox" : "app uses void/sandbox"] : [],
|
|
367
|
+
live: bindings.needsLive ? ["app uses void/live"] : [],
|
|
368
|
+
email: bindings.needsEmail ? [bindingReason("email", "email", "app uses void/email")] : [],
|
|
369
|
+
queues: bindings.needsQueues ? ["app uses void/queues"] : []
|
|
370
|
+
};
|
|
371
|
+
const databaseName = dialect === "sqlite" ? "a D1 database" : "a Hyperdrive database";
|
|
372
|
+
if (bindings.needsD1) reasons.database.push(bindingReason("db", databaseName, dialect === "sqlite" ? "app uses env.DB (D1)" : "app uses a database"));
|
|
373
|
+
if (authEnabled) reasons.database.push(`auth requires ${databaseName}`);
|
|
374
|
+
if (migrations.length > 0) reasons.database.push(`checked-in migrations need ${databaseName}`);
|
|
375
|
+
for (const queue of queues) reasons.queues.push(`queues/${queue.filePath} requires ${queue.bindingName}`);
|
|
376
|
+
if (hasEmailHandlers(email)) reasons.email.push("email/ contains inbound email handlers");
|
|
377
|
+
return {
|
|
378
|
+
root,
|
|
379
|
+
config,
|
|
380
|
+
environment,
|
|
381
|
+
paths,
|
|
382
|
+
framework,
|
|
383
|
+
bindings,
|
|
384
|
+
authConfigPath,
|
|
385
|
+
authEnabled,
|
|
386
|
+
dialect,
|
|
387
|
+
bindingNames: resolveBindingNames(config.inference?.bindings),
|
|
388
|
+
needsDatabase: needsApplicationDatabase(bindings, migrations.length),
|
|
389
|
+
migrations,
|
|
390
|
+
jobs,
|
|
391
|
+
queues,
|
|
392
|
+
websockets,
|
|
393
|
+
allWebsockets,
|
|
394
|
+
durableObjects,
|
|
395
|
+
email,
|
|
396
|
+
routes: scanRoutePatternsSync(root, paths, environment),
|
|
397
|
+
middleware: scanMiddlewareSync(root, paths),
|
|
398
|
+
reasons
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
//#endregion
|
|
402
|
+
export { inferDurableResourceName as a, deriveDurableResourceIdentity as i, scanRoutes as n, scanDurableObjectModules as o, scanQueuesSync as r, scanJobsSync as s, analyzeApplicationSync as t };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { n as scanRoutes, t as analyzeApplicationSync } from "./application-analysis-BVsVqc11.mjs";
|
|
2
|
+
//#region src/application-routing.ts
|
|
3
|
+
/** Complete route/page analysis using the same resource and handler inventories. */
|
|
4
|
+
async function completeApplicationAnalysis(analysis) {
|
|
5
|
+
const scan = await scanRoutes(analysis.root, {
|
|
6
|
+
output: analysis.config.output,
|
|
7
|
+
paths: analysis.paths,
|
|
8
|
+
environment: analysis.environment,
|
|
9
|
+
inventory: {
|
|
10
|
+
routes: analysis.routes,
|
|
11
|
+
middleware: analysis.middleware,
|
|
12
|
+
jobs: analysis.jobs,
|
|
13
|
+
queues: analysis.queues,
|
|
14
|
+
websockets: analysis.websockets,
|
|
15
|
+
email: analysis.email
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
...analysis,
|
|
20
|
+
scan
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
async function analyzeApplication(root, options) {
|
|
24
|
+
return completeApplicationAnalysis(analyzeApplicationSync(root, options));
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { completeApplicationAnalysis as n, analyzeApplication as t };
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { a as join } from "./dist-BVqXeR_h.mjs";
|
|
2
|
-
import { t as cfAccessHeaders } from "./cf-access-
|
|
3
|
-
import {
|
|
4
|
-
import { t as ensureCloudflaredToken } from "./cf-access-
|
|
5
|
-
import {
|
|
2
|
+
import { t as cfAccessHeaders } from "./cf-access-TWNzXltp.mjs";
|
|
3
|
+
import { C as writeKeyringPassword, S as readKeyringPassword, c as platformCredentialAccount, o as listPlatformConnections, r as getActivePlatformConnection, s as normalizePlatformApiUrl, x as deleteKeyringPassword } from "./platform-registry-DkPPXfp_.mjs";
|
|
4
|
+
import { t as ensureCloudflaredToken } from "./cf-access-BGe5sWXF.mjs";
|
|
5
|
+
import { i as readProjectPlatformUrl, r as readProjectConfig } from "./project-DKG5Ra8p.mjs";
|
|
6
6
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { createHash, randomBytes } from "node:crypto";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
|
-
//#region src/shared/proxy.ts
|
|
10
|
-
const DEFAULT_PROXY_URL = "https://proxy.void.cloud";
|
|
11
|
-
const STAGING_PROXY_URL = "https://proxy.staging.void.cloud";
|
|
12
|
-
//#endregion
|
|
13
9
|
//#region src/cli/auth.ts
|
|
14
10
|
const CONFIG_DIR = join(homedir(), ".void");
|
|
15
11
|
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
@@ -50,19 +46,22 @@ function readOriginScopedToken(apiUrl, config) {
|
|
|
50
46
|
}
|
|
51
47
|
return fileToken;
|
|
52
48
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
49
|
+
function connectedPlatform(apiUrl) {
|
|
50
|
+
if (!apiUrl) throw new Error("platform: No Void platform connected. Run `void connect <url>` first.");
|
|
51
|
+
const origin = normalizePlatformApiUrl(apiUrl);
|
|
52
|
+
const connection = listPlatformConnections().find((entry) => entry.apiUrl === origin);
|
|
53
|
+
if (!connection) throw new Error(`platform: No connection to ${origin}. Run \`void connect ${origin}\` first.`);
|
|
54
|
+
return connection;
|
|
55
55
|
}
|
|
56
56
|
function getSiteDomain(root = process.cwd()) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return domain;
|
|
57
|
+
const connection = connectedPlatform(getApiUrl(root));
|
|
58
|
+
if (!connection.applicationDomain) throw new Error(`platform: Missing application domain. Run \`void connect ${connection.apiUrl}\` to refresh the connection.`);
|
|
59
|
+
return connection.applicationDomain;
|
|
61
60
|
}
|
|
62
61
|
/**
|
|
63
62
|
* Read the deploy token.
|
|
64
63
|
* Priority: origin-bound VOID_TOKEN > system keychain > migrated config.
|
|
65
|
-
*
|
|
64
|
+
* Environment tokens must name their recipient with VOID_API_URL.
|
|
66
65
|
*/
|
|
67
66
|
function getToken(root = process.cwd()) {
|
|
68
67
|
const envToken = process.env.VOID_TOKEN;
|
|
@@ -74,47 +73,25 @@ function getToken(root = process.cwd()) {
|
|
|
74
73
|
return null;
|
|
75
74
|
}
|
|
76
75
|
const config = readConfig();
|
|
77
|
-
return readTokenForOrigin(apiUrl, config
|
|
76
|
+
return readTokenForOrigin(apiUrl, config);
|
|
78
77
|
}
|
|
79
78
|
/** Account actions follow the selected connection, independently of application metadata. */
|
|
80
79
|
function getAccountCredential() {
|
|
81
80
|
const config = readConfig();
|
|
82
|
-
const apiUrl =
|
|
81
|
+
const apiUrl = connectedPlatform(process.env.VOID_API_URL || getActivePlatformConnection()?.apiUrl).apiUrl;
|
|
83
82
|
return {
|
|
84
83
|
apiUrl,
|
|
85
|
-
token: readTokenForOrigin(apiUrl, config
|
|
84
|
+
token: readTokenForOrigin(apiUrl, config)
|
|
86
85
|
};
|
|
87
86
|
}
|
|
88
|
-
function readTokenForOrigin(apiUrl, config
|
|
87
|
+
function readTokenForOrigin(apiUrl, config) {
|
|
89
88
|
const envToken = process.env.VOID_TOKEN;
|
|
90
89
|
if (envToken) {
|
|
91
|
-
if (
|
|
90
|
+
if (!process.env.VOID_API_URL) throw new Error("auth: Set VOID_API_URL alongside VOID_TOKEN to identify the connected platform that issued it.");
|
|
91
|
+
if (apiUrl !== normalizePlatformApiUrl(process.env.VOID_API_URL)) throw new Error(`auth: VOID_TOKEN is not bound to ${apiUrl}. Set VOID_API_URL to this platform's URL with its matching token, or unset VOID_TOKEN to use the saved login.`);
|
|
92
92
|
return envToken;
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
const originToken = readOriginScopedToken(normalizedApiUrl, config);
|
|
96
|
-
if (originToken) return originToken;
|
|
97
|
-
const account = platformCredentialAccount(normalizedApiUrl);
|
|
98
|
-
if (legacyAccount) {
|
|
99
|
-
const legacyKeyringToken = keyringGet(legacyAccount);
|
|
100
|
-
if (legacyKeyringToken) {
|
|
101
|
-
keyringSet(account, legacyKeyringToken);
|
|
102
|
-
return legacyKeyringToken;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (!legacyAccount) return null;
|
|
106
|
-
const legacyFileToken = config[legacyAccount];
|
|
107
|
-
if (legacyFileToken) {
|
|
108
|
-
if (keyringSet(account, legacyFileToken)) {
|
|
109
|
-
config.api ??= normalizedApiUrl;
|
|
110
|
-
delete config[legacyAccount];
|
|
111
|
-
try {
|
|
112
|
-
writeConfig(config);
|
|
113
|
-
} catch {}
|
|
114
|
-
}
|
|
115
|
-
return legacyFileToken;
|
|
116
|
-
}
|
|
117
|
-
return null;
|
|
94
|
+
return readOriginScopedToken(apiUrl, config);
|
|
118
95
|
}
|
|
119
96
|
function getTokenSource() {
|
|
120
97
|
return process.env.VOID_TOKEN ? "ci" : "manual";
|
|
@@ -139,13 +116,6 @@ function removeToken(root = process.cwd()) {
|
|
|
139
116
|
try {
|
|
140
117
|
const config = readConfig();
|
|
141
118
|
let configChanged = false;
|
|
142
|
-
const legacyAccount = legacyCredentialAccount(root, apiUrl, config);
|
|
143
|
-
if (legacyAccount && keyringDelete(legacyAccount)) removed = true;
|
|
144
|
-
if (legacyAccount && config[legacyAccount]) {
|
|
145
|
-
delete config[legacyAccount];
|
|
146
|
-
configChanged = true;
|
|
147
|
-
removed = true;
|
|
148
|
-
}
|
|
149
119
|
if (config.tokens?.[apiUrl]) {
|
|
150
120
|
delete config.tokens[apiUrl];
|
|
151
121
|
if (Object.keys(config.tokens).length === 0) delete config.tokens;
|
|
@@ -156,21 +126,6 @@ function removeToken(root = process.cwd()) {
|
|
|
156
126
|
} catch {}
|
|
157
127
|
return removed;
|
|
158
128
|
}
|
|
159
|
-
const DEFAULT_API_URL = VOID_CLOUD_PLATFORM.apiUrl;
|
|
160
|
-
const STAGING_API_URL = VOID_CLOUD_STAGING_PLATFORM.apiUrl;
|
|
161
|
-
function legacyCredentialAccount(root, normalizedApiUrl, config) {
|
|
162
|
-
return legacyCredentialAccountForMode(isStagingMode(root), normalizedApiUrl, config);
|
|
163
|
-
}
|
|
164
|
-
function legacyCredentialAccountForMode(staging, normalizedApiUrl, config) {
|
|
165
|
-
const account = staging ? "stagingToken" : "token";
|
|
166
|
-
let configuredUrl;
|
|
167
|
-
try {
|
|
168
|
-
configuredUrl = normalizePlatformApiUrl(config.api ?? (staging ? STAGING_API_URL : DEFAULT_API_URL));
|
|
169
|
-
} catch {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
return configuredUrl === normalizedApiUrl ? account : null;
|
|
173
|
-
}
|
|
174
129
|
function base64Url(buffer) {
|
|
175
130
|
return buffer.toString("base64").replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
176
131
|
}
|
|
@@ -206,40 +161,15 @@ async function exchangeLoginCode(apiUrl, code, state, codeVerifier) {
|
|
|
206
161
|
if (!body || typeof body !== "object" || !("token" in body) || typeof body.token !== "string" || body.token.length === 0) throw new Error("auth: Login code exchange did not return a token.");
|
|
207
162
|
return body.token;
|
|
208
163
|
}
|
|
209
|
-
/**
|
|
210
|
-
* Read the API URL from environment or config file.
|
|
211
|
-
* Priority: VOID_API_URL env var > ~/.void/config.json > default
|
|
212
|
-
*/
|
|
164
|
+
/** Environment and project selections must refer to a verified local connection. */
|
|
213
165
|
function getApiUrl(root = process.cwd()) {
|
|
214
|
-
if (process.env.VOID_API_URL) return normalizePlatformApiUrl(process.env.VOID_API_URL);
|
|
215
|
-
if (isStagingMode(root)) return STAGING_API_URL;
|
|
216
166
|
const projectApiUrl = readProjectPlatformUrl(root);
|
|
217
|
-
if (projectApiUrl)
|
|
218
|
-
|
|
219
|
-
if (listPlatformConnections().some((connection) => connection.apiUrl === projectApiUrl)) return projectApiUrl;
|
|
220
|
-
throw new Error(`platform: Project metadata selected unverified platform ${projectApiUrl}. Connect to it explicitly with \`void connect ${projectApiUrl}\` before forwarding credentials.`);
|
|
221
|
-
}
|
|
222
|
-
const config = readConfig();
|
|
223
|
-
const legacySelection = readLegacyHostedPlatformSelection();
|
|
224
|
-
let apiUrl = (isLegacyVoidCloudProject(root) ? DEFAULT_API_URL : void 0) ?? getActivePlatformConnection()?.apiUrl ?? config.api ?? legacySelection?.apiUrl;
|
|
225
|
-
apiUrl ??= process.env.VOID_TOKEN ? DEFAULT_API_URL : void 0;
|
|
226
|
-
if (!apiUrl) {
|
|
227
|
-
apiUrl = keyringGet("token") ? DEFAULT_API_URL : keyringGet("stagingToken") ? STAGING_API_URL : void 0;
|
|
228
|
-
if (apiUrl) try {
|
|
229
|
-
writeConfig({
|
|
230
|
-
...config,
|
|
231
|
-
api: apiUrl
|
|
232
|
-
});
|
|
233
|
-
} catch {}
|
|
234
|
-
}
|
|
235
|
-
if (!apiUrl) throw new Error("platform: No Void platform selected. Run `void connect <url>` or `void platform install` first.");
|
|
236
|
-
return normalizePlatformApiUrl(apiUrl);
|
|
167
|
+
if (readProjectConfig(root) && !projectApiUrl) throw new Error("platform: This project link has no platform URL. Run `void connect <url>`, then `void project link` to choose its destination.");
|
|
168
|
+
return connectedPlatform(process.env.VOID_API_URL || projectApiUrl || getActivePlatformConnection()?.apiUrl).apiUrl;
|
|
237
169
|
}
|
|
238
170
|
function getProxyUrl(root = process.cwd()) {
|
|
171
|
+
const apiUrl = getApiUrl(root);
|
|
239
172
|
if (process.env.VOID_PROXY_URL) return normalizePlatformApiUrl(process.env.VOID_PROXY_URL);
|
|
240
|
-
const apiUrl = normalizePlatformApiUrl(getApiUrl(root));
|
|
241
|
-
if (apiUrl === STAGING_API_URL) return STAGING_PROXY_URL;
|
|
242
|
-
if (apiUrl === DEFAULT_API_URL) return DEFAULT_PROXY_URL;
|
|
243
173
|
const proxyUrl = listPlatformConnections().find((connection) => connection.apiUrl === apiUrl)?.proxyUrl;
|
|
244
174
|
if (proxyUrl === null || proxyUrl === void 0) throw new Error(`platform: No verified proxy is registered for ${apiUrl}. Reconnect with \`void connect ${apiUrl}\` or set VOID_PROXY_URL explicitly.`);
|
|
245
175
|
return proxyUrl;
|
|
@@ -412,4 +342,4 @@ async function runPlatformLogin(origin, provider = "github", onUrl) {
|
|
|
412
342
|
});
|
|
413
343
|
}
|
|
414
344
|
//#endregion
|
|
415
|
-
export {
|
|
345
|
+
export { getApiUrl as a, getToken as c, readPlatformToken as d, removeToken as f, saveToken as g, savePlatformToken as h, getAccountCredential as i, getTokenSource as l, runPlatformLogin as m, createCodeChallenge as n, getProxyUrl as o, runLogin as p, createCodeVerifier as r, getSiteDomain as s, awaitBrowserCallback as t, openBrowser as u };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as getApiUrl, c as getToken,
|
|
2
|
-
import {
|
|
3
|
-
import { n as PlatformClient } from "./client-
|
|
4
|
-
import { r as selectPlatformLoginMethod } from "./login-
|
|
5
|
-
import { t as discoverPlatform } from "./platform-cmd-
|
|
1
|
+
import { a as getApiUrl, c as getToken, h as savePlatformToken, m as runPlatformLogin, u as openBrowser } from "./auth-CQkSDS50.mjs";
|
|
2
|
+
import { L as log } from "./prompts-BNUoTiaf.mjs";
|
|
3
|
+
import { n as PlatformClient } from "./client-DKAsFA4X.mjs";
|
|
4
|
+
import { r as selectPlatformLoginMethod } from "./login-BuiMyUrx.mjs";
|
|
5
|
+
import { t as discoverPlatform } from "./platform-cmd-DMDEc9uS.mjs";
|
|
6
6
|
import { execFile } from "node:child_process";
|
|
7
7
|
//#region src/cli/auth-link.ts
|
|
8
8
|
async function runAuthLink(root, connectionId) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { o as listPlatformConnections } from "./platform-registry-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { o as listPlatformConnections } from "./platform-registry-DkPPXfp_.mjs";
|
|
2
|
+
import { n as readDeploymentPlatform } from "./project-DKG5Ra8p.mjs";
|
|
3
|
+
import { K as select, tt as isCancel } from "./prompts-BNUoTiaf.mjs";
|
|
4
4
|
//#region src/cli/auth-router.ts
|
|
5
5
|
async function chooseDestination(root, args, interactive) {
|
|
6
6
|
const saved = readDeploymentPlatform(root);
|
|
@@ -37,7 +37,7 @@ async function chooseDestination(root, args, interactive) {
|
|
|
37
37
|
}
|
|
38
38
|
async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isTTY)) {
|
|
39
39
|
if (args.subcommand === "link") {
|
|
40
|
-
const { runAccountCommand } = await import("./account-cmd-
|
|
40
|
+
const { runAccountCommand } = await import("./account-cmd-vJhh5lrb.mjs");
|
|
41
41
|
await runAccountCommand(root, {
|
|
42
42
|
subcommand: "link",
|
|
43
43
|
...args.connectionId ? { connectionId: args.connectionId } : {}
|
|
@@ -45,17 +45,17 @@ async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isT
|
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
if (args.subcommand === "token") {
|
|
48
|
-
const { runAccountCommand } = await import("./account-cmd-
|
|
48
|
+
const { runAccountCommand } = await import("./account-cmd-vJhh5lrb.mjs");
|
|
49
49
|
await runAccountCommand(root, { subcommand: "token" });
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
const destination = await chooseDestination(root, args, interactive);
|
|
53
53
|
if (destination.platform === "cloudflare") {
|
|
54
|
-
const { runCloudflareCommand } = await import("./cloudflare-cmd-
|
|
54
|
+
const { runCloudflareCommand } = await import("./cloudflare-cmd-CmY8dGkd.mjs");
|
|
55
55
|
await runCloudflareCommand(root, { subcommand: args.subcommand === "whoami" || args.subcommand === "status" ? "status" : args.subcommand });
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
const { runAccountCommand } = await import("./account-cmd-
|
|
58
|
+
const { runAccountCommand } = await import("./account-cmd-vJhh5lrb.mjs");
|
|
59
59
|
const subcommand = args.subcommand === "status" ? "whoami" : args.subcommand;
|
|
60
60
|
if (!destination.apiUrl) {
|
|
61
61
|
await runAccountCommand(root, { subcommand });
|
|
@@ -77,11 +77,17 @@ function resolveSocialProviders(env, configuredProviders) {
|
|
|
77
77
|
}
|
|
78
78
|
return Object.keys(providers).length > 0 ? providers : void 0;
|
|
79
79
|
}
|
|
80
|
-
function appendAuthHeaders(c, source) {
|
|
80
|
+
function appendAuthHeaders(c, source, includeCachePolicy) {
|
|
81
81
|
if (!source) return;
|
|
82
82
|
source.forEach((value, key) => {
|
|
83
|
+
if (!includeCachePolicy && ["cache-control", "pragma"].includes(key.toLowerCase())) return;
|
|
83
84
|
c.header(key, value, { append: key.toLowerCase() === "set-cookie" });
|
|
84
85
|
});
|
|
86
|
+
if (source.has("set-cookie") && !(source.get("cache-control") ?? "").split(",").some((directive) => [
|
|
87
|
+
"private",
|
|
88
|
+
"no-store",
|
|
89
|
+
"no-cache"
|
|
90
|
+
].includes(directive.trim().toLowerCase()))) c.header("Cache-Control", "private, no-store");
|
|
85
91
|
}
|
|
86
92
|
function resolveUserConfig(userConfig, defaults, request, env, dialect) {
|
|
87
93
|
const mergeEmailAndPasswordDefaults = (options) => {
|
|
@@ -175,7 +181,12 @@ function createVoidAuthRuntime(dialect, resolveDatabase, runVoidAuthMigrations)
|
|
|
175
181
|
}, async () => {
|
|
176
182
|
await next();
|
|
177
183
|
});
|
|
178
|
-
|
|
184
|
+
const credentialed = [
|
|
185
|
+
"cookie",
|
|
186
|
+
"authorization",
|
|
187
|
+
"cf-access-jwt-assertion"
|
|
188
|
+
].some((header) => c.req.raw.headers.has(header));
|
|
189
|
+
appendAuthHeaders(c, result.headers, state !== null || credentialed || result.headers?.has("set-cookie") === true);
|
|
179
190
|
} finally {
|
|
180
191
|
await dispose();
|
|
181
192
|
}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { n as PlatformClient, t as PlatformApiError } from "./client-
|
|
5
|
-
import { a as dim, c as import_picocolors, r as cliTitle } from "./output-
|
|
1
|
+
import { r as readProjectConfig } from "./project-DKG5Ra8p.mjs";
|
|
2
|
+
import { c as getToken } from "./auth-CQkSDS50.mjs";
|
|
3
|
+
import { H as outro, L as log, N as intro } from "./prompts-BNUoTiaf.mjs";
|
|
4
|
+
import { n as PlatformClient, t as PlatformApiError } from "./client-DKAsFA4X.mjs";
|
|
5
|
+
import { a as dim, c as import_picocolors, r as cliTitle } from "./output-CbM85T4k.mjs";
|
|
6
6
|
import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
|
|
7
7
|
import { appendFileSync, writeFileSync } from "node:fs";
|
|
8
8
|
//#region src/cli/build-cmd.ts
|
|
9
9
|
const POLL_MS = 1e3;
|
|
10
|
+
const BUILD_LOG_DRAIN_TIMEOUT_MS = 12e4;
|
|
11
|
+
function isBuildLogComplete(page) {
|
|
12
|
+
if (!page.terminal) return false;
|
|
13
|
+
if (page.logsComplete === null || page.logsComplete === void 0) throw new Error("This platform cannot confirm that the final build logs were captured. Ask its administrator to upgrade the platform runtime, or read the retained logs without --follow.");
|
|
14
|
+
return page.logsComplete === true;
|
|
15
|
+
}
|
|
10
16
|
function sleep(ms) {
|
|
11
17
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
18
|
}
|
|
@@ -24,7 +30,7 @@ function isFatalFollowError(err) {
|
|
|
24
30
|
}
|
|
25
31
|
/**
|
|
26
32
|
* Pure follow-loop: repeatedly fetch pages since a cursor, write each new
|
|
27
|
-
* line, and stop when the build
|
|
33
|
+
* line, and stop when the terminal build confirms its final logs were captured. `fetchPage`,
|
|
28
34
|
* `write`, and `sleep` are injected so this is unit-testable. Returns the
|
|
29
35
|
* final status + terminal flag.
|
|
30
36
|
*
|
|
@@ -37,6 +43,7 @@ function isFatalFollowError(err) {
|
|
|
37
43
|
async function followBuildLogs(opts) {
|
|
38
44
|
let cursor = opts.since;
|
|
39
45
|
let status = opts.status;
|
|
46
|
+
let terminalSince = null;
|
|
40
47
|
const pollMs = opts.pollMs ?? POLL_MS;
|
|
41
48
|
for (;;) {
|
|
42
49
|
await opts.sleep(pollMs);
|
|
@@ -51,10 +58,15 @@ async function followBuildLogs(opts) {
|
|
|
51
58
|
for (const l of pageResult.lines) opts.write(l.line);
|
|
52
59
|
cursor = pageResult.lastSeq;
|
|
53
60
|
status = pageResult.status;
|
|
54
|
-
if (pageResult
|
|
61
|
+
if (isBuildLogComplete(pageResult)) return {
|
|
55
62
|
status,
|
|
56
63
|
terminal: true
|
|
57
64
|
};
|
|
65
|
+
if (pageResult.terminal) {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
terminalSince ??= now;
|
|
68
|
+
if (now - terminalSince >= BUILD_LOG_DRAIN_TIMEOUT_MS) throw new Error("Build finished, but its log producer did not confirm completion. Retry the command to recover the final log tail.");
|
|
69
|
+
} else terminalSince = null;
|
|
58
70
|
}
|
|
59
71
|
}
|
|
60
72
|
async function runBuildCommand(root, args) {
|
|
@@ -116,14 +128,14 @@ async function runBuildLogsCommand(root, args) {
|
|
|
116
128
|
await sleep(POLL_MS);
|
|
117
129
|
}
|
|
118
130
|
if (first.external) {
|
|
119
|
-
log.message(`This build ran on GitHub Actions. View logs:\n${import_picocolors.default.
|
|
131
|
+
log.message(`This build ran on GitHub Actions. View logs:\n${import_picocolors.default.blue(first.external)}`);
|
|
120
132
|
return;
|
|
121
133
|
}
|
|
122
134
|
if (args.output) writeFileSync(args.output, "");
|
|
123
135
|
for (const l of first.lines) write(l.line);
|
|
124
136
|
let status = first.status;
|
|
125
137
|
let terminal = first.terminal;
|
|
126
|
-
if (args.follow && !
|
|
138
|
+
if (args.follow && !isBuildLogComplete(first)) ({status, terminal} = await followBuildLogs({
|
|
127
139
|
fetchPage: (since) => client.getBuildLogs(projectId, buildId, since),
|
|
128
140
|
write,
|
|
129
141
|
sleep,
|