void 0.20.2 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/agents-gni4eqBu.mjs +111 -0
- package/dist/auth-3sGB0zJ1.mjs +22 -0
- package/dist/{auth-DPl6kck4.mjs → auth-B9_D6ygs.mjs} +6 -241
- package/dist/auth-CAw7zHqj.mjs +2 -0
- package/dist/auth-client-BWBT8HLp.mjs +6 -0
- package/dist/auth-client-Bawdj38n.d.mts +7 -0
- package/dist/auth-client-react-7GFffu8R.d.mts +7 -0
- package/dist/auth-client-react-CMLwT2xI.mjs +6 -0
- package/dist/auth-client-solid-DyTFL4cq.d.mts +7 -0
- package/dist/auth-client-solid-UoreJWZG.mjs +6 -0
- package/dist/auth-client-svelte-Cv_WvrRk.mjs +6 -0
- package/dist/auth-client-svelte-zetW0KIH.d.mts +7 -0
- package/dist/auth-client-vue-CFk7Xbv3.mjs +6 -0
- package/dist/auth-client-vue-bChShbQP.d.mts +7 -0
- package/dist/{auth-cmd-gniL2fNt.mjs → auth-cmd-MkBG2u1f.mjs} +5 -5
- package/dist/{auth-link-NZdjCmSc.mjs → auth-link-Devmv96E.mjs} +5 -5
- package/dist/{better-auth-shared-DSCeohOK.d.mts → better-auth-shared-BoVwA5Vm.d.mts} +1 -6
- package/dist/{better-auth-shared-CYw1T3k4.mjs → better-auth-shared-syGYYmnY.mjs} +1 -1
- package/dist/{build-cmd-sI18tX_O.mjs → build-cmd-DsBGwtfs.mjs} +6 -4
- package/dist/{cache-IHn5MwBC.mjs → cache-BMw8eMyF.mjs} +6 -4
- package/dist/{cancel-deploy-C5qTOdLi.mjs → cancel-deploy-B3_s9NIN.mjs} +5 -3
- package/dist/cf-access-rAZxzMkL.mjs +181 -0
- package/dist/cf-build-output-CTdlo6Rt.mjs +520 -0
- package/dist/cli/cf-compat.d.mts +1 -0
- package/dist/cli/cf-compat.mjs +934 -0
- package/dist/cli/cli.mjs +61 -38
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/client-DAAivdid.mjs +2 -0
- package/dist/{client-dHfSJvAN.mjs → client-PdAJ-F0t.mjs} +148 -89
- package/dist/{cloudflare-auth-6M5llVPC.mjs → cloudflare-auth-BCmTc1X_.mjs} +13 -44
- package/dist/{cloudflare-cmd-4RPGN3KB.mjs → cloudflare-cmd-D6PrKn7o.mjs} +4 -7
- package/dist/{cloudflare-connect-t1UU5svD.mjs → cloudflare-connect-DloREDlc.mjs} +6 -6
- package/dist/cloudflare-operations-BHNJVDbN.mjs +2 -0
- package/dist/{cloudflare-operations-BzWnlC1_.mjs → cloudflare-operations-CPEdHYhM.mjs} +37 -39
- package/dist/cloudflare-user-output-Q-k0QoNQ.mjs +20 -0
- package/dist/collect-DAUItMDS.mjs +2 -0
- package/dist/collect-DXHNWHcT.mjs +48 -0
- package/dist/config--T87TD8T.mjs +2 -0
- package/dist/{config-NOG_U1aK.mjs → config-BSe70f4T.mjs} +4 -6
- package/dist/config-DDIFxQYx.mjs +2 -0
- package/dist/{config-uNGuFsI2.mjs → config-Dxr6cTXn.mjs} +22 -37
- package/dist/config-DywxBLQC.d.mts +185 -0
- package/dist/config-entry.d.mts +6 -0
- package/dist/config-entry.mjs +7 -0
- package/dist/config-uP7ZDtVZ.mjs +21 -0
- package/dist/config-write-y3CBI_ux.mjs +60 -0
- package/dist/{connect-Bfk31O_8.mjs → connect-BvC9kolB.mjs} +8 -6
- package/dist/{create-project-Bk9Z0-Jg.mjs → create-project-C9lQhRzj.mjs} +9 -25
- package/dist/create-project-CI-17RVJ.mjs +2 -0
- package/dist/database-provider-Cx525bwX.mjs +6 -0
- package/dist/database-provider.mjs +1 -5
- package/dist/{db-BkRoptAt.mjs → db-R7IQgOv5.mjs} +48 -44
- package/dist/{delete-DouASY9P.mjs → delete-CghI_NXn.mjs} +6 -4
- package/dist/deploy-CYPymbtG.mjs +2 -0
- package/dist/{deploy-DTaWUS1S.mjs → deploy-H968Lo4T.mjs} +765 -197
- package/dist/discover-BBzDZe_o.mjs +2 -0
- package/dist/{discover-xvfrgJeo.mjs → discover-C4O6YxVS.mjs} +3 -8
- package/dist/{dist-BrsS7cai.mjs → dist-4WkAWhWx.mjs} +1 -15
- package/dist/{dist-m40_XgNh.mjs → dist-Bn8Kodjp.mjs} +1 -1
- package/dist/dist-C5fND3R0.mjs +2 -0
- package/dist/dist-D7-nEOXi.mjs +2 -0
- package/dist/{output-B0cfNSx5.mjs → dist-Dn6nn2IU.mjs} +3 -926
- package/dist/{domain-1RhhOVrC.mjs → domain-CITt8lC-.mjs} +7 -5
- package/dist/{route-types-Da-DpyUp.mjs → drizzle-Beb2Am5S.mjs} +1 -280
- package/dist/{email-Ce6SQq-i.mjs → email-C5kaZXzJ.mjs} +2 -2
- package/dist/{email-C-lGh51B.mjs → email-_8VmyX7V.mjs} +14 -12
- package/dist/{entry-DU3oDoQ3.mjs → entry-DdRFGK0y.mjs} +2 -2
- package/dist/{env-DJHsPE7Z.mjs → env-DV4r3nHz.mjs} +9 -7
- package/dist/{env-DBKmK4vc.mjs → env-DX_v-Q-v.mjs} +1 -1
- package/dist/env-Yz4HcvHs.mjs +78 -0
- package/dist/env-helpers--wFmQ_5Q.mjs +136 -0
- package/dist/{env-types-BNPhro-M.mjs → env-types-CWDtqHgw.mjs} +6 -2
- package/dist/{env-validation-CF6KvTRf.mjs → env-validation-BsFEXps5.mjs} +19 -28
- package/dist/env-validation-DIDGM7h4.mjs +2 -0
- package/dist/fetch-CXDChK7B.mjs +18 -0
- package/dist/fetch-_SeGZao9.d.mts +57 -0
- package/dist/fetch-stream-AOByI7Ki.mjs +81 -0
- package/dist/fetch-stream-Bjf0hoZb.d.mts +49 -0
- package/dist/gen-BBiIZw6g.mjs +2 -0
- package/dist/{gen-B_wPnVTK.mjs → gen-CFOEEc-t.mjs} +13 -11
- package/dist/{generate-RTK8_kK1.mjs → generate-C0VY6RVf.mjs} +2 -2
- package/dist/{github-cmd-PW7ZnWTp.mjs → github-cmd-jYjha2LO.mjs} +18 -22
- package/dist/{handler-D1hLsObx.d.mts → handler-BXJTXd02.d.mts} +6 -1
- package/dist/handler-DghKr6dU.mjs +150 -0
- package/dist/head-D_QRR5Yd.mjs +112 -0
- package/dist/head-client-DzmJGN4C.mjs +90 -0
- package/dist/{headers-BAHwgHdW.mjs → headers-B_HBMgi0.mjs} +2 -2
- package/dist/{help-CwOX-zmI.mjs → help-C46mnlUS.mjs} +17 -12
- package/dist/help-CS_nAsWu.mjs +2 -0
- package/dist/index.d.mts +2 -20
- package/dist/index.mjs +116 -60
- package/dist/{init-BWZ7q5Z4.mjs → init-CSXmvxKu.mjs} +49 -50
- package/dist/{link-Rmvu2Wl_.mjs → link-DxMOALXk.mjs} +7 -5
- package/dist/{list-DEE2S6mY.mjs → list-0wQs0oYg.mjs} +7 -5
- package/dist/live-CB1y5IuC.mjs +411 -0
- package/dist/live-CKiJilLr.d.mts +105 -0
- package/dist/local-d1-DzykTWY8.mjs +104 -0
- package/dist/{login-Uvferzmm.mjs → login-CKk5NX4d.mjs} +6 -11
- package/dist/login-Ch9cgWRF.mjs +2 -0
- package/dist/{logs-27FenuiC.mjs → logs-hxWBSoej.mjs} +6 -4
- package/dist/migrate-CLty4mZR.mjs +2 -0
- package/dist/migrate-DcW8F2W8.mjs +285 -0
- package/dist/migration-handler-DM4clYj5.d.mts +51 -0
- package/dist/{neon-DHwd2zvC.mjs → neon-n74ta1Pr.mjs} +1 -1
- package/dist/{node-Ez5KW5rn.mjs → node-Cupyf7-s.mjs} +6 -6
- package/dist/{operator-auth-B3e08unv.mjs → operator-auth-BkVgJqv-.mjs} +2 -2
- package/dist/{operator-client-LUZnlnYk.mjs → operator-client-A0iex2yi.mjs} +2 -1
- package/dist/{operator-cmd-CjOTmAYE.mjs → operator-cmd-BEUYhaHB.mjs} +6 -6
- package/dist/output-urU86XeT.mjs +146 -0
- package/dist/{package-json-CPoWX79C.mjs → package-json-iCbMg5XF.mjs} +1 -1
- package/dist/pages/client.d.mts +5 -2
- package/dist/pages/client.mjs +5 -3
- package/dist/pages/head-client.mjs +1 -89
- package/dist/pages/head.mjs +1 -111
- package/dist/pages/index.d.mts +2 -3
- package/dist/pages/index.mjs +7 -7
- package/dist/pages/islands-plugin.mjs +2 -2
- package/dist/pages/prefetch.d.mts +2 -30
- package/dist/pages/prefetch.mjs +1 -89
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +3 -3
- package/dist/pages/serialize.d.mts +2 -9
- package/dist/pages/serialize.mjs +1 -13
- package/dist/plan-BEZ8VJW0.mjs +256 -0
- package/dist/plan-DpuOr14e.mjs +2 -0
- package/dist/{platform-auth-config-DrbQXXiW.mjs → platform-auth-config-Df6yVw-e.mjs} +6 -6
- package/dist/{platform-auth-protection-Bhtvp0B_.mjs → platform-auth-protection-Jb0yftay.mjs} +7 -5
- package/dist/{platform-auth-recovery-CeOKGVeJ.mjs → platform-auth-recovery-DmRyIfW0.mjs} +6 -5
- package/dist/platform-cmd-C9Vt7m-d.mjs +2 -0
- package/dist/{platform-cmd-BFhieCdV.mjs → platform-cmd-DRxCOTwy.mjs} +8 -5
- package/dist/{platform-domain-C74PULqV.mjs → platform-domain-IjiXgrXJ.mjs} +4 -3
- package/dist/{platform-lifecycle-BwAIgz-t.mjs → platform-lifecycle-BquAaU-5.mjs} +263 -56
- package/dist/platform-lifecycle-CuJIZNvA.mjs +2 -0
- package/dist/{platform-management-COogu_Se.mjs → platform-management-CCQKGsq4.mjs} +12 -7
- package/dist/platform-management-Cgyed0WY.mjs +2 -0
- package/dist/{platform-recovery-ewqLefp1.mjs → platform-recovery-DS8ih1SW.mjs} +3 -3
- package/dist/platform-registry-BJbgZLS1.mjs +431 -0
- package/dist/{plugin-inference-BDRfZngg.mjs → plugin-inference-DsvtJLll.mjs} +4 -4
- package/dist/prefetch-Bsc_Pb6c.mjs +90 -0
- package/dist/prefetch-Ce6la4EI.d.mts +31 -0
- package/dist/{prepare-blNRQvQl.mjs → prepare-CaUxODOU.mjs} +3 -2
- package/dist/prepare-D4CkM3_v.mjs +2 -0
- package/dist/{prepare-CtDJjoOj.mjs → prepare-pcWcxSCh.mjs} +13 -11
- package/dist/prerender-render-Cf_WDE9W.mjs +111 -0
- package/dist/prerender-render.mjs +1 -110
- package/dist/{preset-lAy0B0BQ.mjs → preset-Dowh9tTt.mjs} +16 -118
- package/dist/project-BEBFDFLz.mjs +2 -0
- package/dist/project-CWNIPoXc.mjs +209 -0
- package/dist/{project-cmd-DmZK9Hxf.mjs → project-cmd-2lN--YAX.mjs} +18 -16
- package/dist/{project-paths-SK8nMHPp.mjs → project-paths-CKQ-Q5JS.mjs} +47 -14
- package/dist/project-slug-23TpquG4.mjs +8 -0
- package/dist/project-slug-DofjTFd-.mjs +2 -0
- package/dist/{project-team-D8jOJMUJ.mjs → project-team-Dapn9HZn.mjs} +9 -5
- package/dist/{project-token-DA34bf-C.mjs → project-token-C90v9SJK.mjs} +6 -4
- package/dist/{project-tsconfig-Ql2XsSQp.mjs → project-tsconfig-CwfqUnVp.mjs} +2 -2
- package/dist/{protocol-C-pqYJjE.d.mts → protocol-ZH3jP4a7.d.mts} +1 -1
- package/dist/providers-BNKRacMr.d.mts +7 -0
- package/dist/provision-CNgEBkVA.mjs +3 -0
- package/dist/{provision-CSJOjjQk.mjs → provision-Cck2m3jJ.mjs} +11 -25
- package/dist/queues-BWKt1Xo4.d.mts +7 -0
- package/dist/{requests-CUExwGQQ.mjs → requests-CzX46I0i.mjs} +5 -3
- package/dist/resolve-project-BTotl8Nn.mjs +2 -0
- package/dist/{resolve-project--Vxawf7z.mjs → resolve-project-Xvis70DG.mjs} +2 -8
- package/dist/response-Tn7rU0MV.mjs +30 -0
- package/dist/{rollback-CDNGU1gr.mjs → rollback-BEeyc73H.mjs} +6 -4
- package/dist/{rolldown-runtime-rQ84J-ij.mjs → rolldown-runtime-DXIUcv95.mjs} +1 -10
- package/dist/route-types-Id82-veQ.mjs +280 -0
- package/dist/{local-d1-D2I6Ox5F.mjs → runner-BGVsGgkb.mjs} +6 -114
- package/dist/runner-CQs_cDSG.mjs +2 -0
- package/dist/runner-mysql-1o47achK.mjs +2 -0
- package/dist/{runner-mysql-7BPUNGmL.mjs → runner-mysql-BhwMk2Bm.mjs} +2 -9
- package/dist/{runner-pg-BkEza-dX.mjs → runner-pg-CJ_JeGF6.mjs} +2 -9
- package/dist/runner-pg-D7z01mQS.mjs +2 -0
- package/dist/runtime/ai.mjs +1 -1
- package/dist/runtime/auth-client-react.d.mts +2 -6
- package/dist/runtime/auth-client-react.mjs +1 -5
- package/dist/runtime/auth-client-solid.d.mts +2 -6
- package/dist/runtime/auth-client-solid.mjs +1 -5
- package/dist/runtime/auth-client-svelte.d.mts +2 -6
- package/dist/runtime/auth-client-svelte.mjs +1 -5
- package/dist/runtime/auth-client-vue.d.mts +2 -6
- package/dist/runtime/auth-client-vue.mjs +1 -5
- package/dist/runtime/auth-client.d.mts +2 -6
- package/dist/runtime/auth-client.mjs +1 -5
- package/dist/runtime/auth.mjs +1 -21
- package/dist/runtime/better-auth-mysql.d.mts +1 -1
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/client-react.d.mts +3 -3
- package/dist/runtime/client-react.mjs +3 -3
- package/dist/runtime/client-solid.d.mts +3 -3
- package/dist/runtime/client-solid.mjs +3 -3
- package/dist/runtime/client-svelte.d.mts +3 -3
- package/dist/runtime/client-svelte.mjs +3 -3
- package/dist/runtime/client-vue.d.mts +3 -3
- package/dist/runtime/client-vue.mjs +3 -3
- package/dist/runtime/client.d.mts +3 -3
- package/dist/runtime/client.mjs +3 -3
- package/dist/runtime/db.mjs +1 -1
- package/dist/runtime/durable.mjs +1 -1
- package/dist/runtime/email/testing.mjs +1 -1
- package/dist/runtime/env-helpers.mjs +1 -135
- package/dist/runtime/env-public-client.mjs +1 -1
- package/dist/runtime/env-public.mjs +2 -2
- package/dist/runtime/env.mjs +1 -77
- package/dist/runtime/fetch-stream.d.mts +2 -49
- package/dist/runtime/fetch-stream.mjs +2 -80
- package/dist/runtime/fetch.d.mts +2 -57
- package/dist/runtime/fetch.mjs +2 -17
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/handler.mjs +1 -149
- package/dist/runtime/kv.mjs +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live-server.mjs +2 -2
- package/dist/runtime/live.d.mts +2 -104
- package/dist/runtime/live.mjs +1 -410
- package/dist/runtime/migration-handler-mysql.d.mts +1 -1
- package/dist/runtime/migration-handler-pg.d.mts +1 -1
- package/dist/runtime/migration-handler.d.mts +2 -50
- package/dist/runtime/queues.d.mts +2 -6
- package/dist/runtime/queues.mjs +1 -1
- package/dist/runtime/remote/index.mjs +49 -8
- package/dist/runtime/response.mjs +1 -29
- package/dist/runtime/sandbox.d.mts +4 -56
- package/dist/runtime/sandbox.mjs +82 -221
- package/dist/runtime/sse.mjs +1 -171
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/validator.mjs +1 -71
- package/dist/runtime/ws-server.d.mts +2 -2
- package/dist/runtime/ws-server.mjs +2 -2
- package/dist/runtime/ws.d.mts +2 -121
- package/dist/{scan-CpK-57ug.mjs → scan-DJbooZm2.mjs} +3 -3
- package/dist/{scan-BMH4rzlv.mjs → scan-DdDvRCU1.mjs} +8 -26
- package/dist/{secret-Bzzi2e9E.mjs → secret-wnTel5Yw.mjs} +8 -6
- package/dist/serialize-BPvnNQuA.mjs +14 -0
- package/dist/serialize-CfSwWfF2.d.mts +10 -0
- package/dist/{skills-C0RvGjeE.mjs → skills-B-690E7h.mjs} +3 -2
- package/dist/sse-BaC1jXko.mjs +172 -0
- package/dist/{subcommand-prompt-Bmyn5Rlc.mjs → subcommand-prompt-Gj3VzLIh.mjs} +2 -1
- package/dist/sveltekit.d.mts +2 -1
- package/dist/sveltekit.mjs +3 -2
- package/dist/validate-DqJ33oHj.mjs +2 -0
- package/dist/validate-qNhV00PD.mjs +180 -0
- package/dist/validator-BTOu0fB0.mjs +72 -0
- package/dist/{wrangler--imS8n0d.mjs → wrangler-D01qs6VB.mjs} +259 -71
- package/dist/ws-BwcqizuH.d.mts +122 -0
- package/dist/{yarn-pnp-DxSInkzL.mjs → yarn-pnp-CVEc3gE7.mjs} +1 -1
- package/package.json +19 -8
- package/skills/void/SKILL.md +7 -5
- package/skills/void/docs/guide/ai.md +3 -3
- package/skills/void/docs/guide/app-types.md +12 -11
- package/skills/void/docs/guide/auth.md +2 -2
- package/skills/void/docs/guide/database/d1.md +1 -1
- package/skills/void/docs/guide/database/mysql.md +1 -1
- package/skills/void/docs/guide/database/postgresql.md +3 -3
- package/skills/void/docs/guide/deployment.md +16 -16
- package/skills/void/docs/guide/durable-state.md +2 -2
- package/skills/void/docs/guide/edge/headers.md +3 -3
- package/skills/void/docs/guide/edge/prerendering.md +1 -1
- package/skills/void/docs/guide/edge/redirects.md +4 -4
- package/skills/void/docs/guide/edge/revalidation.md +6 -6
- package/skills/void/docs/guide/edge/rewrites.md +28 -27
- package/skills/void/docs/guide/edge/static-assets.md +1 -1
- package/skills/void/docs/guide/email.md +27 -25
- package/skills/void/docs/guide/env-migration.md +1 -1
- package/skills/void/docs/guide/index.md +1 -1
- package/skills/void/docs/guide/pages-routing/head.md +1 -1
- package/skills/void/docs/guide/platform/administration/access.md +171 -0
- package/skills/void/docs/guide/platform/administration/email.md +121 -0
- package/skills/void/docs/guide/platform/administration/operations.md +97 -0
- package/skills/void/docs/guide/platform/administration/projects.md +56 -0
- package/skills/void/docs/guide/platform/development/local.md +119 -0
- package/skills/void/docs/guide/platform/development/runtime.md +124 -0
- package/skills/void/docs/guide/platform/development/schema-ci.md +95 -0
- package/skills/void/docs/guide/platform/installation/ci.md +58 -0
- package/skills/void/docs/guide/platform/installation/credentials.md +90 -0
- package/skills/void/docs/guide/platform/installation/domains.md +68 -0
- package/skills/void/docs/guide/platform/installation/first-deployment.md +82 -0
- package/skills/void/docs/guide/platform/installation/maintenance.md +137 -0
- package/skills/void/docs/guide/platform/installation/prerequisites.md +88 -0
- package/skills/void/docs/guide/platform/installation/setup.md +169 -0
- package/skills/void/docs/guide/platform/installation/uninstall.md +54 -0
- package/skills/void/docs/guide/platform-administration.md +6 -414
- package/skills/void/docs/guide/platform-development.md +5 -316
- package/skills/void/docs/guide/project-collaboration.md +1 -1
- package/skills/void/docs/guide/remote-dev.md +2 -2
- package/skills/void/docs/guide/sandboxes.md +10 -25
- package/skills/void/docs/guide/self-hosted-platform.md +11 -694
- package/skills/void/docs/guide/ssg.md +1 -1
- package/skills/void/docs/guide/websockets.md +1 -1
- package/skills/void/docs/integrations/cloudflare.md +86 -84
- package/skills/void/docs/integrations/frameworks/analog.md +14 -9
- package/skills/void/docs/integrations/frameworks/astro.md +14 -10
- package/skills/void/docs/integrations/frameworks/nuxt.md +14 -9
- package/skills/void/docs/integrations/frameworks/overview.md +35 -29
- package/skills/void/docs/integrations/frameworks/react-router.md +1 -1
- package/skills/void/docs/integrations/frameworks/sveltekit.md +33 -30
- package/skills/void/docs/integrations/frameworks/tanstack-start.md +1 -1
- package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -5
- package/skills/void/docs/reference/api.md +55 -38
- package/skills/void/docs/reference/cli.md +60 -34
- package/skills/void/docs/reference/config.md +57 -34
- package/skills/void/docs/reference/resource-inference.md +10 -10
- package/skills/void/docs/reference/structure.md +2 -2
- package/dist/validate-tBBN_dXH.mjs +0 -505
|
@@ -1,689 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { n as isVoidAccessGatedUrl, t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
|
|
4
|
-
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
|
|
7
|
-
import { homedir, hostname } from "node:os";
|
|
8
|
-
import { spawnSync } from "node:child_process";
|
|
9
|
-
import { Entry } from "@napi-rs/keyring";
|
|
10
|
-
import { parsePlatformInstallationManifest } from "@void/platform";
|
|
1
|
+
import { t as __commonJSMin } from "./rolldown-runtime-DXIUcv95.mjs";
|
|
2
|
+
import "node:fs";
|
|
11
3
|
import { styleText } from "node:util";
|
|
12
4
|
import process$1, { stdin, stdout } from "node:process";
|
|
13
5
|
import * as l from "node:readline";
|
|
14
6
|
import l__default from "node:readline";
|
|
15
7
|
import { ReadStream } from "node:tty";
|
|
16
|
-
//#region ../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
17
|
-
var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
18
|
-
let p = process || {};
|
|
19
|
-
let argv = p.argv || [];
|
|
20
|
-
let env = p.env || {};
|
|
21
|
-
let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
22
|
-
let formatter = (open, close, replace = open) => (input) => {
|
|
23
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
24
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
25
|
-
};
|
|
26
|
-
let replaceClose = (string, close, replace, index) => {
|
|
27
|
-
let result = "", cursor = 0;
|
|
28
|
-
do {
|
|
29
|
-
result += string.substring(cursor, index) + replace;
|
|
30
|
-
cursor = index + close.length;
|
|
31
|
-
index = string.indexOf(close, cursor);
|
|
32
|
-
} while (~index);
|
|
33
|
-
return result + string.substring(cursor);
|
|
34
|
-
};
|
|
35
|
-
let createColors = (enabled = isColorSupported) => {
|
|
36
|
-
let f = enabled ? formatter : () => String;
|
|
37
|
-
return {
|
|
38
|
-
isColorSupported: enabled,
|
|
39
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
40
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
41
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
42
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
43
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
44
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
45
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
46
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
47
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
48
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
49
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
50
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
51
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
52
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
53
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
54
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
55
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
56
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
57
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
58
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
59
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
60
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
61
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
62
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
63
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
64
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
65
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
66
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
67
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
68
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
69
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
70
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
71
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
72
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
73
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
74
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
75
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
76
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
77
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
78
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
79
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
module.exports = createColors();
|
|
83
|
-
module.exports.createColors = createColors;
|
|
84
|
-
}));
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region src/cli/keyring.ts
|
|
87
|
-
function readKeyringPassword(service, account) {
|
|
88
|
-
try {
|
|
89
|
-
return new Entry(service, account).getPassword();
|
|
90
|
-
} catch {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function writeKeyringPassword(service, account, password) {
|
|
95
|
-
try {
|
|
96
|
-
new Entry(service, account).setPassword(password);
|
|
97
|
-
return true;
|
|
98
|
-
} catch {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
function deleteKeyringPassword(service, account) {
|
|
103
|
-
try {
|
|
104
|
-
new Entry(service, account).deletePassword();
|
|
105
|
-
return true;
|
|
106
|
-
} catch {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const DEFAULT_REGISTRY = {
|
|
111
|
-
activeConnectionId: null,
|
|
112
|
-
connections: [],
|
|
113
|
-
schemaVersion: 1
|
|
114
|
-
};
|
|
115
|
-
const PLATFORM_RECOVERY_KEYRING_SERVICE = "dev.void.cli.platform";
|
|
116
|
-
const PLATFORM_RECOVERY_ENVELOPE_VERSION = 1;
|
|
117
|
-
function platformRegistryDirectory() {
|
|
118
|
-
return process.env.VOID_PLATFORM_REGISTRY_DIR ?? join(homedir(), ".void", "platforms");
|
|
119
|
-
}
|
|
120
|
-
function normalizePlatformApiUrl(value) {
|
|
121
|
-
let url;
|
|
122
|
-
try {
|
|
123
|
-
url = new URL(value);
|
|
124
|
-
} catch {
|
|
125
|
-
throw new Error(`platform: Invalid platform URL ${JSON.stringify(value)}.`);
|
|
126
|
-
}
|
|
127
|
-
if (!(url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1")) && url.protocol !== "https:" || url.username || url.password) throw new Error("platform: Platform URLs must use HTTPS and must not contain credentials.");
|
|
128
|
-
if (url.search || url.hash) throw new Error("platform: Platform URLs must not contain query parameters or fragments.");
|
|
129
|
-
if (url.pathname !== "/" && url.pathname !== "") throw new Error("platform: Platform URLs must not contain a path.");
|
|
130
|
-
return url.origin;
|
|
131
|
-
}
|
|
132
|
-
function platformConnectionId(apiUrl) {
|
|
133
|
-
return createHash("sha256").update(normalizePlatformApiUrl(apiUrl)).digest("hex").slice(0, 20);
|
|
134
|
-
}
|
|
135
|
-
function platformCredentialAccount(apiUrl) {
|
|
136
|
-
return `platform:${createHash("sha256").update(normalizePlatformApiUrl(apiUrl)).digest("hex")}`;
|
|
137
|
-
}
|
|
138
|
-
function parseConnection(value) {
|
|
139
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("platform: Invalid connection entry in the local registry.");
|
|
140
|
-
const entry = value;
|
|
141
|
-
const apiUrl = normalizePlatformApiUrl(String(entry.apiUrl ?? ""));
|
|
142
|
-
const id = String(entry.id ?? "");
|
|
143
|
-
if (id !== platformConnectionId(apiUrl)) throw new Error("platform: Connection id does not match its API URL.");
|
|
144
|
-
if (entry.kind !== "connected" && entry.kind !== "installed") throw new Error("platform: Invalid connection kind in the local registry.");
|
|
145
|
-
const lastUsedAt = String(entry.lastUsedAt ?? "");
|
|
146
|
-
if (!Number.isFinite(Date.parse(lastUsedAt))) throw new Error("platform: Invalid connection timestamp in the local registry.");
|
|
147
|
-
const optionalString = (input) => typeof input === "string" && input !== "" ? input : null;
|
|
148
|
-
const proxyUrl = optionalString(entry.proxyUrl) ?? (apiUrl === "https://api.void.cloud" ? "https://proxy.void.cloud" : apiUrl === "https://api.staging.void.cloud" ? "https://proxy.staging.void.cloud" : null);
|
|
149
|
-
return {
|
|
150
|
-
accountId: optionalString(entry.accountId),
|
|
151
|
-
apiUrl,
|
|
152
|
-
applicationDomain: optionalString(entry.applicationDomain),
|
|
153
|
-
displayName: typeof entry.displayName === "string" && entry.displayName.trim() ? entry.displayName.trim() : new URL(apiUrl).hostname,
|
|
154
|
-
id,
|
|
155
|
-
installationId: optionalString(entry.installationId),
|
|
156
|
-
kind: entry.kind,
|
|
157
|
-
lastUsedAt,
|
|
158
|
-
proxyUrl: proxyUrl === null ? null : normalizePlatformApiUrl(proxyUrl)
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function readRegistry(directory) {
|
|
162
|
-
try {
|
|
163
|
-
const parsed = JSON.parse(readFileSync(join(directory, "registry.json"), "utf8"));
|
|
164
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("registry must be an object");
|
|
165
|
-
const value = parsed;
|
|
166
|
-
if (value.schemaVersion !== 1 || !Array.isArray(value.connections)) throw new Error("unsupported schema");
|
|
167
|
-
const connections = value.connections.map(parseConnection);
|
|
168
|
-
return {
|
|
169
|
-
activeConnectionId: typeof value.activeConnectionId === "string" && connections.some((connection) => connection.id === value.activeConnectionId) ? value.activeConnectionId : null,
|
|
170
|
-
connections,
|
|
171
|
-
schemaVersion: 1
|
|
172
|
-
};
|
|
173
|
-
} catch (error) {
|
|
174
|
-
if (error.code === "ENOENT") return DEFAULT_REGISTRY;
|
|
175
|
-
throw new Error(`platform: Could not read ${join(directory, "registry.json")}: ${error instanceof Error ? error.message : String(error)}`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
function withRegistryLock(directory, operation) {
|
|
179
|
-
mkdirSync(directory, {
|
|
180
|
-
recursive: true,
|
|
181
|
-
mode: 448
|
|
182
|
-
});
|
|
183
|
-
const lockPath = join(directory, ".registry.lock");
|
|
184
|
-
let descriptor;
|
|
185
|
-
try {
|
|
186
|
-
descriptor = openSync(lockPath, "wx", 384);
|
|
187
|
-
} catch (error) {
|
|
188
|
-
if (error.code !== "EEXIST") throw error;
|
|
189
|
-
if (Date.now() - statSync(lockPath).mtimeMs < 6e5) throw new Error("platform: Another process is updating the platform registry.");
|
|
190
|
-
rmSync(lockPath, { force: true });
|
|
191
|
-
descriptor = openSync(lockPath, "wx", 384);
|
|
192
|
-
}
|
|
193
|
-
try {
|
|
194
|
-
return operation();
|
|
195
|
-
} finally {
|
|
196
|
-
closeSync(descriptor);
|
|
197
|
-
rmSync(lockPath, { force: true });
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
function writeJsonAtomically(path, value) {
|
|
201
|
-
const temporary = `${path}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
202
|
-
try {
|
|
203
|
-
writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, {
|
|
204
|
-
mode: 384,
|
|
205
|
-
flag: "wx"
|
|
206
|
-
});
|
|
207
|
-
renameSync(temporary, path);
|
|
208
|
-
} finally {
|
|
209
|
-
rmSync(temporary, { force: true });
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
function acquirePlatformLifecycleLock(accountId, installationSlug, directory = platformRegistryDirectory()) {
|
|
213
|
-
if (!/^[A-Za-z0-9_-]+$/.test(accountId) || !/^[a-z0-9][a-z0-9-]{0,79}$/.test(installationSlug)) throw new Error("platform: Invalid lifecycle lock identity.");
|
|
214
|
-
const lockDirectory = join(directory, "locks");
|
|
215
|
-
mkdirSync(lockDirectory, {
|
|
216
|
-
recursive: true,
|
|
217
|
-
mode: 448
|
|
218
|
-
});
|
|
219
|
-
const lockPath = join(lockDirectory, `${accountId}-${installationSlug}.lock`);
|
|
220
|
-
const acquire = () => {
|
|
221
|
-
try {
|
|
222
|
-
const descriptor = openSync(lockPath, "wx", 384);
|
|
223
|
-
writeFileSync(descriptor, `${JSON.stringify({
|
|
224
|
-
host: hostname(),
|
|
225
|
-
pid: process.pid,
|
|
226
|
-
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
227
|
-
})}\n`);
|
|
228
|
-
return descriptor;
|
|
229
|
-
} catch (error) {
|
|
230
|
-
if (error.code !== "EEXIST") throw error;
|
|
231
|
-
let stale = false;
|
|
232
|
-
try {
|
|
233
|
-
const owner = JSON.parse(readFileSync(lockPath, "utf8"));
|
|
234
|
-
if (owner.host === hostname() && typeof owner.pid === "number") try {
|
|
235
|
-
process.kill(owner.pid, 0);
|
|
236
|
-
} catch (ownerError) {
|
|
237
|
-
stale = ownerError.code === "ESRCH";
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
const startedAt = typeof owner.startedAt === "string" ? Date.parse(owner.startedAt) : NaN;
|
|
241
|
-
stale = Number.isFinite(startedAt) && Date.now() - startedAt > 72e5;
|
|
242
|
-
}
|
|
243
|
-
} catch {
|
|
244
|
-
stale = Date.now() - statSync(lockPath).mtimeMs > 72e5;
|
|
245
|
-
}
|
|
246
|
-
if (!stale) throw new Error(`platform: Another lifecycle operation is active for ${installationSlug} in account ${accountId}.`);
|
|
247
|
-
rmSync(lockPath, { force: true });
|
|
248
|
-
return acquire();
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
const descriptor = acquire();
|
|
252
|
-
let released = false;
|
|
253
|
-
return () => {
|
|
254
|
-
if (released) return;
|
|
255
|
-
released = true;
|
|
256
|
-
closeSync(descriptor);
|
|
257
|
-
rmSync(lockPath, { force: true });
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
function listPlatformConnections(directory = platformRegistryDirectory()) {
|
|
261
|
-
return readRegistry(directory).connections;
|
|
262
|
-
}
|
|
263
|
-
function assertPlatformInstallationSlugAvailable(installationSlug, directory = platformRegistryDirectory()) {
|
|
264
|
-
const collision = listInstallationManifests(directory).find((manifest) => manifest.status !== "uninstalled" && manifest.deployment.installationSlug === installationSlug);
|
|
265
|
-
if (collision) throw new Error(`platform: Installation ${collision.id} already uses this name. Resume it with \`void platform install --resume --name ${collision.id}\`.`);
|
|
266
|
-
}
|
|
267
|
-
function getActivePlatformConnection(directory = platformRegistryDirectory()) {
|
|
268
|
-
const registry = readRegistry(directory);
|
|
269
|
-
return registry.connections.find((connection) => connection.id === registry.activeConnectionId) ?? (registry.connections.length === 1 ? registry.connections[0] : null);
|
|
270
|
-
}
|
|
271
|
-
function savePlatformConnection(input, directory = platformRegistryDirectory()) {
|
|
272
|
-
const apiUrl = normalizePlatformApiUrl(input.apiUrl);
|
|
273
|
-
const id = platformConnectionId(apiUrl);
|
|
274
|
-
const lastUsedAt = input.lastUsedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
275
|
-
const connection = parseConnection({
|
|
276
|
-
...input,
|
|
277
|
-
apiUrl,
|
|
278
|
-
id,
|
|
279
|
-
lastUsedAt
|
|
280
|
-
});
|
|
281
|
-
return withRegistryLock(directory, () => {
|
|
282
|
-
const connections = readRegistry(directory).connections.filter((entry) => entry.id !== id);
|
|
283
|
-
connections.push(connection);
|
|
284
|
-
connections.sort((left, right) => left.displayName.localeCompare(right.displayName));
|
|
285
|
-
writeJsonAtomically(join(directory, "registry.json"), {
|
|
286
|
-
activeConnectionId: id,
|
|
287
|
-
connections,
|
|
288
|
-
schemaVersion: 1
|
|
289
|
-
});
|
|
290
|
-
return connection;
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
function selectPlatformConnection(selector, directory = platformRegistryDirectory()) {
|
|
294
|
-
return withRegistryLock(directory, () => {
|
|
295
|
-
const current = readRegistry(directory);
|
|
296
|
-
const normalizedUrl = (() => {
|
|
297
|
-
try {
|
|
298
|
-
return normalizePlatformApiUrl(selector);
|
|
299
|
-
} catch {
|
|
300
|
-
return null;
|
|
301
|
-
}
|
|
302
|
-
})();
|
|
303
|
-
const matches = current.connections.filter((entry) => entry.id === selector || entry.installationId === selector || entry.displayName.toLowerCase() === selector.toLowerCase() || normalizedUrl !== null && entry.apiUrl === normalizedUrl);
|
|
304
|
-
if (matches.length !== 1) throw new Error(matches.length === 0 ? `platform: No installed or connected platform matches ${JSON.stringify(selector)}.` : `platform: More than one platform matches ${JSON.stringify(selector)}. Use its id or URL.`);
|
|
305
|
-
const selected = {
|
|
306
|
-
...matches[0],
|
|
307
|
-
lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
308
|
-
};
|
|
309
|
-
const connections = current.connections.map((entry) => entry.id === selected.id ? selected : entry);
|
|
310
|
-
writeJsonAtomically(join(directory, "registry.json"), {
|
|
311
|
-
activeConnectionId: selected.id,
|
|
312
|
-
connections,
|
|
313
|
-
schemaVersion: 1
|
|
314
|
-
});
|
|
315
|
-
return selected;
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
function installationManifestPath(accountId, installationId, directory = platformRegistryDirectory()) {
|
|
319
|
-
if (!/^[A-Za-z0-9_-]+$/.test(accountId) || !/^[a-z0-9][a-z0-9-]{7,79}$/.test(installationId)) throw new Error("platform: Invalid account or installation id.");
|
|
320
|
-
return join(directory, accountId, `${installationId}.json`);
|
|
321
|
-
}
|
|
322
|
-
function writeInstallationManifest(manifest, directory = platformRegistryDirectory()) {
|
|
323
|
-
const path = installationManifestPath(manifest.account.id, manifest.id, directory);
|
|
324
|
-
const parent = join(directory, manifest.account.id);
|
|
325
|
-
mkdirSync(parent, {
|
|
326
|
-
recursive: true,
|
|
327
|
-
mode: 448
|
|
328
|
-
});
|
|
329
|
-
writeJsonAtomically(path, manifest);
|
|
330
|
-
}
|
|
331
|
-
function listInstallationManifests(directory = platformRegistryDirectory()) {
|
|
332
|
-
const manifests = [];
|
|
333
|
-
let accountDirectories;
|
|
334
|
-
try {
|
|
335
|
-
accountDirectories = readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
336
|
-
} catch (error) {
|
|
337
|
-
if (error.code === "ENOENT") return [];
|
|
338
|
-
throw error;
|
|
339
|
-
}
|
|
340
|
-
for (const accountId of accountDirectories) {
|
|
341
|
-
const accountPath = join(directory, accountId);
|
|
342
|
-
for (const entry of readdirSync(accountPath, { withFileTypes: true })) {
|
|
343
|
-
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
344
|
-
const path = join(accountPath, entry.name);
|
|
345
|
-
try {
|
|
346
|
-
manifests.push(parsePlatformInstallationManifest(JSON.parse(readFileSync(path, "utf8"))));
|
|
347
|
-
} catch (error) {
|
|
348
|
-
throw new Error(`platform: Invalid installation manifest ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return manifests.sort((left, right) => left.deployment.displayName.localeCompare(right.deployment.displayName));
|
|
353
|
-
}
|
|
354
|
-
function resolveInstallationManifest(selector, directory = platformRegistryDirectory()) {
|
|
355
|
-
const manifests = listInstallationManifests(directory).filter((manifest) => manifest.status !== "uninstalled" && (!selector || manifest.id === selector || manifest.deployment.installationSlug === selector || manifest.deployment.displayName.toLowerCase() === selector.toLowerCase()));
|
|
356
|
-
if (manifests.length !== 1) throw new Error(manifests.length === 0 ? `platform: No local installation matches ${JSON.stringify(selector)}.` : "platform: Multiple local installations match; specify an installation id.");
|
|
357
|
-
return manifests[0];
|
|
358
|
-
}
|
|
359
|
-
function writePendingInstallationSecrets(manifest, secrets, directory = platformRegistryDirectory()) {
|
|
360
|
-
const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
|
|
361
|
-
writeEncryptedRecoveryMaterial(manifest, "pending", manifestPath.replace(/\.json$/, ".secrets.enc"), secrets, directory);
|
|
362
|
-
rmSync(manifestPath.replace(/\.json$/, ".secrets"), { force: true });
|
|
363
|
-
}
|
|
364
|
-
function readPendingInstallationSecrets(manifest, directory = platformRegistryDirectory()) {
|
|
365
|
-
return readRecoveryMaterial(manifest, "pending", directory);
|
|
366
|
-
}
|
|
367
|
-
function promoteInstallationSecrets(manifest, directory = platformRegistryDirectory()) {
|
|
368
|
-
const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
|
|
369
|
-
const values = readPendingInstallationSecrets(manifest, directory);
|
|
370
|
-
if (!values) throw new Error("platform: Pending installation recovery material is missing.");
|
|
371
|
-
writeEncryptedRecoveryMaterial(manifest, "recovery", manifestPath.replace(/\.json$/, ".recovery.enc"), values, directory);
|
|
372
|
-
rmSync(manifestPath.replace(/\.json$/, ".secrets.enc"), { force: true });
|
|
373
|
-
rmSync(manifestPath.replace(/\.json$/, ".secrets"), { force: true });
|
|
374
|
-
rmSync(manifestPath.replace(/\.json$/, ".recovery"), { force: true });
|
|
375
|
-
}
|
|
376
|
-
function readInstallationRecoverySecrets(manifest, directory = platformRegistryDirectory()) {
|
|
377
|
-
const pending = readPendingInstallationSecrets(manifest, directory);
|
|
378
|
-
if (!pending) return readRecoveryMaterial(manifest, "recovery", directory);
|
|
379
|
-
const updateState = pendingWorkerSecretUpdateState(manifest, pending.workerSecretUpdatesJson);
|
|
380
|
-
if (updateState === "stale") return readRecoveryMaterial(manifest, "recovery", directory);
|
|
381
|
-
if (updateState === "committed") return Object.fromEntries(Object.entries(pending).filter(([name]) => name !== "workerSecretUpdatesJson"));
|
|
382
|
-
return pending;
|
|
383
|
-
}
|
|
384
|
-
function pendingWorkerSecretUpdateState(manifest, value) {
|
|
385
|
-
if (!value) return "active";
|
|
386
|
-
let parsed;
|
|
387
|
-
try {
|
|
388
|
-
parsed = JSON.parse(value);
|
|
389
|
-
} catch {
|
|
390
|
-
return "active";
|
|
391
|
-
}
|
|
392
|
-
if (!parsed || typeof parsed !== "object" || !("schema" in parsed) || parsed.schema !== 1 || !("id" in parsed) || typeof parsed.id !== "string" || !("baselineGeneration" in parsed) || !Number.isSafeInteger(parsed.baselineGeneration) || !("generation" in parsed) || parsed.generation !== null && !Number.isSafeInteger(parsed.generation)) return "active";
|
|
393
|
-
return platformWorkerSecretUpdateIntentState(manifest, {
|
|
394
|
-
baselineGeneration: Number(parsed.baselineGeneration),
|
|
395
|
-
generation: parsed.generation === null ? null : Number(parsed.generation),
|
|
396
|
-
id: parsed.id
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
function platformWorkerSecretUpdateIntentState(manifest, intent) {
|
|
400
|
-
const latestGeneration = latestPlatformWorkerCutoverGeneration(manifest);
|
|
401
|
-
const latestState = manifest.steps.flatMap((step) => {
|
|
402
|
-
const match = /^worker-secret-updates:(\d+):(pending|committed)$/.exec(step.key);
|
|
403
|
-
return match ? [{
|
|
404
|
-
generation: Number(match[1]),
|
|
405
|
-
id: step.resultHash,
|
|
406
|
-
state: match[2]
|
|
407
|
-
}] : [];
|
|
408
|
-
}).sort((left, right) => right.generation - left.generation || (left.state === right.state ? 0 : left.state === "committed" ? -1 : 1))[0];
|
|
409
|
-
if (!latestState) return intent.generation === null && intent.baselineGeneration === latestGeneration ? "active" : "stale";
|
|
410
|
-
if (latestState.generation !== latestGeneration || latestState.id !== intent.id) return "stale";
|
|
411
|
-
return latestState.state === "committed" ? "committed" : "active";
|
|
412
|
-
}
|
|
413
|
-
function latestPlatformWorkerCutoverGeneration(manifest) {
|
|
414
|
-
return Math.max(0, ...manifest.steps.flatMap((step) => {
|
|
415
|
-
const match = /^worker-(?:cutover|secret-updates|traffic-state):(\d+)/.exec(step.key);
|
|
416
|
-
return match ? [Number(match[1])] : [];
|
|
417
|
-
}));
|
|
418
|
-
}
|
|
419
|
-
function removeInstallationRecoverySecrets(manifest, directory = platformRegistryDirectory()) {
|
|
420
|
-
const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
|
|
421
|
-
rmSync(manifestPath.replace(/\.json$/, ".recovery.enc"), { force: true });
|
|
422
|
-
rmSync(manifestPath.replace(/\.json$/, ".secrets.enc"), { force: true });
|
|
423
|
-
rmSync(manifestPath.replace(/\.json$/, ".recovery"), { force: true });
|
|
424
|
-
rmSync(manifestPath.replace(/\.json$/, ".secrets"), { force: true });
|
|
425
|
-
}
|
|
426
|
-
function readRecoveryMaterial(manifest, kind, directory) {
|
|
427
|
-
const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
|
|
428
|
-
const encryptedPath = manifestPath.replace(/\.json$/, `.${kind === "pending" ? "secrets" : "recovery"}.enc`);
|
|
429
|
-
try {
|
|
430
|
-
const envelope = parseRecoveryEnvelope(JSON.parse(readFileSync(encryptedPath, "utf8")));
|
|
431
|
-
const key = platformRecoveryKey(directory, false);
|
|
432
|
-
if (!key) throw new Error("the encryption key is unavailable; restore it from the system keychain or set VOID_PLATFORM_RECOVERY_KEY");
|
|
433
|
-
const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(envelope.iv, "base64"));
|
|
434
|
-
decipher.setAAD(recoveryAad(manifest, kind));
|
|
435
|
-
decipher.setAuthTag(Buffer.from(envelope.tag, "base64"));
|
|
436
|
-
const plaintext = Buffer.concat([decipher.update(Buffer.from(envelope.ciphertext, "base64")), decipher.final()]);
|
|
437
|
-
return parseRecoveryValues(JSON.parse(plaintext.toString("utf8")), `${kind} recovery material`);
|
|
438
|
-
} catch (error) {
|
|
439
|
-
if (error.code !== "ENOENT") throw new Error(`platform: Could not read encrypted ${kind} material: ${error instanceof Error ? error.message : String(error)}`);
|
|
440
|
-
}
|
|
441
|
-
const legacyPath = manifestPath.replace(/\.json$/, kind === "pending" ? ".secrets" : ".recovery");
|
|
442
|
-
try {
|
|
443
|
-
const values = parseRecoveryValues(JSON.parse(readFileSync(legacyPath, "utf8")), `legacy ${kind} recovery material`);
|
|
444
|
-
writeEncryptedRecoveryMaterial(manifest, kind, encryptedPath, values, directory);
|
|
445
|
-
rmSync(legacyPath, { force: true });
|
|
446
|
-
return values;
|
|
447
|
-
} catch (error) {
|
|
448
|
-
if (error.code === "ENOENT") return null;
|
|
449
|
-
throw new Error(`platform: Could not migrate legacy ${kind} material: ${error instanceof Error ? error.message : String(error)}`);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
function writeEncryptedRecoveryMaterial(manifest, kind, path, values, directory) {
|
|
453
|
-
const key = platformRecoveryKey(directory, true);
|
|
454
|
-
const iv = randomBytes(12);
|
|
455
|
-
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
456
|
-
cipher.setAAD(recoveryAad(manifest, kind));
|
|
457
|
-
writeJsonAtomically(path, {
|
|
458
|
-
algorithm: "aes-256-gcm",
|
|
459
|
-
ciphertext: Buffer.concat([cipher.update(JSON.stringify(parseRecoveryValues(values, `${kind} recovery material`)), "utf8"), cipher.final()]).toString("base64"),
|
|
460
|
-
iv: iv.toString("base64"),
|
|
461
|
-
schemaVersion: PLATFORM_RECOVERY_ENVELOPE_VERSION,
|
|
462
|
-
tag: cipher.getAuthTag().toString("base64")
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
function recoveryAad(manifest, kind) {
|
|
466
|
-
return Buffer.from(`void-platform-recovery-v1\0${manifest.account.id}\0${manifest.id}\0${manifest.ownershipNonce}\0${kind}`);
|
|
467
|
-
}
|
|
468
|
-
function platformRecoveryKey(directory, create) {
|
|
469
|
-
const fromEnvironment = process.env.VOID_PLATFORM_RECOVERY_KEY;
|
|
470
|
-
if (fromEnvironment) return parseRecoveryKey(fromEnvironment, "VOID_PLATFORM_RECOVERY_KEY");
|
|
471
|
-
const account = `recovery:${createHash("sha256").update(resolve(directory)).digest("hex")}`;
|
|
472
|
-
const saved = readKeyringPassword(PLATFORM_RECOVERY_KEYRING_SERVICE, account);
|
|
473
|
-
if (saved) return parseRecoveryKey(saved, "system keychain recovery key");
|
|
474
|
-
if (!create) return null;
|
|
475
|
-
const generated = randomBytes(32);
|
|
476
|
-
if (!writeKeyringPassword(PLATFORM_RECOVERY_KEYRING_SERVICE, account, generated.toString("base64"))) throw new Error("platform: The system keychain is unavailable. Refusing to write platform secrets to disk. Configure a system keychain or set a base64-encoded 32-byte VOID_PLATFORM_RECOVERY_KEY from your secret manager.");
|
|
477
|
-
return generated;
|
|
478
|
-
}
|
|
479
|
-
function parseRecoveryKey(value, name) {
|
|
480
|
-
const key = Buffer.from(value, "base64");
|
|
481
|
-
if (key.byteLength !== 32 || key.toString("base64") !== value) throw new Error(`platform: ${name} must be a canonical base64-encoded 32-byte key.`);
|
|
482
|
-
return key;
|
|
483
|
-
}
|
|
484
|
-
function parseRecoveryEnvelope(value) {
|
|
485
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("encrypted recovery envelope must be an object");
|
|
486
|
-
const envelope = value;
|
|
487
|
-
if (envelope.schemaVersion !== PLATFORM_RECOVERY_ENVELOPE_VERSION || envelope.algorithm !== "aes-256-gcm" || typeof envelope.ciphertext !== "string" || typeof envelope.iv !== "string" || typeof envelope.tag !== "string") throw new Error("encrypted recovery envelope is invalid");
|
|
488
|
-
if (Buffer.from(envelope.iv, "base64").byteLength !== 12) throw new Error("encrypted recovery IV is invalid");
|
|
489
|
-
if (Buffer.from(envelope.tag, "base64").byteLength !== 16) throw new Error("encrypted recovery tag is invalid");
|
|
490
|
-
return envelope;
|
|
491
|
-
}
|
|
492
|
-
function parseRecoveryValues(value, name) {
|
|
493
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object`);
|
|
494
|
-
const entries = Object.entries(value);
|
|
495
|
-
if (entries.some(([, entry]) => typeof entry !== "string")) throw new Error(`${name} values must be strings`);
|
|
496
|
-
return Object.fromEntries(entries);
|
|
497
|
-
}
|
|
498
|
-
function removePlatformConnectionForInstallation(installationId, directory = platformRegistryDirectory()) {
|
|
499
|
-
withRegistryLock(directory, () => {
|
|
500
|
-
const current = readRegistry(directory);
|
|
501
|
-
const connections = current.connections.filter((connection) => connection.installationId !== installationId);
|
|
502
|
-
writeJsonAtomically(join(directory, "registry.json"), {
|
|
503
|
-
activeConnectionId: current.activeConnectionId && connections.some((connection) => connection.id === current.activeConnectionId) ? current.activeConnectionId : connections[0]?.id ?? null,
|
|
504
|
-
connections,
|
|
505
|
-
schemaVersion: 1
|
|
506
|
-
});
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
//#endregion
|
|
510
|
-
//#region src/cli/cf-access.ts
|
|
511
|
-
const ACCESS_KEYRING_SERVICE = "dev.void.cli.access";
|
|
512
|
-
const keyringTokens = /* @__PURE__ */ new Map();
|
|
513
|
-
function usableToken(token) {
|
|
514
|
-
try {
|
|
515
|
-
const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf8"));
|
|
516
|
-
return typeof payload.exp === "number" && payload.exp > Date.now() / 1e3 + 60;
|
|
517
|
-
} catch {
|
|
518
|
-
return false;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
function rememberOriginToken(origin, token) {
|
|
522
|
-
let entries = {};
|
|
523
|
-
if (process.env.VOID_ACCESS_CREDENTIALS) {
|
|
524
|
-
const parsed = JSON.parse(process.env.VOID_ACCESS_CREDENTIALS);
|
|
525
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("platform: VOID_ACCESS_CREDENTIALS must contain an origin-keyed JSON object.");
|
|
526
|
-
entries = parsed;
|
|
527
|
-
}
|
|
528
|
-
process.env.VOID_ACCESS_CREDENTIALS = JSON.stringify({
|
|
529
|
-
...entries,
|
|
530
|
-
[origin]: { CF_ACCESS_TOKEN: token }
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
function forgetOriginToken(origin) {
|
|
534
|
-
if (!process.env.VOID_ACCESS_CREDENTIALS) return;
|
|
535
|
-
const parsed = JSON.parse(process.env.VOID_ACCESS_CREDENTIALS);
|
|
536
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("platform: VOID_ACCESS_CREDENTIALS must contain an origin-keyed JSON object.");
|
|
537
|
-
const entries = { ...parsed };
|
|
538
|
-
delete entries[origin];
|
|
539
|
-
process.env.VOID_ACCESS_CREDENTIALS = JSON.stringify(entries);
|
|
540
|
-
}
|
|
541
|
-
function isCloudflareAccessChallenge(response) {
|
|
542
|
-
const location = response.headers.get("Location");
|
|
543
|
-
if (!location || response.status < 300 || response.status >= 400) return false;
|
|
544
|
-
try {
|
|
545
|
-
const target = new URL(location);
|
|
546
|
-
return target.protocol === "https:" && !target.username && !target.password && /^[a-z0-9-]+\.cloudflareaccess\.com$/.test(target.hostname) && target.pathname.startsWith("/cdn-cgi/access/login");
|
|
547
|
-
} catch {
|
|
548
|
-
return false;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
/** Called for a selected origin, never for a redirect destination. */
|
|
552
|
-
function ensurePlatformAccessToken(apiUrl, challenged = false, required = false, rejectedToken) {
|
|
553
|
-
const origin = normalizePlatformApiUrl(apiUrl);
|
|
554
|
-
if (!origin.startsWith("https://")) return;
|
|
555
|
-
const headers = cfAccessHeaders(process.env, origin);
|
|
556
|
-
if (headers["CF-Access-Client-Id"]) return;
|
|
557
|
-
if (!challenged && headers["cf-access-token"] && usableToken(headers["cf-access-token"])) return;
|
|
558
|
-
const account = platformCredentialAccount(origin);
|
|
559
|
-
if (!keyringTokens.has(origin)) {
|
|
560
|
-
if (keyringTokens.size >= 64) keyringTokens.delete(keyringTokens.keys().next().value);
|
|
561
|
-
keyringTokens.set(origin, readKeyringPassword(ACCESS_KEYRING_SERVICE, account));
|
|
562
|
-
}
|
|
563
|
-
const stored = keyringTokens.get(origin);
|
|
564
|
-
if (!challenged && stored && usableToken(stored)) {
|
|
565
|
-
rememberOriginToken(origin, stored);
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
if (!challenged && !required && !stored && !headers["cf-access-token"]) return;
|
|
569
|
-
const rejectedTokens = new Set([
|
|
570
|
-
headers["cf-access-token"],
|
|
571
|
-
stored,
|
|
572
|
-
rejectedToken
|
|
573
|
-
].filter((token) => typeof token === "string" && token.length > 0));
|
|
574
|
-
if (challenged && rejectedTokens.size > 0) {
|
|
575
|
-
forgetOriginToken(origin);
|
|
576
|
-
keyringTokens.set(origin, null);
|
|
577
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error(`platform: Cloudflare Access rejected the cached credential for ${origin}. Re-run this command in an interactive terminal to renew it.`);
|
|
578
|
-
console.error(`Renew Cloudflare Access authentication for ${origin}.`);
|
|
579
|
-
runCloudflared([
|
|
580
|
-
"access",
|
|
581
|
-
"login",
|
|
582
|
-
origin
|
|
583
|
-
], {
|
|
584
|
-
inherit: true,
|
|
585
|
-
timeoutMs: 12e4
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
let token = runCloudflared([
|
|
589
|
-
"access",
|
|
590
|
-
"token",
|
|
591
|
-
`-app=${origin}`
|
|
592
|
-
]);
|
|
593
|
-
if (token && rejectedTokens.has(token)) token = null;
|
|
594
|
-
if ((!token || !usableToken(token)) && process.stdin.isTTY && process.stdout.isTTY) {
|
|
595
|
-
console.error(`Authenticate to Cloudflare Access for ${origin}.`);
|
|
596
|
-
runCloudflared([
|
|
597
|
-
"access",
|
|
598
|
-
"login",
|
|
599
|
-
origin
|
|
600
|
-
], {
|
|
601
|
-
inherit: true,
|
|
602
|
-
timeoutMs: 12e4
|
|
603
|
-
});
|
|
604
|
-
token = runCloudflared([
|
|
605
|
-
"access",
|
|
606
|
-
"token",
|
|
607
|
-
`-app=${origin}`
|
|
608
|
-
]);
|
|
609
|
-
}
|
|
610
|
-
if (!token || !usableToken(token)) throw new Error("platform: Cloudflare Access authentication is required. Install cloudflared and sign in interactively, or set VOID_ACCESS_ORIGIN with scoped CF_ACCESS_CLIENT_ID/CF_ACCESS_CLIENT_SECRET credentials for CI.");
|
|
611
|
-
rememberOriginToken(origin, token);
|
|
612
|
-
keyringTokens.set(origin, token);
|
|
613
|
-
writeKeyringPassword(ACCESS_KEYRING_SERVICE, account, token);
|
|
614
|
-
}
|
|
615
|
-
const probedHosts = /* @__PURE__ */ new Set();
|
|
616
|
-
/**
|
|
617
|
-
* If the CLI is about to talk to a Cloudflare-Access-gated staging host,
|
|
618
|
-
* probe the locally-installed `cloudflared` binary for a cached user JWT
|
|
619
|
-
* and export it as `CF_ACCESS_TOKEN`. On interactive shells with no cached
|
|
620
|
-
* token, open a browser login flow to populate the cache, then re-read it.
|
|
621
|
-
*
|
|
622
|
-
* Cached per-host so that an early non-gated call (e.g. prod) does not
|
|
623
|
-
* permanently disable the probe for a later gated call (e.g. staging) in
|
|
624
|
-
* the same process. Noop when:
|
|
625
|
-
* - a service-token pair is already set (CI path)
|
|
626
|
-
* - `CF_ACCESS_TOKEN` is already set (manual override or prior probe)
|
|
627
|
-
* - the target host is not gated
|
|
628
|
-
* - `cloudflared` is not installed
|
|
629
|
-
*/
|
|
630
|
-
function ensureCloudflaredToken(apiUrl) {
|
|
631
|
-
if (!isVoidAccessGatedUrl(apiUrl) || process.env.VOID_ACCESS_ORIGIN || process.env.VOID_ACCESS_CREDENTIALS) {
|
|
632
|
-
ensurePlatformAccessToken(apiUrl);
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
if (process.env.CF_ACCESS_CLIENT_ID && process.env.CF_ACCESS_CLIENT_SECRET) return;
|
|
636
|
-
if (process.env.CF_ACCESS_TOKEN) return;
|
|
637
|
-
if (!isVoidAccessGatedUrl(apiUrl)) return;
|
|
638
|
-
const host = new URL(apiUrl).hostname;
|
|
639
|
-
if (probedHosts.has(host)) return;
|
|
640
|
-
probedHosts.add(host);
|
|
641
|
-
let token = runCloudflared([
|
|
642
|
-
"access",
|
|
643
|
-
"token",
|
|
644
|
-
`-app=${apiUrl}`
|
|
645
|
-
]);
|
|
646
|
-
if (!token && process.stdin.isTTY && process.stdout.isTTY) {
|
|
647
|
-
runCloudflared([
|
|
648
|
-
"access",
|
|
649
|
-
"login",
|
|
650
|
-
apiUrl
|
|
651
|
-
], {
|
|
652
|
-
inherit: true,
|
|
653
|
-
timeoutMs: 12e4
|
|
654
|
-
});
|
|
655
|
-
token = runCloudflared([
|
|
656
|
-
"access",
|
|
657
|
-
"token",
|
|
658
|
-
`-app=${apiUrl}`
|
|
659
|
-
]);
|
|
660
|
-
}
|
|
661
|
-
if (token) process.env.CF_ACCESS_TOKEN = token;
|
|
662
|
-
}
|
|
663
|
-
function runCloudflared(args, opts) {
|
|
664
|
-
try {
|
|
665
|
-
const result = spawnSync("cloudflared", args, {
|
|
666
|
-
encoding: "utf-8",
|
|
667
|
-
stdio: opts?.inherit ? "inherit" : [
|
|
668
|
-
"ignore",
|
|
669
|
-
"pipe",
|
|
670
|
-
"pipe"
|
|
671
|
-
],
|
|
672
|
-
timeout: opts?.timeoutMs ?? 5e3
|
|
673
|
-
});
|
|
674
|
-
if (result.error || result.status !== 0) return null;
|
|
675
|
-
const out = (result.stdout ?? "").trim();
|
|
676
|
-
return out.length > 0 ? out : null;
|
|
677
|
-
} catch {
|
|
678
|
-
return null;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
/** A protected API and proxy have separate audiences and separately scoped credentials. */
|
|
682
|
-
function ensurePlatformProxyAccess(apiUrl, proxyUrl) {
|
|
683
|
-
ensurePlatformAccessToken(apiUrl);
|
|
684
|
-
ensurePlatformAccessToken(proxyUrl, false, Object.keys(cfAccessHeaders(process.env, apiUrl)).length > 0);
|
|
685
|
-
}
|
|
686
|
-
//#endregion
|
|
687
8
|
//#region ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
|
|
688
9
|
const getCodePointsLength = (() => {
|
|
689
10
|
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
@@ -1474,51 +795,6 @@ var n = class extends y {
|
|
|
1474
795
|
};
|
|
1475
796
|
//#endregion
|
|
1476
797
|
//#region ../../node_modules/.pnpm/@clack+prompts@1.8.0/node_modules/@clack/prompts/dist/index.mjs
|
|
1477
|
-
var dist_exports = /* @__PURE__ */ __exportAll({
|
|
1478
|
-
MULTISELECT_INSTRUCTIONS: () => MULTISELECT_INSTRUCTIONS,
|
|
1479
|
-
SELECT_INSTRUCTIONS: () => SELECT_INSTRUCTIONS,
|
|
1480
|
-
S_BAR: () => S_BAR,
|
|
1481
|
-
S_BAR_END: () => S_BAR_END,
|
|
1482
|
-
S_BAR_H: () => S_BAR_H,
|
|
1483
|
-
S_BAR_START: () => S_BAR_START,
|
|
1484
|
-
S_CHECKBOX_ACTIVE: () => S_CHECKBOX_ACTIVE,
|
|
1485
|
-
S_CHECKBOX_INACTIVE: () => S_CHECKBOX_INACTIVE,
|
|
1486
|
-
S_CHECKBOX_SELECTED: () => S_CHECKBOX_SELECTED,
|
|
1487
|
-
S_CONNECT_LEFT: () => S_CONNECT_LEFT,
|
|
1488
|
-
S_CORNER_BOTTOM_LEFT: () => S_CORNER_BOTTOM_LEFT,
|
|
1489
|
-
S_CORNER_BOTTOM_RIGHT: () => S_CORNER_BOTTOM_RIGHT,
|
|
1490
|
-
S_CORNER_TOP_RIGHT: () => S_CORNER_TOP_RIGHT,
|
|
1491
|
-
S_ERROR: () => S_ERROR,
|
|
1492
|
-
S_INFO: () => S_INFO,
|
|
1493
|
-
S_PASSWORD_MASK: () => S_PASSWORD_MASK,
|
|
1494
|
-
S_RADIO_ACTIVE: () => S_RADIO_ACTIVE,
|
|
1495
|
-
S_RADIO_INACTIVE: () => S_RADIO_INACTIVE,
|
|
1496
|
-
S_STEP_ACTIVE: () => S_STEP_ACTIVE,
|
|
1497
|
-
S_STEP_CANCEL: () => S_STEP_CANCEL,
|
|
1498
|
-
S_STEP_ERROR: () => S_STEP_ERROR,
|
|
1499
|
-
S_STEP_SUBMIT: () => S_STEP_SUBMIT,
|
|
1500
|
-
S_SUCCESS: () => S_SUCCESS,
|
|
1501
|
-
S_WARN: () => S_WARN,
|
|
1502
|
-
cancel: () => cancel,
|
|
1503
|
-
confirm: () => confirm,
|
|
1504
|
-
formatInstructionFooter: () => formatInstructionFooter,
|
|
1505
|
-
intro: () => intro,
|
|
1506
|
-
isCI: () => isCI,
|
|
1507
|
-
isCancel: () => isCancel,
|
|
1508
|
-
limitOptions: () => limitOptions,
|
|
1509
|
-
log: () => log,
|
|
1510
|
-
multiselect: () => multiselect,
|
|
1511
|
-
note: () => note,
|
|
1512
|
-
outro: () => outro,
|
|
1513
|
-
password: () => password,
|
|
1514
|
-
select: () => select,
|
|
1515
|
-
spinner: () => spinner,
|
|
1516
|
-
symbol: () => symbol,
|
|
1517
|
-
symbolBar: () => symbolBar,
|
|
1518
|
-
text: () => text,
|
|
1519
|
-
unicode: () => unicode,
|
|
1520
|
-
unicodeOr: () => unicodeOr
|
|
1521
|
-
});
|
|
1522
798
|
function isUnicodeSupported() {
|
|
1523
799
|
if (process$1.platform !== "win32") return process$1.env.TERM !== "linux";
|
|
1524
800
|
return Boolean(process$1.env.CI) || Boolean(process$1.env.WT_SESSION) || Boolean(process$1.env.TERMINUS_SUBLIME) || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
@@ -2031,203 +1307,4 @@ ${r ? styleText("cyan", S_BAR_END) : ""}
|
|
|
2031
1307
|
}
|
|
2032
1308
|
}).prompt();
|
|
2033
1309
|
//#endregion
|
|
2034
|
-
|
|
2035
|
-
function getPackageDir() {
|
|
2036
|
-
let dir = join(fileURLToPath(import.meta.url), "..");
|
|
2037
|
-
for (let i = 0; i < 5; i++) {
|
|
2038
|
-
if (existsSync(join(dir, "package.json"))) {
|
|
2039
|
-
if (JSON.parse(readFileSync(join(dir, "package.json"), "utf-8")).name === "void") return dir;
|
|
2040
|
-
}
|
|
2041
|
-
dir = join(dir, "..");
|
|
2042
|
-
}
|
|
2043
|
-
throw new Error("Could not find void package root");
|
|
2044
|
-
}
|
|
2045
|
-
const agents = {
|
|
2046
|
-
"claude-code": {
|
|
2047
|
-
displayName: "Claude Code",
|
|
2048
|
-
skillsDir: ".claude/skills",
|
|
2049
|
-
detect: (root) => existsSync(join(root, ".claude")) || existsSync(join(root, "CLAUDE.md"))
|
|
2050
|
-
},
|
|
2051
|
-
amp: {
|
|
2052
|
-
displayName: "Amp",
|
|
2053
|
-
skillsDir: ".agents/skills",
|
|
2054
|
-
detect: (root) => existsSync(join(root, ".agents"))
|
|
2055
|
-
},
|
|
2056
|
-
codex: {
|
|
2057
|
-
displayName: "Codex",
|
|
2058
|
-
skillsDir: ".agents/skills",
|
|
2059
|
-
detect: (root) => existsSync(join(root, ".codex"))
|
|
2060
|
-
},
|
|
2061
|
-
cursor: {
|
|
2062
|
-
displayName: "Cursor",
|
|
2063
|
-
skillsDir: ".agents/skills",
|
|
2064
|
-
detect: (root) => existsSync(join(root, ".cursor"))
|
|
2065
|
-
},
|
|
2066
|
-
windsurf: {
|
|
2067
|
-
displayName: "Windsurf",
|
|
2068
|
-
skillsDir: ".windsurf/skills",
|
|
2069
|
-
detect: (root) => existsSync(join(root, ".windsurf"))
|
|
2070
|
-
},
|
|
2071
|
-
"gemini-cli": {
|
|
2072
|
-
displayName: "Gemini CLI",
|
|
2073
|
-
skillsDir: ".agents/skills",
|
|
2074
|
-
detect: (root) => existsSync(join(root, ".gemini"))
|
|
2075
|
-
},
|
|
2076
|
-
"github-copilot": {
|
|
2077
|
-
displayName: "GitHub Copilot",
|
|
2078
|
-
skillsDir: ".agents/skills",
|
|
2079
|
-
detect: (root) => existsSync(join(root, ".github", "copilot-instructions.md"))
|
|
2080
|
-
},
|
|
2081
|
-
cline: {
|
|
2082
|
-
displayName: "Cline",
|
|
2083
|
-
skillsDir: ".cline/skills",
|
|
2084
|
-
detect: (root) => existsSync(join(root, ".cline"))
|
|
2085
|
-
},
|
|
2086
|
-
roo: {
|
|
2087
|
-
displayName: "Roo Code",
|
|
2088
|
-
skillsDir: ".roo/skills",
|
|
2089
|
-
detect: (root) => existsSync(join(root, ".roo"))
|
|
2090
|
-
},
|
|
2091
|
-
kilo: {
|
|
2092
|
-
displayName: "Kilo Code",
|
|
2093
|
-
skillsDir: ".kilocode/skills",
|
|
2094
|
-
detect: (root) => existsSync(join(root, ".kilocode"))
|
|
2095
|
-
},
|
|
2096
|
-
continue: {
|
|
2097
|
-
displayName: "Continue",
|
|
2098
|
-
skillsDir: ".continue/skills",
|
|
2099
|
-
detect: (root) => existsSync(join(root, ".continue"))
|
|
2100
|
-
},
|
|
2101
|
-
goose: {
|
|
2102
|
-
displayName: "Goose",
|
|
2103
|
-
skillsDir: ".goose/skills",
|
|
2104
|
-
detect: (root) => existsSync(join(root, ".goose"))
|
|
2105
|
-
},
|
|
2106
|
-
opencode: {
|
|
2107
|
-
displayName: "OpenCode",
|
|
2108
|
-
skillsDir: ".agents/skills",
|
|
2109
|
-
detect: (root) => existsSync(join(root, ".opencode"))
|
|
2110
|
-
},
|
|
2111
|
-
trae: {
|
|
2112
|
-
displayName: "Trae",
|
|
2113
|
-
skillsDir: ".trae/skills",
|
|
2114
|
-
detect: (root) => existsSync(join(root, ".trae"))
|
|
2115
|
-
},
|
|
2116
|
-
junie: {
|
|
2117
|
-
displayName: "Junie",
|
|
2118
|
-
skillsDir: ".junie/skills",
|
|
2119
|
-
detect: (root) => existsSync(join(root, ".junie"))
|
|
2120
|
-
},
|
|
2121
|
-
"kiro-cli": {
|
|
2122
|
-
displayName: "Kiro CLI",
|
|
2123
|
-
skillsDir: ".kiro/skills",
|
|
2124
|
-
detect: (root) => existsSync(join(root, ".kiro"))
|
|
2125
|
-
},
|
|
2126
|
-
zencoder: {
|
|
2127
|
-
displayName: "Zencoder",
|
|
2128
|
-
skillsDir: ".zencoder/skills",
|
|
2129
|
-
detect: (root) => existsSync(join(root, ".zencoder"))
|
|
2130
|
-
},
|
|
2131
|
-
"qwen-code": {
|
|
2132
|
-
displayName: "Qwen Code",
|
|
2133
|
-
skillsDir: ".qwen/skills",
|
|
2134
|
-
detect: (root) => existsSync(join(root, ".qwen"))
|
|
2135
|
-
}
|
|
2136
|
-
};
|
|
2137
|
-
function detectAgents(root) {
|
|
2138
|
-
return Object.values(agents).filter((a) => a.detect(root));
|
|
2139
|
-
}
|
|
2140
|
-
//#endregion
|
|
2141
|
-
//#region src/cli/cloudflare-user-output.ts
|
|
2142
|
-
/**
|
|
2143
|
-
* Keep Void's public CLI vocabulary at the product level while preserving real
|
|
2144
|
-
* Cloudflare config filenames and environment variables that users may need to
|
|
2145
|
-
* inspect. The underlying implementation remains available in source and deploy
|
|
2146
|
-
* diagnostics, but normal remediation always points back to Void commands.
|
|
2147
|
-
*/
|
|
2148
|
-
function formatCloudflareUserMessage(message) {
|
|
2149
|
-
const preserved = [];
|
|
2150
|
-
const protect = (value) => {
|
|
2151
|
-
return `\uE000VOID_CF_TERM_${preserved.push(value) - 1}\uE001`;
|
|
2152
|
-
};
|
|
2153
|
-
let result = message.replace(/(?:[A-Za-z]:)?[^\s`"']*wrangler\.jsonc?/gi, protect).replace(/\bWRANGLER_[A-Z0-9_]+\b/g, protect).replace(/\.wrangler\b/gi, protect).replace(/`wrangler deploy`/gi, "`void deploy --platform cloudflare`").replace(/`wrangler secret list[^`]*`/gi, "`void secret list`").replace(/`wrangler secret put\s+([^`]*)`/gi, "`void secret put $1`").replace(/`wrangler d1 migrations apply[^`]*`/gi, "`void db migrate --remote`").replace(/`wrangler d1 migrations list[^`]*`/gi, "`void db status`").replace(/`wrangler[^`]*`/gi, "the underlying Cloudflare operation").replace(/"wrangler[^"\n]*"/gi, "\"Cloudflare operation\"").replace(/\bwrangler uploader\b/gi, "Cloudflare deployment tool").replace(/\bwrangler (?:CLI|binary|process|child)\b/gi, "Cloudflare deployment tool").replace(/\bwrangler config\b/gi, "Cloudflare config").replace(/\bwrangler\b/gi, "Cloudflare tooling");
|
|
2154
|
-
result = result.replace(/\uE000VOID_CF_TERM_(\d+)\uE001/g, (_match, index) => {
|
|
2155
|
-
return preserved[Number(index)] ?? "";
|
|
2156
|
-
});
|
|
2157
|
-
return result;
|
|
2158
|
-
}
|
|
2159
|
-
//#endregion
|
|
2160
|
-
//#region src/cli/output.ts
|
|
2161
|
-
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
2162
|
-
/** Keep recovery commands on the same CLI when using the local checkout launcher. */
|
|
2163
|
-
function cliCommandName() {
|
|
2164
|
-
const entryName = process.argv[1]?.split(/[\\/]/).at(-1);
|
|
2165
|
-
return entryName === "void-dev" || entryName === "void-dev.cmd" ? "void-dev" : "void";
|
|
2166
|
-
}
|
|
2167
|
-
/**
|
|
2168
|
-
* CI-safe spinner wrapper. In CI environments (GitHub Actions, etc.),
|
|
2169
|
-
* `@clack/prompts` spinner emits DEC Private Mode cursor hide/show codes
|
|
2170
|
-
* (`\x1b[?25l` / `\x1b[?25h`) that render as text artifacts. This wrapper
|
|
2171
|
-
* replaces the spinner with plain log output in CI.
|
|
2172
|
-
*/
|
|
2173
|
-
function createSpinner(options) {
|
|
2174
|
-
if (!isCI()) return spinner(options);
|
|
2175
|
-
let currentMessage = "";
|
|
2176
|
-
return {
|
|
2177
|
-
start(msg = "") {
|
|
2178
|
-
currentMessage = msg;
|
|
2179
|
-
if (msg) log.step(msg);
|
|
2180
|
-
},
|
|
2181
|
-
stop(msg = "") {
|
|
2182
|
-
if (msg) log.info(msg);
|
|
2183
|
-
},
|
|
2184
|
-
message(msg = "") {
|
|
2185
|
-
if (msg && msg !== currentMessage) {
|
|
2186
|
-
currentMessage = msg;
|
|
2187
|
-
log.step(msg);
|
|
2188
|
-
}
|
|
2189
|
-
},
|
|
2190
|
-
cancel(msg = "") {
|
|
2191
|
-
if (msg) log.warn(msg);
|
|
2192
|
-
},
|
|
2193
|
-
error(msg = "") {
|
|
2194
|
-
if (msg) log.error(msg);
|
|
2195
|
-
},
|
|
2196
|
-
clear() {},
|
|
2197
|
-
get isCancelled() {
|
|
2198
|
-
return false;
|
|
2199
|
-
}
|
|
2200
|
-
};
|
|
2201
|
-
}
|
|
2202
|
-
function cliTitle(command) {
|
|
2203
|
-
return import_picocolors.default.blue(`void ${command}`);
|
|
2204
|
-
}
|
|
2205
|
-
function sectionTitle(title) {
|
|
2206
|
-
return import_picocolors.default.reset(import_picocolors.default.blue(title));
|
|
2207
|
-
}
|
|
2208
|
-
function categoryTitle(title) {
|
|
2209
|
-
return import_picocolors.default.reset(import_picocolors.default.bold(import_picocolors.default.cyan(title)));
|
|
2210
|
-
}
|
|
2211
|
-
function dim(text) {
|
|
2212
|
-
return import_picocolors.default.dim(text);
|
|
2213
|
-
}
|
|
2214
|
-
function tablePrefix() {
|
|
2215
|
-
return `${import_picocolors.default.gray("│")} `;
|
|
2216
|
-
}
|
|
2217
|
-
function helpLine(command, description) {
|
|
2218
|
-
return `${import_picocolors.default.reset(command.padEnd(34))} ${import_picocolors.default.dim(description)}`;
|
|
2219
|
-
}
|
|
2220
|
-
/**
|
|
2221
|
-
* Ensure a timestamp string will be parsed as UTC by `new Date()`.
|
|
2222
|
-
* DB timestamps lack timezone info — appends 'Z' only when no
|
|
2223
|
-
* existing indicator (Z, z, or numeric offset) is present.
|
|
2224
|
-
*/
|
|
2225
|
-
function ensureUtc(s) {
|
|
2226
|
-
const last = s.at(-1);
|
|
2227
|
-
if (last === "Z" || last === "z") return s;
|
|
2228
|
-
if (s.includes("+", 10)) return s;
|
|
2229
|
-
if (s.lastIndexOf("-") > 9) return s;
|
|
2230
|
-
return s + "Z";
|
|
2231
|
-
}
|
|
2232
|
-
//#endregion
|
|
2233
|
-
export { promoteInstallationSecrets as $, outro as A, ensureCloudflaredToken as B, cancel as C, log as D, intro as E, CANCEL_SYMBOL as F, assertPlatformInstallationSlugAvailable as G, ensurePlatformProxyAccess as H, isCancel as I, listInstallationManifests as J, getActivePlatformConnection as K, settings as L, select as M, symbol as N, multiselect as O, text as P, platformWorkerSecretUpdateIntentState as Q, u$1 as R, S_STEP_SUBMIT as S, dist_exports as T, isCloudflareAccessChallenge as U, ensurePlatformAccessToken as V, acquirePlatformLifecycleLock as W, normalizePlatformApiUrl as X, listPlatformConnections as Y, platformCredentialAccount as Z, S_CHECKBOX_INACTIVE as _, dim as a, savePlatformConnection as at, S_RADIO_INACTIVE as b, import_picocolors as c, writePendingInstallationSecrets as ct, formatCloudflareUserMessage as d, writeKeyringPassword as dt, readInstallationRecoverySecrets as et, detectAgents as f, require_picocolors as ft, S_CHECKBOX_ACTIVE as g, S_BAR_END as h, createSpinner as i, resolveInstallationManifest as it, password as j, note as k, sectionTitle as l, deleteKeyringPassword as lt, S_BAR as m, cliCommandName as n, removeInstallationRecoverySecrets as nt, ensureUtc as o, selectPlatformConnection as ot, getPackageDir as p, latestPlatformWorkerCutoverGeneration as q, cliTitle as r, removePlatformConnectionForInstallation as rt, helpLine as s, writeInstallationManifest as st, categoryTitle as t, readPendingInstallationSecrets as tt, tablePrefix as u, readKeyringPassword as ut, S_PASSWORD_MASK as v, confirm as w, S_STEP_ACTIVE as x, S_RADIO_ACTIVE as y, wrapAnsi as z };
|
|
1310
|
+
export { limitOptions as A, text as B, S_SUCCESS as C, formatInstructionFooter as D, confirm as E, password as F, settings as G, unicodeOr as H, select as I, u$1 as K, spinner as L, multiselect as M, note as N, intro as O, outro as P, symbol as R, S_STEP_SUBMIT as S, cancel as T, CANCEL_SYMBOL as U, unicode as V, isCancel as W, S_RADIO_ACTIVE as _, S_BAR_H as a, S_STEP_CANCEL as b, S_CHECKBOX_INACTIVE as c, S_CORNER_BOTTOM_LEFT as d, S_CORNER_BOTTOM_RIGHT as f, S_PASSWORD_MASK as g, S_INFO as h, S_BAR_END as i, log as j, isCI as k, S_CHECKBOX_SELECTED as l, S_ERROR as m, SELECT_INSTRUCTIONS as n, S_BAR_START as o, S_CORNER_TOP_RIGHT as p, wrapAnsi as q, S_BAR as r, S_CHECKBOX_ACTIVE as s, MULTISELECT_INSTRUCTIONS as t, S_CONNECT_LEFT as u, S_RADIO_INACTIVE as v, S_WARN as w, S_STEP_ERROR as x, S_STEP_ACTIVE as y, symbolBar as z };
|