@geekmidas/cli 10.0.0-alpha.91 → 10.0.0-alpha.93
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/dist/{EndpointGenerator-CVc6Oi1Y.mjs → EndpointGenerator-Bor2tZCm.mjs} +14 -4
- package/dist/EndpointGenerator-Bor2tZCm.mjs.map +1 -0
- package/dist/{EndpointGenerator-CwLjBCFE.cjs → EndpointGenerator-De03t1hd.cjs} +14 -4
- package/dist/EndpointGenerator-De03t1hd.cjs.map +1 -0
- package/dist/{GoDaddyProvider-DqZ1qD_F.cjs → GoDaddyProvider-BZb-V14e.cjs} +11 -10
- package/dist/GoDaddyProvider-BZb-V14e.cjs.map +1 -0
- package/dist/{GoDaddyProvider-DSStJVAv.mjs → GoDaddyProvider-Mi3vptSR.mjs} +11 -10
- package/dist/GoDaddyProvider-Mi3vptSR.mjs.map +1 -0
- package/dist/{HostingerProvider-BI6J7oJr.mjs → HostingerProvider-1mqD6aG8.mjs} +2 -2
- package/dist/{HostingerProvider-BI6J7oJr.mjs.map → HostingerProvider-1mqD6aG8.mjs.map} +1 -1
- package/dist/{HostingerProvider-CyTpG_jy.cjs → HostingerProvider-C6t-PSNe.cjs} +2 -2
- package/dist/{HostingerProvider-CyTpG_jy.cjs.map → HostingerProvider-C6t-PSNe.cjs.map} +1 -1
- package/dist/{LegacyStateStore-DXmNA7hy.cjs → LegacyStateStore-BlYXQQSE.cjs} +44 -10
- package/dist/LegacyStateStore-BlYXQQSE.cjs.map +1 -0
- package/dist/LegacyStateStore-CtwO7fwy.mjs +123 -0
- package/dist/LegacyStateStore-CtwO7fwy.mjs.map +1 -0
- package/dist/{LocalStateStore-CU-O0SBp.mjs → LocalStateStore-D40_SDmJ.mjs} +2 -2
- package/dist/{LocalStateStore-CU-O0SBp.mjs.map → LocalStateStore-D40_SDmJ.mjs.map} +1 -1
- package/dist/{LocalStateStore-BBeTlRTH.cjs → LocalStateStore-oX_zxj9V.cjs} +2 -2
- package/dist/{LocalStateStore-BBeTlRTH.cjs.map → LocalStateStore-oX_zxj9V.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-B--HV-sW.cjs → OpenApiTsGenerator-CS_RtWOz.cjs} +2 -2
- package/dist/{OpenApiTsGenerator-B--HV-sW.cjs.map → OpenApiTsGenerator-CS_RtWOz.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-CkvsPdgg.mjs → OpenApiTsGenerator-DWAF-7Fu.mjs} +2 -2
- package/dist/{OpenApiTsGenerator-CkvsPdgg.mjs.map → OpenApiTsGenerator-DWAF-7Fu.mjs.map} +1 -1
- package/dist/{S3StateStore-bwxcI_wQ.mjs → S3StateStore-BzS0IeSt.mjs} +2 -2
- package/dist/{S3StateStore-bwxcI_wQ.mjs.map → S3StateStore-BzS0IeSt.mjs.map} +1 -1
- package/dist/{S3StateStore-Br8VMY22.cjs → S3StateStore-DeI7jtvi.cjs} +2 -2
- package/dist/{S3StateStore-Br8VMY22.cjs.map → S3StateStore-DeI7jtvi.cjs.map} +1 -1
- package/dist/{SSMStateStore-DoZE1Wi1.cjs → SSMStateStore-CaCtrzFL.cjs} +2 -2
- package/dist/{SSMStateStore-DoZE1Wi1.cjs.map → SSMStateStore-CaCtrzFL.cjs.map} +1 -1
- package/dist/{SSMStateStore-CsOS0W1y.mjs → SSMStateStore-k_Ew7TWx.mjs} +2 -2
- package/dist/{SSMStateStore-CsOS0W1y.mjs.map → SSMStateStore-k_Ew7TWx.mjs.map} +1 -1
- package/dist/{SubscriberGenerator-BPqQf8fB.mjs → SubscriberGenerator-CyN2VF5X.mjs} +6 -5
- package/dist/SubscriberGenerator-CyN2VF5X.mjs.map +1 -0
- package/dist/{SubscriberGenerator-BVn7cQ-2.cjs → SubscriberGenerator-Dvz7EzqK.cjs} +6 -5
- package/dist/SubscriberGenerator-Dvz7EzqK.cjs.map +1 -0
- package/dist/{add-BSHk5Ngn.mjs → add-CP1podDH.mjs} +7 -7
- package/dist/add-CP1podDH.mjs.map +1 -0
- package/dist/{add-DmmBDV2e.cjs → add-VcyJnsPX.cjs} +8 -8
- package/dist/add-VcyJnsPX.cjs.map +1 -0
- package/dist/{aws-BTawF0F-.cjs → aws-BTReGjpY.cjs} +24 -6
- package/dist/aws-BTReGjpY.cjs.map +1 -0
- package/dist/{aws-B-6uEhgP.mjs → aws-Dz2bYxK1.mjs} +24 -6
- package/dist/aws-Dz2bYxK1.mjs.map +1 -0
- package/dist/awsStore-B5We7bMg.cjs +136 -0
- package/dist/awsStore-B5We7bMg.cjs.map +1 -0
- package/dist/awsStore-BWa1KNY-.mjs +119 -0
- package/dist/awsStore-BWa1KNY-.mjs.map +1 -0
- package/dist/{bundler-D6eBfVkl.mjs → bundler-BWrh-AJH.mjs} +5 -5
- package/dist/{bundler-D6eBfVkl.mjs.map → bundler-BWrh-AJH.mjs.map} +1 -1
- package/dist/{bundler-BQJiB7Ub.cjs → bundler-Dfsr6KXU.cjs} +5 -5
- package/dist/{bundler-BQJiB7Ub.cjs.map → bundler-Dfsr6KXU.cjs.map} +1 -1
- package/dist/{cli-DD-Yk-I5.mjs → cli-B8otnZfX.mjs} +6 -6
- package/dist/{cli-DD-Yk-I5.mjs.map → cli-B8otnZfX.mjs.map} +1 -1
- package/dist/{cli-BE9mqeX8.cjs → cli-DL19w4OE.cjs} +5 -5
- package/dist/{cli-BE9mqeX8.cjs.map → cli-DL19w4OE.cjs.map} +1 -1
- package/dist/compose-BHVKLluX.cjs +1523 -0
- package/dist/compose-BHVKLluX.cjs.map +1 -0
- package/dist/compose-DrEB_4F-.mjs +1476 -0
- package/dist/compose-DrEB_4F-.mjs.map +1 -0
- package/dist/{config-pST7E0CS.d.cts → config-CHX5GOo3.d.mts} +8 -8
- package/dist/{config-CdEcTrjG.d.mts.map → config-CHX5GOo3.d.mts.map} +1 -1
- package/dist/{config-CdEcTrjG.d.mts → config-DCCcrOSo.d.cts} +8 -8
- package/dist/{config-pST7E0CS.d.cts.map → config-DCCcrOSo.d.cts.map} +1 -1
- package/dist/config.cjs +8 -7
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +8 -7
- package/dist/config.mjs.map +1 -1
- package/dist/{credentialSchemas-BJqRJNK4.mjs → credentialSchemas-BJFvfkaz.mjs} +5 -4
- package/dist/credentialSchemas-BJFvfkaz.mjs.map +1 -0
- package/dist/{credentialSchemas-DCR4Wd1W.cjs → credentialSchemas-CAPKFkrG.cjs} +5 -4
- package/dist/credentialSchemas-CAPKFkrG.cjs.map +1 -0
- package/dist/{credentials-CnVqoXMb.mjs → credentials-C4KII3PD.mjs} +3 -2
- package/dist/{credentials-CnVqoXMb.mjs.map → credentials-C4KII3PD.mjs.map} +1 -1
- package/dist/{credentials-BKfIugu2.cjs → credentials-QBu7VgaQ.cjs} +3 -2
- package/dist/credentials-QBu7VgaQ.cjs.map +1 -0
- package/dist/{databases-CzszQV0N.mjs → databases-BeGP5eDh.mjs} +11 -10
- package/dist/databases-BeGP5eDh.mjs.map +1 -0
- package/dist/{databases-BY-pEImp.cjs → databases-DGALFDG3.cjs} +11 -10
- package/dist/databases-DGALFDG3.cjs.map +1 -0
- package/dist/{define-DR8xGYfL.mjs → define-6poNqm5O.mjs} +12 -3
- package/dist/define-6poNqm5O.mjs.map +1 -0
- package/dist/{define-DzRz8FgH.cjs → define-crmMcXFS.cjs} +12 -3
- package/dist/define-crmMcXFS.cjs.map +1 -0
- package/dist/deploy/public.cjs +18 -16
- package/dist/deploy/public.cjs.map +1 -1
- package/dist/deploy/public.d.cts +31 -31
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +31 -31
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +18 -17
- package/dist/deploy/public.mjs.map +1 -1
- package/dist/{deploy-CuHasEA4.cjs → deploy-C3Mhnmus.cjs} +15 -13
- package/dist/deploy-C3Mhnmus.cjs.map +1 -0
- package/dist/{deploy-QNtx_eWR.mjs → deploy-DYIyIUYd.mjs} +15 -13
- package/dist/deploy-DYIyIUYd.mjs.map +1 -0
- package/dist/{discover-D1It5r_h.cjs → discover-DPgu-ScS.cjs} +4 -3
- package/dist/discover-DPgu-ScS.cjs.map +1 -0
- package/dist/{discover-CU0paUyH.d.cts → discover-DqwlBVyY.d.mts} +2 -2
- package/dist/{discover-CU0paUyH.d.cts.map → discover-DqwlBVyY.d.mts.map} +1 -1
- package/dist/{discover-BPelzeGW.mjs → discover-qjFapetL.mjs} +4 -3
- package/dist/discover-qjFapetL.mjs.map +1 -0
- package/dist/{discover-DFiJxwfv.d.mts → discover-vk2r5giK.d.cts} +2 -2
- package/dist/{discover-DFiJxwfv.d.mts.map → discover-vk2r5giK.d.cts.map} +1 -1
- package/dist/{dokploy-CYcMLh9-.mjs → dokploy-o4I6vb9W.mjs} +3 -3
- package/dist/{dokploy-CYcMLh9-.mjs.map → dokploy-o4I6vb9W.mjs.map} +1 -1
- package/dist/{dokploy-DIowwyIB.cjs → dokploy-rivb1RFt.cjs} +3 -3
- package/dist/{dokploy-DIowwyIB.cjs.map → dokploy-rivb1RFt.cjs.map} +1 -1
- package/dist/{drivers-DTZzxeIl.mjs → drivers-CTaWrA_L.mjs} +2 -2
- package/dist/{drivers-DTZzxeIl.mjs.map → drivers-CTaWrA_L.mjs.map} +1 -1
- package/dist/{drivers-LYSdQDmd.cjs → drivers-DDojgzz0.cjs} +2 -2
- package/dist/{drivers-LYSdQDmd.cjs.map → drivers-DDojgzz0.cjs.map} +1 -1
- package/dist/{encryption-BrEef7Jk.mjs → encryption-B6ilrT7p.mjs} +7 -6
- package/dist/encryption-B6ilrT7p.mjs.map +1 -0
- package/dist/{encryption-CjYdUb2s.cjs → encryption-D7zmwzWz.cjs} +7 -6
- package/dist/encryption-D7zmwzWz.cjs.map +1 -0
- package/dist/{engine-BhJ7ZP9K.cjs → engine-Cfx8fEZU.cjs} +40 -28
- package/dist/engine-Cfx8fEZU.cjs.map +1 -0
- package/dist/{engine-2h4k5ICq.mjs → engine-DjEcovm-.mjs} +40 -28
- package/dist/engine-DjEcovm-.mjs.map +1 -0
- package/dist/errors-D8Gwp5kU.mjs +23 -0
- package/dist/errors-D8Gwp5kU.mjs.map +1 -0
- package/dist/errors-DMC4Umsb.cjs +34 -0
- package/dist/errors-DMC4Umsb.cjs.map +1 -0
- package/dist/{github-BCDF6xVH.mjs → github-CzBbs43W.mjs} +31 -9
- package/dist/github-CzBbs43W.mjs.map +1 -0
- package/dist/{github-B5Bw4HIu.cjs → github-zneTMvnO.cjs} +31 -9
- package/dist/github-zneTMvnO.cjs.map +1 -0
- package/dist/{index-YFNxR5Ns.d.mts → index-BiYU7cUl.d.mts} +6 -6
- package/dist/{index-D-F_hTDz.d.cts.map → index-BiYU7cUl.d.mts.map} +1 -1
- package/dist/{index-D-F_hTDz.d.cts → index-Dm6V9bwh.d.cts} +6 -6
- package/dist/{index-YFNxR5Ns.d.mts.map → index-Dm6V9bwh.d.cts.map} +1 -1
- package/dist/index.cjs +256 -346
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +252 -341
- package/dist/index.mjs.map +1 -1
- package/dist/{local-BjxDfPvy.cjs → local-B61kUh0w.cjs} +3 -3
- package/dist/{local-BjxDfPvy.cjs.map → local-B61kUh0w.cjs.map} +1 -1
- package/dist/{local-IuoIF3CT.mjs → local-Otp74ak0.mjs} +3 -3
- package/dist/{local-IuoIF3CT.mjs.map → local-Otp74ak0.mjs.map} +1 -1
- package/dist/{migrate-DWZz9kah.mjs → migrate-BaC4w0sb.mjs} +8 -7
- package/dist/migrate-BaC4w0sb.mjs.map +1 -0
- package/dist/{migrate-q2YYLJLE.cjs → migrate-C8wTpakT.cjs} +8 -7
- package/dist/migrate-C8wTpakT.cjs.map +1 -0
- package/dist/{migrate-DbtcuOr_.mjs → migrate-CsBZKALY.mjs} +9 -8
- package/dist/migrate-CsBZKALY.mjs.map +1 -0
- package/dist/{migrate-CGaancHY.cjs → migrate-DFjbGnSr.cjs} +8 -7
- package/dist/migrate-DFjbGnSr.cjs.map +1 -0
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.d.cts +1 -10
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -10
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +3 -3
- package/dist/{provider-C9_-45d5.cjs → provider-BqpjG9QM.cjs} +4 -3
- package/dist/provider-BqpjG9QM.cjs.map +1 -0
- package/dist/{provider-q4lsYzYG.mjs → provider-CEOKk8NS.mjs} +4 -3
- package/dist/provider-CEOKk8NS.mjs.map +1 -0
- package/dist/{ready-BpNbORRB.cjs → ready-D3PIjx3S.cjs} +9 -8
- package/dist/ready-D3PIjx3S.cjs.map +1 -0
- package/dist/{ready-b6vm0-W-.mjs → ready-naOSJpeJ.mjs} +9 -8
- package/dist/ready-naOSJpeJ.mjs.map +1 -0
- package/dist/reconcile/public.cjs +1 -1
- package/dist/reconcile/public.d.cts +2 -2
- package/dist/reconcile/public.d.mts +2 -2
- package/dist/reconcile/public.mjs +1 -1
- package/dist/{reconcile-Dh1Jk7WE.mjs → reconcile--I7V4Klj.mjs} +2 -2
- package/dist/{reconcile-Dh1Jk7WE.mjs.map → reconcile--I7V4Klj.mjs.map} +1 -1
- package/dist/{resolve-DNg0icnh.mjs → resolve-Ccjlpnd9.mjs} +12 -11
- package/dist/resolve-Ccjlpnd9.mjs.map +1 -0
- package/dist/{resolve-Cns0v6dN.cjs → resolve-g8htuR80.cjs} +12 -11
- package/dist/resolve-g8htuR80.cjs.map +1 -0
- package/dist/{rollback-UIjS25F1.cjs → rollback--ympG9ss.cjs} +13 -11
- package/dist/rollback--ympG9ss.cjs.map +1 -0
- package/dist/{rollback-CFrNLmxs.mjs → rollback-Drbg0OeR.mjs} +13 -11
- package/dist/rollback-Drbg0OeR.mjs.map +1 -0
- package/dist/{runtime-CN_kmqxo.d.cts → runtime-D_J3ExJn.d.cts} +11 -19
- package/dist/runtime-D_J3ExJn.d.cts.map +1 -0
- package/dist/{runtime-Cjvon3oj.d.mts → runtime-_wEVtshH.d.mts} +11 -19
- package/dist/runtime-_wEVtshH.d.mts.map +1 -0
- package/dist/sandbox/credentials-worker.cjs +3 -3
- package/dist/sandbox/credentials-worker.mjs +3 -3
- package/dist/sandbox/discover-worker.cjs +1 -1
- package/dist/sandbox/discover-worker.mjs +1 -1
- package/dist/sandbox/migrate-worker.cjs +3 -3
- package/dist/sandbox/migrate-worker.mjs +3 -3
- package/dist/{sandbox-CL--ZDui.cjs → sandbox-CHv3OYXg.cjs} +4 -3
- package/dist/sandbox-CHv3OYXg.cjs.map +1 -0
- package/dist/{sandbox-M8UnLhXE.d.cts → sandbox-CPJq1Kia.d.mts} +4 -26
- package/dist/sandbox-CPJq1Kia.d.mts.map +1 -0
- package/dist/{sandbox-Dm247NGx.mjs → sandbox-CbVB7uOD.mjs} +4 -3
- package/dist/sandbox-CbVB7uOD.mjs.map +1 -0
- package/dist/{sandbox-M8UnLhXE.d.mts → sandbox-JwuPAl7I.d.cts} +4 -26
- package/dist/sandbox-JwuPAl7I.d.cts.map +1 -0
- package/dist/secrets-DJteijZo.cjs +47 -0
- package/dist/secrets-DJteijZo.cjs.map +1 -0
- package/dist/secrets-DbPmAS4k.mjs +36 -0
- package/dist/secrets-DbPmAS4k.mjs.map +1 -0
- package/dist/{secretsManager-Chs9VV2r.mjs → secretsManager-C6wm-9uZ.mjs} +24 -3
- package/dist/secretsManager-C6wm-9uZ.mjs.map +1 -0
- package/dist/{secretsManager-DcMlHnRC.cjs → secretsManager-Cwwgs81g.cjs} +24 -3
- package/dist/secretsManager-Cwwgs81g.cjs.map +1 -0
- package/dist/{seeds-odfgSCmu.mjs → seeds-BSL55F6q.mjs} +946 -107
- package/dist/seeds-BSL55F6q.mjs.map +1 -0
- package/dist/{seeds-CkIPFGNO.cjs → seeds-c-ByX9je.cjs} +1065 -130
- package/dist/seeds-c-ByX9je.cjs.map +1 -0
- package/dist/{sniffer-BTtX3NUM.mjs → sniffer-BTtGAtm3.mjs} +14 -8
- package/dist/sniffer-BTtGAtm3.mjs.map +1 -0
- package/dist/{sniffer-IAQEpsQb.cjs → sniffer-Dq5BS98f.cjs} +14 -8
- package/dist/{sniffer-IAQEpsQb.cjs.map → sniffer-Dq5BS98f.cjs.map} +1 -1
- package/dist/{sst-CJzvyrEz.mjs → sst-BaRXp2Dd.mjs} +18 -8
- package/dist/sst-BaRXp2Dd.mjs.map +1 -0
- package/dist/{sst-BgcOsaBi.cjs → sst-CnKY-CSh.cjs} +18 -8
- package/dist/sst-CnKY-CSh.cjs.map +1 -0
- package/dist/stack-1PeLJS2j.cjs +1346 -0
- package/dist/stack-1PeLJS2j.cjs.map +1 -0
- package/dist/stack-Co4uZkAo.mjs +1239 -0
- package/dist/stack-Co4uZkAo.mjs.map +1 -0
- package/dist/{stages-CUn6gvXL.cjs → stages-BI8JvPzI.cjs} +6 -5
- package/dist/stages-BI8JvPzI.cjs.map +1 -0
- package/dist/{stages-CnZRYmkI.mjs → stages-DY-fQKmo.mjs} +6 -5
- package/dist/stages-DY-fQKmo.mjs.map +1 -0
- package/dist/target/public.cjs +3 -3
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +3 -3
- package/dist/{terminal-DuapRxh6.cjs → terminal-8XngdSTo.cjs} +6 -5
- package/dist/terminal-8XngdSTo.cjs.map +1 -0
- package/dist/{terminal-D8TPK7o9.mjs → terminal-C4XRdwnU.mjs} +7 -6
- package/dist/terminal-C4XRdwnU.mjs.map +1 -0
- package/dist/{types-NqX1Hz4P.d.cts → types-B6lmD3en.d.mts} +94 -47
- package/dist/types-B6lmD3en.d.mts.map +1 -0
- package/dist/{types-ZHuZ89hv.d.mts → types-BibpiHKB.d.cts} +95 -46
- package/dist/types-BibpiHKB.d.cts.map +1 -0
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-CJ0lKFq-.mjs → workspace-Bzw7Zs82.mjs} +34 -33
- package/dist/workspace-Bzw7Zs82.mjs.map +1 -0
- package/dist/{workspace-CwW3Gkru.cjs → workspace-CHOB2Xg3.cjs} +34 -33
- package/dist/workspace-CHOB2Xg3.cjs.map +1 -0
- package/package.json +15 -15
- package/dist/EndpointGenerator-CVc6Oi1Y.mjs.map +0 -1
- package/dist/EndpointGenerator-CwLjBCFE.cjs.map +0 -1
- package/dist/GoDaddyProvider-DSStJVAv.mjs.map +0 -1
- package/dist/GoDaddyProvider-DqZ1qD_F.cjs.map +0 -1
- package/dist/LegacyStateStore-DXmNA7hy.cjs.map +0 -1
- package/dist/LegacyStateStore-ZkdmiUFZ.mjs +0 -89
- package/dist/LegacyStateStore-ZkdmiUFZ.mjs.map +0 -1
- package/dist/SubscriberGenerator-BPqQf8fB.mjs.map +0 -1
- package/dist/SubscriberGenerator-BVn7cQ-2.cjs.map +0 -1
- package/dist/add-BSHk5Ngn.mjs.map +0 -1
- package/dist/add-DmmBDV2e.cjs.map +0 -1
- package/dist/aws-B-6uEhgP.mjs.map +0 -1
- package/dist/aws-BTawF0F-.cjs.map +0 -1
- package/dist/awsStore-7VmS_cZR.cjs +0 -54
- package/dist/awsStore-7VmS_cZR.cjs.map +0 -1
- package/dist/awsStore-B529csle.mjs +0 -43
- package/dist/awsStore-B529csle.mjs.map +0 -1
- package/dist/compose-Bhmf0n4o.mjs +0 -3140
- package/dist/compose-Bhmf0n4o.mjs.map +0 -1
- package/dist/compose-CvpU6ooi.cjs +0 -3265
- package/dist/compose-CvpU6ooi.cjs.map +0 -1
- package/dist/credentialSchemas-BJqRJNK4.mjs.map +0 -1
- package/dist/credentialSchemas-DCR4Wd1W.cjs.map +0 -1
- package/dist/credentials-BKfIugu2.cjs.map +0 -1
- package/dist/databases-BY-pEImp.cjs.map +0 -1
- package/dist/databases-CzszQV0N.mjs.map +0 -1
- package/dist/define-DR8xGYfL.mjs.map +0 -1
- package/dist/define-DzRz8FgH.cjs.map +0 -1
- package/dist/deploy-CuHasEA4.cjs.map +0 -1
- package/dist/deploy-QNtx_eWR.mjs.map +0 -1
- package/dist/discover-BPelzeGW.mjs.map +0 -1
- package/dist/discover-D1It5r_h.cjs.map +0 -1
- package/dist/encryption-BrEef7Jk.mjs.map +0 -1
- package/dist/encryption-CjYdUb2s.cjs.map +0 -1
- package/dist/engine-2h4k5ICq.mjs.map +0 -1
- package/dist/engine-BhJ7ZP9K.cjs.map +0 -1
- package/dist/github-B5Bw4HIu.cjs.map +0 -1
- package/dist/github-BCDF6xVH.mjs.map +0 -1
- package/dist/migrate-CGaancHY.cjs.map +0 -1
- package/dist/migrate-DWZz9kah.mjs.map +0 -1
- package/dist/migrate-DbtcuOr_.mjs.map +0 -1
- package/dist/migrate-q2YYLJLE.cjs.map +0 -1
- package/dist/provider-C9_-45d5.cjs.map +0 -1
- package/dist/provider-q4lsYzYG.mjs.map +0 -1
- package/dist/ready-BpNbORRB.cjs.map +0 -1
- package/dist/ready-b6vm0-W-.mjs.map +0 -1
- package/dist/resolve-Cns0v6dN.cjs.map +0 -1
- package/dist/resolve-DNg0icnh.mjs.map +0 -1
- package/dist/rollback-CFrNLmxs.mjs.map +0 -1
- package/dist/rollback-UIjS25F1.cjs.map +0 -1
- package/dist/runtime-CN_kmqxo.d.cts.map +0 -1
- package/dist/runtime-Cjvon3oj.d.mts.map +0 -1
- package/dist/sandbox-CL--ZDui.cjs.map +0 -1
- package/dist/sandbox-Dm247NGx.mjs.map +0 -1
- package/dist/sandbox-M8UnLhXE.d.cts.map +0 -1
- package/dist/sandbox-M8UnLhXE.d.mts.map +0 -1
- package/dist/secretsManager-Chs9VV2r.mjs.map +0 -1
- package/dist/secretsManager-DcMlHnRC.cjs.map +0 -1
- package/dist/seeds-CkIPFGNO.cjs.map +0 -1
- package/dist/seeds-odfgSCmu.mjs.map +0 -1
- package/dist/sniffer-BTtX3NUM.mjs.map +0 -1
- package/dist/sst-BgcOsaBi.cjs.map +0 -1
- package/dist/sst-CJzvyrEz.mjs.map +0 -1
- package/dist/stages-CUn6gvXL.cjs.map +0 -1
- package/dist/stages-CnZRYmkI.mjs.map +0 -1
- package/dist/terminal-D8TPK7o9.mjs.map +0 -1
- package/dist/terminal-DuapRxh6.cjs.map +0 -1
- package/dist/types-NqX1Hz4P.d.cts.map +0 -1
- package/dist/types-ZHuZ89hv.d.mts.map +0 -1
- package/dist/workspace-CJ0lKFq-.mjs.map +0 -1
- package/dist/workspace-CwW3Gkru.cjs.map +0 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
|
|
3
|
+
import { r as storedCredentials, s as run$1, t as MissingCredential, x as gkmHome } from "./credentials-C4KII3PD.mjs";
|
|
4
|
+
import { d as output, r as discover, u as ConstructGenerator } from "./discover-qjFapetL.mjs";
|
|
4
5
|
import { t as appKey } from "./derive-B4vDpzgP.mjs";
|
|
5
|
-
import { $ as RotationInProgress, B as LOGS_PORT, G as checkS3Config, H as provisioningOf, J as BucketNameUnavailable, K as AccessKeyLimit, Q as RecordedBucketUnreachable, R as stageSampleRate, U as stageProvider, W as S3_PROVISIONING, X as IamUserNotOwned, Y as BucketOwnedByAnotherProject, Z as ProvisionedBucketUnreachable, _ as PUBLIC_ENV_PREFIXES, a as allConstructGlobs, at as SERVER_IPV6_KEY, et as S3RegionRequired, it as SERVER_IPV4_KEY, j as TEST_STAGE, lt as UnknownSecretsStoreProvider, q as BucketKeySetElsewhere, st as isReservedStageKey, v as getPublicEnvPrefix, z as telemetryEnv } from "./workspace-
|
|
6
|
+
import { $ as RotationInProgress, B as LOGS_PORT, G as checkS3Config, H as provisioningOf, J as BucketNameUnavailable, K as AccessKeyLimit, Q as RecordedBucketUnreachable, R as stageSampleRate, U as stageProvider, W as S3_PROVISIONING, X as IamUserNotOwned, Y as BucketOwnedByAnotherProject, Z as ProvisionedBucketUnreachable, _ as PUBLIC_ENV_PREFIXES, a as allConstructGlobs, at as SERVER_IPV6_KEY, et as S3RegionRequired, it as SERVER_IPV4_KEY, j as TEST_STAGE, lt as UnknownSecretsStoreProvider, ot as cnameTarget, q as BucketKeySetElsewhere, st as isReservedStageKey, v as getPublicEnvPrefix, z as telemetryEnv } from "./workspace-Bzw7Zs82.mjs";
|
|
6
7
|
import { ConfigNotFound, NotInAnApp, loadWorkspaceAppInfo, loadWorkspaceConfig } from "./config.mjs";
|
|
7
|
-
import { a as telemetryArgs, c as startTelemetryCode, n as runtimeFor, u as writeTelemetryModule } from "./EndpointGenerator-
|
|
8
|
-
import { a as DEFAULT_STORAGE, i as DEFAULT_EVENTS$1, n as readFakes, o as holdsEveryCache, r as DEFAULT_CACHE, t as SubscriberGenerator } from "./SubscriberGenerator-
|
|
9
|
-
import { c as runtimeOf } from "./resolve-
|
|
8
|
+
import { a as telemetryArgs, c as startTelemetryCode, n as runtimeFor, u as writeTelemetryModule } from "./EndpointGenerator-Bor2tZCm.mjs";
|
|
9
|
+
import { a as DEFAULT_STORAGE, i as DEFAULT_EVENTS$1, n as readFakes, o as holdsEveryCache, r as DEFAULT_CACHE, t as SubscriberGenerator } from "./SubscriberGenerator-CyN2VF5X.mjs";
|
|
10
|
+
import { c as runtimeOf } from "./resolve-Ccjlpnd9.mjs";
|
|
10
11
|
import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
|
|
11
12
|
import { constants, existsSync, readFileSync } from "node:fs";
|
|
12
13
|
import { appendFile, chmod, copyFile, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -15,7 +16,7 @@ import { promisify } from "node:util";
|
|
|
15
16
|
import { Cron } from "@geekmidas/constructs/crons";
|
|
16
17
|
import { Queue } from "@geekmidas/constructs/queue";
|
|
17
18
|
import { CLIENT_IP_HEADER, DEFAULT_POSTGRES_VERSION, TELEMETRY_KEYS, cacheTable, cookieDomain, dependenciesOf, dependentsOf, externalApiUrl, kebabCase, mobileOrigins, provideKey, providedKeyFor, provisionOrder, publicEnvFor, schemeBase, scopedName } from "@geekmidas/manifest";
|
|
18
|
-
import { createServer } from "node:net";
|
|
19
|
+
import { createServer, isIPv4, isIPv6 } from "node:net";
|
|
19
20
|
import { execFile, spawn } from "node:child_process";
|
|
20
21
|
import { createCipheriv, createDecipheriv, createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
|
|
21
22
|
import { config } from "dotenv";
|
|
@@ -63,7 +64,7 @@ function rootSite(sites) {
|
|
|
63
64
|
throw new AmbiguousRootSite(sites.map(({ name }) => name), declared.length > 1);
|
|
64
65
|
}
|
|
65
66
|
/** Several sites could hold the base domain, and none of them says it does. */
|
|
66
|
-
var AmbiguousRootSite = class extends
|
|
67
|
+
var AmbiguousRootSite = class extends GkmError {
|
|
67
68
|
sites;
|
|
68
69
|
tooMany;
|
|
69
70
|
constructor(sites, tooMany = false) {
|
|
@@ -76,7 +77,7 @@ var AmbiguousRootSite = class extends Error {
|
|
|
76
77
|
//#endregion
|
|
77
78
|
//#region src/target/dokploy/domain.ts
|
|
78
79
|
/** A stage was deployed that `domains` gives no domain. */
|
|
79
|
-
var NoDomainForStage = class extends
|
|
80
|
+
var NoDomainForStage = class extends GkmError {
|
|
80
81
|
stage;
|
|
81
82
|
constructor(stage) {
|
|
82
83
|
super(`No domain for stage "${stage}". Add it to gkm.config.ts: domains: { ${stage}: 'example.com' }.`);
|
|
@@ -167,7 +168,7 @@ const LOGS_PASSWORD_KEY = "ZO_ROOT_USER_PASSWORD";
|
|
|
167
168
|
*/
|
|
168
169
|
const LOCAL_LOGS_EMAIL = "admin@gkm.localhost";
|
|
169
170
|
/** A root password OpenObserve would refuse to start with. */
|
|
170
|
-
var LogsPasswordWeak = class extends
|
|
171
|
+
var LogsPasswordWeak = class extends GkmError {
|
|
171
172
|
stage;
|
|
172
173
|
constructor(stage) {
|
|
173
174
|
super(`The stage '${stage}' sets ${LOGS_PASSWORD_KEY}, and OpenObserve refuses it: a root password must be 8 to 128 characters with a lowercase letter, an uppercase letter, a digit and a symbol. Set another with gkm secrets:set ${LOGS_PASSWORD_KEY} '…' --stage ${stage}, or unset it to have one generated.`);
|
|
@@ -176,7 +177,7 @@ var LogsPasswordWeak = class extends Error {
|
|
|
176
177
|
}
|
|
177
178
|
};
|
|
178
179
|
/** A deployed stage with logs on and no root password generated yet. */
|
|
179
|
-
var LogsPasswordMissing = class extends
|
|
180
|
+
var LogsPasswordMissing = class extends GkmError {
|
|
180
181
|
stage;
|
|
181
182
|
constructor(stage) {
|
|
182
183
|
super(`The stage '${stage}' runs OpenObserve and has no ${LOGS_PASSWORD_KEY} in its secrets. Run gkm compose --stage ${stage} without --dry-run once to generate it, or set one: gkm secrets:set ${LOGS_PASSWORD_KEY} '…' --stage ${stage}`);
|
|
@@ -433,7 +434,7 @@ function validateEnvironmentVariables(requiredVars, secrets) {
|
|
|
433
434
|
* `DeployIdentity` is what a deploy names and claims its resources by instead.
|
|
434
435
|
*/
|
|
435
436
|
/** A namespace that cannot be part of a Dokploy name or an image path. */
|
|
436
|
-
var DeployNamespaceInvalid = class extends
|
|
437
|
+
var DeployNamespaceInvalid = class extends GkmError {
|
|
437
438
|
namespace;
|
|
438
439
|
constructor(namespace) {
|
|
439
440
|
super(`deploy.namespace '${namespace}' is not usable as a name: use lowercase letters, digits and single '-' between them (e.g. 'acme' or 'acme-platform') in gkm.config.ts.`);
|
|
@@ -442,7 +443,7 @@ var DeployNamespaceInvalid = class extends Error {
|
|
|
442
443
|
}
|
|
443
444
|
};
|
|
444
445
|
/** A workspace name with nothing a target can name a resource by. */
|
|
445
|
-
var DeployProjectNameInvalid = class extends
|
|
446
|
+
var DeployProjectNameInvalid = class extends GkmError {
|
|
446
447
|
workspaceName;
|
|
447
448
|
constructor(workspaceName) {
|
|
448
449
|
super(`The workspace name '${workspaceName}' has no letters or digits to name deployed resources by. Set "name" in gkm.config.ts.`);
|
|
@@ -548,7 +549,7 @@ function applicationName(identity, app) {
|
|
|
548
549
|
/** Key length for AES-256 encryption */
|
|
549
550
|
const KEY_LENGTH = 32;
|
|
550
551
|
/** A keystore project key that is not `<namespace>/<project>`. */
|
|
551
|
-
var KeystoreProjectInvalid = class extends
|
|
552
|
+
var KeystoreProjectInvalid = class extends GkmError {
|
|
552
553
|
key;
|
|
553
554
|
constructor(key) {
|
|
554
555
|
super(`'${key}' is not a keystore project: expected '<namespace>/<project>' in lowercase letters, digits and '-', as deployIdentity() produces. Pass the workspace's identity key.`);
|
|
@@ -557,7 +558,7 @@ var KeystoreProjectInvalid = class extends Error {
|
|
|
557
558
|
}
|
|
558
559
|
};
|
|
559
560
|
/** A stage has no key, here or at the place keys used to be kept. */
|
|
560
|
-
var KeyNotFound = class extends
|
|
561
|
+
var KeyNotFound = class extends GkmError {
|
|
561
562
|
stage;
|
|
562
563
|
project;
|
|
563
564
|
path;
|
|
@@ -754,7 +755,7 @@ var FileSecretsStore = class {
|
|
|
754
755
|
}
|
|
755
756
|
};
|
|
756
757
|
/** A stage's secrets file exists, and the key that opens it does not. */
|
|
757
|
-
var MissingSecretsKey = class extends
|
|
758
|
+
var MissingSecretsKey = class extends GkmError {
|
|
758
759
|
stage;
|
|
759
760
|
project;
|
|
760
761
|
path;
|
|
@@ -829,7 +830,7 @@ async function storeFromConfig(workspace, config, options = {}) {
|
|
|
829
830
|
const profile = options.profile ? { profile: options.profile } : {};
|
|
830
831
|
switch (config.provider) {
|
|
831
832
|
case "ssm": {
|
|
832
|
-
const { AwsSecretsStore } = await import("./aws-
|
|
833
|
+
const { AwsSecretsStore } = await import("./aws-Dz2bYxK1.mjs").then((n) => n.t);
|
|
833
834
|
return new AwsSecretsStore({
|
|
834
835
|
project: workspace.name,
|
|
835
836
|
region: config.region,
|
|
@@ -838,7 +839,7 @@ async function storeFromConfig(workspace, config, options = {}) {
|
|
|
838
839
|
}
|
|
839
840
|
case "secrets-manager": {
|
|
840
841
|
const { kmsKeyId } = config;
|
|
841
|
-
const { SecretsManagerSecretsStore } = await import("./secretsManager-
|
|
842
|
+
const { SecretsManagerSecretsStore } = await import("./secretsManager-C6wm-9uZ.mjs").then((n) => n.n);
|
|
842
843
|
return new SecretsManagerSecretsStore({
|
|
843
844
|
project: workspace.name,
|
|
844
845
|
region: config.region,
|
|
@@ -1842,7 +1843,7 @@ function planFor(manifest, stage, order, options = {}) {
|
|
|
1842
1843
|
* code either way — declare a database, or select a backend that brings its own
|
|
1843
1844
|
* broker.
|
|
1844
1845
|
*/
|
|
1845
|
-
var CacheNeedsDatabase = class extends
|
|
1846
|
+
var CacheNeedsDatabase = class extends GkmError {
|
|
1846
1847
|
ids;
|
|
1847
1848
|
constructor(ids) {
|
|
1848
1849
|
super(`A cache backed by the database needs a declared database, and none was declared, and on this deploy target that is where a cache lives. Declare one. Caches affected: ${ids.join(", ")}.`);
|
|
@@ -1861,7 +1862,7 @@ var CacheNeedsDatabase = class extends Error {
|
|
|
1861
1862
|
* `orders.cache('Sessions')` names the database, which is a fact about the
|
|
1862
1863
|
* application rather than a deployment choice.
|
|
1863
1864
|
*/
|
|
1864
|
-
var CacheIsAmbiguous = class extends
|
|
1865
|
+
var CacheIsAmbiguous = class extends GkmError {
|
|
1865
1866
|
ids;
|
|
1866
1867
|
databases;
|
|
1867
1868
|
constructor(ids, databases) {
|
|
@@ -1871,7 +1872,7 @@ var CacheIsAmbiguous = class extends Error {
|
|
|
1871
1872
|
this.name = "CacheIsAmbiguous";
|
|
1872
1873
|
}
|
|
1873
1874
|
};
|
|
1874
|
-
var PgBossNeedsDatabase = class extends
|
|
1875
|
+
var PgBossNeedsDatabase = class extends GkmError {
|
|
1875
1876
|
ids;
|
|
1876
1877
|
constructor(ids) {
|
|
1877
1878
|
super(`pg-boss keeps its queues in a declared database, and none was declared. Declare one: on this deploy target, events are carried by pg-boss. Queues and topics affected: ${ids.join(", ")}.`);
|
|
@@ -3127,7 +3128,7 @@ CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile
|
|
|
3127
3128
|
* prune` to one app's slice. Nothing is built on the host.
|
|
3128
3129
|
*/
|
|
3129
3130
|
/** A workspace of packages with no turbo.json, which every image prunes with. */
|
|
3130
|
-
var MonorepoNeedsTurbo = class extends
|
|
3131
|
+
var MonorepoNeedsTurbo = class extends GkmError {
|
|
3131
3132
|
buildRoot;
|
|
3132
3133
|
constructor(buildRoot) {
|
|
3133
3134
|
super(`${buildRoot} is a workspace of packages, and its images are built from a turbo-pruned slice of it — but it has no turbo.json.\n\nTo fix this:
|
|
@@ -3666,7 +3667,7 @@ function schemaOf(resource, plan) {
|
|
|
3666
3667
|
* On SNS each topic and queue is its own address, so there is no project-wide
|
|
3667
3668
|
* one to hand out — a cron's schedule store, say, cannot live there.
|
|
3668
3669
|
*/
|
|
3669
|
-
var UnprovisionedEventsBackend = class extends
|
|
3670
|
+
var UnprovisionedEventsBackend = class extends GkmError {
|
|
3670
3671
|
backend;
|
|
3671
3672
|
constructor(backend) {
|
|
3672
3673
|
super(`'${backend}' has no single broker address: each topic and queue is addressed by its own ARN. Something asked for one without naming the topic or queue.`);
|
|
@@ -4299,7 +4300,7 @@ const LEGACY_LOCAL_LOGIN = Object.freeze({
|
|
|
4299
4300
|
password: "geekmidas"
|
|
4300
4301
|
});
|
|
4301
4302
|
/** No login this workspace knows opens its Postgres. */
|
|
4302
|
-
var PostgresLoginRefused = class extends
|
|
4303
|
+
var PostgresLoginRefused = class extends GkmError {
|
|
4303
4304
|
port;
|
|
4304
4305
|
user;
|
|
4305
4306
|
constructor(port, user) {
|
|
@@ -4310,7 +4311,7 @@ var PostgresLoginRefused = class extends Error {
|
|
|
4310
4311
|
}
|
|
4311
4312
|
};
|
|
4312
4313
|
/** No login this workspace knows opens its MinIO. */
|
|
4313
|
-
var MinioLoginRefused = class extends
|
|
4314
|
+
var MinioLoginRefused = class extends GkmError {
|
|
4314
4315
|
port;
|
|
4315
4316
|
user;
|
|
4316
4317
|
constructor(port, user) {
|
|
@@ -4657,7 +4658,7 @@ async function heldElsewhere(kept, keys, observed, probe, ours) {
|
|
|
4657
4658
|
return held;
|
|
4658
4659
|
}
|
|
4659
4660
|
/** The window was exhausted. */
|
|
4660
|
-
var NoPortAvailable = class extends
|
|
4661
|
+
var NoPortAvailable = class extends GkmError {
|
|
4661
4662
|
/** Where the search started. */
|
|
4662
4663
|
from;
|
|
4663
4664
|
/** The window searched, so the caller can report what was full. */
|
|
@@ -5403,7 +5404,7 @@ const REDIS_PASSWORD_KEY = "REDIS_PASSWORD";
|
|
|
5403
5404
|
/** Redis's own count of logical databases, before `--databases` raises it. */
|
|
5404
5405
|
const REDIS_DATABASES = 16;
|
|
5405
5406
|
/** A deployed stage that runs the stack's Redis and has no password yet. */
|
|
5406
|
-
var RedisPasswordMissing = class extends
|
|
5407
|
+
var RedisPasswordMissing = class extends GkmError {
|
|
5407
5408
|
stage;
|
|
5408
5409
|
constructor(stage) {
|
|
5409
5410
|
super(`The stage '${stage}' runs the stack's Redis and has no ${REDIS_PASSWORD_KEY} in its secrets. Run gkm compose --stage ${stage} without --dry-run once to generate it, or set one: gkm secrets:set ${REDIS_PASSWORD_KEY} '…' --stage ${stage}`);
|
|
@@ -5637,7 +5638,7 @@ function localCredentialsPath(project) {
|
|
|
5637
5638
|
return join(project.home ?? gkmHome(), "local", namespace, `${name}.json`);
|
|
5638
5639
|
}
|
|
5639
5640
|
/** The local stage's logins file is there, and its key is not. */
|
|
5640
|
-
var LocalCredentialsKeyMissing = class extends
|
|
5641
|
+
var LocalCredentialsKeyMissing = class extends GkmError {
|
|
5641
5642
|
path;
|
|
5642
5643
|
stage;
|
|
5643
5644
|
constructor(path, stage) {
|
|
@@ -5648,7 +5649,7 @@ var LocalCredentialsKeyMissing = class extends Error {
|
|
|
5648
5649
|
}
|
|
5649
5650
|
};
|
|
5650
5651
|
/** Another gkm held the logins file's lock for longer than any write takes. */
|
|
5651
|
-
var LocalCredentialsLocked = class extends
|
|
5652
|
+
var LocalCredentialsLocked = class extends GkmError {
|
|
5652
5653
|
lock;
|
|
5653
5654
|
constructor(lock) {
|
|
5654
5655
|
super(`Another gkm has been writing the local logins for over ${LOCK_TIMEOUT_MS / 1e3}s. If none is running, remove ${lock} and run the command again.`);
|
|
@@ -6348,7 +6349,7 @@ export async function stopQueues(): Promise<void> {
|
|
|
6348
6349
|
* reached by building server images for a project that deploys to AWS — where
|
|
6349
6350
|
* a subscriber is a Lambda instead.
|
|
6350
6351
|
*/
|
|
6351
|
-
var WorkerSubscribersNeedPush = class extends
|
|
6352
|
+
var WorkerSubscribersNeedPush = class extends GkmError {
|
|
6352
6353
|
worker;
|
|
6353
6354
|
subscribers;
|
|
6354
6355
|
constructor(worker, subscribers) {
|
|
@@ -6579,7 +6580,7 @@ logger.info({ port }, 'Worker started');
|
|
|
6579
6580
|
//#endregion
|
|
6580
6581
|
//#region src/build/workers.ts
|
|
6581
6582
|
/** A worker with background work and no backend app to build it from. */
|
|
6582
|
-
var WorkerHasNoApp = class extends
|
|
6583
|
+
var WorkerHasNoApp = class extends GkmError {
|
|
6583
6584
|
worker;
|
|
6584
6585
|
constructor(worker) {
|
|
6585
6586
|
super(`The worker '${worker}' has crons, queues or subscribers, and the workspace has no backend app that builds a server to carry its entry. Declare a RestApi whose app holds the worker's code.`);
|
|
@@ -6588,7 +6589,7 @@ var WorkerHasNoApp = class extends Error {
|
|
|
6588
6589
|
}
|
|
6589
6590
|
};
|
|
6590
6591
|
/** A worker whose service name an app already has. */
|
|
6591
|
-
var WorkerNameTaken = class extends
|
|
6592
|
+
var WorkerNameTaken = class extends GkmError {
|
|
6592
6593
|
worker;
|
|
6593
6594
|
service;
|
|
6594
6595
|
constructor(worker, service) {
|
|
@@ -6688,7 +6689,7 @@ const DEV_SERVICES = ["minio", "mailpit"];
|
|
|
6688
6689
|
*/
|
|
6689
6690
|
const STORAGE_KEY_PAIR = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"];
|
|
6690
6691
|
/** Dev services asked of a target that runs no containers. */
|
|
6691
|
-
var DevServicesNeedServerTarget = class extends
|
|
6692
|
+
var DevServicesNeedServerTarget = class extends GkmError {
|
|
6692
6693
|
target;
|
|
6693
6694
|
constructor(target) {
|
|
6694
6695
|
super(`--allow-dev-services applies to server targets only, and '${target}' deploys to AWS, where a bucket is S3 and mail is the stage's own. Drop --allow-dev-services.`);
|
|
@@ -6701,7 +6702,7 @@ var DevServicesNeedServerTarget = class extends Error {
|
|
|
6701
6702
|
* switch now: every construct the stage does not account for gets its dev
|
|
6702
6703
|
* service.
|
|
6703
6704
|
*/
|
|
6704
|
-
var AllowDevServicesTakesNoValue = class extends
|
|
6705
|
+
var AllowDevServicesTakesNoValue = class extends GkmError {
|
|
6705
6706
|
value;
|
|
6706
6707
|
constructor(value) {
|
|
6707
6708
|
super(`--allow-dev-services takes no value (it was given '${value}'). It runs the dev service for every bucket and mail the stage does not account for — no key in its secrets, no provider in deploy.<kind>.<stage> — so there is nothing to list. Pass --allow-dev-services on its own.`);
|
|
@@ -6729,7 +6730,7 @@ function assertDevServicesFlag(argv) {
|
|
|
6729
6730
|
* A deployed stage with mail or object storage that its secrets do not
|
|
6730
6731
|
* configure — every missing key, across every app, at once.
|
|
6731
6732
|
*/
|
|
6732
|
-
var ExternalServicesNotConfigured = class extends
|
|
6733
|
+
var ExternalServicesNotConfigured = class extends GkmError {
|
|
6733
6734
|
stage;
|
|
6734
6735
|
missing;
|
|
6735
6736
|
constructor(stage, missing) {
|
|
@@ -6946,6 +6947,126 @@ function reportDevServices(ctx, uses) {
|
|
|
6946
6947
|
}
|
|
6947
6948
|
}
|
|
6948
6949
|
//#endregion
|
|
6950
|
+
//#region src/deploy/actor.ts
|
|
6951
|
+
/**
|
|
6952
|
+
* Who wrote a stage's deploy state: a GitHub Actions run, or a person at a
|
|
6953
|
+
* machine. Recorded on every state write (`updatedBy`), on every resource
|
|
6954
|
+
* record and on every release (`releasedBy`), so "who put this here" has an
|
|
6955
|
+
* answer that does not depend on anyone's memory.
|
|
6956
|
+
*/
|
|
6957
|
+
/** Whether `env` is a CI job — GitHub Actions or any runner that sets `CI`. */
|
|
6958
|
+
function isCi(env = process.env) {
|
|
6959
|
+
return env.GITHUB_ACTIONS === "true" || env.CI === "true";
|
|
6960
|
+
}
|
|
6961
|
+
/** Who this process is writing as. */
|
|
6962
|
+
function currentActor(env = process.env) {
|
|
6963
|
+
if (env.GITHUB_ACTIONS === "true") {
|
|
6964
|
+
const server = env.GITHUB_SERVER_URL ?? "https://github.com";
|
|
6965
|
+
return {
|
|
6966
|
+
kind: "github",
|
|
6967
|
+
actor: env.GITHUB_ACTOR ?? "unknown",
|
|
6968
|
+
run: `${server}/${env.GITHUB_REPOSITORY ?? "unknown"}/actions/runs/${env.GITHUB_RUN_ID ?? "unknown"}`,
|
|
6969
|
+
...env.GITHUB_WORKFLOW ? { workflow: env.GITHUB_WORKFLOW } : {}
|
|
6970
|
+
};
|
|
6971
|
+
}
|
|
6972
|
+
let user = "unknown";
|
|
6973
|
+
try {
|
|
6974
|
+
user = userInfo().username;
|
|
6975
|
+
} catch {}
|
|
6976
|
+
return {
|
|
6977
|
+
kind: "local",
|
|
6978
|
+
user,
|
|
6979
|
+
host: hostname()
|
|
6980
|
+
};
|
|
6981
|
+
}
|
|
6982
|
+
/** `octocat (deploy, https://github.com/…/runs/1)` or `ada@laptop`. */
|
|
6983
|
+
function describeActor(actor) {
|
|
6984
|
+
if (!actor) return "unknown";
|
|
6985
|
+
if (actor.kind === "local") return `${actor.user}@${actor.host}`;
|
|
6986
|
+
return `${actor.actor} (${actor.workflow ? `${actor.workflow}, ` : ""}${actor.run})`;
|
|
6987
|
+
}
|
|
6988
|
+
//#endregion
|
|
6989
|
+
//#region src/deploy/dnsResources.ts
|
|
6990
|
+
/** The resource type of a DNS record gkm wrote. */
|
|
6991
|
+
const DNS_RECORD_RESOURCE = "dns-record";
|
|
6992
|
+
/** A record's full name: `api.example.com`, or the domain for `@`. */
|
|
6993
|
+
function dnsRecordFqdn(domain, name) {
|
|
6994
|
+
return name === "@" || name === "" ? domain : `${name}.${domain}`;
|
|
6995
|
+
}
|
|
6996
|
+
/** `dns-record:<fqdn>:<type>` */
|
|
6997
|
+
function dnsResourceKey(fqdn, type) {
|
|
6998
|
+
return `${DNS_RECORD_RESOURCE}:${fqdn.toLowerCase()}:${type.toUpperCase()}`;
|
|
6999
|
+
}
|
|
7000
|
+
/** The resource record a written DNS record is kept as. */
|
|
7001
|
+
function dnsRecordResource(record) {
|
|
7002
|
+
const fqdn = dnsRecordFqdn(record.domain, record.name).toLowerCase();
|
|
7003
|
+
const type = record.type.toUpperCase();
|
|
7004
|
+
const data = {
|
|
7005
|
+
domain: record.domain,
|
|
7006
|
+
name: record.name,
|
|
7007
|
+
value: record.value,
|
|
7008
|
+
ttl: record.ttl,
|
|
7009
|
+
...record.provider ? { provider: record.provider } : {}
|
|
7010
|
+
};
|
|
7011
|
+
return {
|
|
7012
|
+
key: dnsResourceKey(fqdn, type),
|
|
7013
|
+
type: DNS_RECORD_RESOURCE,
|
|
7014
|
+
id: `${fqdn} ${type}`,
|
|
7015
|
+
status: "ready",
|
|
7016
|
+
data
|
|
7017
|
+
};
|
|
7018
|
+
}
|
|
7019
|
+
/** Records that gkm wrote `record` — or updates the value it holds. */
|
|
7020
|
+
async function recordDnsResource(journal, record) {
|
|
7021
|
+
const { key, type, id, data } = dnsRecordResource(record);
|
|
7022
|
+
await journal.ready({
|
|
7023
|
+
key,
|
|
7024
|
+
type,
|
|
7025
|
+
...data ? { data } : {}
|
|
7026
|
+
}, id);
|
|
7027
|
+
}
|
|
7028
|
+
/** Forgets a DNS record gkm deleted. */
|
|
7029
|
+
async function forgetDnsResource(journal, record) {
|
|
7030
|
+
await journal.forget(dnsResourceKey(dnsRecordFqdn(record.domain, record.name), record.type));
|
|
7031
|
+
}
|
|
7032
|
+
/**
|
|
7033
|
+
* The changes a DNS step made, kept: what it created, updated or wrote is
|
|
7034
|
+
* recorded, what it deleted is forgotten. A record it found already right is
|
|
7035
|
+
* recorded only if gkm wrote it before; one it left to a person is not.
|
|
7036
|
+
*/
|
|
7037
|
+
async function recordDnsChanges(journal, changes, providerOf) {
|
|
7038
|
+
for (const change of changes) {
|
|
7039
|
+
if (change.action === "delete") {
|
|
7040
|
+
await forgetDnsResource(journal, change);
|
|
7041
|
+
continue;
|
|
7042
|
+
}
|
|
7043
|
+
const written = change.action === "create" || change.action === "update" || change.action === "write";
|
|
7044
|
+
const known = change.action === "unchanged" && journal.record(dnsResourceKey(dnsRecordFqdn(change.domain, change.name), change.type)) !== void 0;
|
|
7045
|
+
if (!written && !known || change.value === void 0) continue;
|
|
7046
|
+
const provider = providerOf(change.domain);
|
|
7047
|
+
await recordDnsResource(journal, {
|
|
7048
|
+
domain: change.domain,
|
|
7049
|
+
name: change.name,
|
|
7050
|
+
type: change.type,
|
|
7051
|
+
value: change.value,
|
|
7052
|
+
ttl: change.ttl ?? 0,
|
|
7053
|
+
...provider ? { provider } : {}
|
|
7054
|
+
});
|
|
7055
|
+
}
|
|
7056
|
+
}
|
|
7057
|
+
/** Every DNS record gkm wrote for the stage, from its resource records. */
|
|
7058
|
+
function dnsResources(resources) {
|
|
7059
|
+
return Object.values(resources).filter((record) => record.type === DNS_RECORD_RESOURCE).map((record) => {
|
|
7060
|
+
const data = record.data ?? {};
|
|
7061
|
+
const [fqdn = "", type = ""] = (record.id ?? "").split(" ");
|
|
7062
|
+
return {
|
|
7063
|
+
...data,
|
|
7064
|
+
type,
|
|
7065
|
+
fqdn
|
|
7066
|
+
};
|
|
7067
|
+
}).sort((a, b) => a.fqdn.localeCompare(b.fqdn) || a.type.localeCompare(b.type));
|
|
7068
|
+
}
|
|
7069
|
+
//#endregion
|
|
6949
7070
|
//#region src/deploy/StateProvider.ts
|
|
6950
7071
|
/**
|
|
6951
7072
|
* Check if value is a StateProvider implementation.
|
|
@@ -6953,29 +7074,7 @@ function reportDevServices(ctx, uses) {
|
|
|
6953
7074
|
function isStateProvider(value) {
|
|
6954
7075
|
return typeof value === "object" && value !== null && typeof value.read === "function" && typeof value.write === "function";
|
|
6955
7076
|
}
|
|
6956
|
-
|
|
6957
|
-
//#region src/deploy/StateStore.ts
|
|
6958
|
-
/**
|
|
6959
|
-
* Deploy state store.
|
|
6960
|
-
*
|
|
6961
|
-
* `StateProvider` reads and writes a whole stage at once, with nothing to stop
|
|
6962
|
-
* two runs of the same stage from overwriting each other and nowhere to record
|
|
6963
|
-
* a resource the moment it exists. A `StateStore` adds the three things a
|
|
6964
|
-
* deploy needs to be safe against crashes and concurrent runs:
|
|
6965
|
-
*
|
|
6966
|
-
* - `lock(stage)`: one run per stage. A second gets `StateLocked`, naming the
|
|
6967
|
-
* holder, instead of racing the first.
|
|
6968
|
-
* - Versioned `read` and conditional `write`: a write names the version it was
|
|
6969
|
-
* based on, and raises `StateVersionConflict` when the stored state moved on
|
|
6970
|
-
* underneath it, so nothing is lost silently even without the lock.
|
|
6971
|
-
* - Per-resource records: `putResource` journals one resource at a time, so a
|
|
6972
|
-
* run that dies half way leaves behind the ids of everything it created.
|
|
6973
|
-
*
|
|
6974
|
-
* Built-in stores: `LocalStateStore`, `SSMStateStore`, `S3StateStore`. A
|
|
6975
|
-
* custom `StateProvider` is wrapped by `LegacyStateStore`, which keeps it
|
|
6976
|
-
* working but cannot lock.
|
|
6977
|
-
*/
|
|
6978
|
-
var StateLocked = class extends Error {
|
|
7077
|
+
var StateLocked = class extends GkmError {
|
|
6979
7078
|
stage;
|
|
6980
7079
|
holder;
|
|
6981
7080
|
location;
|
|
@@ -6988,7 +7087,7 @@ var StateLocked = class extends Error {
|
|
|
6988
7087
|
this.name = "StateLocked";
|
|
6989
7088
|
}
|
|
6990
7089
|
};
|
|
6991
|
-
var StateVersionConflict = class extends
|
|
7090
|
+
var StateVersionConflict = class extends GkmError {
|
|
6992
7091
|
stage;
|
|
6993
7092
|
expectedVersion;
|
|
6994
7093
|
actualVersion;
|
|
@@ -7000,7 +7099,7 @@ var StateVersionConflict = class extends Error {
|
|
|
7000
7099
|
this.name = "StateVersionConflict";
|
|
7001
7100
|
}
|
|
7002
7101
|
};
|
|
7003
|
-
var StageStateMissing = class extends
|
|
7102
|
+
var StageStateMissing = class extends GkmError {
|
|
7004
7103
|
stage;
|
|
7005
7104
|
constructor(stage) {
|
|
7006
7105
|
super(`There is no deploy state for stage '${stage}' to record a resource in. Write the stage's state first (write with expectedVersion: null).`);
|
|
@@ -7008,7 +7107,7 @@ var StageStateMissing = class extends Error {
|
|
|
7008
7107
|
this.name = "StageStateMissing";
|
|
7009
7108
|
}
|
|
7010
7109
|
};
|
|
7011
|
-
var StateUnreadable = class extends
|
|
7110
|
+
var StateUnreadable = class extends GkmError {
|
|
7012
7111
|
stage;
|
|
7013
7112
|
location;
|
|
7014
7113
|
constructor(stage, location, cause) {
|
|
@@ -7018,11 +7117,11 @@ var StateUnreadable = class extends Error {
|
|
|
7018
7117
|
this.name = "StateUnreadable";
|
|
7019
7118
|
}
|
|
7020
7119
|
};
|
|
7021
|
-
var StateSchemaTooNew = class extends
|
|
7120
|
+
var StateSchemaTooNew = class extends GkmError {
|
|
7022
7121
|
stage;
|
|
7023
7122
|
schemaVersion;
|
|
7024
7123
|
constructor(stage, schemaVersion) {
|
|
7025
|
-
super(`Deploy state for stage '${stage}' has schema version ${String(schemaVersion)}, newer than this @geekmidas/cli understands (
|
|
7124
|
+
super(`Deploy state for stage '${stage}' has schema version ${String(schemaVersion)}, newer than this @geekmidas/cli understands (3). Upgrade @geekmidas/cli to the version that wrote it.`);
|
|
7026
7125
|
this.stage = stage;
|
|
7027
7126
|
this.schemaVersion = schemaVersion;
|
|
7028
7127
|
this.name = "StateSchemaTooNew";
|
|
@@ -7033,7 +7132,7 @@ var StateSchemaTooNew = class extends Error {
|
|
|
7033
7132
|
* in for a store, so a deploy that cannot be protected from a concurrent one
|
|
7034
7133
|
* says so.
|
|
7035
7134
|
*/
|
|
7036
|
-
var StateStoreWithoutLocking = class extends
|
|
7135
|
+
var StateStoreWithoutLocking = class extends GkmError {
|
|
7037
7136
|
provider;
|
|
7038
7137
|
constructor(provider) {
|
|
7039
7138
|
super(`The custom state provider '${provider}' has no lock and no versions, so two deploys of the same stage can still overwrite each other. Implement StateStore (lock, versioned read, conditional write) or use the 'local', 'ssm' or 's3' state provider.`);
|
|
@@ -7041,7 +7140,7 @@ var StateStoreWithoutLocking = class extends Error {
|
|
|
7041
7140
|
this.name = "StateStoreWithoutLocking";
|
|
7042
7141
|
}
|
|
7043
7142
|
};
|
|
7044
|
-
var StateStoreNeedsWorkspaceName = class extends
|
|
7143
|
+
var StateStoreNeedsWorkspaceName = class extends GkmError {
|
|
7045
7144
|
provider;
|
|
7046
7145
|
constructor(provider) {
|
|
7047
7146
|
super(`The '${provider}' state provider keys state by workspace name. Set "name" in gkm.config.ts.`);
|
|
@@ -7049,7 +7148,7 @@ var StateStoreNeedsWorkspaceName = class extends Error {
|
|
|
7049
7148
|
this.name = "StateStoreNeedsWorkspaceName";
|
|
7050
7149
|
}
|
|
7051
7150
|
};
|
|
7052
|
-
var UnknownStateProvider = class extends
|
|
7151
|
+
var UnknownStateProvider = class extends GkmError {
|
|
7053
7152
|
config;
|
|
7054
7153
|
constructor(config) {
|
|
7055
7154
|
super(`Unknown state provider ${JSON.stringify(config)}. Use 'local', 'ssm', 's3', or an object implementing StateStore or StateProvider.`);
|
|
@@ -7057,8 +7156,24 @@ var UnknownStateProvider = class extends Error {
|
|
|
7057
7156
|
this.name = "UnknownStateProvider";
|
|
7058
7157
|
}
|
|
7059
7158
|
};
|
|
7159
|
+
/**
|
|
7160
|
+
* A deploy, setup or rollback of a stage in CI, with the stage's state kept on
|
|
7161
|
+
* the runner — which is discarded when the job ends.
|
|
7162
|
+
*/
|
|
7163
|
+
var LocalStateInCi = class extends GkmError {
|
|
7164
|
+
stage;
|
|
7165
|
+
operation;
|
|
7166
|
+
region;
|
|
7167
|
+
constructor(stage, operation, region) {
|
|
7168
|
+
super(`\`gkm ${operation}\` would keep stage '${stage}'s deploy state in .gkm/ on this CI runner, and the runner is discarded when the job ends: the next run would start without it — no releases to roll back to, no record of what was created. Keep the state in AWS — in gkm.config.ts:\n\n state: { provider: 'ssm', region: '${region}' },\n\nthen move the state you already have, from the machine that holds it:\n\n gkm state:push --stage ${stage}\n`);
|
|
7169
|
+
this.stage = stage;
|
|
7170
|
+
this.operation = operation;
|
|
7171
|
+
this.region = region;
|
|
7172
|
+
this.name = "LocalStateInCi";
|
|
7173
|
+
}
|
|
7174
|
+
};
|
|
7060
7175
|
/** A lock or write that could not get at the state backend in time. */
|
|
7061
|
-
var StateStoreBusy = class extends
|
|
7176
|
+
var StateStoreBusy = class extends GkmError {
|
|
7062
7177
|
stage;
|
|
7063
7178
|
location;
|
|
7064
7179
|
constructor(stage, location) {
|
|
@@ -7085,6 +7200,10 @@ function decodeDocument(stage, body, location) {
|
|
|
7085
7200
|
schemaVersion: 2,
|
|
7086
7201
|
document: parsed
|
|
7087
7202
|
};
|
|
7203
|
+
if (schemaVersion === 3) return {
|
|
7204
|
+
schemaVersion: 3,
|
|
7205
|
+
document: parsed
|
|
7206
|
+
};
|
|
7088
7207
|
throw new StateSchemaTooNew(stage, schemaVersion);
|
|
7089
7208
|
}
|
|
7090
7209
|
function encodeDocument(document) {
|
|
@@ -7124,6 +7243,79 @@ function migrateV1(stage, state) {
|
|
|
7124
7243
|
updatedAt: now
|
|
7125
7244
|
};
|
|
7126
7245
|
}
|
|
7246
|
+
const isEmpty = (value) => !value || Object.keys(value).length === 0;
|
|
7247
|
+
/**
|
|
7248
|
+
* Whether a v2 state in the Dokploy shape was written by the compose target.
|
|
7249
|
+
*
|
|
7250
|
+
* Before v3 every target wrote the Dokploy shape, and compose filled none of
|
|
7251
|
+
* its Dokploy fields. So the rule is the shape's content, not the target the
|
|
7252
|
+
* workspace names now: a state whose every Dokploy-only field is empty — no
|
|
7253
|
+
* project or environment id, no application or service ids, no credentials,
|
|
7254
|
+
* generated secrets, backups or registry — holds nothing only Dokploy could
|
|
7255
|
+
* use, and reading it as compose loses nothing. One with any of them was
|
|
7256
|
+
* written by Dokploy and is kept exactly as it is.
|
|
7257
|
+
*
|
|
7258
|
+
* The configured target is not used: a document decodes the same wherever it
|
|
7259
|
+
* is read (`state:show`, `state:push`) without a workspace, a stage can be
|
|
7260
|
+
* moved between targets, and `--target` can override a run.
|
|
7261
|
+
*/
|
|
7262
|
+
function writtenByCompose(state) {
|
|
7263
|
+
return !state.projectId && !state.environmentId && isEmpty(state.applications) && !state.services?.postgresId && !state.services?.redisId && isEmpty(state.appCredentials) && isEmpty(state.generatedSecrets) && !state.backups && !state.registryId;
|
|
7264
|
+
}
|
|
7265
|
+
/**
|
|
7266
|
+
* A v2 state and its records as v3 keeps them. A compose-written state
|
|
7267
|
+
* becomes the compose shape: its `dnsRecords` become `dns-record` resources,
|
|
7268
|
+
* and `dnsVerified` and the empty Dokploy fields go — the DNS check is made
|
|
7269
|
+
* on every deploy. A Dokploy state is returned as it is.
|
|
7270
|
+
*/
|
|
7271
|
+
function upgradeV2State(state, resources) {
|
|
7272
|
+
if (!writtenByCompose(state)) return {
|
|
7273
|
+
state,
|
|
7274
|
+
resources
|
|
7275
|
+
};
|
|
7276
|
+
const compose = {
|
|
7277
|
+
provider: "compose",
|
|
7278
|
+
stage: state.stage,
|
|
7279
|
+
lastDeployedAt: state.lastDeployedAt,
|
|
7280
|
+
...state.identity ? { identity: state.identity } : {},
|
|
7281
|
+
...state.releases ? { releases: state.releases } : {}
|
|
7282
|
+
};
|
|
7283
|
+
const upgraded = { ...resources };
|
|
7284
|
+
for (const record of Object.values(state.dnsRecords ?? {})) {
|
|
7285
|
+
const resource = migratedDnsResource(record);
|
|
7286
|
+
upgraded[resource.key] = resource;
|
|
7287
|
+
}
|
|
7288
|
+
return {
|
|
7289
|
+
state: compose,
|
|
7290
|
+
resources: upgraded
|
|
7291
|
+
};
|
|
7292
|
+
}
|
|
7293
|
+
/** A v2 `dnsRecords` entry as the `dns-record` resource v3 keeps. */
|
|
7294
|
+
function migratedDnsResource(record) {
|
|
7295
|
+
return {
|
|
7296
|
+
...dnsRecordResource({
|
|
7297
|
+
domain: record.domain,
|
|
7298
|
+
name: record.name,
|
|
7299
|
+
type: record.type,
|
|
7300
|
+
value: record.value,
|
|
7301
|
+
ttl: record.ttl
|
|
7302
|
+
}),
|
|
7303
|
+
updatedAt: record.createdAt
|
|
7304
|
+
};
|
|
7305
|
+
}
|
|
7306
|
+
/** A v2 document as v3 — not written until the next write. */
|
|
7307
|
+
function migrateV2(document) {
|
|
7308
|
+
const { state, resources } = upgradeV2State(document.state, document.resources);
|
|
7309
|
+
return {
|
|
7310
|
+
schemaVersion: 3,
|
|
7311
|
+
stage: document.stage,
|
|
7312
|
+
serial: document.serial,
|
|
7313
|
+
state,
|
|
7314
|
+
resources,
|
|
7315
|
+
updatedAt: document.updatedAt,
|
|
7316
|
+
history: []
|
|
7317
|
+
};
|
|
7318
|
+
}
|
|
7127
7319
|
function newLockHolder(options) {
|
|
7128
7320
|
let owner = "unknown";
|
|
7129
7321
|
try {
|
|
@@ -7142,14 +7334,33 @@ function contentVersion(body) {
|
|
|
7142
7334
|
return createHash("sha256").update(body).digest("hex").slice(0, 16);
|
|
7143
7335
|
}
|
|
7144
7336
|
/**
|
|
7337
|
+
* `history` with this write at its head. A run makes many writes — one per
|
|
7338
|
+
* resource it journals — so a run is one entry: a write by the run that
|
|
7339
|
+
* wrote the newest entry (the same lock) replaces it, and any other is
|
|
7340
|
+
* added. Without a lock, each write is its own entry.
|
|
7341
|
+
*/
|
|
7342
|
+
function appendHistory(history, entry, sameRun) {
|
|
7343
|
+
return [entry, ...sameRun ? history.slice(1) : history].slice(0, 20);
|
|
7344
|
+
}
|
|
7345
|
+
/**
|
|
7145
7346
|
* A store over a backend that can read and conditionally write one blob per
|
|
7146
|
-
* stage, and create a lock object only if it does not exist. Migration
|
|
7147
|
-
* resource records are the same for every such backend, so they
|
|
7347
|
+
* stage, and create a lock object only if it does not exist. Migration,
|
|
7348
|
+
* resource records and history are the same for every such backend, so they
|
|
7349
|
+
* live here.
|
|
7148
7350
|
*/
|
|
7149
7351
|
var DocumentStateStore = class {
|
|
7352
|
+
/** The lock this store holds for each stage — what its writes are for. */
|
|
7353
|
+
held = /* @__PURE__ */ new Map();
|
|
7354
|
+
/** Per stage, the lock whose run wrote the newest history entry. */
|
|
7355
|
+
logged = /* @__PURE__ */ new Map();
|
|
7356
|
+
/** Who this store writes as. */
|
|
7357
|
+
actor() {
|
|
7358
|
+
return currentActor();
|
|
7359
|
+
}
|
|
7150
7360
|
async lock(stage, options) {
|
|
7151
7361
|
const holder = newLockHolder(options);
|
|
7152
7362
|
await this.createLock(stage, holder);
|
|
7363
|
+
this.held.set(stage, holder);
|
|
7153
7364
|
let released = false;
|
|
7154
7365
|
return {
|
|
7155
7366
|
stage,
|
|
@@ -7157,6 +7368,7 @@ var DocumentStateStore = class {
|
|
|
7157
7368
|
release: async () => {
|
|
7158
7369
|
if (released) return;
|
|
7159
7370
|
released = true;
|
|
7371
|
+
if (this.held.get(stage)?.id === holder.id) this.held.delete(stage);
|
|
7160
7372
|
await this.removeLock(stage, holder);
|
|
7161
7373
|
}
|
|
7162
7374
|
};
|
|
@@ -7172,19 +7384,21 @@ var DocumentStateStore = class {
|
|
|
7172
7384
|
return {
|
|
7173
7385
|
state: current.document.state,
|
|
7174
7386
|
resources: current.document.resources,
|
|
7387
|
+
history: current.document.history,
|
|
7175
7388
|
version: current.version
|
|
7176
7389
|
};
|
|
7177
7390
|
}
|
|
7178
7391
|
async write(stage, state, options) {
|
|
7179
7392
|
if (options.expectedVersion === null) {
|
|
7180
|
-
const document = {
|
|
7181
|
-
schemaVersion:
|
|
7393
|
+
const document = this.stamp(stage, {
|
|
7394
|
+
schemaVersion: 3,
|
|
7182
7395
|
stage,
|
|
7183
7396
|
serial: 1,
|
|
7184
7397
|
state,
|
|
7185
7398
|
resources: {},
|
|
7186
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7187
|
-
|
|
7399
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7400
|
+
history: []
|
|
7401
|
+
});
|
|
7188
7402
|
return this.writeRaw(stage, encodeDocument(document), null);
|
|
7189
7403
|
}
|
|
7190
7404
|
return this.mutate(stage, options.expectedVersion, (document) => ({
|
|
@@ -7199,7 +7413,8 @@ var DocumentStateStore = class {
|
|
|
7199
7413
|
...document.resources,
|
|
7200
7414
|
[record.key]: {
|
|
7201
7415
|
...record,
|
|
7202
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7416
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7417
|
+
updatedBy: this.actor()
|
|
7203
7418
|
}
|
|
7204
7419
|
}
|
|
7205
7420
|
}));
|
|
@@ -7213,6 +7428,25 @@ var DocumentStateStore = class {
|
|
|
7213
7428
|
};
|
|
7214
7429
|
});
|
|
7215
7430
|
}
|
|
7431
|
+
/** `document` as this write leaves it: who wrote it, in its history. */
|
|
7432
|
+
stamp(stage, document) {
|
|
7433
|
+
const by = this.actor();
|
|
7434
|
+
const holder = this.held.get(stage);
|
|
7435
|
+
const operation = holder?.operation ?? "write";
|
|
7436
|
+
const history = document.history ?? [];
|
|
7437
|
+
const sameRun = holder !== void 0 && this.logged.get(stage) === holder.id && history[0]?.operation === operation;
|
|
7438
|
+
if (holder) this.logged.set(stage, holder.id);
|
|
7439
|
+
return {
|
|
7440
|
+
...document,
|
|
7441
|
+
updatedBy: by,
|
|
7442
|
+
history: appendHistory(history, {
|
|
7443
|
+
serial: document.serial,
|
|
7444
|
+
at: document.updatedAt,
|
|
7445
|
+
by,
|
|
7446
|
+
operation
|
|
7447
|
+
}, sameRun)
|
|
7448
|
+
};
|
|
7449
|
+
}
|
|
7216
7450
|
async mutate(stage, expectedVersion, change) {
|
|
7217
7451
|
const current = await this.readDocument(stage);
|
|
7218
7452
|
if (!current) {
|
|
@@ -7221,25 +7455,31 @@ var DocumentStateStore = class {
|
|
|
7221
7455
|
}
|
|
7222
7456
|
if (expectedVersion !== void 0 && current.version !== expectedVersion) throw new StateVersionConflict(stage, expectedVersion, current.version);
|
|
7223
7457
|
const next = change(current.document);
|
|
7458
|
+
next.schemaVersion = 3;
|
|
7224
7459
|
next.serial = current.document.serial + 1;
|
|
7225
7460
|
next.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7226
|
-
return this.writeRaw(stage, encodeDocument(next), current.version);
|
|
7461
|
+
return this.writeRaw(stage, encodeDocument(this.stamp(stage, next)), current.version);
|
|
7227
7462
|
}
|
|
7228
7463
|
/**
|
|
7229
|
-
* Reads the stage's document
|
|
7230
|
-
*
|
|
7231
|
-
*
|
|
7464
|
+
* Reads the stage's document as v3. A v1 document is migrated in place on
|
|
7465
|
+
* the way — itself a conditional write: if another run migrated (or wrote)
|
|
7466
|
+
* first, its result is read instead. A v2 document is upgraded in memory
|
|
7467
|
+
* and written as v3 by the next write.
|
|
7232
7468
|
*/
|
|
7233
7469
|
async readDocument(stage, attempt = 0) {
|
|
7234
7470
|
const raw = await this.readRaw(stage);
|
|
7235
7471
|
if (!raw) return null;
|
|
7236
7472
|
const decoded = decodeDocument(stage, raw.body, this.location(stage));
|
|
7237
|
-
if (decoded.schemaVersion ===
|
|
7473
|
+
if (decoded.schemaVersion === 3) return {
|
|
7238
7474
|
document: decoded.document,
|
|
7239
7475
|
version: raw.version
|
|
7240
7476
|
};
|
|
7477
|
+
if (decoded.schemaVersion === 2) return {
|
|
7478
|
+
document: migrateV2(decoded.document),
|
|
7479
|
+
version: raw.version
|
|
7480
|
+
};
|
|
7241
7481
|
await this.writeV1Backup(stage, raw.body);
|
|
7242
|
-
const document = migrateV1(stage, decoded.state);
|
|
7482
|
+
const document = this.stamp(stage, migrateV2(migrateV1(stage, decoded.state)));
|
|
7243
7483
|
try {
|
|
7244
7484
|
return {
|
|
7245
7485
|
document,
|
|
@@ -7251,6 +7491,22 @@ var DocumentStateStore = class {
|
|
|
7251
7491
|
}
|
|
7252
7492
|
}
|
|
7253
7493
|
};
|
|
7494
|
+
/** Whether `config` keeps state on this machine — `local`, or none given. */
|
|
7495
|
+
function isLocalState(config) {
|
|
7496
|
+
return !config || config.provider === "local";
|
|
7497
|
+
}
|
|
7498
|
+
/**
|
|
7499
|
+
* Refuses, with `LocalStateInCi`, a run that would write a deployed stage's
|
|
7500
|
+
* state to a CI runner's disk — the local stage, which runs on the runner
|
|
7501
|
+
* itself, is exempt. Local use is untouched. The region the message
|
|
7502
|
+
* suggests is the secrets store's, when the workspace keeps them in AWS.
|
|
7503
|
+
*/
|
|
7504
|
+
function assertStateOutlivesRun(workspace, stage, operation, env = process.env) {
|
|
7505
|
+
if (stage === workspace.stages?.local) return;
|
|
7506
|
+
if (!isCi(env) || !isLocalState(workspace.state)) return;
|
|
7507
|
+
const store = workspace.secrets?.store;
|
|
7508
|
+
throw new LocalStateInCi(stage, operation, typeof store === "object" && store && typeof store.region === "string" ? store.region : "<region>");
|
|
7509
|
+
}
|
|
7254
7510
|
function isStateStore(value) {
|
|
7255
7511
|
return typeof value === "object" && value !== null && typeof value.lock === "function" && typeof value.read === "function" && typeof value.write === "function" && typeof value.putResource === "function";
|
|
7256
7512
|
}
|
|
@@ -7267,17 +7523,17 @@ function isStateStore(value) {
|
|
|
7267
7523
|
async function createStateStore(options) {
|
|
7268
7524
|
const { config, workspaceRoot, workspaceName } = options;
|
|
7269
7525
|
if (!config || config.provider === "local") {
|
|
7270
|
-
const { LocalStateStore } = await import("./LocalStateStore-
|
|
7526
|
+
const { LocalStateStore } = await import("./LocalStateStore-D40_SDmJ.mjs").then((n) => n.n);
|
|
7271
7527
|
return new LocalStateStore(workspaceRoot);
|
|
7272
7528
|
}
|
|
7273
7529
|
if (isStateStore(config.provider)) return config.provider;
|
|
7274
7530
|
if (isStateProvider(config.provider)) {
|
|
7275
|
-
const { LegacyStateStore } = await import("./LegacyStateStore-
|
|
7531
|
+
const { LegacyStateStore } = await import("./LegacyStateStore-CtwO7fwy.mjs");
|
|
7276
7532
|
return new LegacyStateStore(config.provider, { warn: options.warn });
|
|
7277
7533
|
}
|
|
7278
7534
|
if (config.provider === "ssm") {
|
|
7279
7535
|
if (!workspaceName) throw new StateStoreNeedsWorkspaceName("ssm");
|
|
7280
|
-
const { SSMStateStore } = await import("./SSMStateStore-
|
|
7536
|
+
const { SSMStateStore } = await import("./SSMStateStore-k_Ew7TWx.mjs");
|
|
7281
7537
|
const ssm = config;
|
|
7282
7538
|
return SSMStateStore.create({
|
|
7283
7539
|
workspaceName,
|
|
@@ -7287,7 +7543,7 @@ async function createStateStore(options) {
|
|
|
7287
7543
|
}
|
|
7288
7544
|
if (config.provider === "s3") {
|
|
7289
7545
|
if (!workspaceName) throw new StateStoreNeedsWorkspaceName("s3");
|
|
7290
|
-
const { S3StateStore } = await import("./S3StateStore-
|
|
7546
|
+
const { S3StateStore } = await import("./S3StateStore-BzS0IeSt.mjs");
|
|
7291
7547
|
const s3 = config;
|
|
7292
7548
|
return S3StateStore.create({
|
|
7293
7549
|
workspaceName,
|
|
@@ -7322,7 +7578,7 @@ async function createDnsProvider(options) {
|
|
|
7322
7578
|
if (isDnsProvider(config.provider)) return config.provider;
|
|
7323
7579
|
const provider = config.provider;
|
|
7324
7580
|
if (provider === "hostinger") {
|
|
7325
|
-
const { HostingerProvider } = await import("./HostingerProvider-
|
|
7581
|
+
const { HostingerProvider } = await import("./HostingerProvider-1mqD6aG8.mjs");
|
|
7326
7582
|
return new HostingerProvider();
|
|
7327
7583
|
}
|
|
7328
7584
|
if (provider === "route53") {
|
|
@@ -7335,7 +7591,7 @@ async function createDnsProvider(options) {
|
|
|
7335
7591
|
});
|
|
7336
7592
|
}
|
|
7337
7593
|
if (provider === "godaddy") {
|
|
7338
|
-
const { GoDaddyProvider } = await import("./GoDaddyProvider-
|
|
7594
|
+
const { GoDaddyProvider } = await import("./GoDaddyProvider-Mi3vptSR.mjs");
|
|
7339
7595
|
return new GoDaddyProvider(options.godaddy ?? {});
|
|
7340
7596
|
}
|
|
7341
7597
|
if (provider === "cloudflare") throw new DnsProviderNotImplemented("cloudflare");
|
|
@@ -7346,7 +7602,7 @@ async function createDnsProvider(options) {
|
|
|
7346
7602
|
* scoped to updates only. What reads them falls back to writing every record,
|
|
7347
7603
|
* which is idempotent, without a diff.
|
|
7348
7604
|
*/
|
|
7349
|
-
var DnsRecordsUnreadable = class extends
|
|
7605
|
+
var DnsRecordsUnreadable = class extends GkmError {
|
|
7350
7606
|
provider;
|
|
7351
7607
|
domain;
|
|
7352
7608
|
reason;
|
|
@@ -7368,7 +7624,7 @@ var DnsProviderNotImplemented = class extends Error {
|
|
|
7368
7624
|
}
|
|
7369
7625
|
};
|
|
7370
7626
|
/** A `provider:` that is none of the built-ins, nor a DnsProvider object. */
|
|
7371
|
-
var DnsProviderUnknown = class extends
|
|
7627
|
+
var DnsProviderUnknown = class extends GkmError {
|
|
7372
7628
|
config;
|
|
7373
7629
|
constructor(config) {
|
|
7374
7630
|
super(`Unknown DNS provider: ${JSON.stringify(config)}. dns takes 'route53', 'godaddy', 'hostinger', 'manual', or an object implementing DnsProvider.`);
|
|
@@ -7392,6 +7648,31 @@ function createEmptyState(stage, projectId, environmentId) {
|
|
|
7392
7648
|
lastDeployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7393
7649
|
};
|
|
7394
7650
|
}
|
|
7651
|
+
/** A new compose stage's state. */
|
|
7652
|
+
function createComposeState(stage) {
|
|
7653
|
+
return {
|
|
7654
|
+
provider: "compose",
|
|
7655
|
+
stage,
|
|
7656
|
+
lastDeployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7657
|
+
};
|
|
7658
|
+
}
|
|
7659
|
+
/**
|
|
7660
|
+
* `state` as the Dokploy target keeps it. A stage whose state another target
|
|
7661
|
+
* wrote — one moved from compose to Dokploy — keeps its core (releases,
|
|
7662
|
+
* identity) and starts with no Dokploy ids, as a first deploy would.
|
|
7663
|
+
*/
|
|
7664
|
+
function asDokployState(state) {
|
|
7665
|
+
if (state.provider === "dokploy") return state;
|
|
7666
|
+
const { provider: _provider, ...core } = state;
|
|
7667
|
+
return {
|
|
7668
|
+
...core,
|
|
7669
|
+
provider: "dokploy",
|
|
7670
|
+
projectId: "",
|
|
7671
|
+
environmentId: "",
|
|
7672
|
+
applications: {},
|
|
7673
|
+
services: {}
|
|
7674
|
+
};
|
|
7675
|
+
}
|
|
7395
7676
|
/**
|
|
7396
7677
|
* Set application ID in state (mutates state)
|
|
7397
7678
|
*/
|
|
@@ -7411,12 +7692,13 @@ function restorable(history, index, current) {
|
|
|
7411
7692
|
* `current`, and what was current becomes `previous`. Releasing what already
|
|
7412
7693
|
* runs — a redeploy of the same digest — changes nothing.
|
|
7413
7694
|
*/
|
|
7414
|
-
function recordRelease(state, appName, image, releasedAt = /* @__PURE__ */ new Date()) {
|
|
7695
|
+
function recordRelease(state, appName, image, by, releasedAt = /* @__PURE__ */ new Date()) {
|
|
7415
7696
|
const releases = state.releases?.[appName];
|
|
7416
7697
|
if (releases && sameImage(releases.current, image)) return;
|
|
7417
7698
|
const entry = {
|
|
7418
7699
|
...image,
|
|
7419
|
-
releasedAt: releasedAt.toISOString()
|
|
7700
|
+
releasedAt: releasedAt.toISOString(),
|
|
7701
|
+
releasedBy: by
|
|
7420
7702
|
};
|
|
7421
7703
|
const history = [entry, ...releases?.history ?? []].slice(0, 10);
|
|
7422
7704
|
const previous = releases?.current;
|
|
@@ -7864,6 +8146,422 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
|
7864
8146
|
return results;
|
|
7865
8147
|
}
|
|
7866
8148
|
//#endregion
|
|
8149
|
+
//#region src/compose/dns.ts
|
|
8150
|
+
/**
|
|
8151
|
+
* A compose stage's DNS: the records its public hosts need, and the check that
|
|
8152
|
+
* they resolve to its server before a certificate is asked for.
|
|
8153
|
+
*
|
|
8154
|
+
* - **The server** (`serverAddress`): the stage's own secrets hold its public
|
|
8155
|
+
* addresses — `GKM_SERVER_IPV4`, and `GKM_SERVER_IPV6` where it has one.
|
|
8156
|
+
* Reserved for gkm: never handed to an app.
|
|
8157
|
+
* - **The plan** (`planStackDns`, pure): every public host the stack serves —
|
|
8158
|
+
* its apex, each app, each file server, the public log UI — pointed at the
|
|
8159
|
+
* server. An A record per host (and an AAAA with an IPv6 address), or, where
|
|
8160
|
+
* the domain's `dns` entry says `records: { mode: 'cname', target }`, one A
|
|
8161
|
+
* record for the target and a CNAME to it for every other host but the
|
|
8162
|
+
* apex, which DNS forbids a CNAME at.
|
|
8163
|
+
* - **Applying it** (`applyStackDns`): through the domain's provider in `dns`,
|
|
8164
|
+
* a record set at a time. A record with the right value is left alone; one
|
|
8165
|
+
* with another value is replaced and the change printed. A `manual` domain
|
|
8166
|
+
* is printed and nothing else. A dry run reads, prints and writes nothing.
|
|
8167
|
+
* - **The check** (`checkStackDns`): each host resolved with the system
|
|
8168
|
+
* resolver. One that is not the server stops the deploy with
|
|
8169
|
+
* {@link HostNotPointingAtServer}, before Caddy or Traefik ask Let's Encrypt
|
|
8170
|
+
* for a certificate it cannot get — and use up the rate limit trying.
|
|
8171
|
+
*/
|
|
8172
|
+
/** The line that says how to set the server's address. */
|
|
8173
|
+
function serverAddressHint(stage) {
|
|
8174
|
+
return `gkm secrets:set ${SERVER_IPV4_KEY} '<ip>' --stage ${stage}`;
|
|
8175
|
+
}
|
|
8176
|
+
/** A server address in the stage's secrets that is not an address. */
|
|
8177
|
+
var ServerAddressInvalid = class extends GkmError {
|
|
8178
|
+
stage;
|
|
8179
|
+
key;
|
|
8180
|
+
value;
|
|
8181
|
+
constructor(stage, key, value) {
|
|
8182
|
+
const ipv4 = key === SERVER_IPV4_KEY;
|
|
8183
|
+
super(`${key} in the '${stage}' stage's secrets is ${JSON.stringify(value)}, which is not an ${ipv4 ? "IPv4 address (like 203.0.113.10)" : "IPv6 address (like 2001:db8::10)"}. Set the server's public address: gkm secrets:set ${key} '<ip>' --stage ${stage}.`);
|
|
8184
|
+
this.stage = stage;
|
|
8185
|
+
this.key = key;
|
|
8186
|
+
this.value = value;
|
|
8187
|
+
this.name = "ServerAddressInvalid";
|
|
8188
|
+
}
|
|
8189
|
+
};
|
|
8190
|
+
/**
|
|
8191
|
+
* A compose stage that serves real domains with no server address: its hosts
|
|
8192
|
+
* cannot be pointed or checked, and a certificate would be asked for blind.
|
|
8193
|
+
*/
|
|
8194
|
+
var ServerAddressMissing = class extends GkmError {
|
|
8195
|
+
stage;
|
|
8196
|
+
domain;
|
|
8197
|
+
constructor(stage, domain) {
|
|
8198
|
+
super(`The '${stage}' stage serves ${domain} and its secrets hold no ${SERVER_IPV4_KEY} — the public address of the server its stack runs on, which its hosts' DNS records point at and every deploy checks before asking for certificates. Set it: ${serverAddressHint(stage)} (and ${SERVER_IPV6_KEY} for an IPv6 address).`);
|
|
8199
|
+
this.stage = stage;
|
|
8200
|
+
this.domain = domain;
|
|
8201
|
+
this.name = "ServerAddressMissing";
|
|
8202
|
+
}
|
|
8203
|
+
};
|
|
8204
|
+
/**
|
|
8205
|
+
* The server's address from the stage's secrets, checked — `undefined` when
|
|
8206
|
+
* `GKM_SERVER_IPV4` is not set.
|
|
8207
|
+
*
|
|
8208
|
+
* @throws {ServerAddressInvalid} for a value that is not an address
|
|
8209
|
+
*/
|
|
8210
|
+
function serverAddress(stage, custom) {
|
|
8211
|
+
const ipv4 = custom?.[SERVER_IPV4_KEY]?.trim();
|
|
8212
|
+
const ipv6 = custom?.[SERVER_IPV6_KEY]?.trim();
|
|
8213
|
+
if (ipv6 && !isIPv6(ipv6)) throw new ServerAddressInvalid(stage, SERVER_IPV6_KEY, ipv6);
|
|
8214
|
+
if (!ipv4) return void 0;
|
|
8215
|
+
if (!isIPv4(ipv4)) throw new ServerAddressInvalid(stage, SERVER_IPV4_KEY, ipv4);
|
|
8216
|
+
return {
|
|
8217
|
+
ipv4,
|
|
8218
|
+
...ipv6 ? { ipv6 } : {}
|
|
8219
|
+
};
|
|
8220
|
+
}
|
|
8221
|
+
/**
|
|
8222
|
+
* A name that resolves to this machine by definition — `localhost` and every
|
|
8223
|
+
* `*.localhost` — and is in nobody's DNS.
|
|
8224
|
+
*/
|
|
8225
|
+
function isLocalHost(host) {
|
|
8226
|
+
const name = host.toLowerCase().replace(/\.$/, "");
|
|
8227
|
+
return name === "localhost" || name.endsWith(".localhost");
|
|
8228
|
+
}
|
|
8229
|
+
/**
|
|
8230
|
+
* The server's address, required where the stage serves real domains — not
|
|
8231
|
+
* `*.localhost` ones, which point at this machine already.
|
|
8232
|
+
*
|
|
8233
|
+
* @throws {ServerAddressMissing} when the stage has a domain and no address
|
|
8234
|
+
* @throws {ServerAddressInvalid} for a value that is not an address
|
|
8235
|
+
*/
|
|
8236
|
+
function requiredServerAddress(stage, domain, custom) {
|
|
8237
|
+
const server = serverAddress(stage, custom);
|
|
8238
|
+
if (!server && domain && !isLocalHost(domain)) throw new ServerAddressMissing(stage, domain);
|
|
8239
|
+
return server;
|
|
8240
|
+
}
|
|
8241
|
+
const MANAGED = [
|
|
8242
|
+
"A",
|
|
8243
|
+
"AAAA",
|
|
8244
|
+
"CNAME"
|
|
8245
|
+
];
|
|
8246
|
+
/** Every public host the stack serves, once each, sorted. */
|
|
8247
|
+
function stackHosts(stack) {
|
|
8248
|
+
return [...new Set(stack.routes.map((route) => route.host))].sort();
|
|
8249
|
+
}
|
|
8250
|
+
/** The TTL a domain's records are written with. */
|
|
8251
|
+
function recordTtl(config) {
|
|
8252
|
+
const ttl = "ttl" in config ? config.ttl : void 0;
|
|
8253
|
+
if (ttl) return ttl;
|
|
8254
|
+
return config.provider === "godaddy" ? 600 : 300;
|
|
8255
|
+
}
|
|
8256
|
+
function providerName(config) {
|
|
8257
|
+
return typeof config.provider === "string" ? config.provider : "custom";
|
|
8258
|
+
}
|
|
8259
|
+
/** The records a stage's hosts need — pure. */
|
|
8260
|
+
function planStackDns(input) {
|
|
8261
|
+
const { stage, server } = input;
|
|
8262
|
+
const dns = input.dns ? normalizeDnsConfig(input.dns) : {};
|
|
8263
|
+
const records = /* @__PURE__ */ new Map();
|
|
8264
|
+
const uncovered = [];
|
|
8265
|
+
const add = (host, domain, type, value) => {
|
|
8266
|
+
const name = extractSubdomain(host, domain);
|
|
8267
|
+
records.set(`${domain} ${name} ${type}`, {
|
|
8268
|
+
host,
|
|
8269
|
+
domain,
|
|
8270
|
+
name,
|
|
8271
|
+
type,
|
|
8272
|
+
value,
|
|
8273
|
+
ttl: recordTtl(dns[domain])
|
|
8274
|
+
});
|
|
8275
|
+
};
|
|
8276
|
+
const pointAt = (host, domain) => {
|
|
8277
|
+
add(host, domain, "A", server.ipv4);
|
|
8278
|
+
if (server.ipv6) add(host, domain, "AAAA", server.ipv6);
|
|
8279
|
+
};
|
|
8280
|
+
for (const raw of input.hosts) {
|
|
8281
|
+
const host = raw.toLowerCase();
|
|
8282
|
+
const domain = findRootDomain(host, dns);
|
|
8283
|
+
if (!domain) {
|
|
8284
|
+
uncovered.push(host);
|
|
8285
|
+
continue;
|
|
8286
|
+
}
|
|
8287
|
+
const target = cnameTarget(dns[domain].records, stage);
|
|
8288
|
+
if (target) pointAt(target, domain);
|
|
8289
|
+
if (target && host !== domain && host !== target) add(host, domain, "CNAME", target);
|
|
8290
|
+
else pointAt(host, domain);
|
|
8291
|
+
}
|
|
8292
|
+
const domains = /* @__PURE__ */ new Map();
|
|
8293
|
+
for (const record of [...records.values()].sort((a, b) => a.domain.localeCompare(b.domain) || a.name.localeCompare(b.name) || a.type.localeCompare(b.type))) {
|
|
8294
|
+
const config = dns[record.domain];
|
|
8295
|
+
const plan = domains.get(record.domain) ?? {
|
|
8296
|
+
domain: record.domain,
|
|
8297
|
+
provider: providerName(config),
|
|
8298
|
+
config,
|
|
8299
|
+
records: []
|
|
8300
|
+
};
|
|
8301
|
+
plan.records.push(record);
|
|
8302
|
+
domains.set(record.domain, plan);
|
|
8303
|
+
}
|
|
8304
|
+
return {
|
|
8305
|
+
stage,
|
|
8306
|
+
server,
|
|
8307
|
+
domains: [...domains.values()],
|
|
8308
|
+
uncovered: uncovered.sort()
|
|
8309
|
+
};
|
|
8310
|
+
}
|
|
8311
|
+
/** `api.example.com A 203.0.113.10 (TTL 600)` */
|
|
8312
|
+
function describe(record) {
|
|
8313
|
+
return `${record.host.padEnd(32)} ${record.type.padEnd(5)} ${record.value} (TTL ${record.ttl})`;
|
|
8314
|
+
}
|
|
8315
|
+
function printManual(plan, log, why) {
|
|
8316
|
+
log(` ${plan.domain}: ${why} — create these records at its DNS host:`);
|
|
8317
|
+
for (const record of plan.records) log(` ${describe(record)}`);
|
|
8318
|
+
return plan.records.map((r) => ({
|
|
8319
|
+
domain: r.domain,
|
|
8320
|
+
name: r.name,
|
|
8321
|
+
type: r.type,
|
|
8322
|
+
action: "manual",
|
|
8323
|
+
value: r.value,
|
|
8324
|
+
ttl: r.ttl
|
|
8325
|
+
}));
|
|
8326
|
+
}
|
|
8327
|
+
/** The existing records of every planned name, for the types gkm manages. */
|
|
8328
|
+
async function existingRecords(provider, plan) {
|
|
8329
|
+
const names = [...new Set(plan.records.map((r) => r.name))];
|
|
8330
|
+
const wanted = names.flatMap((name) => MANAGED.map((type) => ({
|
|
8331
|
+
name,
|
|
8332
|
+
type
|
|
8333
|
+
})));
|
|
8334
|
+
if (provider.readRecords) return provider.readRecords(plan.domain, wanted);
|
|
8335
|
+
return (await provider.getRecords(plan.domain)).filter((r) => names.includes(r.name) && MANAGED.includes(r.type));
|
|
8336
|
+
}
|
|
8337
|
+
const same = (a, b) => a.trim().replace(/\.$/, "").toLowerCase() === b.trim().replace(/\.$/, "").toLowerCase();
|
|
8338
|
+
/**
|
|
8339
|
+
* What each domain's records need, compared with what is there: creates,
|
|
8340
|
+
* updates, and the deletes a change of mode needs — a name moving from an A
|
|
8341
|
+
* record to a CNAME, or back, cannot hold both. Nothing else is deleted.
|
|
8342
|
+
*/
|
|
8343
|
+
function diffDomainDns(plan, existing) {
|
|
8344
|
+
const changes = [];
|
|
8345
|
+
const find = (name, type) => existing.find((r) => r.name === name && r.type === type);
|
|
8346
|
+
const planned = /* @__PURE__ */ new Map();
|
|
8347
|
+
for (const record of plan.records) {
|
|
8348
|
+
const types = planned.get(record.name) ?? /* @__PURE__ */ new Set();
|
|
8349
|
+
types.add(record.type);
|
|
8350
|
+
planned.set(record.name, types);
|
|
8351
|
+
}
|
|
8352
|
+
for (const [name, types] of planned) {
|
|
8353
|
+
const conflicting = types.has("CNAME") ? ["A", "AAAA"] : ["CNAME"];
|
|
8354
|
+
for (const type of conflicting) {
|
|
8355
|
+
const found = find(name, type);
|
|
8356
|
+
if (!found || found.values.length === 0) continue;
|
|
8357
|
+
changes.push({
|
|
8358
|
+
domain: plan.domain,
|
|
8359
|
+
name,
|
|
8360
|
+
type,
|
|
8361
|
+
action: "delete",
|
|
8362
|
+
previous: found.values.join(", ")
|
|
8363
|
+
});
|
|
8364
|
+
}
|
|
8365
|
+
}
|
|
8366
|
+
for (const record of plan.records) {
|
|
8367
|
+
const found = find(record.name, record.type);
|
|
8368
|
+
const base = {
|
|
8369
|
+
domain: plan.domain,
|
|
8370
|
+
name: record.name,
|
|
8371
|
+
type: record.type,
|
|
8372
|
+
value: record.value,
|
|
8373
|
+
ttl: record.ttl
|
|
8374
|
+
};
|
|
8375
|
+
if (!found || found.values.length === 0) changes.push({
|
|
8376
|
+
...base,
|
|
8377
|
+
action: "create"
|
|
8378
|
+
});
|
|
8379
|
+
else if (found.values.length === 1 && same(found.values[0], record.value)) changes.push({
|
|
8380
|
+
...base,
|
|
8381
|
+
action: "unchanged"
|
|
8382
|
+
});
|
|
8383
|
+
else changes.push({
|
|
8384
|
+
...base,
|
|
8385
|
+
action: "update",
|
|
8386
|
+
previous: found.values.join(", ")
|
|
8387
|
+
});
|
|
8388
|
+
}
|
|
8389
|
+
return changes;
|
|
8390
|
+
}
|
|
8391
|
+
/** A host's full name from a domain and a relative name. */
|
|
8392
|
+
function fullName(domain, name) {
|
|
8393
|
+
return name === "@" ? domain : `${name}.${domain}`;
|
|
8394
|
+
}
|
|
8395
|
+
function printChange(change, dryRun, log) {
|
|
8396
|
+
const host = fullName(change.domain, change.name).padEnd(32);
|
|
8397
|
+
const type = change.type.padEnd(5);
|
|
8398
|
+
const would = dryRun ? "would " : "";
|
|
8399
|
+
switch (change.action) {
|
|
8400
|
+
case "unchanged":
|
|
8401
|
+
log(` ✓ ${host} ${type} ${change.value} (TTL ${change.ttl}) — up to date`);
|
|
8402
|
+
break;
|
|
8403
|
+
case "create":
|
|
8404
|
+
log(` + ${host} ${type} ${change.value} (TTL ${change.ttl}) — ${would}create`);
|
|
8405
|
+
break;
|
|
8406
|
+
case "update":
|
|
8407
|
+
log(` ~ ${host} ${type} ${change.previous} → ${change.value} (TTL ${change.ttl}) — ${would}update`);
|
|
8408
|
+
break;
|
|
8409
|
+
case "write":
|
|
8410
|
+
log(dryRun ? ` ? ${host} ${type} ${change.value} (TTL ${change.ttl}) — would write; current value unknown (key cannot read DNS)` : ` ! ${host} ${type} ${change.value} (TTL ${change.ttl}) — written (not diffed)`);
|
|
8411
|
+
break;
|
|
8412
|
+
case "delete": log(` - ${host} ${type} ${change.previous} — ${would}delete (a name cannot hold a CNAME and an A record)`);
|
|
8413
|
+
}
|
|
8414
|
+
}
|
|
8415
|
+
/**
|
|
8416
|
+
* Each domain's records, through its provider. Returns every change, the
|
|
8417
|
+
* unchanged included; a dry run makes none of them.
|
|
8418
|
+
*/
|
|
8419
|
+
async function applyStackDns(plan, options = {}) {
|
|
8420
|
+
const dryRun = options.dryRun === true;
|
|
8421
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
8422
|
+
const providerFor = options.providerFor ?? ((config) => createDnsProvider({
|
|
8423
|
+
config,
|
|
8424
|
+
...options.credentials ? { godaddy: options.credentials } : {}
|
|
8425
|
+
}));
|
|
8426
|
+
const changes = [];
|
|
8427
|
+
for (const host of plan.uncovered) log(` ⚠ ${host} is under no domain in dns — point it at ${plan.server.ipv4} yourself`);
|
|
8428
|
+
for (const domain of plan.domains) {
|
|
8429
|
+
if (domain.provider === "manual") {
|
|
8430
|
+
changes.push(...printManual(domain, log, "manual"));
|
|
8431
|
+
continue;
|
|
8432
|
+
}
|
|
8433
|
+
const provider = await providerFor(domain.config);
|
|
8434
|
+
if (!provider) {
|
|
8435
|
+
changes.push(...printManual(domain, log, "manual"));
|
|
8436
|
+
continue;
|
|
8437
|
+
}
|
|
8438
|
+
log(` ${domain.domain} (${provider.name})${dryRun ? " — dry run" : ""}`);
|
|
8439
|
+
let existing;
|
|
8440
|
+
let diff;
|
|
8441
|
+
try {
|
|
8442
|
+
existing = await existingRecords(provider, domain);
|
|
8443
|
+
diff = diffDomainDns(domain, existing);
|
|
8444
|
+
} catch (error) {
|
|
8445
|
+
if (!(error instanceof DnsRecordsUnreadable)) throw error;
|
|
8446
|
+
log(` ℹ The ${provider.name} key cannot read ${domain.domain}'s DNS records, so changes cannot be diffed: every record is written (idempotent).`);
|
|
8447
|
+
existing = [];
|
|
8448
|
+
diff = domain.records.map((r) => ({
|
|
8449
|
+
domain: r.domain,
|
|
8450
|
+
name: r.name,
|
|
8451
|
+
type: r.type,
|
|
8452
|
+
action: "write",
|
|
8453
|
+
value: r.value,
|
|
8454
|
+
ttl: r.ttl
|
|
8455
|
+
}));
|
|
8456
|
+
}
|
|
8457
|
+
for (const change of diff) printChange(change, dryRun, log);
|
|
8458
|
+
if (!plan.server.ipv6) for (const name of new Set(domain.records.map((r) => r.name))) {
|
|
8459
|
+
const aaaa = existing.find((r) => r.name === name && r.type === "AAAA");
|
|
8460
|
+
const planned = domain.records.find((r) => r.name === name && r.type === "A");
|
|
8461
|
+
if (aaaa && planned && aaaa.values.length > 0) log(` ⚠ ${fullName(domain.domain, name)} also has AAAA ${aaaa.values.join(", ")}: set ${SERVER_IPV6_KEY} in the '${plan.stage}' stage's secrets to the server's IPv6 address, or remove that record, or IPv6 clients go elsewhere`);
|
|
8462
|
+
}
|
|
8463
|
+
changes.push(...diff);
|
|
8464
|
+
if (dryRun) continue;
|
|
8465
|
+
const deletes = diff.filter((c) => c.action === "delete");
|
|
8466
|
+
if (deletes.length > 0) await provider.deleteRecords(domain.domain, deletes.map((c) => ({
|
|
8467
|
+
name: c.name,
|
|
8468
|
+
type: c.type
|
|
8469
|
+
})));
|
|
8470
|
+
const writes = diff.filter((c) => c.action === "create" || c.action === "update" || c.action === "write");
|
|
8471
|
+
if (writes.length > 0) await provider.upsertRecords(domain.domain, writes.map((c) => ({
|
|
8472
|
+
name: c.name,
|
|
8473
|
+
type: c.type,
|
|
8474
|
+
value: c.value,
|
|
8475
|
+
ttl: c.ttl
|
|
8476
|
+
})));
|
|
8477
|
+
}
|
|
8478
|
+
return changes;
|
|
8479
|
+
}
|
|
8480
|
+
/** The system resolver: what the server's own clients would be told. */
|
|
8481
|
+
const systemLookup = async (host) => {
|
|
8482
|
+
return (await lookup(host, { all: true })).map((a) => a.address);
|
|
8483
|
+
};
|
|
8484
|
+
/** Hosts that do not resolve to the stage's server. */
|
|
8485
|
+
var HostNotPointingAtServer = class extends GkmError {
|
|
8486
|
+
stage;
|
|
8487
|
+
hosts;
|
|
8488
|
+
expected;
|
|
8489
|
+
fix;
|
|
8490
|
+
constructor(stage, hosts, expected, fix) {
|
|
8491
|
+
const want = expected.ipv6 ? `${expected.ipv4} (and ${expected.ipv6})` : expected.ipv4;
|
|
8492
|
+
const lines = hosts.map((h) => ` - ${h.host} → ${h.resolved.length > 0 ? h.resolved.join(", ") : `nothing${h.error ? ` (${h.error})` : ""}`}, expected ${want}`);
|
|
8493
|
+
super(`${hosts.length === 1 ? "A host" : `${hosts.length} hosts`} of '${stage}' do${hosts.length === 1 ? "es" : ""} not resolve to its server, so a certificate for ${hosts.length === 1 ? "it" : "them"} cannot be issued:\n${lines.join("\n")}\n${fix}\nRecords can take a few minutes to propagate. With a CDN or proxy in front of the server, pass --skip-dns-check.`);
|
|
8494
|
+
this.stage = stage;
|
|
8495
|
+
this.hosts = hosts;
|
|
8496
|
+
this.expected = expected;
|
|
8497
|
+
this.fix = fix;
|
|
8498
|
+
this.name = "HostNotPointingAtServer";
|
|
8499
|
+
}
|
|
8500
|
+
};
|
|
8501
|
+
/**
|
|
8502
|
+
* Every host resolved: each must resolve to the server's IPv4 address and to
|
|
8503
|
+
* nothing but the server's addresses.
|
|
8504
|
+
*
|
|
8505
|
+
* @throws {HostNotPointingAtServer} naming every host that does not
|
|
8506
|
+
*/
|
|
8507
|
+
async function checkStackDns(input) {
|
|
8508
|
+
const lookup = input.lookup ?? systemLookup;
|
|
8509
|
+
const { server } = input;
|
|
8510
|
+
const ours = new Set([server.ipv4, server.ipv6].filter(Boolean).map((a) => a.toLowerCase()));
|
|
8511
|
+
const bad = [];
|
|
8512
|
+
const ok = [];
|
|
8513
|
+
for (const host of input.hosts) {
|
|
8514
|
+
let resolved;
|
|
8515
|
+
try {
|
|
8516
|
+
resolved = [...new Set(await lookup(host))];
|
|
8517
|
+
} catch (error) {
|
|
8518
|
+
const code = error && typeof error === "object" && "code" in error ? String(error.code) : error instanceof Error ? error.message : String(error);
|
|
8519
|
+
bad.push({
|
|
8520
|
+
host,
|
|
8521
|
+
resolved: [],
|
|
8522
|
+
error: code
|
|
8523
|
+
});
|
|
8524
|
+
continue;
|
|
8525
|
+
}
|
|
8526
|
+
if (resolved.some((a) => a.toLowerCase() === server.ipv4.toLowerCase()) && resolved.every((a) => ours.has(a.toLowerCase()))) ok.push(host);
|
|
8527
|
+
else bad.push({
|
|
8528
|
+
host,
|
|
8529
|
+
resolved
|
|
8530
|
+
});
|
|
8531
|
+
}
|
|
8532
|
+
if (bad.length > 0) throw new HostNotPointingAtServer(input.stage, bad, {
|
|
8533
|
+
ipv4: server.ipv4,
|
|
8534
|
+
...server.ipv6 ? { ipv6: server.ipv6 } : {}
|
|
8535
|
+
}, dnsFix(input, bad));
|
|
8536
|
+
return ok;
|
|
8537
|
+
}
|
|
8538
|
+
/** How to fix it: `gkm setup`, or the records to create by hand. */
|
|
8539
|
+
function dnsFix(input, bad) {
|
|
8540
|
+
const hosts = bad.map((h) => h.host);
|
|
8541
|
+
let plan;
|
|
8542
|
+
try {
|
|
8543
|
+
plan = planStackDns({
|
|
8544
|
+
stage: input.stage,
|
|
8545
|
+
hosts,
|
|
8546
|
+
server: input.server,
|
|
8547
|
+
dns: input.dns
|
|
8548
|
+
});
|
|
8549
|
+
} catch {
|
|
8550
|
+
plan = {
|
|
8551
|
+
stage: input.stage,
|
|
8552
|
+
server: input.server,
|
|
8553
|
+
domains: [],
|
|
8554
|
+
uncovered: hosts
|
|
8555
|
+
};
|
|
8556
|
+
}
|
|
8557
|
+
const automatic = plan.domains.filter((d) => d.provider !== "manual");
|
|
8558
|
+
const byHand = [...plan.domains.filter((d) => d.provider === "manual").flatMap((d) => d.records.map(describe)), ...plan.uncovered.flatMap((host) => [`${host.padEnd(32)} A ${input.server.ipv4}`, ...input.server.ipv6 ? [`${host.padEnd(32)} AAAA ${input.server.ipv6}`] : []])];
|
|
8559
|
+
const lines = [];
|
|
8560
|
+
if (automatic.length > 0) lines.push(`Fix: gkm setup --stage ${input.stage} writes the records for ${automatic.map((d) => d.domain).join(", ")} (gkm setup --stage ${input.stage} --dry-run shows them first).`);
|
|
8561
|
+
if (byHand.length > 0) lines.push(`${automatic.length > 0 ? "And create" : "Fix: create"} these records at the DNS host:`, ...byHand.map((line) => ` ${line}`));
|
|
8562
|
+
return lines.join("\n");
|
|
8563
|
+
}
|
|
8564
|
+
//#endregion
|
|
7867
8565
|
//#region src/docker/imageRef.ts
|
|
7868
8566
|
/**
|
|
7869
8567
|
* An image reference, checked before it reaches `docker`.
|
|
@@ -7882,7 +8580,7 @@ const REFERENCE = new RegExp(`^(?:${DOMAIN}/)?${PATH_COMPONENT}(?:/${PATH_COMPON
|
|
|
7882
8580
|
/** Docker refuses a repository name longer than this. */
|
|
7883
8581
|
const MAX_NAME_LENGTH = 255;
|
|
7884
8582
|
/** A value that is not an image reference was about to be built or pushed. */
|
|
7885
|
-
var ImageRefInvalid = class extends
|
|
8583
|
+
var ImageRefInvalid = class extends GkmError {
|
|
7886
8584
|
ref;
|
|
7887
8585
|
constructor(ref) {
|
|
7888
8586
|
super(`'${ref}' is not a valid image reference. An image is \`[registry/]name[:tag]\`: the name lowercase letters, digits and . _ - separators, the tag up to 128 of letters, digits, _ . and -, not starting with . or -. Check docker.registry in gkm.config.ts and the --tag passed.`);
|
|
@@ -7918,7 +8616,7 @@ var DockerPushFailed = class extends Error {
|
|
|
7918
8616
|
}
|
|
7919
8617
|
};
|
|
7920
8618
|
/** `gkm docker --push` was asked for with nowhere to push to. */
|
|
7921
|
-
var PushNeedsRegistry = class extends
|
|
8619
|
+
var PushNeedsRegistry = class extends GkmError {
|
|
7922
8620
|
imageName;
|
|
7923
8621
|
constructor(imageName) {
|
|
7924
8622
|
super(`Registry is required to push Docker image '${imageName}'. Use --registry or configure docker.registry in gkm.config.ts`);
|
|
@@ -8185,7 +8883,7 @@ function constructsOf$1(manifest, kind) {
|
|
|
8185
8883
|
return Object.entries(manifest).filter(([, d]) => d.kind === kind).map(([id]) => id).sort();
|
|
8186
8884
|
}
|
|
8187
8885
|
/** A stage that names `false` for a kind, and declares constructs of it. */
|
|
8188
|
-
var StageProviderDisabled = class extends
|
|
8886
|
+
var StageProviderDisabled = class extends GkmError {
|
|
8189
8887
|
kind;
|
|
8190
8888
|
stage;
|
|
8191
8889
|
ids;
|
|
@@ -8256,14 +8954,9 @@ var DeployJournal = class DeployJournal {
|
|
|
8256
8954
|
this.version = version;
|
|
8257
8955
|
this.existed = existed;
|
|
8258
8956
|
}
|
|
8259
|
-
|
|
8260
|
-
* The stage's journal — its stored state, or `initial` written as the
|
|
8261
|
-
* stage's first state, so there is somewhere to record the very first
|
|
8262
|
-
* resource before it is created.
|
|
8263
|
-
*/
|
|
8264
|
-
static async open(store, stage, initial) {
|
|
8957
|
+
static async open(store, stage, initial, adopt = (stored) => stored) {
|
|
8265
8958
|
const stored = await store.read(stage);
|
|
8266
|
-
if (stored) return new DeployJournal(store, stage, stored.state, stored.resources, stored.version, true);
|
|
8959
|
+
if (stored) return new DeployJournal(store, stage, adopt(stored.state), stored.resources, stored.version, true);
|
|
8267
8960
|
const state = initial();
|
|
8268
8961
|
const version = await store.write(stage, state, { expectedVersion: null });
|
|
8269
8962
|
return new DeployJournal(store, stage, state, {}, version, false);
|
|
@@ -8282,10 +8975,13 @@ var DeployJournal = class DeployJournal {
|
|
|
8282
8975
|
status: "pending"
|
|
8283
8976
|
});
|
|
8284
8977
|
}
|
|
8285
|
-
/**
|
|
8978
|
+
/**
|
|
8979
|
+
* Records `entry` as existing with `id`; a no-op if it already is, with
|
|
8980
|
+
* the same data.
|
|
8981
|
+
*/
|
|
8286
8982
|
async ready(entry, id) {
|
|
8287
8983
|
const current = this.resources[entry.key];
|
|
8288
|
-
if (current?.status === "ready" && current.id === id) return;
|
|
8984
|
+
if (current?.status === "ready" && current.id === id && JSON.stringify(current.data) === JSON.stringify(entry.data)) return;
|
|
8289
8985
|
await this.put({
|
|
8290
8986
|
...entry,
|
|
8291
8987
|
status: "ready",
|
|
@@ -8330,6 +9026,17 @@ var DeployJournal = class DeployJournal {
|
|
|
8330
9026
|
...staleId ? { staleId } : {}
|
|
8331
9027
|
};
|
|
8332
9028
|
}
|
|
9029
|
+
/** Removes `key`'s record — a resource that no longer exists. */
|
|
9030
|
+
async forget(key) {
|
|
9031
|
+
if (!(key in this.resources)) return;
|
|
9032
|
+
this.version = await this.store.deleteResource(this.stage, key, { expectedVersion: this.version });
|
|
9033
|
+
const { [key]: _removed, ...resources } = this.resources;
|
|
9034
|
+
this.resources = resources;
|
|
9035
|
+
}
|
|
9036
|
+
/** Every record, as the journal last wrote or read it. */
|
|
9037
|
+
records() {
|
|
9038
|
+
return this.resources;
|
|
9039
|
+
}
|
|
8333
9040
|
/** Writes the stage's state, keeping its resource records. */
|
|
8334
9041
|
async save() {
|
|
8335
9042
|
this.state.lastDeployedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -8347,6 +9054,138 @@ var DeployJournal = class DeployJournal {
|
|
|
8347
9054
|
}
|
|
8348
9055
|
};
|
|
8349
9056
|
//#endregion
|
|
9057
|
+
//#region src/providers/dns.ts
|
|
9058
|
+
/** Whether the workspace deploys through the compose target. */
|
|
9059
|
+
function deploysWithCompose(workspace) {
|
|
9060
|
+
return workspace.deploy?.default === "compose" || Object.values(workspace.apps).some((app) => app.resolvedDeployTarget === "compose");
|
|
9061
|
+
}
|
|
9062
|
+
/**
|
|
9063
|
+
* A compose stage that serves a domain has its server's address in its
|
|
9064
|
+
* secrets — checked before `gkm setup --stage` does anything else.
|
|
9065
|
+
*
|
|
9066
|
+
* @throws {ServerAddressMissing} for a compose stage with a domain and none
|
|
9067
|
+
* @throws {ServerAddressInvalid} for a value that is not an address
|
|
9068
|
+
*/
|
|
9069
|
+
function assertStageServer(workspace, stage, secrets) {
|
|
9070
|
+
if (stage === workspace.stages.local) return void 0;
|
|
9071
|
+
if (!deploysWithCompose(workspace)) return serverAddress(stage, secrets?.custom);
|
|
9072
|
+
return requiredServerAddress(stage, workspace.domains?.[stage], secrets?.custom);
|
|
9073
|
+
}
|
|
9074
|
+
/**
|
|
9075
|
+
* The hosts a compose stage serves: its stack composed as a deploy would —
|
|
9076
|
+
* with the secrets it would generate made up in memory, never written — and
|
|
9077
|
+
* every route's host read off it.
|
|
9078
|
+
*/
|
|
9079
|
+
async function composeStageHosts(options) {
|
|
9080
|
+
const { workspace, stage } = options;
|
|
9081
|
+
const runnables = options.runnables ?? {};
|
|
9082
|
+
const background = options.background ?? {};
|
|
9083
|
+
const manifest = options.manifest ?? await discover({
|
|
9084
|
+
patterns: constructGlobs(workspace),
|
|
9085
|
+
cwd: workspace.root,
|
|
9086
|
+
runnables,
|
|
9087
|
+
background
|
|
9088
|
+
});
|
|
9089
|
+
const stored = await (await secretsStoreFor(workspace, stage, {
|
|
9090
|
+
...options.profile ? { profile: options.profile } : {},
|
|
9091
|
+
...options.home ? { home: options.home } : {}
|
|
9092
|
+
})).read(stage);
|
|
9093
|
+
const { deployedStackSecrets } = await import("./secrets-DbPmAS4k.mjs").then((n) => n.n);
|
|
9094
|
+
const { composeStack } = await import("./stack-Co4uZkAo.mjs").then((n) => n.c);
|
|
9095
|
+
const { secrets } = deployedStackSecrets(workspace, stage, stored, manifest);
|
|
9096
|
+
return stackHosts(composeStack({
|
|
9097
|
+
workspace,
|
|
9098
|
+
manifest,
|
|
9099
|
+
runnables,
|
|
9100
|
+
background,
|
|
9101
|
+
stage,
|
|
9102
|
+
identity: deployIdentity(workspace, stage),
|
|
9103
|
+
images: {
|
|
9104
|
+
mode: "pull",
|
|
9105
|
+
tag: "dns",
|
|
9106
|
+
...workspace.deploy?.registry ? { registry: workspace.deploy.registry } : {}
|
|
9107
|
+
},
|
|
9108
|
+
secrets,
|
|
9109
|
+
buildOnly: true,
|
|
9110
|
+
allowDevServices: true
|
|
9111
|
+
}));
|
|
9112
|
+
}
|
|
9113
|
+
/**
|
|
9114
|
+
* `GKM_SERVER_IPV4` from the stage's secrets and `dns`: each public host's
|
|
9115
|
+
* records, created or corrected. A dry run reads and prints, and writes
|
|
9116
|
+
* nothing.
|
|
9117
|
+
*/
|
|
9118
|
+
async function provisionStageDns(options) {
|
|
9119
|
+
const { workspace, stage } = options;
|
|
9120
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
9121
|
+
if (stage === workspace.stages.local || !workspace.dns || !deploysWithCompose(workspace)) return {
|
|
9122
|
+
mode: "none",
|
|
9123
|
+
hosts: [],
|
|
9124
|
+
changes: []
|
|
9125
|
+
};
|
|
9126
|
+
const server = serverAddress(stage, (await (await secretsStoreFor(workspace, stage, {
|
|
9127
|
+
...options.profile ? { profile: options.profile } : {},
|
|
9128
|
+
...options.home ? { home: options.home } : {}
|
|
9129
|
+
})).read(stage))?.custom);
|
|
9130
|
+
if (!server) {
|
|
9131
|
+
log(`\n🌐 DNS for '${stage}': no GKM_SERVER_IPV4 in its secrets, so no records — ${serverAddressHint(stage)}`);
|
|
9132
|
+
return {
|
|
9133
|
+
mode: "none",
|
|
9134
|
+
hosts: [],
|
|
9135
|
+
changes: []
|
|
9136
|
+
};
|
|
9137
|
+
}
|
|
9138
|
+
const hosts = [...options.hosts ?? await composeStageHosts({
|
|
9139
|
+
workspace,
|
|
9140
|
+
stage,
|
|
9141
|
+
...options.profile ? { profile: options.profile } : {},
|
|
9142
|
+
...options.home ? { home: options.home } : {},
|
|
9143
|
+
...options.manifest ? { manifest: options.manifest } : {},
|
|
9144
|
+
...options.runnables ? { runnables: options.runnables } : {},
|
|
9145
|
+
...options.background ? { background: options.background } : {}
|
|
9146
|
+
})];
|
|
9147
|
+
log(`\n🌐 DNS for '${stage}' → ${server.ipv4}${server.ipv6 ? ` / ${server.ipv6}` : ""}${options.dryRun ? " (dry run — nothing is written)" : ""}`);
|
|
9148
|
+
const plan = planStackDns({
|
|
9149
|
+
stage,
|
|
9150
|
+
hosts,
|
|
9151
|
+
server,
|
|
9152
|
+
dns: workspace.dns
|
|
9153
|
+
});
|
|
9154
|
+
try {
|
|
9155
|
+
const changes = await applyStackDns(plan, {
|
|
9156
|
+
...options.dryRun ? { dryRun: true } : {},
|
|
9157
|
+
log,
|
|
9158
|
+
credentials: {
|
|
9159
|
+
env: options.env ?? process.env,
|
|
9160
|
+
...options.home ? { home: options.home } : {},
|
|
9161
|
+
log
|
|
9162
|
+
},
|
|
9163
|
+
...options.providerFor ? { providerFor: options.providerFor } : {}
|
|
9164
|
+
});
|
|
9165
|
+
if (options.journal && !options.dryRun) {
|
|
9166
|
+
const providers = new Map(plan.domains.map((domain) => [domain.domain, domain.provider]));
|
|
9167
|
+
await recordDnsChanges(options.journal, changes, (domain) => providers.get(domain));
|
|
9168
|
+
}
|
|
9169
|
+
return {
|
|
9170
|
+
mode: "records",
|
|
9171
|
+
hosts,
|
|
9172
|
+
changes
|
|
9173
|
+
};
|
|
9174
|
+
} catch (error) {
|
|
9175
|
+
if (error instanceof MissingCredential) {
|
|
9176
|
+
log(` ⚠ ${error.message}`);
|
|
9177
|
+
log(" Until then, create these records yourself:");
|
|
9178
|
+
for (const domain of plan.domains) for (const r of domain.records) log(` ${r.host.padEnd(32)} ${r.type.padEnd(5)} ${r.value} (TTL ${r.ttl})`);
|
|
9179
|
+
return {
|
|
9180
|
+
mode: "records",
|
|
9181
|
+
hosts,
|
|
9182
|
+
changes: []
|
|
9183
|
+
};
|
|
9184
|
+
}
|
|
9185
|
+
throw error;
|
|
9186
|
+
}
|
|
9187
|
+
}
|
|
9188
|
+
//#endregion
|
|
8350
9189
|
//#region src/providers/aws.ts
|
|
8351
9190
|
/**
|
|
8352
9191
|
* The AWS account a provider provisions in — the stage's, found the way the
|
|
@@ -8421,7 +9260,7 @@ async function awsClientConfig(credential, region) {
|
|
|
8421
9260
|
}
|
|
8422
9261
|
const SUFFIX_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
8423
9262
|
/** A name that S3 would refuse — what the name builder never returns. */
|
|
8424
|
-
var InvalidBucketName = class extends
|
|
9263
|
+
var InvalidBucketName = class extends GkmError {
|
|
8425
9264
|
bucket;
|
|
8426
9265
|
reason;
|
|
8427
9266
|
constructor(bucket, reason) {
|
|
@@ -9318,7 +10157,7 @@ async function provisionStage(options) {
|
|
|
9318
10157
|
});
|
|
9319
10158
|
const lock = dryRun ? void 0 : await stateStore.lock(stage, { operation: "provision" });
|
|
9320
10159
|
try {
|
|
9321
|
-
const state = dryRun ? await readOnlyState(stateStore, stage) : journalState(await DeployJournal.open(stateStore, stage, () => createEmptyState(stage, "", "")));
|
|
10160
|
+
const state = dryRun ? await readOnlyState(stateStore, stage) : journalState(await DeployJournal.open(stateStore, stage, () => deploysWithCompose(workspace) ? createComposeState(stage) : createEmptyState(stage, "", "")));
|
|
9322
10161
|
const writeSecrets = async (values) => {
|
|
9323
10162
|
if (dryRun) return;
|
|
9324
10163
|
const stored = await secretsStore.read(stage) ?? initStageSecrets(stage);
|
|
@@ -9423,7 +10262,7 @@ const LOOPBACK = /* @__PURE__ */ new Set([
|
|
|
9423
10262
|
* `localhost` — what an older `gkm secrets:init`, `gkm setup` or `gkm init`
|
|
9424
10263
|
* generated. Set by hand wins over derived, so the app would be handed it.
|
|
9425
10264
|
*/
|
|
9426
|
-
var StaleStageSecrets = class extends
|
|
10265
|
+
var StaleStageSecrets = class extends GkmError {
|
|
9427
10266
|
stage;
|
|
9428
10267
|
stale;
|
|
9429
10268
|
constructor(stage, stale) {
|
|
@@ -9533,6 +10372,6 @@ function reportPlannedSeeds(planned, log) {
|
|
|
9533
10372
|
for (const { folder, seeds } of planned) log(`🌱 ${folder}: would run ${seeds.length} (${seeds.join(", ")})`);
|
|
9534
10373
|
}
|
|
9535
10374
|
//#endregion
|
|
9536
|
-
export {
|
|
10375
|
+
export { contentVersion as $, projectKey as $n, bucketClient as $t, orchestrateDns as A, telemetryOf as An, workspace_exports as At, setBackupState as B, findAvailablePort as Bn, stackRedis as Bt, HostNotPointingAtServer as C, planFor as Cn, QueueGenerator as Ct, serverAddressHint as D, isTelemetryKey as Dn, constructGlobs as Dt, requiredServerAddress as E, appTelemetry as En, backendsOf as Et, getBackupState as F, portKeys as Fn, withGeneratedSecrets as Ft, LocalStateInCi as G, prepareEntryCredentials as Gn, applyPolicies as Gt, setPostgresBackupId as H, loadEnvFiles as Hn, LOCAL_CA_PATH as Ht, getGeneratedSecret as I, portsOf as In, REDIS_SERVICE as It, StateStoreBusy as J, storeFromConfig as Jn, postgresDatabaseNames as Jt, StageStateMissing as K, isRemoteStore as Kn, applyPostgres as Kt, recordRelease as L, primaryPortKey as Ln, STACK_CACHE as Lt, asDokployState as M, DEFAULT_IMAGES as Mn, loadLocalCredentials as Mt, createComposeState as N, describeServices as Nn, postgresSuperuser as Nt, stackHosts as O, scopeTelemetryEnv as On, derivedContainers as Ot, createEmptyState as P, fakeKey as Pn, readLocalCredentials as Pt, assertStateOutlivesRun as Q, keystoreProject as Qn, ensurePostgresLogin as Qt, recordRollback as R, createCredentialsPreload as Rn, redisService as Rt, validateImageRef as S, TELEMETRY_CONTAINER as Sn, resolveHost as Sr, workerEntryDir as St, isLocalHost as T, hostFor as Tn, FAKE_ENV as Tt, DnsRecordsUnreadable as U, loadPortState as Un, forgetState as Ut, setGeneratedSecret as V, isPortAvailable as Vn, withRedisPassword as Vt, DocumentStateStore as W, loadSecretsForApp as Wn, applyBuckets as Wt, StateVersionConflict as X, FileSecretsStore as Xn, quoteIdentifier as Xt, StateStoreWithoutLocking as Y, store_exports as Yn, postgresStatements as Yt, appendHistory as Z, getKeyPath as Zn, LEGACY_LOCAL_LOGIN as Zt, appDockerfile as _, providerOf as _n, logsService as _r, requiredStageKeys as _t, provisionStage as a, envFor as an, isOwnedBy as ar, describeActor as at, workerDockerfile as b, composeFor as bn, NoDomainForStage as br, WorkerGenerator as bt, deploysWithCompose as c, imageLayout as cn, projectName as cr, DevServicesNeedServerTarget as ct, StageProviderDisabled as d, detectPackageManager as dn, storage_exports as dr, assertDevServicesFlag as dt, pgClient as en, readKey as er, createStateStore as et, assertStageProvidersEnabled as f, findBuildRoot as fn, toEmbeddableSecrets as fr, assertExternalServices as ft, DockerPushFailed as g, eventsBackendFor as gn, logsAccess as gr, reportDevServices as gt, DockerBuildFailed as h, cacheBackendFor as hn, LOGS_SERVICE as hr, manifestServiceDeclarations as ht, assertNoStaleSecrets as i, workerEnvKeys as in, imageRef as ir, currentActor as it, verifyDnsRecords as j, usesTelemetry as jn, LOCAL_RABBITMQ_USER as jt, systemLookup as k, surfaceClientTraced as kn, reconcileWorkspace as kt, provisionStageDns as l, TURBO_VERSION as ln, initStageSecrets as lr, ExternalServicesNotConfigured as lt, stageProviderNotes as m, isImageBuild as mn, LOCAL_LOGS_EMAIL as mr, externalServices as mt, reportDatabaseRuns as n, dockerfileOf as nn, deployIdentity as nr, upgradeV2State as nt, verifyStageProviders as o, localRolePassword as on, markerOf as or, AllowDevServicesTakesNoValue as ot, provisionCommand as p, imageBuildCredentials as pn, withCustomSecret as pr, devServicesUsed as pt, StateLocked as q, secretsStoreFor as qn, bucketPolicies as qt, reportPlannedSeeds as r, networkEnv as rn, imageName as rr, dnsResources as rt, assertStageServer as s, composeBuildPaths as sn, ownershipMarker as sr, DEV_SERVICES as st, DeploySeedsFailed as t, appEnvKeys as tn, applicationName as tr, newLockHolder as tt, DeployJournal as u, WORKER_PORT as un, maskPassword as ur, STORAGE_KEY_PAIR as ut, dockerCommand as v, storageBackendFor as vn, stackLogs as vr, suppliedOnly as vt, checkStackDns as w, resourceName as wn, CronGenerator as wt, workerDockerfileOf as x, EMULATOR_ACCESS_KEY_ID as xn, isMainFrontendApp as xr, workerBundleName as xt, ensureDockerignore as y, CLUSTER_DATABASE as yn, withLogsPassword as yr, workerUnits as yt, setApplicationId as z, createEntryWrapper as zn, runsRedis as zt };
|
|
9537
10376
|
|
|
9538
|
-
//# sourceMappingURL=seeds-
|
|
10377
|
+
//# sourceMappingURL=seeds-BSL55F6q.mjs.map
|