@geekmidas/cli 10.0.0-alpha.9 → 10.0.0-alpha.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +315 -414
- package/bin/adjacent-tsconfig.mjs +46 -8
- package/bin/gkm.mjs +11 -3
- package/bin/owning-tsconfig-jsx-register.mjs +18 -0
- package/bin/owning-tsconfig-jsx.mjs +108 -0
- package/dist/EndpointGenerator-CVc6Oi1Y.mjs +1021 -0
- package/dist/EndpointGenerator-CVc6Oi1Y.mjs.map +1 -0
- package/dist/EndpointGenerator-CwLjBCFE.cjs +1080 -0
- package/dist/EndpointGenerator-CwLjBCFE.cjs.map +1 -0
- package/dist/GoDaddyProvider-DSStJVAv.mjs +387 -0
- package/dist/GoDaddyProvider-DSStJVAv.mjs.map +1 -0
- package/dist/GoDaddyProvider-DqZ1qD_F.cjs +387 -0
- package/dist/GoDaddyProvider-DqZ1qD_F.cjs.map +1 -0
- package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-BI6J7oJr.mjs} +22 -23
- package/dist/HostingerProvider-BI6J7oJr.mjs.map +1 -0
- package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-CyTpG_jy.cjs} +22 -23
- package/dist/HostingerProvider-CyTpG_jy.cjs.map +1 -0
- package/dist/LegacyStateStore-DXmNA7hy.cjs +89 -0
- package/dist/LegacyStateStore-DXmNA7hy.cjs.map +1 -0
- package/dist/LegacyStateStore-ZkdmiUFZ.mjs +89 -0
- package/dist/LegacyStateStore-ZkdmiUFZ.mjs.map +1 -0
- package/dist/LocalStateStore-BBeTlRTH.cjs +178 -0
- package/dist/LocalStateStore-BBeTlRTH.cjs.map +1 -0
- package/dist/LocalStateStore-CU-O0SBp.mjs +167 -0
- package/dist/LocalStateStore-CU-O0SBp.mjs.map +1 -0
- package/dist/OpenApiTsGenerator-B--HV-sW.cjs +541 -0
- package/dist/OpenApiTsGenerator-B--HV-sW.cjs.map +1 -0
- package/dist/OpenApiTsGenerator-CkvsPdgg.mjs +536 -0
- package/dist/OpenApiTsGenerator-CkvsPdgg.mjs.map +1 -0
- package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-Bllus2NR.cjs} +21 -22
- package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
- package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-QXxjkZO1.mjs} +13 -13
- package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
- package/dist/S3StateStore-Br8VMY22.cjs +160 -0
- package/dist/S3StateStore-Br8VMY22.cjs.map +1 -0
- package/dist/S3StateStore-bwxcI_wQ.mjs +161 -0
- package/dist/S3StateStore-bwxcI_wQ.mjs.map +1 -0
- package/dist/SSMStateStore-CsOS0W1y.mjs +154 -0
- package/dist/SSMStateStore-CsOS0W1y.mjs.map +1 -0
- package/dist/SSMStateStore-DoZE1Wi1.cjs +153 -0
- package/dist/SSMStateStore-DoZE1Wi1.cjs.map +1 -0
- package/dist/SubscriberGenerator-BPqQf8fB.mjs +448 -0
- package/dist/SubscriberGenerator-BPqQf8fB.mjs.map +1 -0
- package/dist/SubscriberGenerator-BVn7cQ-2.cjs +489 -0
- package/dist/SubscriberGenerator-BVn7cQ-2.cjs.map +1 -0
- package/dist/add-CNMF0Q3m.cjs +594 -0
- package/dist/add-CNMF0Q3m.cjs.map +1 -0
- package/dist/add-DHk1roh_.mjs +592 -0
- package/dist/add-DHk1roh_.mjs.map +1 -0
- package/dist/appPorts-C9z9Pzn9.mjs +223 -0
- package/dist/appPorts-C9z9Pzn9.mjs.map +1 -0
- package/dist/appPorts-Cu79hJF6.cjs +264 -0
- package/dist/appPorts-Cu79hJF6.cjs.map +1 -0
- package/dist/aws-B-6uEhgP.mjs +71 -0
- package/dist/aws-B-6uEhgP.mjs.map +1 -0
- package/dist/aws-BTawF0F-.cjs +82 -0
- package/dist/aws-BTawF0F-.cjs.map +1 -0
- package/dist/awsStore-7VmS_cZR.cjs +54 -0
- package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
- package/dist/awsStore-B529csle.mjs +43 -0
- package/dist/awsStore-B529csle.mjs.map +1 -0
- package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-C8DnCmxK.mjs} +11 -8
- package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
- package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-oDEsPj02.cjs} +22 -20
- package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
- package/dist/{bundler-BY1OmV1e.cjs → bundler-BQJiB7Ub.cjs} +38 -35
- package/dist/bundler-BQJiB7Ub.cjs.map +1 -0
- package/dist/{bundler-Be8Zg4Wd.mjs → bundler-D6eBfVkl.mjs} +36 -32
- package/dist/bundler-D6eBfVkl.mjs.map +1 -0
- package/dist/cli-BE9mqeX8.cjs +69 -0
- package/dist/cli-BE9mqeX8.cjs.map +1 -0
- package/dist/cli-DD-Yk-I5.mjs +69 -0
- package/dist/cli-DD-Yk-I5.mjs.map +1 -0
- package/dist/compose-Bhmf0n4o.mjs +3140 -0
- package/dist/compose-Bhmf0n4o.mjs.map +1 -0
- package/dist/compose-CvpU6ooi.cjs +3265 -0
- package/dist/compose-CvpU6ooi.cjs.map +1 -0
- package/dist/config-CdEcTrjG.d.mts +269 -0
- package/dist/config-CdEcTrjG.d.mts.map +1 -0
- package/dist/config-pST7E0CS.d.cts +269 -0
- package/dist/config-pST7E0CS.d.cts.map +1 -0
- package/dist/config.cjs +420 -11
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +4 -120
- package/dist/config.d.mts +4 -120
- package/dist/config.mjs +404 -4
- package/dist/config.mjs.map +1 -0
- package/dist/credentialSchemas-BJqRJNK4.mjs +236 -0
- package/dist/credentialSchemas-BJqRJNK4.mjs.map +1 -0
- package/dist/credentialSchemas-DCR4Wd1W.cjs +271 -0
- package/dist/credentialSchemas-DCR4Wd1W.cjs.map +1 -0
- package/dist/credentials-BKfIugu2.cjs +513 -0
- package/dist/credentials-BKfIugu2.cjs.map +1 -0
- package/dist/credentials-CnVqoXMb.mjs +388 -0
- package/dist/credentials-CnVqoXMb.mjs.map +1 -0
- package/dist/databases-BY-pEImp.cjs +597 -0
- package/dist/databases-BY-pEImp.cjs.map +1 -0
- package/dist/databases-CzszQV0N.mjs +494 -0
- package/dist/databases-CzszQV0N.mjs.map +1 -0
- package/dist/define-DR8xGYfL.mjs +97 -0
- package/dist/define-DR8xGYfL.mjs.map +1 -0
- package/dist/define-DzRz8FgH.cjs +144 -0
- package/dist/define-DzRz8FgH.cjs.map +1 -0
- package/dist/deploy/public.cjs +208 -0
- package/dist/deploy/public.cjs.map +1 -0
- package/dist/deploy/public.d.cts +649 -0
- package/dist/deploy/public.d.cts.map +1 -0
- package/dist/deploy/public.d.mts +649 -0
- package/dist/deploy/public.d.mts.map +1 -0
- package/dist/deploy/public.mjs +142 -0
- package/dist/deploy/public.mjs.map +1 -0
- package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
- package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
- package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
- package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
- package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
- package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
- package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
- package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
- package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
- package/dist/deploy/sniffer-hooks.cjs +13 -7
- package/dist/deploy/sniffer-hooks.cjs.map +1 -1
- package/dist/deploy/sniffer-hooks.d.cts +1 -2
- package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
- package/dist/deploy/sniffer-hooks.d.mts +1 -2
- package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
- package/dist/deploy/sniffer-hooks.mjs +10 -3
- package/dist/deploy/sniffer-hooks.mjs.map +1 -1
- package/dist/deploy/sniffer-loader.cjs +16 -7
- package/dist/deploy/sniffer-loader.cjs.map +1 -1
- package/dist/deploy/sniffer-loader.d.cts +1 -1
- package/dist/deploy/sniffer-loader.d.mts +1 -1
- package/dist/deploy/sniffer-loader.mjs +14 -3
- package/dist/deploy/sniffer-loader.mjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.cjs +11 -11
- package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
- package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
- package/dist/deploy/sniffer-routes-worker.mjs +4 -4
- package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
- package/dist/deploy/sniffer-worker.cjs +15 -6
- package/dist/deploy/sniffer-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-worker.d.cts +1 -3
- package/dist/deploy/sniffer-worker.d.cts.map +1 -1
- package/dist/deploy/sniffer-worker.d.mts +1 -3
- package/dist/deploy/sniffer-worker.d.mts.map +1 -1
- package/dist/deploy/sniffer-worker.mjs +15 -4
- package/dist/deploy/sniffer-worker.mjs.map +1 -1
- package/dist/deploy-CuHasEA4.cjs +554 -0
- package/dist/deploy-CuHasEA4.cjs.map +1 -0
- package/dist/deploy-QNtx_eWR.mjs +525 -0
- package/dist/deploy-QNtx_eWR.mjs.map +1 -0
- package/dist/derive-B4vDpzgP.mjs +150 -0
- package/dist/derive-B4vDpzgP.mjs.map +1 -0
- package/dist/derive-DAbo49sm.cjs +161 -0
- package/dist/derive-DAbo49sm.cjs.map +1 -0
- package/dist/discover-BPelzeGW.mjs +526 -0
- package/dist/discover-BPelzeGW.mjs.map +1 -0
- package/dist/discover-CU0paUyH.d.cts +108 -0
- package/dist/discover-CU0paUyH.d.cts.map +1 -0
- package/dist/discover-D1It5r_h.cjs +599 -0
- package/dist/discover-D1It5r_h.cjs.map +1 -0
- package/dist/discover-DFiJxwfv.d.mts +108 -0
- package/dist/discover-DFiJxwfv.d.mts.map +1 -0
- package/dist/dokploy-CYcMLh9-.mjs +38 -0
- package/dist/dokploy-CYcMLh9-.mjs.map +1 -0
- package/dist/dokploy-DIowwyIB.cjs +38 -0
- package/dist/dokploy-DIowwyIB.cjs.map +1 -0
- package/dist/drivers-DTZzxeIl.mjs +177 -0
- package/dist/drivers-DTZzxeIl.mjs.map +1 -0
- package/dist/drivers-LYSdQDmd.cjs +200 -0
- package/dist/drivers-LYSdQDmd.cjs.map +1 -0
- package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
- package/dist/emit-C1e8qD08.mjs.map +1 -0
- package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
- package/dist/emit-Dmc1nvdS.cjs.map +1 -0
- package/dist/encryption-BrEef7Jk.mjs +88 -0
- package/dist/encryption-BrEef7Jk.mjs.map +1 -0
- package/dist/encryption-CjYdUb2s.cjs +89 -0
- package/dist/encryption-CjYdUb2s.cjs.map +1 -0
- package/dist/engine-2h4k5ICq.mjs +3085 -0
- package/dist/engine-2h4k5ICq.mjs.map +1 -0
- package/dist/engine-BhJ7ZP9K.cjs +3198 -0
- package/dist/engine-BhJ7ZP9K.cjs.map +1 -0
- package/dist/github-B5Bw4HIu.cjs +669 -0
- package/dist/github-B5Bw4HIu.cjs.map +1 -0
- package/dist/github-BCDF6xVH.mjs +669 -0
- package/dist/github-BCDF6xVH.mjs.map +1 -0
- package/dist/{index-C6e-ULLx.d.mts → index-D-F_hTDz.d.cts} +39 -24
- package/dist/index-D-F_hTDz.d.cts.map +1 -0
- package/dist/{index-CR5urhWX.d.cts → index-YFNxR5Ns.d.mts} +39 -24
- package/dist/index-YFNxR5Ns.d.mts.map +1 -0
- package/dist/index.cjs +9487 -12080
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +9420 -12026
- package/dist/index.mjs.map +1 -1
- package/dist/local-BjxDfPvy.cjs +241 -0
- package/dist/local-BjxDfPvy.cjs.map +1 -0
- package/dist/local-IuoIF3CT.mjs +224 -0
- package/dist/local-IuoIF3CT.mjs.map +1 -0
- package/dist/migrate-CGaancHY.cjs +93 -0
- package/dist/migrate-CGaancHY.cjs.map +1 -0
- package/dist/migrate-DWZz9kah.mjs +93 -0
- package/dist/migrate-DWZz9kah.mjs.map +1 -0
- package/dist/migrate-DbtcuOr_.mjs +265 -0
- package/dist/migrate-DbtcuOr_.mjs.map +1 -0
- package/dist/migrate-q2YYLJLE.cjs +270 -0
- package/dist/migrate-q2YYLJLE.cjs.map +1 -0
- package/dist/openapi.cjs +214 -10
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +47 -17
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +47 -17
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +208 -5
- package/dist/openapi.mjs.map +1 -0
- package/dist/provider-C9_-45d5.cjs +56 -0
- package/dist/provider-C9_-45d5.cjs.map +1 -0
- package/dist/provider-q4lsYzYG.mjs +45 -0
- package/dist/provider-q4lsYzYG.mjs.map +1 -0
- package/dist/ready-BpNbORRB.cjs +402 -0
- package/dist/ready-BpNbORRB.cjs.map +1 -0
- package/dist/ready-b6vm0-W-.mjs +373 -0
- package/dist/ready-b6vm0-W-.mjs.map +1 -0
- package/dist/reconcile/public.cjs +3 -5
- package/dist/reconcile/public.d.cts +11 -87
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +11 -87
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +3 -4
- package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
- package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
- package/dist/{reconcile-CFs8C_1a.mjs → reconcile-Dh1Jk7WE.mjs} +4 -7
- package/dist/reconcile-Dh1Jk7WE.mjs.map +1 -0
- package/dist/resolve-Cns0v6dN.cjs +315 -0
- package/dist/resolve-Cns0v6dN.cjs.map +1 -0
- package/dist/resolve-DNg0icnh.mjs +262 -0
- package/dist/resolve-DNg0icnh.mjs.map +1 -0
- package/dist/rollback-CFrNLmxs.mjs +132 -0
- package/dist/rollback-CFrNLmxs.mjs.map +1 -0
- package/dist/rollback-UIjS25F1.cjs +161 -0
- package/dist/rollback-UIjS25F1.cjs.map +1 -0
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
- package/dist/runtime-CN_kmqxo.d.cts +90 -0
- package/dist/runtime-CN_kmqxo.d.cts.map +1 -0
- package/dist/runtime-Cjvon3oj.d.mts +90 -0
- package/dist/runtime-Cjvon3oj.d.mts.map +1 -0
- package/dist/sandbox/config-worker.cjs +43 -0
- package/dist/sandbox/config-worker.cjs.map +1 -0
- package/dist/sandbox/config-worker.d.cts +1 -0
- package/dist/sandbox/config-worker.d.mts +1 -0
- package/dist/sandbox/config-worker.mjs +44 -0
- package/dist/sandbox/config-worker.mjs.map +1 -0
- package/dist/sandbox/credentials-worker.cjs +54 -0
- package/dist/sandbox/credentials-worker.cjs.map +1 -0
- package/dist/sandbox/credentials-worker.d.cts +1 -0
- package/dist/sandbox/credentials-worker.d.mts +1 -0
- package/dist/sandbox/credentials-worker.mjs +55 -0
- package/dist/sandbox/credentials-worker.mjs.map +1 -0
- package/dist/sandbox/discover-worker.cjs +47 -0
- package/dist/sandbox/discover-worker.cjs.map +1 -0
- package/dist/sandbox/discover-worker.d.cts +1 -0
- package/dist/sandbox/discover-worker.d.mts +1 -0
- package/dist/sandbox/discover-worker.mjs +48 -0
- package/dist/sandbox/discover-worker.mjs.map +1 -0
- package/dist/sandbox/migrate-worker.cjs +75 -0
- package/dist/sandbox/migrate-worker.cjs.map +1 -0
- package/dist/sandbox/migrate-worker.d.cts +1 -0
- package/dist/sandbox/migrate-worker.d.mts +1 -0
- package/dist/sandbox/migrate-worker.mjs +76 -0
- package/dist/sandbox/migrate-worker.mjs.map +1 -0
- package/dist/sandbox-CL--ZDui.cjs +164 -0
- package/dist/sandbox-CL--ZDui.cjs.map +1 -0
- package/dist/sandbox-Dm247NGx.mjs +117 -0
- package/dist/sandbox-Dm247NGx.mjs.map +1 -0
- package/dist/sandbox-M8UnLhXE.d.cts +126 -0
- package/dist/sandbox-M8UnLhXE.d.cts.map +1 -0
- package/dist/sandbox-M8UnLhXE.d.mts +126 -0
- package/dist/sandbox-M8UnLhXE.d.mts.map +1 -0
- package/dist/{workspace-zoqRbihZ.mjs → schemas-BObwxB_t.cjs} +998 -1659
- package/dist/schemas-BObwxB_t.cjs.map +1 -0
- package/dist/{workspace-C6VJQVtG.cjs → schemas-D-xeKJDD.mjs} +913 -1842
- package/dist/schemas-D-xeKJDD.mjs.map +1 -0
- package/dist/secretsManager-Chs9VV2r.mjs +76 -0
- package/dist/secretsManager-Chs9VV2r.mjs.map +1 -0
- package/dist/secretsManager-DcMlHnRC.cjs +87 -0
- package/dist/secretsManager-DcMlHnRC.cjs.map +1 -0
- package/dist/seeds-CkIPFGNO.cjs +10560 -0
- package/dist/seeds-CkIPFGNO.cjs.map +1 -0
- package/dist/seeds-odfgSCmu.mjs +9538 -0
- package/dist/seeds-odfgSCmu.mjs.map +1 -0
- package/dist/sniffer-BTtX3NUM.mjs +1262 -0
- package/dist/sniffer-BTtX3NUM.mjs.map +1 -0
- package/dist/sniffer-IAQEpsQb.cjs +1333 -0
- package/dist/sniffer-IAQEpsQb.cjs.map +1 -0
- package/dist/sst-BgcOsaBi.cjs +453 -0
- package/dist/sst-BgcOsaBi.cjs.map +1 -0
- package/dist/sst-CJzvyrEz.mjs +430 -0
- package/dist/sst-CJzvyrEz.mjs.map +1 -0
- package/dist/stages-CUn6gvXL.cjs +174 -0
- package/dist/stages-CUn6gvXL.cjs.map +1 -0
- package/dist/stages-CnZRYmkI.mjs +174 -0
- package/dist/stages-CnZRYmkI.mjs.map +1 -0
- package/dist/target/public.cjs +15 -0
- package/dist/target/public.d.cts +28 -0
- package/dist/target/public.d.cts.map +1 -0
- package/dist/target/public.d.mts +28 -0
- package/dist/target/public.d.mts.map +1 -0
- package/dist/target/public.mjs +4 -0
- package/dist/terminal-D8TPK7o9.mjs +84 -0
- package/dist/terminal-D8TPK7o9.mjs.map +1 -0
- package/dist/terminal-DuapRxh6.cjs +84 -0
- package/dist/terminal-DuapRxh6.cjs.map +1 -0
- package/dist/types-NqX1Hz4P.d.cts +7454 -0
- package/dist/types-NqX1Hz4P.d.cts.map +1 -0
- package/dist/types-ZHuZ89hv.d.mts +7453 -0
- package/dist/types-ZHuZ89hv.d.mts.map +1 -0
- package/dist/utils-D2Nk1Nv2.cjs +205 -0
- package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
- package/dist/utils-D_fxUqvU.mjs +156 -0
- package/dist/utils-D_fxUqvU.mjs.map +1 -0
- package/dist/vitest.cjs +65 -0
- package/dist/vitest.cjs.map +1 -0
- package/dist/vitest.d.cts +29 -0
- package/dist/vitest.d.cts.map +1 -0
- package/dist/vitest.d.mts +29 -0
- package/dist/vitest.d.mts.map +1 -0
- package/dist/vitest.mjs +65 -0
- package/dist/vitest.mjs.map +1 -0
- package/dist/workerRuntime-BXfhbe13.cjs +108 -0
- package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
- package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
- package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
- package/dist/workspace/index.cjs +8 -4
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +2 -3
- package/dist/workspace-CJ0lKFq-.mjs +1979 -0
- package/dist/workspace-CJ0lKFq-.mjs.map +1 -0
- package/dist/workspace-CwW3Gkru.cjs +2355 -0
- package/dist/workspace-CwW3Gkru.cjs.map +1 -0
- package/package.json +53 -22
- package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
- package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
- package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
- package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
- package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
- package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
- package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
- package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
- package/dist/LocalStateProvider-Bn6tS-oL.mjs +0 -42
- package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
- package/dist/LocalStateProvider-Db9SEjyH.cjs +0 -43
- package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
- package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
- package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
- package/dist/SSMStateProvider-BRt2py-A.mjs +0 -66
- package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
- package/dist/SSMStateProvider-DyX8s9HI.cjs +0 -66
- package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
- package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
- package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
- package/dist/bundler-BY1OmV1e.cjs.map +0 -1
- package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
- package/dist/chunk-Duj1WY3L.mjs +0 -7
- package/dist/config-BZ1F0WuA.cjs +0 -462
- package/dist/config-BZ1F0WuA.cjs.map +0 -1
- package/dist/config-DVVph9yz.mjs +0 -402
- package/dist/config-DVVph9yz.mjs.map +0 -1
- package/dist/config.d.cts.map +0 -1
- package/dist/config.d.mts.map +0 -1
- package/dist/credentials-B5zRHdAl.mjs +0 -141
- package/dist/credentials-B5zRHdAl.mjs.map +0 -1
- package/dist/credentials-BapzjyV5.cjs +0 -195
- package/dist/credentials-BapzjyV5.cjs.map +0 -1
- package/dist/credentials-Xamqe_NJ.cjs +0 -2681
- package/dist/credentials-Xamqe_NJ.cjs.map +0 -1
- package/dist/credentials-dP8vRVRv.mjs +0 -2549
- package/dist/credentials-dP8vRVRv.mjs.map +0 -1
- package/dist/discover-CAlFgYec.mjs +0 -229
- package/dist/discover-CAlFgYec.mjs.map +0 -1
- package/dist/discover-DTmFeloL.cjs +0 -271
- package/dist/discover-DTmFeloL.cjs.map +0 -1
- package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
- package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
- package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
- package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
- package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
- package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
- package/dist/emit-CbcRolsa.cjs.map +0 -1
- package/dist/emit-CiZS_5Ub.mjs.map +0 -1
- package/dist/encryption-C6jaU0hE.cjs +0 -54
- package/dist/encryption-C6jaU0hE.cjs.map +0 -1
- package/dist/encryption-CHzzeR8a.cjs +0 -4
- package/dist/encryption-CQUncu7v.mjs +0 -3
- package/dist/encryption-D-abyhZx.mjs +0 -42
- package/dist/encryption-D-abyhZx.mjs.map +0 -1
- package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
- package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
- package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
- package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
- package/dist/generator-CNzBw7g5.cjs +0 -289
- package/dist/generator-CNzBw7g5.cjs.map +0 -1
- package/dist/generator-VE2JrFlY.mjs +0 -253
- package/dist/generator-VE2JrFlY.mjs.map +0 -1
- package/dist/index-C6e-ULLx.d.mts.map +0 -1
- package/dist/index-CR5urhWX.d.cts.map +0 -1
- package/dist/openapi-SjsgARie.cjs +0 -2075
- package/dist/openapi-SjsgARie.cjs.map +0 -1
- package/dist/openapi-Xx0A7Wg0.mjs +0 -2021
- package/dist/openapi-Xx0A7Wg0.mjs.map +0 -1
- package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
- package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
- package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
- package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
- package/dist/openapi-react-query.cjs +0 -4
- package/dist/openapi-react-query.d.cts +0 -11
- package/dist/openapi-react-query.d.cts.map +0 -1
- package/dist/openapi-react-query.d.mts +0 -11
- package/dist/openapi-react-query.d.mts.map +0 -1
- package/dist/openapi-react-query.mjs +0 -4
- package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
- package/dist/reconcile-D0pimNiy.cjs.map +0 -1
- package/dist/setup-BA8ciTPU.mjs +0 -11
- package/dist/setup-BsZvZP6f.cjs +0 -11
- package/dist/setup-C8KOx8_8.mjs +0 -443
- package/dist/setup-C8KOx8_8.mjs.map +0 -1
- package/dist/setup-hC6hI86f.cjs +0 -473
- package/dist/setup-hC6hI86f.cjs.map +0 -1
- package/dist/storage-BJmzYxt8.cjs +0 -363
- package/dist/storage-BJmzYxt8.cjs.map +0 -1
- package/dist/storage-BM9hGpgv.cjs +0 -7
- package/dist/storage-Bi24WfoW.mjs +0 -297
- package/dist/storage-Bi24WfoW.mjs.map +0 -1
- package/dist/storage-CYlGwWTj.mjs +0 -3
- package/dist/sync-CmEuNZsB.mjs +0 -76
- package/dist/sync-CmEuNZsB.mjs.map +0 -1
- package/dist/sync-D306yOWu.cjs +0 -4
- package/dist/sync-SizaChmC.cjs +0 -93
- package/dist/sync-SizaChmC.cjs.map +0 -1
- package/dist/sync-hOqAWHR6.mjs +0 -3
- package/dist/types-6pkp2RRj.d.mts +0 -2220
- package/dist/types-6pkp2RRj.d.mts.map +0 -1
- package/dist/types-Y3fKQSAK.d.cts +0 -2220
- package/dist/types-Y3fKQSAK.d.cts.map +0 -1
- package/dist/workspace-BzrG_2SI.mjs +0 -8
- package/dist/workspace-C6VJQVtG.cjs.map +0 -1
- package/dist/workspace-XXtNhqJl.cjs +0 -9
- package/dist/workspace-zoqRbihZ.mjs.map +0 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
+
import { i as CommandFailed, t as MissingCredential } from "./credentials-CnVqoXMb.mjs";
|
|
3
|
+
import { i as activeSandbox } from "./sandbox-Dm247NGx.mjs";
|
|
4
|
+
import { t as appKey } from "./derive-B4vDpzgP.mjs";
|
|
5
|
+
import { t as defineTarget } from "./define-DR8xGYfL.mjs";
|
|
6
|
+
import { t as LocalSandbox } from "./local-IuoIF3CT.mjs";
|
|
7
|
+
import { n as detectPackageManager } from "./utils-D_fxUqvU.mjs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { readFile, rm } from "node:fs/promises";
|
|
11
|
+
import { kebabCase } from "@geekmidas/manifest";
|
|
12
|
+
//#region src/target/sst/health.ts
|
|
13
|
+
/** Surfaces that never answered healthy. */
|
|
14
|
+
var SurfacesUnhealthy = class extends Error {
|
|
15
|
+
stage;
|
|
16
|
+
surfaces;
|
|
17
|
+
constructor(stage, surfaces) {
|
|
18
|
+
const lines = surfaces.map(({ app, url, status, error }) => ` - ${app}: ${url} → ${status ?? error ?? "no answer"}`);
|
|
19
|
+
super(`The "${stage}" stage was deployed, but ${surfaces.length === 1 ? "a surface does" : "surfaces do"} not answer healthy:\n${lines.join("\n")}\nCheck its logs in CloudWatch, fix it, and deploy again.`);
|
|
20
|
+
this.stage = stage;
|
|
21
|
+
this.surfaces = surfaces;
|
|
22
|
+
this.name = "SurfacesUnhealthy";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/** `path` under `base`, keeping any path `base` already has. */
|
|
26
|
+
function healthUrl(base, path) {
|
|
27
|
+
const root = base.endsWith("/") ? base : `${base}/`;
|
|
28
|
+
return new URL(path.replace(/^\//, ""), root).toString();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Ask `url` until it answers 2xx or the attempts run out, emitting
|
|
32
|
+
* `health.checked` for each. Resolves with the last answer.
|
|
33
|
+
*/
|
|
34
|
+
async function checkHealth(app, url, options) {
|
|
35
|
+
let last = { healthy: false };
|
|
36
|
+
for (let attempt = 1; attempt <= options.attempts; attempt++) {
|
|
37
|
+
options.signal.throwIfAborted();
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch(url, {
|
|
40
|
+
redirect: "follow",
|
|
41
|
+
signal: AbortSignal.any([options.signal, AbortSignal.timeout(options.timeoutMs)])
|
|
42
|
+
});
|
|
43
|
+
await response.arrayBuffer().catch(() => void 0);
|
|
44
|
+
last = {
|
|
45
|
+
healthy: response.ok,
|
|
46
|
+
status: response.status
|
|
47
|
+
};
|
|
48
|
+
} catch (error) {
|
|
49
|
+
options.signal.throwIfAborted();
|
|
50
|
+
last = {
|
|
51
|
+
healthy: false,
|
|
52
|
+
error: error instanceof Error ? error.message : String(error)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
options.emit({
|
|
56
|
+
type: "health.checked",
|
|
57
|
+
app,
|
|
58
|
+
url,
|
|
59
|
+
healthy: last.healthy,
|
|
60
|
+
...last.status !== void 0 ? { status: last.status } : {},
|
|
61
|
+
attempt
|
|
62
|
+
});
|
|
63
|
+
if (last.healthy) return last;
|
|
64
|
+
if (attempt < options.attempts) await wait(options.delayMs, options.signal);
|
|
65
|
+
}
|
|
66
|
+
return last;
|
|
67
|
+
}
|
|
68
|
+
function wait(ms, signal) {
|
|
69
|
+
if (ms <= 0) return Promise.resolve();
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
const timer = setTimeout(() => {
|
|
72
|
+
signal.removeEventListener("abort", stop);
|
|
73
|
+
resolve();
|
|
74
|
+
}, ms);
|
|
75
|
+
const stop = () => {
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
reject(signal.reason);
|
|
78
|
+
};
|
|
79
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/target/sst/outputs.ts
|
|
84
|
+
/**
|
|
85
|
+
* The surface URLs an `sst deploy` reports.
|
|
86
|
+
*
|
|
87
|
+
* SST writes whatever `run()` in `sst.config.ts` returns to
|
|
88
|
+
* `.sst/outputs.json` after every successful deploy — `{"Api": "https://…"}`.
|
|
89
|
+
* What `run()` returns is the project's to write, so this reads it leniently:
|
|
90
|
+
* nested objects are walked, anything that is not an http(s) URL is ignored,
|
|
91
|
+
* and an output names a surface by its id in any casing, with or without a
|
|
92
|
+
* `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).
|
|
93
|
+
*/
|
|
94
|
+
/** Where SST leaves the last successful deploy's outputs, under the project. */
|
|
95
|
+
const SST_OUTPUTS_FILE = join(".sst", "outputs.json");
|
|
96
|
+
/** `.sst/outputs.json` is there, and is not JSON. */
|
|
97
|
+
var SstOutputsUnreadable = class extends Error {
|
|
98
|
+
path;
|
|
99
|
+
reason;
|
|
100
|
+
constructor(path, reason) {
|
|
101
|
+
super(`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \`sst deploy\`; delete it and deploy again.`);
|
|
102
|
+
this.path = path;
|
|
103
|
+
this.reason = reason;
|
|
104
|
+
this.name = "SstOutputsUnreadable";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Remove what an earlier deploy wrote, so the outputs read after this one
|
|
109
|
+
* are this one's — not another stage's, deployed from the same checkout.
|
|
110
|
+
*/
|
|
111
|
+
async function clearOutputs(cwd) {
|
|
112
|
+
await rm(join(cwd, SST_OUTPUTS_FILE), { force: true });
|
|
113
|
+
}
|
|
114
|
+
/** The deploy's outputs, or `{}` when it wrote none. */
|
|
115
|
+
async function readOutputs(cwd) {
|
|
116
|
+
const path = join(cwd, SST_OUTPUTS_FILE);
|
|
117
|
+
if (!existsSync(path)) return {};
|
|
118
|
+
try {
|
|
119
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
120
|
+
} catch (error) {
|
|
121
|
+
throw new SstOutputsUnreadable(path, error instanceof Error ? error.message : String(error));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */
|
|
125
|
+
function urlsIn(value, path = [], found = []) {
|
|
126
|
+
if (typeof value === "string") {
|
|
127
|
+
if (isHttpUrl(value)) found.push({
|
|
128
|
+
path,
|
|
129
|
+
url: value
|
|
130
|
+
});
|
|
131
|
+
} else if (value && typeof value === "object" && !Array.isArray(value)) for (const [key, child] of Object.entries(value)) urlsIn(child, [...path, key], found);
|
|
132
|
+
return found;
|
|
133
|
+
}
|
|
134
|
+
function isHttpUrl(value) {
|
|
135
|
+
try {
|
|
136
|
+
const { protocol } = new URL(value);
|
|
137
|
+
return protocol === "http:" || protocol === "https:";
|
|
138
|
+
} catch {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The app an output's key path names, kebab-cased as app keys are: its last
|
|
144
|
+
* segment, without a `url` suffix — or its parent's, when the last segment
|
|
145
|
+
* is only `url`. Exact names are tried first, so an app called `api-url`
|
|
146
|
+
* still finds `ApiUrl`.
|
|
147
|
+
*/
|
|
148
|
+
function namesOf(path) {
|
|
149
|
+
const names = [];
|
|
150
|
+
for (const segment of [...path].reverse()) {
|
|
151
|
+
const name = kebabCase(segment);
|
|
152
|
+
names.push(name);
|
|
153
|
+
const bare = name.replace(/-?url$/, "");
|
|
154
|
+
if (bare) {
|
|
155
|
+
names.push(bare);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return names;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Each app's URL from the outputs, for the apps given. An app no output
|
|
163
|
+
* names is left out.
|
|
164
|
+
*/
|
|
165
|
+
function surfaceUrls(outputs, apps) {
|
|
166
|
+
const found = urlsIn(outputs);
|
|
167
|
+
const urls = {};
|
|
168
|
+
for (const app of apps) {
|
|
169
|
+
const exact = found.find(({ path }) => namesOf(path)[0] === app);
|
|
170
|
+
const loose = found.find(({ path }) => namesOf(path).includes(app));
|
|
171
|
+
const match = exact ?? loose;
|
|
172
|
+
if (match) urls[app] = match.url;
|
|
173
|
+
}
|
|
174
|
+
return urls;
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/target/sst/index.ts
|
|
178
|
+
/**
|
|
179
|
+
* The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`
|
|
180
|
+
* provisions it, and the surfaces SST reports are health-checked.
|
|
181
|
+
*
|
|
182
|
+
* `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads
|
|
183
|
+
* `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What
|
|
184
|
+
* the target adds is the run around the two commands — the lock, the events,
|
|
185
|
+
* verification, and credentials kept where they belong.
|
|
186
|
+
*
|
|
187
|
+
* Both commands run in the sandbox: the build executes the project's code,
|
|
188
|
+
* and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second
|
|
189
|
+
* needs AWS, so the AWS credential goes into that one command's environment
|
|
190
|
+
* and nowhere else — not the build's, not the process the deploy runs in.
|
|
191
|
+
* What `sst deploy` needs beyond them, the sandbox already passes: `PATH`
|
|
192
|
+
* for node and the package manager, and `HOME`, under which SST keeps its
|
|
193
|
+
* toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK
|
|
194
|
+
* finds `~/.aws` for a profile. Its state — the Pulumi backend and the
|
|
195
|
+
* passphrase — is in the stage's own account, reached with that credential.
|
|
196
|
+
*/
|
|
197
|
+
var sst_exports = /* @__PURE__ */ __exportAll({
|
|
198
|
+
SstConfigNotFound: () => SstConfigNotFound,
|
|
199
|
+
awsEnv: () => awsEnv,
|
|
200
|
+
createSstTarget: () => createSstTarget,
|
|
201
|
+
projectCommand: () => projectCommand,
|
|
202
|
+
sstTarget: () => sstTarget
|
|
203
|
+
});
|
|
204
|
+
/** A cold build of every handler and site. */
|
|
205
|
+
const BUILD_TIMEOUT_MS = 18e5;
|
|
206
|
+
/**
|
|
207
|
+
* A first deploy creates CloudFront distributions and, with a database, a
|
|
208
|
+
* VPC and an RDS instance — each of which alone can take a quarter of an hour.
|
|
209
|
+
*/
|
|
210
|
+
const DEPLOY_TIMEOUT_MS = 54e5;
|
|
211
|
+
/** The workspace has no `sst.config.ts` for `sst deploy` to run. */
|
|
212
|
+
var SstConfigNotFound = class extends Error {
|
|
213
|
+
cwd;
|
|
214
|
+
constructor(cwd) {
|
|
215
|
+
super(`No sst.config.ts in ${cwd}. The sst target runs \`sst deploy\` at the workspace root: scaffold one with \`gkm init --deploy sst\` and copy its sst.config.ts, or deploy through another target with --target.`);
|
|
216
|
+
this.cwd = cwd;
|
|
217
|
+
this.name = "SstConfigNotFound";
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* The project's own copy of `bin`, through its package manager — never one
|
|
222
|
+
* `npx` would download, which would be code nobody installed.
|
|
223
|
+
*/
|
|
224
|
+
function projectCommand(pm, bin, args) {
|
|
225
|
+
switch (pm) {
|
|
226
|
+
case "pnpm": return ["pnpm", [
|
|
227
|
+
"exec",
|
|
228
|
+
bin,
|
|
229
|
+
...args
|
|
230
|
+
]];
|
|
231
|
+
case "yarn": return ["yarn", [bin, ...args]];
|
|
232
|
+
case "bun": return ["bunx", [bin, ...args]];
|
|
233
|
+
case "npm": return ["npx", [
|
|
234
|
+
"--no-install",
|
|
235
|
+
bin,
|
|
236
|
+
...args
|
|
237
|
+
]];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The variables `credential` is to the AWS SDK and to SST.
|
|
242
|
+
*
|
|
243
|
+
* A profile is passed alone: given keys too, every SDK would take the keys.
|
|
244
|
+
*/
|
|
245
|
+
function awsEnv(credential) {
|
|
246
|
+
const region = credential.region ? {
|
|
247
|
+
AWS_REGION: credential.region,
|
|
248
|
+
AWS_DEFAULT_REGION: credential.region
|
|
249
|
+
} : {};
|
|
250
|
+
if ("profile" in credential) return {
|
|
251
|
+
AWS_PROFILE: credential.profile,
|
|
252
|
+
...region
|
|
253
|
+
};
|
|
254
|
+
return {
|
|
255
|
+
AWS_ACCESS_KEY_ID: credential.accessKeyId,
|
|
256
|
+
AWS_SECRET_ACCESS_KEY: credential.secretAccessKey,
|
|
257
|
+
...credential.sessionToken ? { AWS_SESSION_TOKEN: credential.sessionToken } : {},
|
|
258
|
+
...region
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* `env` without any `AWS_*`, so a host sandbox that passes some cannot put
|
|
263
|
+
* a second account beside the one the credential names.
|
|
264
|
+
*/
|
|
265
|
+
function withoutAws(env) {
|
|
266
|
+
return Object.fromEntries(Object.entries(env).filter(([name]) => !name.startsWith("AWS_")));
|
|
267
|
+
}
|
|
268
|
+
/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */
|
|
269
|
+
function kindsOf(manifest) {
|
|
270
|
+
return new Map(Object.entries(manifest).map(([id, declaration]) => [appKey(id), declaration.kind]));
|
|
271
|
+
}
|
|
272
|
+
async function exec(ctx, run, [command, args], options) {
|
|
273
|
+
const result = await run.sandbox.exec(command, args, {
|
|
274
|
+
cwd: ctx.cwd,
|
|
275
|
+
env: options.env,
|
|
276
|
+
timeoutMs: options.timeoutMs,
|
|
277
|
+
output: ctx.childOutput,
|
|
278
|
+
signal: ctx.signal
|
|
279
|
+
});
|
|
280
|
+
if (result.exitCode !== 0) throw new CommandFailed(command, args, result.exitCode, result.signal);
|
|
281
|
+
}
|
|
282
|
+
/** The `sst` target, with its health checks tuned — for tests and hosts. */
|
|
283
|
+
function createSstTarget(options = {}) {
|
|
284
|
+
const health = {
|
|
285
|
+
attempts: options.health?.attempts ?? 6,
|
|
286
|
+
delayMs: options.health?.delayMs ?? 5e3,
|
|
287
|
+
timeoutMs: options.health?.timeoutMs ?? 1e4
|
|
288
|
+
};
|
|
289
|
+
return defineTarget({
|
|
290
|
+
name: "sst",
|
|
291
|
+
runtime: "aws",
|
|
292
|
+
capabilities: {
|
|
293
|
+
rollback: false,
|
|
294
|
+
migrations: "target",
|
|
295
|
+
images: false
|
|
296
|
+
},
|
|
297
|
+
credentials: ["aws"],
|
|
298
|
+
async validate(ctx) {
|
|
299
|
+
if (!existsSync(join(ctx.cwd, "sst.config.ts"))) throw new SstConfigNotFound(ctx.cwd);
|
|
300
|
+
const aws = await ctx.credentials.get({
|
|
301
|
+
kind: "aws",
|
|
302
|
+
stage: ctx.stage
|
|
303
|
+
}, { signal: ctx.signal });
|
|
304
|
+
if (!aws) throw new MissingCredential("aws", ctx.stage);
|
|
305
|
+
if (!("profile" in aws)) {
|
|
306
|
+
ctx.secrets.mask(aws.secretAccessKey);
|
|
307
|
+
if (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);
|
|
308
|
+
}
|
|
309
|
+
for (const app of ctx.apps) if (ctx.workspace.apps[app]?.type === "mobile") ctx.skip(app, "mobile apps deploy through their own toolchain");
|
|
310
|
+
const skipped = new Set(ctx.skipped.map(({ app }) => app));
|
|
311
|
+
const apps = ctx.apps.filter((app) => !skipped.has(app));
|
|
312
|
+
ctx.logger.info(`\n🚀 Deploying "${ctx.workspace.name}" to the "${ctx.stage}" stage with SST`);
|
|
313
|
+
ctx.logger.info(` AWS: ${"profile" in aws ? `profile "${aws.profile}"` : "access keys"}`);
|
|
314
|
+
const deployable = Object.values(ctx.workspace.apps).filter((app) => app.type !== "mobile").length;
|
|
315
|
+
if (apps.length < deployable) ctx.logger.warn(` sst deploy deploys every construct of the stage, not only ${apps.join(", ")}.`);
|
|
316
|
+
return {
|
|
317
|
+
sandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),
|
|
318
|
+
pm: detectPackageManager(ctx.cwd),
|
|
319
|
+
aws,
|
|
320
|
+
apps,
|
|
321
|
+
urls: {}
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
async plan(ctx, run) {
|
|
325
|
+
const kinds = kindsOf(ctx.manifest);
|
|
326
|
+
for (const app of run.apps) ctx.emit({
|
|
327
|
+
type: "resource.planned",
|
|
328
|
+
key: `application:${app}`,
|
|
329
|
+
resourceType: kinds.get(app) ?? "application",
|
|
330
|
+
action: "ensure"
|
|
331
|
+
});
|
|
332
|
+
const [build, buildArgs] = buildCommand(ctx, run);
|
|
333
|
+
const [deploy, deployArgs] = deployCommand(ctx, run);
|
|
334
|
+
ctx.logger.info(` Would run: ${[build, ...buildArgs].join(" ")}`);
|
|
335
|
+
ctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(" ")}`);
|
|
336
|
+
},
|
|
337
|
+
async build(ctx, run) {
|
|
338
|
+
ctx.logger.info("\n📦 Building the manifest SST deploys");
|
|
339
|
+
await exec(ctx, run, buildCommand(ctx, run), {
|
|
340
|
+
env: { ...run.sandbox.env },
|
|
341
|
+
timeoutMs: BUILD_TIMEOUT_MS
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
async release(ctx, run) {
|
|
345
|
+
ctx.logger.info(`\n☁️ sst deploy --stage ${ctx.stage}`);
|
|
346
|
+
await clearOutputs(ctx.cwd);
|
|
347
|
+
await exec(ctx, run, deployCommand(ctx, run), {
|
|
348
|
+
env: {
|
|
349
|
+
...withoutAws(run.sandbox.env),
|
|
350
|
+
...awsEnv(run.aws)
|
|
351
|
+
},
|
|
352
|
+
timeoutMs: DEPLOY_TIMEOUT_MS
|
|
353
|
+
});
|
|
354
|
+
run.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);
|
|
355
|
+
for (const app of run.apps) ctx.emit({
|
|
356
|
+
type: "app.deployed",
|
|
357
|
+
app,
|
|
358
|
+
applicationId: ctx.name(app),
|
|
359
|
+
imageRef: "",
|
|
360
|
+
url: run.urls[app] ?? ""
|
|
361
|
+
});
|
|
362
|
+
},
|
|
363
|
+
async verify(ctx, run) {
|
|
364
|
+
const unhealthy = [];
|
|
365
|
+
for (const app of run.apps) {
|
|
366
|
+
const base = run.urls[app];
|
|
367
|
+
if (!base) {
|
|
368
|
+
ctx.logger.warn(` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`);
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
const url = healthUrl(base, ctx.workspace.apps[app]?.type === "backend" ? "/health" : "/");
|
|
372
|
+
const answer = await checkHealth(app, url, {
|
|
373
|
+
...health,
|
|
374
|
+
signal: ctx.signal,
|
|
375
|
+
emit: ctx.emit
|
|
376
|
+
});
|
|
377
|
+
if (answer.healthy) ctx.logger.info(` ✓ ${app}: ${url}`);
|
|
378
|
+
else unhealthy.push({
|
|
379
|
+
app,
|
|
380
|
+
url,
|
|
381
|
+
...answer.status !== void 0 ? { status: answer.status } : {},
|
|
382
|
+
...answer.error ? { error: answer.error } : {}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (unhealthy.length > 0) throw new SurfacesUnhealthy(ctx.stage, unhealthy);
|
|
386
|
+
},
|
|
387
|
+
result(ctx, run) {
|
|
388
|
+
return {
|
|
389
|
+
apps: run.apps.map((appName) => ({
|
|
390
|
+
appName,
|
|
391
|
+
type: ctx.workspace.apps[appName]?.type ?? "backend",
|
|
392
|
+
success: true,
|
|
393
|
+
...run.urls[appName] ? { url: run.urls[appName] } : {}
|
|
394
|
+
})),
|
|
395
|
+
projectId: "",
|
|
396
|
+
environmentId: "",
|
|
397
|
+
successCount: ctx.dryRun ? 0 : run.apps.length,
|
|
398
|
+
failedCount: 0,
|
|
399
|
+
stage: ctx.stage,
|
|
400
|
+
identity: ctx.identity.key,
|
|
401
|
+
tag: ctx.tag,
|
|
402
|
+
dryRun: ctx.dryRun,
|
|
403
|
+
skipped: [...ctx.skipped],
|
|
404
|
+
urls: { ...run.urls },
|
|
405
|
+
changes: []
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function buildCommand(ctx, run) {
|
|
411
|
+
return projectCommand(run.pm, "gkm", [
|
|
412
|
+
"build",
|
|
413
|
+
"--provider",
|
|
414
|
+
"aws",
|
|
415
|
+
"--stage",
|
|
416
|
+
ctx.stage
|
|
417
|
+
]);
|
|
418
|
+
}
|
|
419
|
+
function deployCommand(ctx, run) {
|
|
420
|
+
return projectCommand(run.pm, "sst", [
|
|
421
|
+
"deploy",
|
|
422
|
+
"--stage",
|
|
423
|
+
ctx.stage
|
|
424
|
+
]);
|
|
425
|
+
}
|
|
426
|
+
const sstTarget = createSstTarget();
|
|
427
|
+
//#endregion
|
|
428
|
+
export { SurfacesUnhealthy as i, sst_exports as n, SstOutputsUnreadable as r, SstConfigNotFound as t };
|
|
429
|
+
|
|
430
|
+
//# sourceMappingURL=sst-CJzvyrEz.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sst-CJzvyrEz.mjs","names":[],"sources":["../src/target/sst/health.ts","../src/target/sst/outputs.ts","../src/target/sst/index.ts"],"sourcesContent":["/**\n * Whether a released surface answers.\n *\n * The paths are the ones the local stack's healthchecks use\n * (`reconcile/apps.ts`): an API's `/health`, a site's `/`. A surface is\n * asked a few times, because a fresh deploy can take a moment to answer — a\n * Lambda's first start, a distribution still settling — and healthy means a\n * 2xx, after redirects.\n */\n\nimport type { TargetEvent } from '../types';\n\nexport interface HealthCheckOptions {\n\t/** How many times a surface is asked before it counts as down. */\n\tattempts: number;\n\t/** The wait between two attempts. */\n\tdelayMs: number;\n\t/** How long one request may take. */\n\ttimeoutMs: number;\n\tsignal: AbortSignal;\n\temit: (event: TargetEvent) => void;\n}\n\n/** Surfaces that never answered healthy. */\nexport class SurfacesUnhealthy extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** Each surface that failed, with the last thing it answered. */\n\t\treadonly surfaces: readonly {\n\t\t\tapp: string;\n\t\t\turl: string;\n\t\t\tstatus?: number;\n\t\t\terror?: string;\n\t\t}[],\n\t) {\n\t\tconst lines = surfaces.map(\n\t\t\t({ app, url, status, error }) =>\n\t\t\t\t` - ${app}: ${url} → ${status ?? error ?? 'no answer'}`,\n\t\t);\n\t\tsuper(\n\t\t\t`The \"${stage}\" stage was deployed, but ${surfaces.length === 1 ? 'a surface does' : 'surfaces do'} not answer healthy:\\n${lines.join('\\n')}\\nCheck its logs in CloudWatch, fix it, and deploy again.`,\n\t\t);\n\t\tthis.name = 'SurfacesUnhealthy';\n\t}\n}\n\n/** `path` under `base`, keeping any path `base` already has. */\nexport function healthUrl(base: string, path: string): string {\n\tconst root = base.endsWith('/') ? base : `${base}/`;\n\treturn new URL(path.replace(/^\\//, ''), root).toString();\n}\n\n/**\n * Ask `url` until it answers 2xx or the attempts run out, emitting\n * `health.checked` for each. Resolves with the last answer.\n */\nexport async function checkHealth(\n\tapp: string,\n\turl: string,\n\toptions: HealthCheckOptions,\n): Promise<{ healthy: boolean; status?: number; error?: string }> {\n\tlet last: { healthy: boolean; status?: number; error?: string } = {\n\t\thealthy: false,\n\t};\n\tfor (let attempt = 1; attempt <= options.attempts; attempt++) {\n\t\toptions.signal.throwIfAborted();\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tredirect: 'follow',\n\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\toptions.signal,\n\t\t\t\t\tAbortSignal.timeout(options.timeoutMs),\n\t\t\t\t]),\n\t\t\t});\n\t\t\t// Drained, so the connection is not held open by an unread body.\n\t\t\tawait response.arrayBuffer().catch(() => undefined);\n\t\t\tlast = { healthy: response.ok, status: response.status };\n\t\t} catch (error) {\n\t\t\t// The run being stopped is not the surface being down.\n\t\t\toptions.signal.throwIfAborted();\n\t\t\tlast = {\n\t\t\t\thealthy: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t\toptions.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp,\n\t\t\turl,\n\t\t\thealthy: last.healthy,\n\t\t\t...(last.status !== undefined ? { status: last.status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (last.healthy) return last;\n\t\tif (attempt < options.attempts) await wait(options.delayMs, options.signal);\n\t}\n\treturn last;\n}\n\nfunction wait(ms: number, signal: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal.removeEventListener('abort', stop);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst stop = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal.reason);\n\t\t};\n\t\tsignal.addEventListener('abort', stop, { once: true });\n\t});\n}\n","/**\n * The surface URLs an `sst deploy` reports.\n *\n * SST writes whatever `run()` in `sst.config.ts` returns to\n * `.sst/outputs.json` after every successful deploy — `{\"Api\": \"https://…\"}`.\n * What `run()` returns is the project's to write, so this reads it leniently:\n * nested objects are walked, anything that is not an http(s) URL is ignored,\n * and an output names a surface by its id in any casing, with or without a\n * `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { kebabCase } from '@geekmidas/manifest';\n\n/** Where SST leaves the last successful deploy's outputs, under the project. */\nexport const SST_OUTPUTS_FILE = join('.sst', 'outputs.json');\n\n/** `.sst/outputs.json` is there, and is not JSON. */\nexport class SstOutputsUnreadable extends Error {\n\tconstructor(\n\t\treadonly path: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \\`sst deploy\\`; delete it and deploy again.`,\n\t\t);\n\t\tthis.name = 'SstOutputsUnreadable';\n\t}\n}\n\n/**\n * Remove what an earlier deploy wrote, so the outputs read after this one\n * are this one's — not another stage's, deployed from the same checkout.\n */\nexport async function clearOutputs(cwd: string): Promise<void> {\n\tawait rm(join(cwd, SST_OUTPUTS_FILE), { force: true });\n}\n\n/** The deploy's outputs, or `{}` when it wrote none. */\nexport async function readOutputs(cwd: string): Promise<unknown> {\n\tconst path = join(cwd, SST_OUTPUTS_FILE);\n\tif (!existsSync(path)) return {};\n\ttry {\n\t\treturn JSON.parse(await readFile(path, 'utf8'));\n\t} catch (error) {\n\t\tthrow new SstOutputsUnreadable(\n\t\t\tpath,\n\t\t\terror instanceof Error ? error.message : String(error),\n\t\t);\n\t}\n}\n\n/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */\nfunction urlsIn(\n\tvalue: unknown,\n\tpath: string[] = [],\n\tfound: { path: string[]; url: string }[] = [],\n): { path: string[]; url: string }[] {\n\tif (typeof value === 'string') {\n\t\tif (isHttpUrl(value)) found.push({ path, url: value });\n\t} else if (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\turlsIn(child, [...path, key], found);\n\t\t}\n\t}\n\treturn found;\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst { protocol } = new URL(value);\n\t\treturn protocol === 'http:' || protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * The app an output's key path names, kebab-cased as app keys are: its last\n * segment, without a `url` suffix — or its parent's, when the last segment\n * is only `url`. Exact names are tried first, so an app called `api-url`\n * still finds `ApiUrl`.\n */\nfunction namesOf(path: string[]): string[] {\n\tconst names: string[] = [];\n\tfor (const segment of [...path].reverse()) {\n\t\tconst name = kebabCase(segment);\n\t\tnames.push(name);\n\t\tconst bare = name.replace(/-?url$/, '');\n\t\tif (bare) {\n\t\t\tnames.push(bare);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn names;\n}\n\n/**\n * Each app's URL from the outputs, for the apps given. An app no output\n * names is left out.\n */\nexport function surfaceUrls(\n\toutputs: unknown,\n\tapps: readonly string[],\n): Record<string, string> {\n\tconst found = urlsIn(outputs);\n\tconst urls: Record<string, string> = {};\n\tfor (const app of apps) {\n\t\t// An exact name beats a stripped one, wherever each is in the file.\n\t\tconst exact = found.find(({ path }) => namesOf(path)[0] === app);\n\t\tconst loose = found.find(({ path }) => namesOf(path).includes(app));\n\t\tconst match = exact ?? loose;\n\t\tif (match) urls[app] = match.url;\n\t}\n\treturn urls;\n}\n","/**\n * The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`\n * provisions it, and the surfaces SST reports are health-checked.\n *\n * `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads\n * `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What\n * the target adds is the run around the two commands — the lock, the events,\n * verification, and credentials kept where they belong.\n *\n * Both commands run in the sandbox: the build executes the project's code,\n * and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second\n * needs AWS, so the AWS credential goes into that one command's environment\n * and nowhere else — not the build's, not the process the deploy runs in.\n * What `sst deploy` needs beyond them, the sandbox already passes: `PATH`\n * for node and the package manager, and `HOME`, under which SST keeps its\n * toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK\n * finds `~/.aws` for a profile. Its state — the Pulumi backend and the\n * passphrase — is in the stage's own account, reached with that credential.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\ttype AwsCredential,\n\tMissingCredential,\n} from '../../deploy/credentials';\nimport type { DeployResult } from '../../deploy/types';\nimport { detectPackageManager, type PackageManager } from '../../init/utils';\nimport { CommandFailed } from '../../run';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { activeSandbox, type Sandbox } from '../../sandbox/sandbox';\nimport { appKey } from '../../workspace/derive';\nimport { defineTarget } from '../define';\nimport type { DeployPhaseContext, DeployTarget } from '../types';\nimport { checkHealth, healthUrl, SurfacesUnhealthy } from './health';\nimport { clearOutputs, readOutputs, surfaceUrls } from './outputs';\n\nexport { SurfacesUnhealthy } from './health';\nexport { SST_OUTPUTS_FILE, SstOutputsUnreadable } from './outputs';\n\n/** A cold build of every handler and site. */\nconst BUILD_TIMEOUT_MS = 30 * 60_000;\n/**\n * A first deploy creates CloudFront distributions and, with a database, a\n * VPC and an RDS instance — each of which alone can take a quarter of an hour.\n */\nconst DEPLOY_TIMEOUT_MS = 90 * 60_000;\n\n/** The workspace has no `sst.config.ts` for `sst deploy` to run. */\nexport class SstConfigNotFound extends Error {\n\tconstructor(readonly cwd: string) {\n\t\tsuper(\n\t\t\t`No sst.config.ts in ${cwd}. The sst target runs \\`sst deploy\\` at the workspace root: scaffold one with \\`gkm init --deploy sst\\` and copy its sst.config.ts, or deploy through another target with --target.`,\n\t\t);\n\t\tthis.name = 'SstConfigNotFound';\n\t}\n}\n\n/** What the phases hand on. */\nexport interface SstRun {\n\tsandbox: Sandbox;\n\tpm: PackageManager;\n\taws: AwsCredential;\n\t/** The apps SST deploys this run: `ctx.apps` without the skipped. */\n\tapps: string[];\n\t/** Each app's URL, from the deploy's outputs. */\n\turls: Record<string, string>;\n}\n\nexport interface SstTargetOptions {\n\t/** How often, and how patiently, `verify` asks each surface. */\n\thealth?: { attempts?: number; delayMs?: number; timeoutMs?: number };\n}\n\n/**\n * The project's own copy of `bin`, through its package manager — never one\n * `npx` would download, which would be code nobody installed.\n */\nexport function projectCommand(\n\tpm: PackageManager,\n\tbin: string,\n\targs: readonly string[],\n): [command: string, args: string[]] {\n\tswitch (pm) {\n\t\tcase 'pnpm':\n\t\t\treturn ['pnpm', ['exec', bin, ...args]];\n\t\tcase 'yarn':\n\t\t\treturn ['yarn', [bin, ...args]];\n\t\tcase 'bun':\n\t\t\treturn ['bunx', [bin, ...args]];\n\t\tcase 'npm':\n\t\t\treturn ['npx', ['--no-install', bin, ...args]];\n\t}\n}\n\n/**\n * The variables `credential` is to the AWS SDK and to SST.\n *\n * A profile is passed alone: given keys too, every SDK would take the keys.\n */\nexport function awsEnv(credential: AwsCredential): Record<string, string> {\n\tconst region: Record<string, string> = credential.region\n\t\t? { AWS_REGION: credential.region, AWS_DEFAULT_REGION: credential.region }\n\t\t: {};\n\tif ('profile' in credential) {\n\t\treturn { AWS_PROFILE: credential.profile, ...region };\n\t}\n\treturn {\n\t\tAWS_ACCESS_KEY_ID: credential.accessKeyId,\n\t\tAWS_SECRET_ACCESS_KEY: credential.secretAccessKey,\n\t\t...(credential.sessionToken\n\t\t\t? { AWS_SESSION_TOKEN: credential.sessionToken }\n\t\t\t: {}),\n\t\t...region,\n\t};\n}\n\n/**\n * `env` without any `AWS_*`, so a host sandbox that passes some cannot put\n * a second account beside the one the credential names.\n */\nfunction withoutAws(\n\tenv: Readonly<Record<string, string>>,\n): Record<string, string> {\n\treturn Object.fromEntries(\n\t\tObject.entries(env).filter(([name]) => !name.startsWith('AWS_')),\n\t);\n}\n\n/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */\nfunction kindsOf(manifest: ConstructManifest): Map<string, string> {\n\treturn new Map(\n\t\tObject.entries(manifest).map(([id, declaration]) => [\n\t\t\tappKey(id),\n\t\t\tdeclaration.kind,\n\t\t]),\n\t);\n}\n\nasync function exec(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n\t[command, args]: [string, string[]],\n\toptions: { env: Record<string, string>; timeoutMs: number },\n): Promise<void> {\n\tconst result = await run.sandbox.exec(command, args, {\n\t\tcwd: ctx.cwd,\n\t\tenv: options.env,\n\t\ttimeoutMs: options.timeoutMs,\n\t\toutput: ctx.childOutput,\n\t\tsignal: ctx.signal,\n\t});\n\tif (result.exitCode !== 0) {\n\t\tthrow new CommandFailed(\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tresult.exitCode,\n\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t);\n\t}\n}\n\n/** The `sst` target, with its health checks tuned — for tests and hosts. */\nexport function createSstTarget(\n\toptions: SstTargetOptions = {},\n): DeployTarget<undefined, SstRun> {\n\tconst health = {\n\t\tattempts: options.health?.attempts ?? 6,\n\t\tdelayMs: options.health?.delayMs ?? 5_000,\n\t\ttimeoutMs: options.health?.timeoutMs ?? 10_000,\n\t};\n\n\treturn defineTarget<undefined, SstRun>({\n\t\tname: 'sst',\n\t\truntime: 'aws',\n\t\t// SST keeps no previous release to return to; migrations run in the\n\t\t// stack, as `fromManifest` provisions the database; and nothing here\n\t\t// builds an image.\n\t\tcapabilities: { rollback: false, migrations: 'target', images: false },\n\t\tcredentials: ['aws'],\n\n\t\tasync validate(ctx) {\n\t\t\tif (!existsSync(join(ctx.cwd, 'sst.config.ts'))) {\n\t\t\t\tthrow new SstConfigNotFound(ctx.cwd);\n\t\t\t}\n\n\t\t\tconst aws = await ctx.credentials.get(\n\t\t\t\t{ kind: 'aws', stage: ctx.stage },\n\t\t\t\t{ signal: ctx.signal },\n\t\t\t);\n\t\t\tif (!aws) throw new MissingCredential('aws', ctx.stage);\n\t\t\tif (!('profile' in aws)) {\n\t\t\t\tctx.secrets.mask(aws.secretAccessKey);\n\t\t\t\tif (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);\n\t\t\t}\n\n\t\t\t// A mobile app ships through its own store's toolchain.\n\t\t\tfor (const app of ctx.apps) {\n\t\t\t\tif (ctx.workspace.apps[app]?.type === 'mobile') {\n\t\t\t\t\tctx.skip(app, 'mobile apps deploy through their own toolchain');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst skipped = new Set(ctx.skipped.map(({ app }) => app));\n\t\t\tconst apps = ctx.apps.filter((app) => !skipped.has(app));\n\n\t\t\tctx.logger.info(\n\t\t\t\t`\\n🚀 Deploying \"${ctx.workspace.name}\" to the \"${ctx.stage}\" stage with SST`,\n\t\t\t);\n\t\t\tctx.logger.info(\n\t\t\t\t` AWS: ${'profile' in aws ? `profile \"${aws.profile}\"` : 'access keys'}`,\n\t\t\t);\n\t\t\t// `sst deploy` takes the whole stack: there is no deploying one app.\n\t\t\tconst deployable = Object.values(ctx.workspace.apps).filter(\n\t\t\t\t(app) => app.type !== 'mobile',\n\t\t\t).length;\n\t\t\tif (apps.length < deployable) {\n\t\t\t\tctx.logger.warn(\n\t\t\t\t\t` sst deploy deploys every construct of the stage, not only ${apps.join(', ')}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),\n\t\t\t\tpm: detectPackageManager(ctx.cwd),\n\t\t\t\taws,\n\t\t\t\tapps,\n\t\t\t\turls: {},\n\t\t\t};\n\t\t},\n\n\t\tasync plan(ctx, run) {\n\t\t\tconst kinds = kindsOf(ctx.manifest);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'resource.planned',\n\t\t\t\t\tkey: `application:${app}`,\n\t\t\t\t\tresourceType: kinds.get(app) ?? 'application',\n\t\t\t\t\taction: 'ensure',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst [build, buildArgs] = buildCommand(ctx, run);\n\t\t\tconst [deploy, deployArgs] = deployCommand(ctx, run);\n\t\t\tctx.logger.info(` Would run: ${[build, ...buildArgs].join(' ')}`);\n\t\t\tctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(' ')}`);\n\t\t},\n\n\t\tasync build(ctx, run) {\n\t\t\tctx.logger.info('\\n📦 Building the manifest SST deploys');\n\t\t\t// No credential: the build runs the project's code and needs none.\n\t\t\tawait exec(ctx, run, buildCommand(ctx, run), {\n\t\t\t\tenv: { ...run.sandbox.env },\n\t\t\t\ttimeoutMs: BUILD_TIMEOUT_MS,\n\t\t\t});\n\t\t},\n\n\t\tasync release(ctx, run) {\n\t\t\tctx.logger.info(`\\n☁️ sst deploy --stage ${ctx.stage}`);\n\t\t\tawait clearOutputs(ctx.cwd);\n\t\t\tawait exec(ctx, run, deployCommand(ctx, run), {\n\t\t\t\tenv: { ...withoutAws(run.sandbox.env), ...awsEnv(run.aws) },\n\t\t\t\ttimeoutMs: DEPLOY_TIMEOUT_MS,\n\t\t\t});\n\n\t\t\trun.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'app.deployed',\n\t\t\t\t\tapp,\n\t\t\t\t\tapplicationId: ctx.name(app),\n\t\t\t\t\t// SST builds no image a registry holds.\n\t\t\t\t\timageRef: '',\n\t\t\t\t\turl: run.urls[app] ?? '',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tasync verify(ctx, run) {\n\t\t\tconst unhealthy: SurfacesUnhealthy['surfaces'][number][] = [];\n\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tconst base = run.urls[app];\n\t\t\t\tif (!base) {\n\t\t\t\t\tctx.logger.warn(\n\t\t\t\t\t\t` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A surface — a `rest-api` — is the backend app it derives.\n\t\t\t\tconst backend = ctx.workspace.apps[app]?.type === 'backend';\n\t\t\t\tconst url = healthUrl(base, backend ? '/health' : '/');\n\t\t\t\tconst answer = await checkHealth(app, url, {\n\t\t\t\t\t...health,\n\t\t\t\t\tsignal: ctx.signal,\n\t\t\t\t\temit: ctx.emit,\n\t\t\t\t});\n\t\t\t\tif (answer.healthy) {\n\t\t\t\t\tctx.logger.info(` ✓ ${app}: ${url}`);\n\t\t\t\t} else {\n\t\t\t\t\tunhealthy.push({\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t...(answer.status !== undefined ? { status: answer.status } : {}),\n\t\t\t\t\t\t...(answer.error ? { error: answer.error } : {}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unhealthy.length > 0) {\n\t\t\t\tthrow new SurfacesUnhealthy(ctx.stage, unhealthy);\n\t\t\t}\n\t\t},\n\n\t\tresult(ctx, run): DeployResult {\n\t\t\treturn {\n\t\t\t\tapps: run.apps.map((appName) => ({\n\t\t\t\t\tappName,\n\t\t\t\t\ttype: ctx.workspace.apps[appName]?.type ?? 'backend',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\t...(run.urls[appName] ? { url: run.urls[appName] } : {}),\n\t\t\t\t})),\n\t\t\t\tprojectId: '',\n\t\t\t\tenvironmentId: '',\n\t\t\t\tsuccessCount: ctx.dryRun ? 0 : run.apps.length,\n\t\t\t\tfailedCount: 0,\n\t\t\t\tstage: ctx.stage,\n\t\t\t\tidentity: ctx.identity.key,\n\t\t\t\ttag: ctx.tag,\n\t\t\t\tdryRun: ctx.dryRun,\n\t\t\t\tskipped: [...ctx.skipped],\n\t\t\t\turls: { ...run.urls },\n\t\t\t\tchanges: [],\n\t\t\t};\n\t\t},\n\t});\n}\n\nfunction buildCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'gkm', [\n\t\t'build',\n\t\t'--provider',\n\t\t'aws',\n\t\t'--stage',\n\t\tctx.stage,\n\t]);\n}\n\nfunction deployCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'sst', ['deploy', '--stage', ctx.stage]);\n}\n\nexport const sstTarget = createSstTarget();\n"],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
const require_workspace = require("./workspace-CwW3Gkru.cjs");
|
|
2
|
+
const require_config = require("./config.cjs");
|
|
3
|
+
let node_fs_promises = require("node:fs/promises");
|
|
4
|
+
//#region src/stages/plan.ts
|
|
5
|
+
/**
|
|
6
|
+
* Which stages a workflow run builds and deploys, from the event that started
|
|
7
|
+
* it and the project's `stages`.
|
|
8
|
+
*
|
|
9
|
+
* The rules live here, in tested code, rather than in a workflow's YAML or in
|
|
10
|
+
* the action that runs `gkm stages --github-output`: a project's deploy
|
|
11
|
+
* workflow names no stage, and what it does for each event is decided by the
|
|
12
|
+
* CLI the project installed.
|
|
13
|
+
*
|
|
14
|
+
* | event | build | deploy |
|
|
15
|
+
* | ------------------- | ------------------ | ------------------------------- |
|
|
16
|
+
* | `push` | every deployed | deployed, less the protected |
|
|
17
|
+
* | `release` | none | the protected |
|
|
18
|
+
* | `workflow_dispatch` | none | the one stage named |
|
|
19
|
+
* | anything else | none | none |
|
|
20
|
+
*
|
|
21
|
+
* A push builds every deployed stage, protected ones included, so a release
|
|
22
|
+
* deploys images built from the very commit its tag names; a release and a
|
|
23
|
+
* manual run deploy what a push already built.
|
|
24
|
+
*/
|
|
25
|
+
function planStages(stages, input) {
|
|
26
|
+
const kept = stages.protected ?? [];
|
|
27
|
+
switch (input.event) {
|
|
28
|
+
case "push": return {
|
|
29
|
+
build: [...stages.deployed],
|
|
30
|
+
deploy: stages.deployed.filter((stage) => !kept.includes(stage))
|
|
31
|
+
};
|
|
32
|
+
case "release": return {
|
|
33
|
+
build: [],
|
|
34
|
+
deploy: [...kept]
|
|
35
|
+
};
|
|
36
|
+
case "workflow_dispatch": {
|
|
37
|
+
const stage = input.stage?.trim();
|
|
38
|
+
if (!stage) throw new DispatchNamesNoStage(stages.deployed);
|
|
39
|
+
if (!stages.deployed.includes(stage)) throw new require_workspace.UndeclaredStage(stage, stages.deployed);
|
|
40
|
+
return {
|
|
41
|
+
build: [],
|
|
42
|
+
deploy: [stage]
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
default: return {
|
|
46
|
+
build: [],
|
|
47
|
+
deploy: []
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A manual run with no stage. Refused rather than read as "nothing to do", so
|
|
53
|
+
* a run started with the field left empty fails where it can be seen.
|
|
54
|
+
*/
|
|
55
|
+
var DispatchNamesNoStage = class extends Error {
|
|
56
|
+
deployed;
|
|
57
|
+
constructor(deployed) {
|
|
58
|
+
super(`A manual run deploys one stage, and none was given. Run the workflow again with stage set to one of: ${deployed.join(", ") || "nothing yet — gkm.config.ts deploys to no stage"}.`);
|
|
59
|
+
this.deployed = deployed;
|
|
60
|
+
this.name = "DispatchNamesNoStage";
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/stages/index.ts
|
|
65
|
+
/**
|
|
66
|
+
* `gkm stages` — the workspace's stages, as gkm.config.ts declares them.
|
|
67
|
+
*
|
|
68
|
+
* ```bash
|
|
69
|
+
* gkm stages # a table
|
|
70
|
+
* gkm stages --json # {"local":"dev","deployed":["prod"],"protected":["prod"]}
|
|
71
|
+
* gkm stages --github-output # a workflow run's build and deploy matrices
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* The config is read by the normal loader (and sandbox), so a workflow never
|
|
75
|
+
* parses TypeScript to learn which stages exist. `--github-output` is what the
|
|
76
|
+
* `geekmidas/toolbox/actions/stages` action runs: it writes the stages, and
|
|
77
|
+
* which of them this run builds and deploys, to `$GITHUB_OUTPUT`.
|
|
78
|
+
*/
|
|
79
|
+
function stagesJson(stages) {
|
|
80
|
+
return {
|
|
81
|
+
local: stages.local,
|
|
82
|
+
deployed: [...stages.deployed],
|
|
83
|
+
protected: [...stages.protected ?? []]
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The region of the workspace's AWS secrets store — `ssm` or
|
|
88
|
+
* `secrets-manager` — or `''` when its deployed stages keep their secrets
|
|
89
|
+
* anywhere else. A job assumes the stage's AWS role only when this is set.
|
|
90
|
+
*/
|
|
91
|
+
function awsSecretsRegion(workspace) {
|
|
92
|
+
const store = workspace.secrets?.store;
|
|
93
|
+
if (typeof store !== "object" || store === null) return "";
|
|
94
|
+
if (store.provider === "ssm" || store.provider === "secrets-manager") return store.region;
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Every output the stages action sets, each a string `fromJSON()` reads, for
|
|
99
|
+
* one workflow run.
|
|
100
|
+
*/
|
|
101
|
+
function githubOutputs(workspace, input) {
|
|
102
|
+
const stages = stagesJson(workspace.stages);
|
|
103
|
+
const plan = planStages(workspace.stages, input);
|
|
104
|
+
return {
|
|
105
|
+
local: JSON.stringify(stages.local),
|
|
106
|
+
deployed: JSON.stringify(stages.deployed),
|
|
107
|
+
protected: JSON.stringify(stages.protected),
|
|
108
|
+
build: JSON.stringify(plan.build),
|
|
109
|
+
deploy: JSON.stringify(plan.deploy),
|
|
110
|
+
"has-build": String(plan.build.length > 0),
|
|
111
|
+
"has-deploy": String(plan.deploy.length > 0),
|
|
112
|
+
"aws-region": awsSecretsRegion(workspace)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** `name=value` lines, as `$GITHUB_OUTPUT` takes single-line values. */
|
|
116
|
+
function formatGithubOutputs(outputs) {
|
|
117
|
+
return Object.entries(outputs).map(([name, value]) => `${name}=${value}\n`).join("");
|
|
118
|
+
}
|
|
119
|
+
/** A message as a workflow command's data: GitHub reads `%`, CR and LF escaped. */
|
|
120
|
+
function workflowCommandData(message) {
|
|
121
|
+
return message.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
|
|
122
|
+
}
|
|
123
|
+
function table(stages) {
|
|
124
|
+
const rows = [
|
|
125
|
+
["STAGE", "KIND"],
|
|
126
|
+
[stages.local, "local"],
|
|
127
|
+
...stages.deployed.map((name) => [name, stages.protected.includes(name) ? "deployed, protected" : "deployed"])
|
|
128
|
+
];
|
|
129
|
+
const width = Math.max(...rows.map(([name]) => name.length));
|
|
130
|
+
return rows.map(([name, kind]) => `${name.padEnd(width)} ${kind}`).join("\n");
|
|
131
|
+
}
|
|
132
|
+
async function stagesCommand(options, deps = {}) {
|
|
133
|
+
const env = deps.env ?? process.env;
|
|
134
|
+
const log = deps.log ?? ((line) => console.log(line));
|
|
135
|
+
if (!options.githubOutput) {
|
|
136
|
+
const stages = stagesJson((await require_config.loadWorkspaceSettings(deps.cwd)).stages);
|
|
137
|
+
log(options.json ? JSON.stringify(stages) : table(stages));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const file = env.GITHUB_OUTPUT;
|
|
142
|
+
if (!file) throw new GithubOutputNotSet();
|
|
143
|
+
const workspace = await require_config.loadWorkspaceSettings(deps.cwd);
|
|
144
|
+
const event = options.event || env.GITHUB_EVENT_NAME;
|
|
145
|
+
if (!event) throw new GithubEventNotSet();
|
|
146
|
+
const outputs = githubOutputs(workspace, {
|
|
147
|
+
event,
|
|
148
|
+
...options.stage ? { stage: options.stage } : {}
|
|
149
|
+
});
|
|
150
|
+
await (0, node_fs_promises.appendFile)(file, formatGithubOutputs(outputs));
|
|
151
|
+
log(`${event}: build ${outputs.build}, deploy ${outputs.deploy}`);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
log(`::error title=gkm stages::${workflowCommandData(error instanceof Error ? error.message : String(error))}`);
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** `--github-output` outside a GitHub Actions step, which sets the file. */
|
|
158
|
+
var GithubOutputNotSet = class extends Error {
|
|
159
|
+
constructor() {
|
|
160
|
+
super("gkm stages --github-output writes to the file GITHUB_OUTPUT names, and it is not set. Run it in a GitHub Actions step, or set GITHUB_OUTPUT to a file to write to.");
|
|
161
|
+
this.name = "GithubOutputNotSet";
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/** No `--event`, and no `GITHUB_EVENT_NAME` to take it from. */
|
|
165
|
+
var GithubEventNotSet = class extends Error {
|
|
166
|
+
constructor() {
|
|
167
|
+
super("gkm stages --github-output plans for an event, and none was given. Pass --event (push, release, workflow_dispatch), or run it in a GitHub Actions step, which sets GITHUB_EVENT_NAME.");
|
|
168
|
+
this.name = "GithubEventNotSet";
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
//#endregion
|
|
172
|
+
exports.stagesCommand = stagesCommand;
|
|
173
|
+
|
|
174
|
+
//# sourceMappingURL=stages-CUn6gvXL.cjs.map
|