void 0.21.9 → 0.23.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 +5 -1
- package/dist/{account-cmd-DZZGK80W.mjs → account-cmd-C84Ee8cO.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-CZuiVsFh.mjs → auth-CCjt0hcq.mjs} +1 -1
- package/dist/{auth-DLNN0D3Z.mjs → auth-CSkdO2Bb.mjs} +4 -47
- package/dist/{auth-link-B_CeugBw.mjs → auth-link-CioEg6uY.mjs} +5 -5
- package/dist/{auth-router-BgEFRuvZ.mjs → auth-router-BsR981d4.mjs} +5 -5
- package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
- package/dist/{build-cmd-Dpt0jd-x.mjs → build-cmd-LzvNJORH.mjs} +19 -7
- package/dist/{cache-7_UeZdTk.mjs → cache-C4MvnrMH.mjs} +4 -4
- package/dist/{cancel-deploy-D23R1RXT.mjs → cancel-deploy-abUxpP2n.mjs} +4 -4
- package/dist/{cf-build-output-CGT03qCD.mjs → cf-build-output-BPqOT964.mjs} +141 -63
- package/dist/cf-build-output-_0HNWysu.mjs +2 -0
- package/dist/cli/cli.mjs +114 -460
- package/dist/cli/cloudflare-operation-process.mjs +1103 -0
- package/dist/cli/env-schema-probe.d.mts +2 -1
- package/dist/cli/env-schema-probe.mjs +3 -3
- package/dist/client-Cu7jWiF1.mjs +2 -0
- package/dist/{client-QTl6ko_D.mjs → client-RV8NVeB8.mjs} +165 -21
- package/dist/{cloudflare-auth-C4_GPZr0.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -43
- package/dist/{cloudflare-cmd-bSmZ1d5L.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +9 -10
- package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
- package/dist/{cloudflare-connect-jAwacxxP.mjs → cloudflare-connect-B8uPZ4nx.mjs} +4 -4
- package/dist/{cloudflare-operations-BipGMJ5O.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
- package/dist/{cloudflare-operations-sMZXpk_S.mjs → cloudflare-operations-fxHb-byx.mjs} +118 -203
- package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
- package/dist/{config-CF69HgXc.d.mts → config-BMHb8RCj.d.mts} +2 -2
- package/dist/{config-CafTW6Cz.mjs → config-Br_JZD6u.mjs} +2 -7
- package/dist/config-C_XRIPx2.mjs +89 -0
- package/dist/{config-s7Xj7tPb.mjs → config-CyQ-wVd7.mjs} +1 -1
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config-write-BSduPMY8.mjs → config-write-B1f88wJA.mjs} +1 -1
- package/dist/{connect-BsUSRzln.mjs → connect-Bd4kJd9U.mjs} +6 -6
- package/dist/{create-project-BniEV0OW.mjs → create-project-Boczwj5r.mjs} +1 -1
- package/dist/{create-project-DBfFSZKY.mjs → create-project-bMf6ffLZ.mjs} +9 -5
- package/dist/{db-hRrvZaq_.mjs → db-8uG64XLl.mjs} +26 -26
- package/dist/{delete-D6dZ9B6B.mjs → delete-NvbiyeJf.mjs} +4 -4
- package/dist/{deploy-WaAQez1O.mjs → deploy-DzAIwqNU.mjs} +944 -607
- package/dist/{deploy-DDz7c8LK.mjs → deploy-bjXdFCtn.mjs} +1 -1
- package/dist/{dist-BR1quN_w.mjs → dist-AoCzRTJE.mjs} +226 -60
- package/dist/{dist-C5fND3R0.mjs → dist-BuDuKZJv.mjs} +1 -1
- package/dist/{dist-Dn6nn2IU.mjs → dist-CTBk70IR.mjs} +42 -42
- package/dist/{domain-Dmhvb2oU.mjs → domain-y5Tvydvo.mjs} +5 -5
- package/dist/{email-DFi-s2t4.mjs → email-B3umsW75.mjs} +15 -30
- package/dist/{env-Csi-tMbT.mjs → env-BS6qYHDb.mjs} +6 -6
- package/dist/{env-public-D_6u46fX.d.mts → env-public-BX_r8HR6.d.mts} +2 -1
- package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
- package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.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-Dz3X1Qab.mjs → gen-B580--vC.mjs} +5 -5
- package/dist/gen-BVaUUumi.mjs +2 -0
- package/dist/{github-cmd-BED3_9JD.mjs → github-cmd-v45BdfKX.mjs} +6 -8
- package/dist/{handler-BXJTXd02.d.mts → handler-CZ4nAylQ.d.mts} +2 -1
- package/dist/{headers-BOg_velo.mjs → headers-DWi2IXWx.mjs} +1 -1
- package/dist/help-DofyZuY7.mjs +2 -0
- package/dist/{help-DC7gdz7L.mjs → help-daGKjXGk.mjs} +268 -666
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +305 -1490
- package/dist/info-B97bTX9N.mjs +113 -0
- package/dist/{init-WO0JlPx8.mjs → init-Bvy7zrBo.mjs} +51 -20
- package/dist/limits-Bq5LG8Id.d.mts +27 -0
- package/dist/limits-Cjuk2VPm.mjs +68 -0
- package/dist/{link-CsHOinF7.mjs → link-CDqqCjFl.mjs} +5 -5
- package/dist/{list-CDb-4bZ1.mjs → list-CZj0dzKY.mjs} +5 -5
- package/dist/{live-CKiJilLr.d.mts → live-Chw1eIMv.d.mts} +1 -1
- package/dist/{local-d1-CC8sKFGu.mjs → local-d1-2CMnpuW_.mjs} +2 -2
- package/dist/login-DYt_An22.mjs +2 -0
- package/dist/{login-DvqXsfGs.mjs → login-UZKFM_u7.mjs} +5 -5
- package/dist/{logs-BdfiOezj.mjs → logs-CUZ6t9t3.mjs} +5 -5
- package/dist/migrate-8_2u55MD.mjs +2 -0
- package/dist/{migrate-B8KuoYsO.mjs → migrate-DHul7PRV.mjs} +5 -4
- package/dist/{node-BM43oz4G.mjs → node-BkyRWRx8.mjs} +2 -2
- package/dist/operator-args-CLgKGlwU.mjs +690 -0
- package/dist/{operator-cmd-03819ATr.mjs → operator-cmd-DBA6dl0m.mjs} +69 -23
- package/dist/output-Dm_A4Tbv.mjs +81 -0
- 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 +3 -3
- package/dist/pages/islands-plugin.d.mts +16 -6
- package/dist/pages/islands-plugin.mjs +2 -2
- 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/{output-CCH48AMM.mjs → picocolors-BTps1_gs.mjs} +2 -76
- package/dist/plan-D1Q5rf-r.mjs +2 -0
- package/dist/plan-NPpwZ_kc.mjs +58 -0
- package/dist/platform-args-BJdRtlLq.mjs +506 -0
- package/dist/platform-args-D3RXyR6h.mjs +2 -0
- package/dist/{platform-auth-config-z92h63q5.mjs → platform-auth-config-B56E9YP1.mjs} +4 -4
- package/dist/{platform-auth-protection-DeE3yr2R.mjs → platform-auth-protection-BDWO_aER.mjs} +3 -3
- package/dist/{platform-auth-recovery-o_340Ixx.mjs → platform-auth-recovery-1gg4CSRe.mjs} +4 -4
- package/dist/{platform-cmd-C4ZV3Vpy.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
- package/dist/{platform-cmd-DNl8WosH.mjs → platform-cmd-DMcQStSc.mjs} +26 -5
- package/dist/{platform-domain-CU1JtJkW.mjs → platform-domain-BNkcz0OB.mjs} +36 -9
- package/dist/{platform-lifecycle-Bc047IeT.mjs → platform-lifecycle-9OyBALhH.mjs} +850 -276
- package/dist/{platform-lifecycle-Bs2qx1E3.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
- package/dist/{platform-management-CVpGI9Y5.mjs → platform-management-CjwLVQwN.mjs} +59 -11
- package/dist/{platform-management-C8tt6D8h.mjs → platform-management-CnyTdcWX.mjs} +1 -1
- package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
- package/dist/{platform-recovery-dvUaptLr.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
- package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
- package/dist/{prepare-DyZ-Yok5.mjs → prepare-B5Mkic5u.mjs} +3 -3
- package/dist/{prepare-C3kt3Rst.mjs → prepare-DOsL0CC9.mjs} +4 -20
- package/dist/prepare-cgvDMtSb.mjs +2 -0
- package/dist/{project-cmd-B44I8J_W.mjs → project-cmd-CNzrqvBv.mjs} +30 -16
- package/dist/{project-team-BkbYIsXN.mjs → project-team-DQOWPfQT.mjs} +4 -4
- package/dist/{project-token-C8xEEQnB.mjs → project-token-CTDYU0Cc.mjs} +4 -4
- package/dist/project-zero-trust-BNAkW-_0.mjs +63 -0
- package/dist/{protocol-ZH3jP4a7.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
- package/dist/protocol-U7bfjHmA.mjs +331 -0
- package/dist/{provision-DNtrtaVD.mjs → provision-C4ORE7G7.mjs} +1 -1
- package/dist/{provision-BhreDAOS.mjs → provision-CJFgTZY8.mjs} +111 -215
- package/dist/{requests-DFyhBMaf.mjs → requests-MhxYnau8.mjs} +4 -4
- package/dist/resource-name-C7LVpcRm.mjs +11 -0
- package/dist/{rollback-DHHxXZiS.mjs → rollback-CJ6iSDoU.mjs} +5 -5
- 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 +84 -17
- 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 +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/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 +3 -0
- package/dist/runtime/sandbox-container.mjs +2 -0
- package/dist/runtime/sandbox.d.mts +4 -32
- package/dist/runtime/sandbox.mjs +151 -75
- 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-XZAqzFlG.d.mts +52 -0
- package/dist/sandbox-container-Bo0eiFKz.d.mts +73 -0
- package/dist/sandbox-container-C6ItmVuN.mjs +281 -0
- package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
- package/dist/{secret-DN9sSNiV.mjs → secret-Dli5fP0B.mjs} +6 -6
- package/dist/{skills-O6FUaizK.mjs → skills-D1II1Juz.mjs} +1 -1
- package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
- package/dist/{subcommand-prompt-BuGYkAkC.mjs → subcommand-prompt-CY1C4fvl.mjs} +2 -2
- package/dist/validate-Dq_L3s0S.mjs +2 -0
- package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
- package/dist/{wrangler-BymcxrRa.mjs → wrangler-7K-bW_DL.mjs} +14 -235
- package/dist/{ws-BwcqizuH.d.mts → ws-CL1w7GXU.d.mts} +13 -2
- package/package.json +48 -33
- package/sandbox.Dockerfile +4 -0
- package/schema.json +10 -22
- package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
- package/skills/void/SKILL.md +50 -133
- 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 +27 -113
- package/skills/void/docs/guide/durable-state.md +43 -18
- package/skills/void/docs/guide/edge/headers.md +3 -47
- 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 +6 -19
- package/skills/void/docs/guide/edge/rewrites.md +56 -284
- package/skills/void/docs/guide/edge/static-assets.md +23 -72
- package/skills/void/docs/guide/email/domains.md +112 -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 +189 -0
- package/skills/void/docs/guide/platform/development/local.md +2 -2
- 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/credentials.md +6 -4
- package/skills/void/docs/guide/platform/installation/domains.md +31 -3
- package/skills/void/docs/guide/platform/installation/first-deployment.md +6 -0
- package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
- package/skills/void/docs/guide/platform/installation/prerequisites.md +21 -16
- package/skills/void/docs/guide/platform/installation/setup.md +9 -5
- package/skills/void/docs/guide/platform/installation/uninstall.md +17 -2
- package/skills/void/docs/guide/platform-administration.md +2 -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 +4 -9
- package/skills/void/docs/guide/sandboxes.md +78 -41
- 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 +88 -0
- package/skills/void/docs/reference/cli/database.md +128 -0
- package/skills/void/docs/reference/cli/deploy.md +85 -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 +127 -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 +45 -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 +33 -1621
- package/skills/void/docs/reference/config.md +26 -32
- package/skills/void/docs/reference/resource-inference.md +3 -58
- package/skills/void/docs/reference/structure.md +14 -41
- package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
- package/dist/cli/cf-compat.mjs +0 -968
- package/dist/client-4cDVv7BO.mjs +0 -2
- package/dist/gen-Vnv2f65C.mjs +0 -2
- package/dist/help-DQMfeKMz.mjs +0 -2
- package/dist/login-DFQk7rbW.mjs +0 -2
- package/dist/migrate-TsHGBnDA.mjs +0 -2
- package/dist/plan-BEZ8VJW0.mjs +0 -256
- package/dist/plan-DpuOr14e.mjs +0 -2
- package/dist/prepare-BZXkjdNe.mjs +0 -2
- package/dist/validate-EKmJWxmy.mjs +0 -2
- /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-
|
|
1
|
+
import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-9OyBALhH.mjs";
|
|
2
2
|
export { runPlatformLifecycleCommand };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as createSpinner } from "./output-CCH48AMM.mjs";
|
|
2
1
|
import { a as listInstallationManifests, d as readInstallationRecoverySecrets, h as resolveInstallationManifest, m as removePlatformConnectionForInstallation, p as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
|
|
3
|
-
import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-
|
|
4
|
-
import {
|
|
2
|
+
import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
|
|
3
|
+
import { i as createSpinner } from "./output-Dm_A4Tbv.mjs";
|
|
4
|
+
import { A as PlatformCloudflareClient, C as revalidatePlatformInstallAction, E as resolvePlatformCloudflareCredential, M as hyperdriveOriginFromConnectionString, N as hyperdriveOriginMatches, P as verifyPlatformRuntimeTokenPermissions, S as platformProvisionIntentHash, T as assertPlatformOperatorCredentialCanApplyPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as formatPlatformInstallPlan, d as loadPlatformRuntime, g as assertProjectZeroTrustAllowsUninstall, h as resolveBootstrapGitHubId, j as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, p as readPlatformProjectZeroTrustState, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as trackedPlatformWorkerTraffic, w as platformDatabaseNameFromOwnerUrl, x as platformAdoptionIntentHash, y as createPlatformInstallPlan } from "./platform-lifecycle-9OyBALhH.mjs";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import { PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE, PLATFORM_R2_OWNERSHIP_MARKER_KEY, createPlatformResourceOwnershipMarker, parsePlatformInstallationManifest, parsePlatformResourceOwnershipMarker, recordInstallationResource, recordInstallationStep, setInstallationDesiredState, transitionInstallation } from "@void/platform";
|
|
7
7
|
//#region src/cli/platform-management.ts
|
|
@@ -58,7 +58,11 @@ async function runInstalledPlatformCommand(args) {
|
|
|
58
58
|
if (args.subcommand === "uninstall") {
|
|
59
59
|
await uninstallPlatform(client, manifest, args, {
|
|
60
60
|
checkpoint: databaseLock?.checkpoint,
|
|
61
|
-
databaseUrl
|
|
61
|
+
databaseUrl,
|
|
62
|
+
readProjectZeroTrust: databaseLock ? databaseLock.readProjectZeroTrust : () => readPlatformProjectZeroTrustState(databaseUrl, manifest.id, manifest.ownershipNonce),
|
|
63
|
+
lockProjectZeroTrust: databaseLock?.lockProjectZeroTrust,
|
|
64
|
+
fenceProjectZeroTrust: databaseLock?.fenceProjectZeroTrust,
|
|
65
|
+
liftProjectZeroTrustFence: databaseLock?.liftProjectZeroTrustFence
|
|
62
66
|
});
|
|
63
67
|
return;
|
|
64
68
|
}
|
|
@@ -73,6 +77,7 @@ async function runInstalledPlatformCommand(args) {
|
|
|
73
77
|
...args.subcommand === "upgrade" && process.env.VOID_EMAIL_SENDER_DOMAIN ? { emailSenderDomain: process.env.VOID_EMAIL_SENDER_DOMAIN } : {},
|
|
74
78
|
applicationDomain: deployment.application.baseDomain,
|
|
75
79
|
controlPlaneDomain: deployment.controlPlane.apiHostname ?? "",
|
|
80
|
+
...args.subcommand !== "rollback" && args.dashboardUrl !== void 0 ? { dashboardUrl: args.dashboardUrl } : {},
|
|
76
81
|
dedicatedZone: deployment.application.dedicatedZone,
|
|
77
82
|
displayName: deployment.displayName,
|
|
78
83
|
installationSlug: deployment.installationSlug,
|
|
@@ -83,7 +88,8 @@ async function runInstalledPlatformCommand(args) {
|
|
|
83
88
|
repairMissing: args.subcommand === "repair",
|
|
84
89
|
allowUnverifiedAiGateway: args.plan,
|
|
85
90
|
includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
|
|
86
|
-
enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
|
|
91
|
+
enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3,
|
|
92
|
+
deploymentExecution: runtime.manifest.deploymentExecution === 1
|
|
87
93
|
});
|
|
88
94
|
markPhase("plan");
|
|
89
95
|
note(formatPlatformInstallPlan(plan), args.subcommand === "upgrade" ? "Upgrade plan" : args.subcommand === "rollback" ? "Rollback plan" : args.subcommand === "enable" ? "Enable plan" : "Repair plan");
|
|
@@ -145,6 +151,7 @@ async function runInstalledPlatformCommand(args) {
|
|
|
145
151
|
const result = await installPlatform(plan, secrets, installation, {
|
|
146
152
|
acquireDatabaseLifecycleLock: async () => Object.assign(async () => {}, {
|
|
147
153
|
checkpoint: databaseLock?.checkpoint,
|
|
154
|
+
liftProjectZeroTrustFence: databaseLock?.liftProjectZeroTrustFence,
|
|
148
155
|
prepareDatabase: databaseLock?.prepareDatabase,
|
|
149
156
|
prepareSandboxDrain: databaseLock?.prepareSandboxDrain,
|
|
150
157
|
readAuthenticationState: databaseLock?.readAuthenticationState,
|
|
@@ -162,9 +169,13 @@ async function runInstalledPlatformCommand(args) {
|
|
|
162
169
|
authoritativeProvisionIntents: true,
|
|
163
170
|
repairMissing: true,
|
|
164
171
|
includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
|
|
165
|
-
enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
|
|
172
|
+
enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3,
|
|
173
|
+
deploymentExecution: runtime.manifest.deploymentExecution === 1
|
|
166
174
|
})).actions.filter((action) => action.kind === "worker"),
|
|
167
|
-
revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action, {
|
|
175
|
+
revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action, {
|
|
176
|
+
repairMissing: args.subcommand === "repair",
|
|
177
|
+
stableWorkerUpdate: args.subcommand === "upgrade"
|
|
178
|
+
})
|
|
168
179
|
});
|
|
169
180
|
progress.message("Finalizing platform changes");
|
|
170
181
|
markPhase("installer complete");
|
|
@@ -315,8 +326,9 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
|
|
|
315
326
|
const interactive = dependencies.interactive ?? process.stdin.isTTY;
|
|
316
327
|
const confirmAction = dependencies.confirm ?? promptForConfirmation;
|
|
317
328
|
if (createdZone && args.deleteZone === true) throw new Error(`platform: Refusing to delete Cloudflare zone ${JSON.stringify(createdZone.name)} automatically. A zone can contain unrelated DNS, settings, and products that the installer cannot exhaustively prove ownership of. Uninstall with --keep-zone, inspect the retained zone in Cloudflare, and delete it manually if appropriate.`);
|
|
329
|
+
await assertProjectZeroTrustAllowsUninstall(dependencies.readProjectZeroTrust);
|
|
318
330
|
const dataMessage = retainData ? "Retain installer-owned Workers, storage, dispatch, AI logs, and Hyperdrive by default." : args.purgeData ? "Delete safely identifiable installer-owned data (--purge-data); retain Workers, R2, AI Gateway, and external PostgreSQL for manual cleanup." : "Retain installer-owned data; external PostgreSQL is never deleted.";
|
|
319
|
-
note(`Disable all platform traffic through installation-owned routing storage.\nRetain DNS records, routes, and custom domains for explicit dashboard cleanup.\nDelete installer-owned Queues.\n${dataMessage}\n${createdZone ? `Keep zone ${createdZone.name} for explicit manual cleanup.` : "Never delete the adopted application zone."}${(manifest.authenticationResources ?? []).length ? "\nRetain Access resources for deliberate cleanup:\n" + manifest.authenticationResources.map((resource) => ` ${resource.ownership} ${resource.kind}: ${resource.name} (${resource.id}, account ${resource.accountId})`).join("\n") : ""}`, "Uninstall plan");
|
|
331
|
+
note(`Disable all platform traffic through installation-owned routing storage.\nRetain DNS records, routes, and custom domains for explicit dashboard cleanup.\nDelete installer-owned Queues unless a retained Worker still uses them.\n${dataMessage}\n${createdZone ? `Keep zone ${createdZone.name} for explicit manual cleanup.` : "Never delete the adopted application zone."}${(manifest.authenticationResources ?? []).length ? "\nRetain Access resources for deliberate cleanup:\n" + manifest.authenticationResources.map((resource) => ` ${resource.ownership} ${resource.kind}: ${resource.name} (${resource.id}, account ${resource.accountId})`).join("\n") : ""}`, "Uninstall plan");
|
|
320
332
|
if (args.plan) {
|
|
321
333
|
outro("No Cloudflare or local installation state was changed.");
|
|
322
334
|
return;
|
|
@@ -345,12 +357,34 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
|
|
|
345
357
|
await verifyPlatformInstallationOwnership(client, manifest, { databaseUrl: dependencies.databaseUrl });
|
|
346
358
|
missingResources = /* @__PURE__ */ new Set();
|
|
347
359
|
}
|
|
348
|
-
|
|
349
|
-
|
|
360
|
+
const { fenceProjectZeroTrust, liftProjectZeroTrustFence, lockProjectZeroTrust } = dependencies;
|
|
361
|
+
if (!lockProjectZeroTrust || !fenceProjectZeroTrust || !liftProjectZeroTrustFence) throw new Error("platform: Refusing to uninstall because no platform database connection is available to hold off project Zero Trust changes.");
|
|
362
|
+
const releaseProjectZeroTrust = await lockProjectZeroTrust();
|
|
363
|
+
let fenced = false;
|
|
364
|
+
let disablingTraffic = false;
|
|
365
|
+
const stopProjectZeroTrustHold = async () => {
|
|
366
|
+
if (fenced && !disablingTraffic) await liftProjectZeroTrustFence().catch((error) => {
|
|
367
|
+
log.warn(`Could not reopen project Zero Trust changes after the uninstall stopped: ${error instanceof Error ? error.message : String(error)}\nRun \`void platform uninstall\` again, or \`void platform repair\` to keep the platform.`);
|
|
368
|
+
});
|
|
369
|
+
await releaseProjectZeroTrust();
|
|
370
|
+
};
|
|
371
|
+
let next = manifest;
|
|
372
|
+
try {
|
|
373
|
+
await assertProjectZeroTrustAllowsUninstall(dependencies.readProjectZeroTrust);
|
|
374
|
+
fenced = true;
|
|
375
|
+
await fenceProjectZeroTrust();
|
|
376
|
+
next = transitionInstallation(manifest, "uninstalling", (/* @__PURE__ */ new Date()).toISOString());
|
|
377
|
+
writeInstallationManifest(next);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
await stopProjectZeroTrustHold();
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
350
382
|
try {
|
|
351
383
|
await writeRemoteManifestIfPresent(client, next);
|
|
352
384
|
const routing = next.resources.find((resource) => resource.key === "routing-kv" && resource.state === "ready");
|
|
385
|
+
disablingTraffic = true;
|
|
353
386
|
if (routing) await client.putKvValue(next.account.id, routing.id, PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
|
|
387
|
+
await releaseProjectZeroTrust();
|
|
354
388
|
for (const key of missingResources) {
|
|
355
389
|
const resource = requireResource(next, key);
|
|
356
390
|
next = updateResourceState(next, key, resource.ownership === "created" ? "deleted" : "retained");
|
|
@@ -383,6 +417,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
|
|
|
383
417
|
zone: 8
|
|
384
418
|
};
|
|
385
419
|
const resources = [...next.resources].sort((left, right) => resourceDeletionPriority(left, deletionPriority) - resourceDeletionPriority(right, deletionPriority));
|
|
420
|
+
const queuesInUse = hasRoutingCheckpoint && resources.some((resource) => resource.kind === "queue" && shouldDeleteResource(resource, retainData)) && await hasLiveInstallationWorker(client, next);
|
|
386
421
|
for (const resource of resources) {
|
|
387
422
|
if (resource.state !== "ready") continue;
|
|
388
423
|
if (!hasRoutingCheckpoint && resource.kind !== "zone") {
|
|
@@ -395,7 +430,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
|
|
|
395
430
|
await writeLifecycleCheckpoint(client, next);
|
|
396
431
|
continue;
|
|
397
432
|
}
|
|
398
|
-
if (resource.kind === "dns-record" && !zone) {
|
|
433
|
+
if (resource.kind === "dns-record" && !zone || resource.kind === "queue" && queuesInUse) {
|
|
399
434
|
next = updateResourceState(next, resource.key, "retained");
|
|
400
435
|
await writeLifecycleCheckpoint(client, next);
|
|
401
436
|
continue;
|
|
@@ -420,6 +455,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
|
|
|
420
455
|
removePlatformConnectionForInstallation(next.id);
|
|
421
456
|
log.success(retainData ? `${next.deployment.displayName} was uninstalled; data resources were retained and recorded in ${next.id}.` : `${next.deployment.displayName} was uninstalled.`);
|
|
422
457
|
} catch (error) {
|
|
458
|
+
await stopProjectZeroTrustHold().catch(() => {});
|
|
423
459
|
next = transitionInstallation(next, "failed", (/* @__PURE__ */ new Date()).toISOString());
|
|
424
460
|
writeInstallationManifest(next);
|
|
425
461
|
await writeRemoteManifestIfPresent(client, next).catch(() => {});
|
|
@@ -505,6 +541,18 @@ function shouldDeleteResource(resource, retainData) {
|
|
|
505
541
|
if (resource.kind === "worker-route" || resource.kind === "worker-custom-domain") return false;
|
|
506
542
|
return !(retainData && DATA_RESOURCE_KINDS.has(resource.kind));
|
|
507
543
|
}
|
|
544
|
+
async function hasLiveInstallationWorker(client, manifest) {
|
|
545
|
+
const names = manifest.deployment.resources;
|
|
546
|
+
const installationWorkers = /* @__PURE__ */ new Set([
|
|
547
|
+
names.apiWorker,
|
|
548
|
+
names.proxyWorker,
|
|
549
|
+
names.emailGatewayWorker,
|
|
550
|
+
names.tailWorker,
|
|
551
|
+
names.dispatchWorker,
|
|
552
|
+
...manifest.resources.filter((resource) => resource.kind === "worker").map((resource) => resource.name)
|
|
553
|
+
]);
|
|
554
|
+
return (await client.listWorkerNames(manifest.account.id)).some((name) => installationWorkers.has(name));
|
|
555
|
+
}
|
|
508
556
|
function resourceDeletionPriority(resource, priorities) {
|
|
509
557
|
return resource.key === "routing-kv" ? 100 : priorities[resource.kind] ?? 99;
|
|
510
558
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-
|
|
1
|
+
import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-CjwLVQwN.mjs";
|
|
2
2
|
export { runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { B as text, E as confirm, I as select, W as isCancel } from "./dist-CTBk70IR.mjs";
|
|
2
|
+
import { n as OperatorClient, r as OperatorClientError } from "./operator-client-DUwumHpQ.mjs";
|
|
3
|
+
import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-8KnOVXVd.mjs";
|
|
4
|
+
import { stripVTControlCharacters } from "node:util";
|
|
5
|
+
import { PLAN_EDITABLE_LIMIT_KEYS, PLAN_LIMITS, parseBuildInstanceType, parsePlanLimitsPatch, parsePlanName, parsePlatformPlanId } from "@void/platform/plans";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
//#region src/cli/platform-plans-config.ts
|
|
8
|
+
const limitLabels = {
|
|
9
|
+
requestsPerMonth: "Requests per billing month",
|
|
10
|
+
cpuMsPerRequest: "Default CPU per request (ms)",
|
|
11
|
+
maxCpuMsPerRequest: "Maximum app CPU per request (ms)",
|
|
12
|
+
subRequestsPerInvocation: "Subrequests per invocation",
|
|
13
|
+
deploysPerDay: "Deployments per day",
|
|
14
|
+
aiNeuronsPerMonth: "AI neurons per billing month",
|
|
15
|
+
retainedDeployments: "Retained Worker deployments",
|
|
16
|
+
sandboxRuntimeSecondsPerMonth: "Sandbox runtime per billing month (seconds)",
|
|
17
|
+
sandboxMaxConcurrentInstances: "Concurrent Sandbox instances",
|
|
18
|
+
concurrentBuilds: "Concurrent builds",
|
|
19
|
+
buildTimeoutMinutes: "Build timeout (minutes)"
|
|
20
|
+
};
|
|
21
|
+
function limitValue(value, key) {
|
|
22
|
+
if (value === 0 && key === "buildTimeoutMinutes") return "platform maximum (60 minutes)";
|
|
23
|
+
return value === 0 ? "unlimited" : value.toLocaleString("en-US");
|
|
24
|
+
}
|
|
25
|
+
function showListing(listing, json) {
|
|
26
|
+
if (json) {
|
|
27
|
+
print(listing);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.log(`Default for new accounts: ${listing.catalog.defaultPlanId}`);
|
|
31
|
+
for (const plan of listing.catalog.plans) {
|
|
32
|
+
const count = listing.accounts.find((entry) => entry.planId === plan.id)?.count ?? 0;
|
|
33
|
+
console.log(`${label(plan)} — ${count} accounts`);
|
|
34
|
+
}
|
|
35
|
+
if (listing.catalog.reconciliation && !listing.catalog.reconciliation.complete) console.log("Account updates are pending. Run void platform config plans sync --yes.");
|
|
36
|
+
}
|
|
37
|
+
function showPreview(preview, before, write = console.error) {
|
|
38
|
+
const after = preview.catalog;
|
|
39
|
+
write(`Change: ${preview.action} ${preview.target}`);
|
|
40
|
+
write(`Accounts affected: ${preview.affectedAccounts}`);
|
|
41
|
+
for (const warning of preview.warnings ?? []) write(stripVTControlCharacters(warning));
|
|
42
|
+
if (typeof preview.usageSampleSize === "number" && preview.usageSampleSize > 0) write(`Usage preview samples ${preview.usageSampleSize} accounts.`);
|
|
43
|
+
if (before.defaultPlanId !== after.defaultPlanId) write(`Default for new accounts: ${before.defaultPlanId} → ${after.defaultPlanId}`);
|
|
44
|
+
for (const plan of after.plans) {
|
|
45
|
+
const previous = before.plans.find((entry) => entry.id === plan.id);
|
|
46
|
+
if (!previous) {
|
|
47
|
+
write(`Add ${label(plan)}; build size ${plan.buildInstanceType}`);
|
|
48
|
+
for (const key of PLAN_EDITABLE_LIMIT_KEYS) write(` ${limitLabels[key]}: ${limitValue(plan.limits[key], key)}`);
|
|
49
|
+
write(` Short project slugs: ${plan.allowShortSlugs ? "allowed" : "not allowed"}`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (previous.name !== plan.name) write(`Name: ${previous.name} → ${plan.name}`);
|
|
53
|
+
if (previous.archived !== plan.archived) write(`${plan.id}: ${plan.archived ? "archive for new assignments" : "restore assignments"}`);
|
|
54
|
+
if (previous.buildInstanceType !== plan.buildInstanceType) write(`Build size: ${previous.buildInstanceType} → ${plan.buildInstanceType}`);
|
|
55
|
+
if (previous.allowShortSlugs !== plan.allowShortSlugs) write(`Short project slugs: ${previous.allowShortSlugs ? "allowed" : "not allowed"} → ${plan.allowShortSlugs ? "allowed" : "not allowed"}`);
|
|
56
|
+
for (const key of PLAN_EDITABLE_LIMIT_KEYS) if (previous.limits[key] !== plan.limits[key]) write(`${limitLabels[key]}: ${limitValue(previous.limits[key], key)} → ${limitValue(plan.limits[key], key)}`);
|
|
57
|
+
}
|
|
58
|
+
for (const plan of before.plans) if (!after.plans.some((entry) => entry.id === plan.id)) {
|
|
59
|
+
write(`Remove ${label(plan)}`);
|
|
60
|
+
const replacement = after.plans.find((entry) => entry.id === preview.replacementPlanId);
|
|
61
|
+
if (replacement) {
|
|
62
|
+
write(`Move accounts to ${label(replacement)}`);
|
|
63
|
+
if (plan.buildInstanceType !== replacement.buildInstanceType) write(`Build size: ${plan.buildInstanceType} → ${replacement.buildInstanceType}`);
|
|
64
|
+
if (plan.allowShortSlugs !== replacement.allowShortSlugs) write(`Short project slugs: ${plan.allowShortSlugs ? "allowed" : "not allowed"} → ${replacement.allowShortSlugs ? "allowed" : "not allowed"}`);
|
|
65
|
+
for (const key of PLAN_EDITABLE_LIMIT_KEYS) if (plan.limits[key] !== replacement.limits[key]) write(`${limitLabels[key]}: ${limitValue(plan.limits[key], key)} → ${limitValue(replacement.limits[key], key)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const account of preview.overLimitAccounts ?? []) write(`Already above proposed limits: ${stripVTControlCharacters(account.login)} (${account.id}): ${account.reasons.join(", ")}`);
|
|
69
|
+
}
|
|
70
|
+
function value(input) {
|
|
71
|
+
if (isCancel(input) || typeof input === "symbol") throw new Error("platform: Cancelled.");
|
|
72
|
+
return input;
|
|
73
|
+
}
|
|
74
|
+
function print(result) {
|
|
75
|
+
console.log(JSON.stringify(result, null, 2));
|
|
76
|
+
}
|
|
77
|
+
function label(plan) {
|
|
78
|
+
return `${stripVTControlCharacters(plan.name)} (${plan.id}${plan.archived ? ", archived" : ""})`;
|
|
79
|
+
}
|
|
80
|
+
async function choosePlan(catalog, message, options = {}) {
|
|
81
|
+
const plans = catalog.plans.filter((plan) => plan.id !== options.exclude && (!options.activeOnly || !plan.archived));
|
|
82
|
+
if (!plans.length) throw new Error("platform: No eligible plans are available.");
|
|
83
|
+
return value(await select({
|
|
84
|
+
message,
|
|
85
|
+
options: plans.map((plan) => ({
|
|
86
|
+
value: plan.id,
|
|
87
|
+
label: label(plan)
|
|
88
|
+
}))
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
async function changesInput(args, plan) {
|
|
92
|
+
if (args.file) {
|
|
93
|
+
const input = JSON.parse(await readFile(args.file, "utf8"));
|
|
94
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error("platform: A plan file must contain a JSON object.");
|
|
95
|
+
const object = input;
|
|
96
|
+
for (const key of Object.keys(object)) if (![
|
|
97
|
+
"name",
|
|
98
|
+
"limits",
|
|
99
|
+
"buildInstanceType",
|
|
100
|
+
"allowShortSlugs"
|
|
101
|
+
].includes(key)) throw new Error(`platform: Unknown plan field ${key}. Use name, limits, buildInstanceType, or allowShortSlugs.`);
|
|
102
|
+
if (object.allowShortSlugs !== void 0 && typeof object.allowShortSlugs !== "boolean") throw new Error("platform: allowShortSlugs must be a boolean.");
|
|
103
|
+
return {
|
|
104
|
+
...object,
|
|
105
|
+
...object.name !== void 0 ? { name: parsePlanName(object.name) } : {},
|
|
106
|
+
...object.buildInstanceType !== void 0 ? { buildInstanceType: parseBuildInstanceType(object.buildInstanceType) } : {},
|
|
107
|
+
...object.limits !== void 0 ? { limits: parsePlanLimitsPatch(object.limits) } : {},
|
|
108
|
+
...args.name ? { name: parsePlanName(args.name) } : {}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (args.name) return { name: parsePlanName(args.name) };
|
|
112
|
+
if (!process.stdin.isTTY || args.json) {
|
|
113
|
+
if (args.action === "add") throw new Error("platform: Supply --name or --file when adding a plan in non-interactive mode.");
|
|
114
|
+
throw new Error("platform: Supply --name or --file with the changes in non-interactive mode.");
|
|
115
|
+
}
|
|
116
|
+
if (args.action === "add") return { name: parsePlanName(value(await text({
|
|
117
|
+
message: "Plan name:",
|
|
118
|
+
initialValue: args.target
|
|
119
|
+
}))) };
|
|
120
|
+
const field = value(await select({
|
|
121
|
+
message: "What would you like to change?",
|
|
122
|
+
options: [
|
|
123
|
+
{
|
|
124
|
+
value: "name",
|
|
125
|
+
label: "Plan name"
|
|
126
|
+
},
|
|
127
|
+
...PLAN_EDITABLE_LIMIT_KEYS.map((key) => ({
|
|
128
|
+
value: key,
|
|
129
|
+
label: `${limitLabels[key]}: ${limitValue(plan.limits[key], key)}`
|
|
130
|
+
})),
|
|
131
|
+
{
|
|
132
|
+
value: "buildInstanceType",
|
|
133
|
+
label: "Build instance size"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}));
|
|
137
|
+
if (field === "name") return { name: parsePlanName(value(await text({
|
|
138
|
+
message: "Plan name:",
|
|
139
|
+
initialValue: plan.name
|
|
140
|
+
}))) };
|
|
141
|
+
if (field === "buildInstanceType") return { buildInstanceType: value(await select({
|
|
142
|
+
message: "Build instance size:",
|
|
143
|
+
initialValue: plan.buildInstanceType,
|
|
144
|
+
options: [{
|
|
145
|
+
value: "standard-3",
|
|
146
|
+
label: "Standard: 2 vCPU, 8 GiB"
|
|
147
|
+
}, {
|
|
148
|
+
value: "standard-4",
|
|
149
|
+
label: "Large: 4 vCPU, 12 GiB"
|
|
150
|
+
}]
|
|
151
|
+
})) };
|
|
152
|
+
const current = plan.limits[field];
|
|
153
|
+
const input = value(await text({
|
|
154
|
+
message: `${limitLabels[field]} (${field === "buildTimeoutMinutes" ? "0 uses the platform maximum of 60 minutes" : "0 means unlimited"}):`,
|
|
155
|
+
initialValue: String(current),
|
|
156
|
+
validate: (value) => /^\d+$/.test(value ?? "") && Number.isSafeInteger(Number(value)) ? void 0 : "Enter a nonnegative whole number."
|
|
157
|
+
}));
|
|
158
|
+
return { limits: parsePlanLimitsPatch({ [field]: Number(input) }) };
|
|
159
|
+
}
|
|
160
|
+
async function apply(client, path, body, args, catalog) {
|
|
161
|
+
if (!args.plan && !args.yes && (!process.stdin.isTTY || args.json)) throw new Error("platform: Configuration changes require --yes or --plan in non-interactive mode.");
|
|
162
|
+
const preview = await client.request(path, {
|
|
163
|
+
method: "POST",
|
|
164
|
+
body: {
|
|
165
|
+
...body,
|
|
166
|
+
dryRun: true
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
if (args.plan) {
|
|
170
|
+
if (args.json) print(preview);
|
|
171
|
+
else showPreview(preview, catalog, console.log);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (!Number.isSafeInteger(preview.expectedRevision)) throw new Error("platform: The platform returned an invalid plan revision.");
|
|
175
|
+
if (!args.yes) {
|
|
176
|
+
showPreview(preview, catalog);
|
|
177
|
+
if (!value(await confirm({
|
|
178
|
+
message: `Apply this change to ${client.origin}?`,
|
|
179
|
+
initialValue: false
|
|
180
|
+
}))) throw new Error("platform: Cancelled.");
|
|
181
|
+
}
|
|
182
|
+
let result = await client.request(path, {
|
|
183
|
+
method: "POST",
|
|
184
|
+
body: {
|
|
185
|
+
...body,
|
|
186
|
+
expectedRevision: preview.expectedRevision
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
const committedCatalog = result.catalog;
|
|
190
|
+
if (!Number.isSafeInteger(committedCatalog?.revision)) throw new Error("platform: The platform returned an invalid saved plan revision. Inspect the catalog before retrying.");
|
|
191
|
+
const committedRevision = committedCatalog.revision;
|
|
192
|
+
const applied = result;
|
|
193
|
+
let previousCursor = catalog.reconciliation?.cursor ?? null;
|
|
194
|
+
while (true) {
|
|
195
|
+
const reconciliation = result.reconciliation;
|
|
196
|
+
if (!reconciliation || reconciliation.complete !== false) break;
|
|
197
|
+
const currentCatalog = result.catalog;
|
|
198
|
+
const cursor = currentCatalog.reconciliation?.cursor ?? null;
|
|
199
|
+
if (reconciliation.error || !Number.isSafeInteger(reconciliation.processed) || reconciliation.processed <= 0 || cursor === previousCursor || currentCatalog.revision !== committedRevision) {
|
|
200
|
+
const pending = {
|
|
201
|
+
...applied,
|
|
202
|
+
...result
|
|
203
|
+
};
|
|
204
|
+
print(pending);
|
|
205
|
+
throw new OperatorClientError("Plan configuration was saved, but account updates are pending. Run void platform config plans sync --yes.", "plan_sync_pending", void 0, pending);
|
|
206
|
+
}
|
|
207
|
+
previousCursor = cursor;
|
|
208
|
+
result = await client.request("/config/plans/sync", {
|
|
209
|
+
method: "POST",
|
|
210
|
+
body: { expectedRevision: committedRevision }
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const completed = {
|
|
214
|
+
...applied,
|
|
215
|
+
...result
|
|
216
|
+
};
|
|
217
|
+
if (args.json) print(completed);
|
|
218
|
+
else console.log(`Saved ${applied.action ?? "plans.sync"} ${applied.target ?? ""}. Account updates complete.`);
|
|
219
|
+
}
|
|
220
|
+
async function runPlatformPlansConfig(args) {
|
|
221
|
+
const origin = resolveOperatorOrigin(args.connection);
|
|
222
|
+
const client = new OperatorClient(origin, readOperatorToken(origin));
|
|
223
|
+
const listing = await client.request("/config/plans");
|
|
224
|
+
const { catalog } = listing;
|
|
225
|
+
if (!args.action) {
|
|
226
|
+
if (!process.stdin.isTTY || args.json) {
|
|
227
|
+
showListing(listing, args.json);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const selected = value(await select({
|
|
231
|
+
message: "Platform plans:",
|
|
232
|
+
options: [
|
|
233
|
+
...catalog.plans.map((plan) => ({
|
|
234
|
+
value: plan.id,
|
|
235
|
+
label: `${label(plan)}${plan.id === catalog.defaultPlanId ? " — default" : ""}`,
|
|
236
|
+
hint: `${listing.accounts.find((entry) => entry.planId === plan.id)?.count ?? 0} accounts`
|
|
237
|
+
})),
|
|
238
|
+
{
|
|
239
|
+
value: ":add",
|
|
240
|
+
label: "Add a plan by copying an existing plan"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
value: ":default",
|
|
244
|
+
label: "Choose the default for new accounts"
|
|
245
|
+
},
|
|
246
|
+
...catalog.reconciliation && !catalog.reconciliation.complete ? [{
|
|
247
|
+
value: ":sync",
|
|
248
|
+
label: "Continue pending account updates"
|
|
249
|
+
}] : []
|
|
250
|
+
]
|
|
251
|
+
}));
|
|
252
|
+
if (selected === ":sync") return runPlatformPlansConfig({
|
|
253
|
+
...args,
|
|
254
|
+
action: "sync"
|
|
255
|
+
});
|
|
256
|
+
if (selected === ":default") {
|
|
257
|
+
const target = await choosePlan(catalog, "Default plan for new accounts:", { activeOnly: true });
|
|
258
|
+
return runPlatformPlansConfig({
|
|
259
|
+
...args,
|
|
260
|
+
action: "default",
|
|
261
|
+
target
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (selected === ":add") {
|
|
265
|
+
const target = parsePlatformPlanId(value(await text({ message: "New plan ID (stable; lowercase letters, digits, and hyphens):" })));
|
|
266
|
+
const copy = await choosePlan(catalog, "Copy limits and build size from:");
|
|
267
|
+
return runPlatformPlansConfig({
|
|
268
|
+
...args,
|
|
269
|
+
action: "add",
|
|
270
|
+
target,
|
|
271
|
+
copy
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
const plan = catalog.plans.find((entry) => entry.id === selected);
|
|
275
|
+
const action = value(await select({
|
|
276
|
+
message: label(plan),
|
|
277
|
+
options: [
|
|
278
|
+
{
|
|
279
|
+
value: "show",
|
|
280
|
+
label: "Show limits and account count"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
value: "set",
|
|
284
|
+
label: "Edit name or limits"
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
value: plan.archived ? "restore" : "archive",
|
|
288
|
+
label: plan.archived ? "Restore assignments to this plan" : "Archive for new assignments"
|
|
289
|
+
},
|
|
290
|
+
...Object.hasOwn(PLAN_LIMITS, plan.id) ? [{
|
|
291
|
+
value: "reset",
|
|
292
|
+
label: "Reset to original limits and build size"
|
|
293
|
+
}] : [],
|
|
294
|
+
{
|
|
295
|
+
value: "remove",
|
|
296
|
+
label: "Remove this plan"
|
|
297
|
+
}
|
|
298
|
+
]
|
|
299
|
+
}));
|
|
300
|
+
return runPlatformPlansConfig({
|
|
301
|
+
...args,
|
|
302
|
+
action,
|
|
303
|
+
target: selected
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
if (args.action === "show") {
|
|
307
|
+
if (!args.target) showListing(listing, args.json);
|
|
308
|
+
else {
|
|
309
|
+
const result = await client.request(`/config/plans/${encodeURIComponent(args.target)}`);
|
|
310
|
+
if (args.json) print(result);
|
|
311
|
+
else {
|
|
312
|
+
const plan = result.plan;
|
|
313
|
+
console.log(`${label(plan)}${result.default ? " — default for new accounts" : ""}`);
|
|
314
|
+
console.log(`Accounts: ${result.accounts}; build size: ${plan.buildInstanceType}`);
|
|
315
|
+
console.log(`Short project slugs: ${plan.allowShortSlugs ? "allowed" : "not allowed"}`);
|
|
316
|
+
for (const key of PLAN_EDITABLE_LIMIT_KEYS) console.log(`${limitLabels[key]}: ${limitValue(plan.limits[key], key)}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
let body = {};
|
|
322
|
+
let path = `/config/plans/${encodeURIComponent(args.target)}/${args.action}`;
|
|
323
|
+
const plan = catalog.plans.find((entry) => entry.id === args.target);
|
|
324
|
+
if (args.action === "add") {
|
|
325
|
+
let copy = args.copy;
|
|
326
|
+
if (!copy) {
|
|
327
|
+
if (!process.stdin.isTTY || args.json) throw new Error("platform: Adding a plan requires --copy <plan-id> in non-interactive mode.");
|
|
328
|
+
copy = await choosePlan(catalog, "Copy limits and build size from:");
|
|
329
|
+
}
|
|
330
|
+
body = {
|
|
331
|
+
id: args.target,
|
|
332
|
+
copyFrom: copy,
|
|
333
|
+
...await changesInput(args)
|
|
334
|
+
};
|
|
335
|
+
path = "/config/plans/add";
|
|
336
|
+
} else if (args.action === "default") {
|
|
337
|
+
body = { planId: args.target };
|
|
338
|
+
path = "/config/plans/default";
|
|
339
|
+
} else if (args.action === "sync") path = "/config/plans/sync";
|
|
340
|
+
else {
|
|
341
|
+
if (!plan) throw new Error("platform: Plan not found. Run void platform config plans show.");
|
|
342
|
+
if (args.action === "set") body = await changesInput(args, plan);
|
|
343
|
+
else if (args.action === "archive" || args.action === "restore") {
|
|
344
|
+
path = `/config/plans/${encodeURIComponent(args.target)}/archive`;
|
|
345
|
+
body = { archived: args.action === "archive" };
|
|
346
|
+
} else if (args.action === "remove") {
|
|
347
|
+
let replacement = args.replacement;
|
|
348
|
+
const needsReplacement = args.target === catalog.defaultPlanId || (listing.accounts.find((entry) => entry.planId === args.target)?.count ?? 0) > 0;
|
|
349
|
+
if (!replacement && needsReplacement && process.stdin.isTTY && !args.json) replacement = await choosePlan(catalog, "Move accounts and any default to:", {
|
|
350
|
+
activeOnly: true,
|
|
351
|
+
exclude: args.target
|
|
352
|
+
});
|
|
353
|
+
body = replacement ? { replacementPlanId: replacement } : {};
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
await apply(client, path, body, args, catalog);
|
|
357
|
+
}
|
|
358
|
+
//#endregion
|
|
359
|
+
export { runPlatformPlansConfig };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
|
|
2
2
|
import { a as listInstallationManifests, g as savePlatformConnection, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-
|
|
3
|
+
import { a as REMOTE_INSTALLATION_MANIFEST_KEY, y as createPlatformInstallPlan } from "./platform-lifecycle-9OyBALhH.mjs";
|
|
4
|
+
import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-CjwLVQwN.mjs";
|
|
5
5
|
import { parsePlatformInstallationManifest, setInstallationEndpoints } from "@void/platform";
|
|
6
6
|
//#region src/cli/platform-recovery.ts
|
|
7
7
|
async function recoverPlatformInstallations(client, accountId, verifyEndpoint = verifyInstallationEndpoint, selector = "") {
|