@geekmidas/cli 10.0.0-alpha.12 → 10.0.0-alpha.121
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 +310 -377
- 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-BDa6pPgE.cjs +1090 -0
- package/dist/EndpointGenerator-BDa6pPgE.cjs.map +1 -0
- package/dist/EndpointGenerator-CP_z_E3e.mjs +1031 -0
- package/dist/EndpointGenerator-CP_z_E3e.mjs.map +1 -0
- package/dist/GoDaddyProvider-3C8U_tVu.cjs +388 -0
- package/dist/GoDaddyProvider-3C8U_tVu.cjs.map +1 -0
- package/dist/GoDaddyProvider-D0MQoOM4.mjs +388 -0
- package/dist/GoDaddyProvider-D0MQoOM4.mjs.map +1 -0
- package/dist/{HostingerProvider-BcyFRbqV.mjs → HostingerProvider-BNpS9aRJ.mjs} +29 -25
- package/dist/HostingerProvider-BNpS9aRJ.mjs.map +1 -0
- package/dist/{HostingerProvider-BOvsgATO.cjs → HostingerProvider-DR1iws1P.cjs} +29 -25
- package/dist/HostingerProvider-DR1iws1P.cjs.map +1 -0
- package/dist/LegacyStateStore-CRi7TosX.mjs +124 -0
- package/dist/LegacyStateStore-CRi7TosX.mjs.map +1 -0
- package/dist/LegacyStateStore-DHsoQGOo.cjs +124 -0
- package/dist/LegacyStateStore-DHsoQGOo.cjs.map +1 -0
- package/dist/LocalStateStore-BQXTkeoS.cjs +178 -0
- package/dist/LocalStateStore-BQXTkeoS.cjs.map +1 -0
- package/dist/LocalStateStore-Dkth0jXX.mjs +167 -0
- package/dist/LocalStateStore-Dkth0jXX.mjs.map +1 -0
- package/dist/OpenApiTsGenerator-CsrukCE-.mjs +536 -0
- package/dist/OpenApiTsGenerator-CsrukCE-.mjs.map +1 -0
- package/dist/OpenApiTsGenerator-FNhY7Ssz.cjs +541 -0
- package/dist/OpenApiTsGenerator-FNhY7Ssz.cjs.map +1 -0
- package/dist/{Route53Provider-CH9XH7bz.cjs → Route53Provider-Bllus2NR.cjs} +21 -22
- package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
- package/dist/{Route53Provider-C0xmer8U.mjs → Route53Provider-QXxjkZO1.mjs} +13 -13
- package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
- package/dist/S3StateStore-DGKZgyKz.cjs +222 -0
- package/dist/S3StateStore-DGKZgyKz.cjs.map +1 -0
- package/dist/S3StateStore-pZZnLLBd.mjs +223 -0
- package/dist/S3StateStore-pZZnLLBd.mjs.map +1 -0
- package/dist/SSMStateStore-CZRMERDA.mjs +205 -0
- package/dist/SSMStateStore-CZRMERDA.mjs.map +1 -0
- package/dist/SSMStateStore-DzkyjQ5D.cjs +204 -0
- package/dist/SSMStateStore-DzkyjQ5D.cjs.map +1 -0
- package/dist/SubscriberGenerator-C8CPxrCK.cjs +592 -0
- package/dist/SubscriberGenerator-C8CPxrCK.cjs.map +1 -0
- package/dist/SubscriberGenerator-y3pncae_.mjs +533 -0
- package/dist/SubscriberGenerator-y3pncae_.mjs.map +1 -0
- package/dist/add-C0kXOsWS.mjs +717 -0
- package/dist/add-C0kXOsWS.mjs.map +1 -0
- package/dist/add-Df8cmz0H.cjs +719 -0
- package/dist/add-Df8cmz0H.cjs.map +1 -0
- package/dist/appPorts-BoXMwolc.mjs +249 -0
- package/dist/appPorts-BoXMwolc.mjs.map +1 -0
- package/dist/appPorts-IW-OZmRi.cjs +296 -0
- package/dist/appPorts-IW-OZmRi.cjs.map +1 -0
- package/dist/aws-8QQ8n-t6.mjs +89 -0
- package/dist/aws-8QQ8n-t6.mjs.map +1 -0
- package/dist/aws-DY9NqQIT.cjs +100 -0
- package/dist/aws-DY9NqQIT.cjs.map +1 -0
- package/dist/awsStore-Bx5nCFnS.mjs +121 -0
- package/dist/awsStore-Bx5nCFnS.mjs.map +1 -0
- package/dist/awsStore-u3ehhMoY.cjs +138 -0
- package/dist/awsStore-u3ehhMoY.cjs.map +1 -0
- package/dist/{backup-provisioner-DXXg6FIL.mjs → backup-provisioner-C8DnCmxK.mjs} +11 -8
- package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
- package/dist/{backup-provisioner-cE2PuCTb.cjs → backup-provisioner-oDEsPj02.cjs} +22 -20
- package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
- package/dist/backups/runner.cjs +519 -0
- package/dist/backups/runner.cjs.map +1 -0
- package/dist/backups/runner.d.cts +102 -0
- package/dist/backups/runner.d.cts.map +1 -0
- package/dist/backups/runner.d.mts +102 -0
- package/dist/backups/runner.d.mts.map +1 -0
- package/dist/backups/runner.mjs +506 -0
- package/dist/backups/runner.mjs.map +1 -0
- package/dist/{bundler-Bux2iF-v.mjs → bundler-B-I4Du99.mjs} +35 -16
- package/dist/bundler-B-I4Du99.mjs.map +1 -0
- package/dist/{bundler-BMekgx7a.cjs → bundler-Dx_grUmc.cjs} +37 -19
- package/dist/bundler-Dx_grUmc.cjs.map +1 -0
- package/dist/cli-Cd9exatJ.cjs +71 -0
- package/dist/cli-Cd9exatJ.cjs.map +1 -0
- package/dist/cli-DL7GxGAe.mjs +71 -0
- package/dist/cli-DL7GxGAe.mjs.map +1 -0
- package/dist/compose-C43c03WZ.mjs +3284 -0
- package/dist/compose-C43c03WZ.mjs.map +1 -0
- package/dist/compose-Mdgea4Yt.cjs +3427 -0
- package/dist/compose-Mdgea4Yt.cjs.map +1 -0
- package/dist/config-D48erO2j.d.mts +269 -0
- package/dist/config-D48erO2j.d.mts.map +1 -0
- package/dist/config-DHDtsQrB.d.cts +269 -0
- package/dist/config-DHDtsQrB.d.cts.map +1 -0
- package/dist/config.cjs +421 -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 +405 -4
- package/dist/config.mjs.map +1 -0
- package/dist/credentialSchemas-B67WJOOm.cjs +272 -0
- package/dist/credentialSchemas-B67WJOOm.cjs.map +1 -0
- package/dist/credentialSchemas-DDOLRCLF.mjs +237 -0
- package/dist/credentialSchemas-DDOLRCLF.mjs.map +1 -0
- package/dist/credentials-B5N5yKk6.mjs +267 -0
- package/dist/credentials-B5N5yKk6.mjs.map +1 -0
- package/dist/credentials-Zqr3QQYB.cjs +350 -0
- package/dist/credentials-Zqr3QQYB.cjs.map +1 -0
- package/dist/databases-BPOgTn1u.mjs +522 -0
- package/dist/databases-BPOgTn1u.mjs.map +1 -0
- package/dist/databases-fOaoBInm.cjs +625 -0
- package/dist/databases-fOaoBInm.cjs.map +1 -0
- package/dist/define-6poNqm5O.mjs +106 -0
- package/dist/define-6poNqm5O.mjs.map +1 -0
- package/dist/define-crmMcXFS.cjs +153 -0
- package/dist/define-crmMcXFS.cjs.map +1 -0
- package/dist/deploy/public.cjs +212 -0
- package/dist/deploy/public.cjs.map +1 -0
- package/dist/deploy/public.d.cts +654 -0
- package/dist/deploy/public.d.cts.map +1 -0
- package/dist/deploy/public.d.mts +654 -0
- package/dist/deploy/public.d.mts.map +1 -0
- package/dist/deploy/public.mjs +145 -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-BMM2hx-K.cjs +2401 -0
- package/dist/deploy-BMM2hx-K.cjs.map +1 -0
- package/dist/deploy-D5YhwDng.mjs +2328 -0
- package/dist/deploy-D5YhwDng.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-C5roJuc9.mjs +560 -0
- package/dist/discover-C5roJuc9.mjs.map +1 -0
- package/dist/discover-CSW_BMWa.d.cts +125 -0
- package/dist/discover-CSW_BMWa.d.cts.map +1 -0
- package/dist/discover-DozUKs8f.cjs +639 -0
- package/dist/discover-DozUKs8f.cjs.map +1 -0
- package/dist/discover-xtT7fgWg.d.mts +125 -0
- package/dist/discover-xtT7fgWg.d.mts.map +1 -0
- package/dist/dns-BIYf20p7.cjs +1057 -0
- package/dist/dns-BIYf20p7.cjs.map +1 -0
- package/dist/dns-agf2VCdV.mjs +926 -0
- package/dist/dns-agf2VCdV.mjs.map +1 -0
- package/dist/dokploy-2p4PK6ej.mjs +38 -0
- package/dist/dokploy-2p4PK6ej.mjs.map +1 -0
- package/dist/dokploy-BANMTroy.cjs +38 -0
- package/dist/dokploy-BANMTroy.cjs.map +1 -0
- package/dist/drivers-BjGDYfnC.mjs +195 -0
- package/dist/drivers-BjGDYfnC.mjs.map +1 -0
- package/dist/drivers-DbjiYpW6.cjs +224 -0
- package/dist/drivers-DbjiYpW6.cjs.map +1 -0
- package/dist/eas-CNi16SoO.cjs +337 -0
- package/dist/eas-CNi16SoO.cjs.map +1 -0
- package/dist/eas-iT2JDHCh.mjs +334 -0
- package/dist/eas-iT2JDHCh.mjs.map +1 -0
- package/dist/{emit-CIlvnDvV.mjs → emit-C1e8qD08.mjs} +13 -26
- package/dist/emit-C1e8qD08.mjs.map +1 -0
- package/dist/{emit-CUD1BWls.cjs → emit-Dmc1nvdS.cjs} +31 -57
- package/dist/emit-Dmc1nvdS.cjs.map +1 -0
- package/dist/encryption-DkXVbyZc.mjs +89 -0
- package/dist/encryption-DkXVbyZc.mjs.map +1 -0
- package/dist/encryption-d2lLtkYx.cjs +90 -0
- package/dist/encryption-d2lLtkYx.cjs.map +1 -0
- package/dist/engine-CatKW6E-.mjs +3089 -0
- package/dist/engine-CatKW6E-.mjs.map +1 -0
- package/dist/engine-DlEHexED.cjs +3202 -0
- package/dist/engine-DlEHexED.cjs.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-BAeaC1Pl.cjs +833 -0
- package/dist/github-BAeaC1Pl.cjs.map +1 -0
- package/dist/github-DErsqKGN.mjs +832 -0
- package/dist/github-DErsqKGN.mjs.map +1 -0
- package/dist/googlePlay-BVcfFWRO.cjs +931 -0
- package/dist/googlePlay-BVcfFWRO.cjs.map +1 -0
- package/dist/googlePlay-BXJ5ZjMK.mjs +931 -0
- package/dist/googlePlay-BXJ5ZjMK.mjs.map +1 -0
- package/dist/identity-CBXr4wNi.mjs +129 -0
- package/dist/identity-CBXr4wNi.mjs.map +1 -0
- package/dist/identity-CbLfgQNT.cjs +182 -0
- package/dist/identity-CbLfgQNT.cjs.map +1 -0
- package/dist/{index-BzJ7QJ9c.d.mts → index-8OfpOtSI.d.cts} +39 -20
- package/dist/index-8OfpOtSI.d.cts.map +1 -0
- package/dist/{index-CfMjtdVC.d.cts → index-Dpji6Bxq.d.mts} +39 -20
- package/dist/index-Dpji6Bxq.d.mts.map +1 -0
- package/dist/index.cjs +14291 -11898
- 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 +13938 -11560
- package/dist/index.mjs.map +1 -1
- package/dist/local-BwC2v2Y8.mjs +224 -0
- package/dist/local-BwC2v2Y8.mjs.map +1 -0
- package/dist/local-DNhnkugT.cjs +241 -0
- package/dist/local-DNhnkugT.cjs.map +1 -0
- package/dist/migrate-Bb1MmGHl.mjs +181 -0
- package/dist/migrate-Bb1MmGHl.mjs.map +1 -0
- package/dist/migrate-D79GI0XM.cjs +271 -0
- package/dist/migrate-D79GI0XM.cjs.map +1 -0
- package/dist/migrate-L4a273dY.cjs +181 -0
- package/dist/migrate-L4a273dY.cjs.map +1 -0
- package/dist/migrate-s4QizIoM.mjs +266 -0
- package/dist/migrate-s4QizIoM.mjs.map +1 -0
- package/dist/openapi.cjs +214 -10
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +38 -17
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +38 -17
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +208 -5
- package/dist/openapi.mjs.map +1 -0
- package/dist/projectBucket-BBbQ1lHF.cjs +263 -0
- package/dist/projectBucket-BBbQ1lHF.cjs.map +1 -0
- package/dist/projectBucket-C_DN4WzF.mjs +222 -0
- package/dist/projectBucket-C_DN4WzF.mjs.map +1 -0
- package/dist/provider-BqpjG9QM.cjs +57 -0
- package/dist/provider-BqpjG9QM.cjs.map +1 -0
- package/dist/provider-CEOKk8NS.mjs +46 -0
- package/dist/provider-CEOKk8NS.mjs.map +1 -0
- package/dist/publish-CcTlmJT6.mjs +123 -0
- package/dist/publish-CcTlmJT6.mjs.map +1 -0
- package/dist/publish-ydscCYsW.cjs +124 -0
- package/dist/publish-ydscCYsW.cjs.map +1 -0
- package/dist/ready-BFFP838V.cjs +404 -0
- package/dist/ready-BFFP838V.cjs.map +1 -0
- package/dist/ready-BOfogqzr.mjs +375 -0
- package/dist/ready-BOfogqzr.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-BI0tWkwz.mjs → reconcile--I7V4Klj.mjs} +4 -7
- package/dist/reconcile--I7V4Klj.mjs.map +1 -0
- package/dist/{reconcile-Bhw5fmKu.cjs → reconcile-CuCQBa5-.cjs} +5 -8
- package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
- package/dist/resolve-BLp2trep.mjs +263 -0
- package/dist/resolve-BLp2trep.mjs.map +1 -0
- package/dist/resolve-BgL-brF9.cjs +316 -0
- package/dist/resolve-BgL-brF9.cjs.map +1 -0
- package/dist/rollback-2cyLXEH1.cjs +165 -0
- package/dist/rollback-2cyLXEH1.cjs.map +1 -0
- package/dist/rollback-DwqZ8zzj.mjs +136 -0
- package/dist/rollback-DwqZ8zzj.mjs.map +1 -0
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
- package/dist/run-BJLIerMM.mjs +133 -0
- package/dist/run-BJLIerMM.mjs.map +1 -0
- package/dist/run-fVZ-rLnc.cjs +174 -0
- package/dist/run-fVZ-rLnc.cjs.map +1 -0
- package/dist/runtime-ACdfK59n.d.cts +82 -0
- package/dist/runtime-ACdfK59n.d.cts.map +1 -0
- package/dist/runtime-YyQuekxi.d.mts +82 -0
- package/dist/runtime-YyQuekxi.d.mts.map +1 -0
- package/dist/s3-CrPoA89T.cjs +215 -0
- package/dist/s3-CrPoA89T.cjs.map +1 -0
- package/dist/s3-DQXZdmCM.mjs +215 -0
- package/dist/s3-DQXZdmCM.mjs.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 +50 -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 +51 -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-C4g1eG31.d.mts +104 -0
- package/dist/sandbox-C4g1eG31.d.mts.map +1 -0
- package/dist/sandbox-CHv3OYXg.cjs +165 -0
- package/dist/sandbox-CHv3OYXg.cjs.map +1 -0
- package/dist/sandbox-CbVB7uOD.mjs +118 -0
- package/dist/sandbox-CbVB7uOD.mjs.map +1 -0
- package/dist/sandbox-CdKgQ3XU.d.cts +104 -0
- package/dist/sandbox-CdKgQ3XU.d.cts.map +1 -0
- package/dist/{workspace-DPV7FtAv.cjs → schemas-BCwKKA42.mjs} +958 -1816
- package/dist/schemas-BCwKKA42.mjs.map +1 -0
- package/dist/{workspace-CtnZnWsa.mjs → schemas-BQ_v0lEX.cjs} +1048 -1626
- package/dist/schemas-BQ_v0lEX.cjs.map +1 -0
- package/dist/secretsManager-CQORubp9.mjs +97 -0
- package/dist/secretsManager-CQORubp9.mjs.map +1 -0
- package/dist/secretsManager-RAGcEDX1.cjs +108 -0
- package/dist/secretsManager-RAGcEDX1.cjs.map +1 -0
- package/dist/seeds-C2w4UqVP.cjs +9347 -0
- package/dist/seeds-C2w4UqVP.cjs.map +1 -0
- package/dist/seeds-Cwtv-U9-.mjs +8350 -0
- package/dist/seeds-Cwtv-U9-.mjs.map +1 -0
- package/dist/serverSetup-BdFOD93s.cjs +631 -0
- package/dist/serverSetup-BdFOD93s.cjs.map +1 -0
- package/dist/serverSetup-utKsoyGH.mjs +631 -0
- package/dist/serverSetup-utKsoyGH.mjs.map +1 -0
- package/dist/sniffer-8C4q6Szd.mjs +1825 -0
- package/dist/sniffer-8C4q6Szd.mjs.map +1 -0
- package/dist/sniffer-CF7wNxMo.cjs +1998 -0
- package/dist/sniffer-CF7wNxMo.cjs.map +1 -0
- package/dist/sst-B-Uz4cvm.cjs +464 -0
- package/dist/sst-B-Uz4cvm.cjs.map +1 -0
- package/dist/sst-C1pxbFEd.mjs +441 -0
- package/dist/sst-C1pxbFEd.mjs.map +1 -0
- package/dist/stage-BvM_u2z4.mjs +302 -0
- package/dist/stage-BvM_u2z4.mjs.map +1 -0
- package/dist/stage-DEQJGW3r.cjs +313 -0
- package/dist/stage-DEQJGW3r.cjs.map +1 -0
- package/dist/stages-Cb9rqRbN.mjs +190 -0
- package/dist/stages-Cb9rqRbN.mjs.map +1 -0
- package/dist/stages-D4SnG5yl.cjs +190 -0
- package/dist/stages-D4SnG5yl.cjs.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-CW_dWeTe.mjs +85 -0
- package/dist/terminal-CW_dWeTe.mjs.map +1 -0
- package/dist/terminal-DJlqcW_U.cjs +85 -0
- package/dist/terminal-DJlqcW_U.cjs.map +1 -0
- package/dist/types-B6UXlEkf.d.cts +7650 -0
- package/dist/types-B6UXlEkf.d.cts.map +1 -0
- package/dist/types-HqVPddRK.d.mts +7649 -0
- package/dist/types-HqVPddRK.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-BwqQnool.cjs +2806 -0
- package/dist/workspace-BwqQnool.cjs.map +1 -0
- package/dist/workspace-D1QbNd55.mjs +2394 -0
- package/dist/workspace-D1QbNd55.mjs.map +1 -0
- package/package.json +54 -22
- package/dist/CachedStateProvider-BEBl2wQT.cjs +0 -60
- package/dist/CachedStateProvider-BEBl2wQT.cjs.map +0 -1
- package/dist/CachedStateProvider-C-8wtlto.mjs +0 -3
- package/dist/CachedStateProvider-Co4n5Wvs.mjs +0 -54
- package/dist/CachedStateProvider-Co4n5Wvs.mjs.map +0 -1
- package/dist/CachedStateProvider-DqhGpzsm.cjs +0 -3
- package/dist/HostingerProvider-BOvsgATO.cjs.map +0 -1
- package/dist/HostingerProvider-BcyFRbqV.mjs.map +0 -1
- package/dist/LocalStateProvider-Bq-0C0sg.mjs +0 -42
- package/dist/LocalStateProvider-Bq-0C0sg.mjs.map +0 -1
- package/dist/LocalStateProvider-yjXZXZDM.cjs +0 -43
- package/dist/LocalStateProvider-yjXZXZDM.cjs.map +0 -1
- package/dist/Route53Provider-C0xmer8U.mjs.map +0 -1
- package/dist/Route53Provider-CH9XH7bz.cjs.map +0 -1
- package/dist/SSMStateProvider-CXtNgPfy.cjs +0 -66
- package/dist/SSMStateProvider-CXtNgPfy.cjs.map +0 -1
- package/dist/SSMStateProvider-DOZifZfE.mjs +0 -66
- package/dist/SSMStateProvider-DOZifZfE.mjs.map +0 -1
- package/dist/backup-provisioner-DXXg6FIL.mjs.map +0 -1
- package/dist/backup-provisioner-cE2PuCTb.cjs.map +0 -1
- package/dist/bundler-BMekgx7a.cjs.map +0 -1
- package/dist/bundler-Bux2iF-v.mjs.map +0 -1
- package/dist/chunk-Duj1WY3L.mjs +0 -7
- package/dist/config-DTsVjKZD.mjs +0 -402
- package/dist/config-DTsVjKZD.mjs.map +0 -1
- package/dist/config-RYR9j6EF.cjs +0 -462
- package/dist/config-RYR9j6EF.cjs.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-DQRvPz2S.cjs +0 -2769
- package/dist/credentials-DQRvPz2S.cjs.map +0 -1
- package/dist/credentials-jMJC63qs.mjs +0 -2625
- package/dist/credentials-jMJC63qs.mjs.map +0 -1
- package/dist/discover-BYHQwQqu.mjs +0 -242
- package/dist/discover-BYHQwQqu.mjs.map +0 -1
- package/dist/discover-DmW9Bscc.cjs +0 -290
- package/dist/discover-DmW9Bscc.cjs.map +0 -1
- package/dist/dokploy-api-5cK2InBm.cjs +0 -3
- package/dist/dokploy-api-D2Ny4Jrc.mjs +0 -3
- package/dist/dokploy-api-pdaBryoY.mjs +0 -706
- package/dist/dokploy-api-pdaBryoY.mjs.map +0 -1
- package/dist/dokploy-api-zqKe9lHH.cjs +0 -718
- package/dist/dokploy-api-zqKe9lHH.cjs.map +0 -1
- package/dist/emit-CIlvnDvV.mjs.map +0 -1
- package/dist/emit-CUD1BWls.cjs.map +0 -1
- package/dist/encryption-D2pL3tHH.cjs +0 -54
- package/dist/encryption-D2pL3tHH.cjs.map +0 -1
- package/dist/encryption-YDsXXi6w.mjs +0 -3
- package/dist/encryption-_4zwjOAR.mjs +0 -42
- package/dist/encryption-_4zwjOAR.mjs.map +0 -1
- package/dist/encryption-sQ2Oxx0d.cjs +0 -4
- package/dist/fullstack-secrets-B6KBHf-g.mjs +0 -87
- package/dist/fullstack-secrets-B6KBHf-g.mjs.map +0 -1
- package/dist/fullstack-secrets-DL8v0y4D.cjs +0 -99
- package/dist/fullstack-secrets-DL8v0y4D.cjs.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/github-BThvbf2W.cjs +0 -197
- package/dist/github-BThvbf2W.cjs.map +0 -1
- package/dist/github-DpMZurEK.mjs +0 -196
- package/dist/github-DpMZurEK.mjs.map +0 -1
- package/dist/index-BzJ7QJ9c.d.mts.map +0 -1
- package/dist/index-CfMjtdVC.d.cts.map +0 -1
- package/dist/keystore-C9rint2E.cjs +0 -101
- package/dist/keystore-C9rint2E.cjs.map +0 -1
- package/dist/keystore-TxeYM7an.mjs +0 -83
- package/dist/keystore-TxeYM7an.mjs.map +0 -1
- package/dist/openapi-Bs3-5q_r.mjs +0 -2021
- package/dist/openapi-Bs3-5q_r.mjs.map +0 -1
- package/dist/openapi-DWLTsYLL.cjs +0 -2075
- package/dist/openapi-DWLTsYLL.cjs.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-BI0tWkwz.mjs.map +0 -1
- package/dist/reconcile-Bhw5fmKu.cjs.map +0 -1
- package/dist/setup-BmLoNrDX.mjs +0 -12
- package/dist/setup-BrR1_xGy.cjs +0 -12
- package/dist/setup-BsNR2LBG.cjs +0 -467
- package/dist/setup-BsNR2LBG.cjs.map +0 -1
- package/dist/setup-D5-JMknk.mjs +0 -437
- package/dist/setup-D5-JMknk.mjs.map +0 -1
- package/dist/storage-B020InPW.mjs +0 -222
- package/dist/storage-B020InPW.mjs.map +0 -1
- package/dist/storage-CSNplaJn.cjs +0 -282
- package/dist/storage-CSNplaJn.cjs.map +0 -1
- package/dist/storage-DGBzMLZa.mjs +0 -4
- package/dist/storage-DlVol_oj.cjs +0 -8
- package/dist/sync-0ILCb-1S.cjs +0 -93
- package/dist/sync-0ILCb-1S.cjs.map +0 -1
- package/dist/sync-CzHXiR9c.mjs +0 -76
- package/dist/sync-CzHXiR9c.mjs.map +0 -1
- package/dist/sync-DYENfOt4.cjs +0 -4
- package/dist/sync-HAau6h_R.mjs +0 -3
- package/dist/types-DVIx8I1N.d.mts +0 -1950
- package/dist/types-DVIx8I1N.d.mts.map +0 -1
- package/dist/types-PMP_qXRY.d.cts +0 -1950
- package/dist/types-PMP_qXRY.d.cts.map +0 -1
- package/dist/workspace-Cji6lE8E.cjs +0 -10
- package/dist/workspace-CkJAtRIX.mjs +0 -9
- package/dist/workspace-CtnZnWsa.mjs.map +0 -1
- package/dist/workspace-DPV7FtAv.cjs.map +0 -1
package/dist/github-BThvbf2W.cjs
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
require('./discover-DmW9Bscc.cjs');
|
|
3
|
-
const require_config = require('./config-RYR9j6EF.cjs');
|
|
4
|
-
const require_workspace = require('./workspace-DPV7FtAv.cjs');
|
|
5
|
-
const require_keystore = require('./keystore-C9rint2E.cjs');
|
|
6
|
-
const node_fs = require_chunk.__toESM(require("node:fs"));
|
|
7
|
-
const node_child_process = require_chunk.__toESM(require("node:child_process"));
|
|
8
|
-
const __aws_sdk_client_iam = require_chunk.__toESM(require("@aws-sdk/client-iam"));
|
|
9
|
-
|
|
10
|
-
//#region src/deploy/github.ts
|
|
11
|
-
const logger = console;
|
|
12
|
-
const GITHUB_OIDC_HOST = "token.actions.githubusercontent.com";
|
|
13
|
-
const AUDIENCE = "sts.amazonaws.com";
|
|
14
|
-
/**
|
|
15
|
-
* What SST needs to create a stack is most of AWS, so this is the default —
|
|
16
|
-
* said out loud in the output, and replaceable with `--policy-arn`.
|
|
17
|
-
*/
|
|
18
|
-
const DEFAULT_POLICY_ARN = "arn:aws:iam::aws:policy/AdministratorAccess";
|
|
19
|
-
const defaultGh = (args, input) => (0, node_child_process.execFileSync)("gh", args, {
|
|
20
|
-
encoding: "utf-8",
|
|
21
|
-
...input === void 0 ? {} : {
|
|
22
|
-
input,
|
|
23
|
-
stdio: [
|
|
24
|
-
"pipe",
|
|
25
|
-
"pipe",
|
|
26
|
-
"pipe"
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
}).trim();
|
|
30
|
-
/** The role a stage deploys as: `<project>-github-<stage>`, within IAM's 64. */
|
|
31
|
-
function roleName(project, stage) {
|
|
32
|
-
return `${project}-github-${stage}`.toLowerCase().replace(/[^a-z0-9+=,.@_-]/g, "-").slice(0, 64);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Who may assume the role: a workflow job running in this repository's
|
|
36
|
-
* `<stage>` environment, and nothing else — not another branch's job, not
|
|
37
|
-
* another environment's. That is what keeps a staging deploy from using the
|
|
38
|
-
* production role.
|
|
39
|
-
*/
|
|
40
|
-
function trustPolicy(providerArn, repo, stage) {
|
|
41
|
-
return JSON.stringify({
|
|
42
|
-
Version: "2012-10-17",
|
|
43
|
-
Statement: [{
|
|
44
|
-
Effect: "Allow",
|
|
45
|
-
Principal: { Federated: providerArn },
|
|
46
|
-
Action: "sts:AssumeRoleWithWebIdentity",
|
|
47
|
-
Condition: { StringEquals: {
|
|
48
|
-
[`${GITHUB_OIDC_HOST}:aud`]: AUDIENCE,
|
|
49
|
-
[`${GITHUB_OIDC_HOST}:sub`]: `repo:${repo}:environment:${stage}`
|
|
50
|
-
} }
|
|
51
|
-
}]
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
/** GitHub's OIDC provider in this account, created if it is not there. */
|
|
55
|
-
async function ensureOidcProvider(iam) {
|
|
56
|
-
const { OpenIDConnectProviderList = [] } = await iam.send(new __aws_sdk_client_iam.ListOpenIDConnectProvidersCommand({}));
|
|
57
|
-
const existing = OpenIDConnectProviderList.find((p) => p.Arn?.endsWith(`oidc-provider/${GITHUB_OIDC_HOST}`))?.Arn;
|
|
58
|
-
if (existing) return existing;
|
|
59
|
-
const created = await iam.send(new __aws_sdk_client_iam.CreateOpenIDConnectProviderCommand({
|
|
60
|
-
Url: `https://${GITHUB_OIDC_HOST}`,
|
|
61
|
-
ClientIDList: [AUDIENCE]
|
|
62
|
-
}));
|
|
63
|
-
return created.OpenIDConnectProviderArn;
|
|
64
|
-
}
|
|
65
|
-
/** The deploy role, created or brought back to this trust and policy. */
|
|
66
|
-
async function ensureRole(iam, name, trust, policyArn) {
|
|
67
|
-
let arn;
|
|
68
|
-
try {
|
|
69
|
-
const { Role } = await iam.send(new __aws_sdk_client_iam.GetRoleCommand({ RoleName: name }));
|
|
70
|
-
await iam.send(new __aws_sdk_client_iam.UpdateAssumeRolePolicyCommand({
|
|
71
|
-
RoleName: name,
|
|
72
|
-
PolicyDocument: trust
|
|
73
|
-
}));
|
|
74
|
-
arn = Role.Arn;
|
|
75
|
-
} catch (error) {
|
|
76
|
-
if (error.name !== "NoSuchEntityException") throw error;
|
|
77
|
-
const { Role } = await iam.send(new __aws_sdk_client_iam.CreateRoleCommand({
|
|
78
|
-
RoleName: name,
|
|
79
|
-
AssumeRolePolicyDocument: trust,
|
|
80
|
-
Description: "Deploys from GitHub Actions (gkm deploy:github)",
|
|
81
|
-
MaxSessionDuration: 3600 * 2
|
|
82
|
-
}));
|
|
83
|
-
arn = Role.Arn;
|
|
84
|
-
}
|
|
85
|
-
await iam.send(new __aws_sdk_client_iam.AttachRolePolicyCommand({
|
|
86
|
-
RoleName: name,
|
|
87
|
-
PolicyArn: policyArn
|
|
88
|
-
}));
|
|
89
|
-
return arn;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* An IAM client for the stage's account.
|
|
93
|
-
*
|
|
94
|
-
* `fromIni` for a named profile, deliberately: it resolves exactly that
|
|
95
|
-
* profile — keys, assume-role, `credential_process` or SSO, whichever
|
|
96
|
-
* ~/.aws/config says — and never falls back to AWS_* in the environment. The
|
|
97
|
-
* provider chain checks the environment first, so exported staging keys would
|
|
98
|
-
* quietly win over `--profile prod` and the production role would land in the
|
|
99
|
-
* staging account.
|
|
100
|
-
*/
|
|
101
|
-
async function iamFor(profile, endpoint) {
|
|
102
|
-
const config = { region: "us-east-1" };
|
|
103
|
-
if (profile) {
|
|
104
|
-
const { fromIni } = await import("@aws-sdk/credential-providers");
|
|
105
|
-
config.credentials = fromIni({ profile });
|
|
106
|
-
}
|
|
107
|
-
if (endpoint) {
|
|
108
|
-
config.endpoint = endpoint;
|
|
109
|
-
config.credentials = {
|
|
110
|
-
accessKeyId: "test",
|
|
111
|
-
secretAccessKey: "test"
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
return new __aws_sdk_client_iam.IAMClient(config);
|
|
115
|
-
}
|
|
116
|
-
async function deployGithubCommand(options, deps = {}) {
|
|
117
|
-
const gh = deps.gh ?? defaultGh;
|
|
118
|
-
const { workspace } = await require_config.loadWorkspaceConfig(deps.cwd);
|
|
119
|
-
require_workspace.assertDeployedStage(workspace.stages, options.stage);
|
|
120
|
-
const repo = options.repo ?? gh([
|
|
121
|
-
"repo",
|
|
122
|
-
"view",
|
|
123
|
-
"--json",
|
|
124
|
-
"nameWithOwner",
|
|
125
|
-
"-q",
|
|
126
|
-
".nameWithOwner"
|
|
127
|
-
]);
|
|
128
|
-
const role = roleName(workspace.name, options.stage);
|
|
129
|
-
const policyArn = options.policyArn ?? DEFAULT_POLICY_ARN;
|
|
130
|
-
const keyPath = require_keystore.getKeyPath(options.stage, workspace.name);
|
|
131
|
-
const hasKey = (0, node_fs.existsSync)(keyPath);
|
|
132
|
-
logger.log(`\n🔐 GitHub → AWS for stage "${options.stage}"\n`);
|
|
133
|
-
logger.log(` Repository: ${repo}`);
|
|
134
|
-
logger.log(` AWS profile: ${options.profile ?? "(default credentials)"}`);
|
|
135
|
-
logger.log(` Role: ${role}`);
|
|
136
|
-
logger.log(` Policy: ${policyArn}${options.policyArn ? "" : " (default; --policy-arn to narrow)"}`);
|
|
137
|
-
logger.log(` Trusted by: repo:${repo}:environment:${options.stage} only`);
|
|
138
|
-
logger.log(` Secrets key: ${hasKey ? keyPath : `none at ${keyPath} — run gkm secrets:init --stage ${options.stage} first`}`);
|
|
139
|
-
if (options.dryRun) {
|
|
140
|
-
logger.log("\n --dry-run: nothing changed.\n");
|
|
141
|
-
return { repo };
|
|
142
|
-
}
|
|
143
|
-
const iam = deps.iam ?? await iamFor(options.profile);
|
|
144
|
-
const providerArn = await ensureOidcProvider(iam).catch((error) => {
|
|
145
|
-
if (/SSO session/i.test(String(error?.message)) && options.profile) throw new SsoSessionExpired(options.profile);
|
|
146
|
-
throw error;
|
|
147
|
-
});
|
|
148
|
-
const roleArn = await ensureRole(iam, role, trustPolicy(providerArn, repo, options.stage), policyArn);
|
|
149
|
-
logger.log(`\n ✓ AWS: ${roleArn}`);
|
|
150
|
-
gh([
|
|
151
|
-
"api",
|
|
152
|
-
"--method",
|
|
153
|
-
"PUT",
|
|
154
|
-
`repos/${repo}/environments/${options.stage}`
|
|
155
|
-
]);
|
|
156
|
-
gh([
|
|
157
|
-
"variable",
|
|
158
|
-
"set",
|
|
159
|
-
"AWS_ROLE_ARN",
|
|
160
|
-
"--env",
|
|
161
|
-
options.stage,
|
|
162
|
-
"--repo",
|
|
163
|
-
repo,
|
|
164
|
-
"--body",
|
|
165
|
-
roleArn
|
|
166
|
-
]);
|
|
167
|
-
logger.log(` ✓ GitHub: environment "${options.stage}", AWS_ROLE_ARN`);
|
|
168
|
-
if (hasKey) {
|
|
169
|
-
gh([
|
|
170
|
-
"secret",
|
|
171
|
-
"set",
|
|
172
|
-
"GKM_SECRETS_KEY",
|
|
173
|
-
"--env",
|
|
174
|
-
options.stage,
|
|
175
|
-
"--repo",
|
|
176
|
-
repo
|
|
177
|
-
], (0, node_fs.readFileSync)(keyPath, "utf-8").trim());
|
|
178
|
-
logger.log(" ✓ GitHub: GKM_SECRETS_KEY");
|
|
179
|
-
} else logger.log(` ⚠ No secrets key for "${options.stage}"; run gkm secrets:init --stage ${options.stage}, then this again.`);
|
|
180
|
-
logger.log(`\n Protect it: add required reviewers to the "${options.stage}" environment in the repository settings.\n`);
|
|
181
|
-
return {
|
|
182
|
-
roleArn,
|
|
183
|
-
repo
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
/** The profile's SSO login has lapsed; the fix is one command away. */
|
|
187
|
-
var SsoSessionExpired = class extends Error {
|
|
188
|
-
constructor(profile) {
|
|
189
|
-
super(`The SSO session for profile "${profile}" has expired or is invalid. Run: aws sso login --profile ${profile}`);
|
|
190
|
-
this.profile = profile;
|
|
191
|
-
this.name = "SsoSessionExpired";
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
//#endregion
|
|
196
|
-
exports.deployGithubCommand = deployGithubCommand;
|
|
197
|
-
//# sourceMappingURL=github-BThvbf2W.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"github-BThvbf2W.cjs","names":["defaultGh: Gh","project: string","stage: string","providerArn: string","repo: string","iam: IAMClient","ListOpenIDConnectProvidersCommand","CreateOpenIDConnectProviderCommand","name: string","trust: string","policyArn: string","arn: string","GetRoleCommand","UpdateAssumeRolePolicyCommand","CreateRoleCommand","AttachRolePolicyCommand","profile?: string","endpoint?: string","config: IAMClientConfig","IAMClient","options: DeployGithubOptions","deps: { iam?: IAMClient; gh?: Gh; cwd?: string }","profile: string"],"sources":["../src/deploy/github.ts"],"sourcesContent":["/**\n * `gkm deploy:github` — let GitHub Actions deploy one stage, with no keys.\n *\n * A stage usually lives in its own AWS account — staging in one, production in\n * another — so this runs once per stage, with that account's profile:\n *\n * gkm deploy:github --stage staging --profile acme-dev\n * gkm deploy:github --stage prod --profile acme-prod\n *\n * In the stage's account it makes sure GitHub's OIDC provider exists, and a\n * role that only this repository's `<stage>` environment can assume. On\n * GitHub it creates that environment and gives it what the generated deploy\n * workflow reads: `AWS_ROLE_ARN`, and the stage's secrets key as\n * `GKM_SECRETS_KEY`. Re-running it converges rather than duplicating.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport {\n\tAttachRolePolicyCommand,\n\tCreateOpenIDConnectProviderCommand,\n\tCreateRoleCommand,\n\tGetRoleCommand,\n\tIAMClient,\n\ttype IAMClientConfig,\n\tListOpenIDConnectProvidersCommand,\n\tUpdateAssumeRolePolicyCommand,\n} from '@aws-sdk/client-iam';\nimport { loadWorkspaceConfig } from '../config.js';\nimport { getKeyPath } from '../secrets/keystore.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\n\nconst logger = console;\n\nconst GITHUB_OIDC_HOST = 'token.actions.githubusercontent.com';\nconst AUDIENCE = 'sts.amazonaws.com';\n\n/**\n * What SST needs to create a stack is most of AWS, so this is the default —\n * said out loud in the output, and replaceable with `--policy-arn`.\n */\nexport const DEFAULT_POLICY_ARN = 'arn:aws:iam::aws:policy/AdministratorAccess';\n\nexport interface DeployGithubOptions {\n\tstage: string;\n\t/** The AWS profile for the stage's account. */\n\tprofile?: string;\n\t/** `owner/name`; defaults to the repository `gh` sees here. */\n\trepo?: string;\n\t/** The policy the deploy role gets. */\n\tpolicyArn?: string;\n\tdryRun?: boolean;\n}\n\n/** Runs `gh` with the given arguments and optional stdin, returning stdout. */\nexport type Gh = (args: string[], input?: string) => string;\n\nconst defaultGh: Gh = (args, input) =>\n\texecFileSync('gh', args, {\n\t\tencoding: 'utf-8',\n\t\t...(input === undefined\n\t\t\t? {}\n\t\t\t: { input, stdio: ['pipe', 'pipe', 'pipe'] as const }),\n\t}).trim();\n\n/** The role a stage deploys as: `<project>-github-<stage>`, within IAM's 64. */\nexport function roleName(project: string, stage: string): string {\n\treturn `${project}-github-${stage}`\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9+=,.@_-]/g, '-')\n\t\t.slice(0, 64);\n}\n\n/**\n * Who may assume the role: a workflow job running in this repository's\n * `<stage>` environment, and nothing else — not another branch's job, not\n * another environment's. That is what keeps a staging deploy from using the\n * production role.\n */\nexport function trustPolicy(\n\tproviderArn: string,\n\trepo: string,\n\tstage: string,\n): string {\n\treturn JSON.stringify({\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tPrincipal: { Federated: providerArn },\n\t\t\t\tAction: 'sts:AssumeRoleWithWebIdentity',\n\t\t\t\tCondition: {\n\t\t\t\t\tStringEquals: {\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:aud`]: AUDIENCE,\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:sub`]: `repo:${repo}:environment:${stage}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n}\n\n/** GitHub's OIDC provider in this account, created if it is not there. */\nexport async function ensureOidcProvider(iam: IAMClient): Promise<string> {\n\tconst { OpenIDConnectProviderList = [] } = await iam.send(\n\t\tnew ListOpenIDConnectProvidersCommand({}),\n\t);\n\tconst existing = OpenIDConnectProviderList.find((p) =>\n\t\tp.Arn?.endsWith(`oidc-provider/${GITHUB_OIDC_HOST}`),\n\t)?.Arn;\n\tif (existing) return existing;\n\n\tconst created = await iam.send(\n\t\tnew CreateOpenIDConnectProviderCommand({\n\t\t\tUrl: `https://${GITHUB_OIDC_HOST}`,\n\t\t\tClientIDList: [AUDIENCE],\n\t\t}),\n\t);\n\treturn created.OpenIDConnectProviderArn!;\n}\n\n/** The deploy role, created or brought back to this trust and policy. */\nexport async function ensureRole(\n\tiam: IAMClient,\n\tname: string,\n\ttrust: string,\n\tpolicyArn: string,\n): Promise<string> {\n\tlet arn: string;\n\ttry {\n\t\tconst { Role } = await iam.send(new GetRoleCommand({ RoleName: name }));\n\t\tawait iam.send(\n\t\t\tnew UpdateAssumeRolePolicyCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tPolicyDocument: trust,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t} catch (error) {\n\t\tif ((error as { name?: string }).name !== 'NoSuchEntityException') {\n\t\t\tthrow error;\n\t\t}\n\t\tconst { Role } = await iam.send(\n\t\t\tnew CreateRoleCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tAssumeRolePolicyDocument: trust,\n\t\t\t\tDescription: 'Deploys from GitHub Actions (gkm deploy:github)',\n\t\t\t\t// SST deploys can run long; the default hour is tight.\n\t\t\t\tMaxSessionDuration: 3600 * 2,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t}\n\n\t// Attaching an attached policy is a no-op, so this converges too.\n\tawait iam.send(\n\t\tnew AttachRolePolicyCommand({ RoleName: name, PolicyArn: policyArn }),\n\t);\n\treturn arn;\n}\n\n/**\n * An IAM client for the stage's account.\n *\n * `fromIni` for a named profile, deliberately: it resolves exactly that\n * profile — keys, assume-role, `credential_process` or SSO, whichever\n * ~/.aws/config says — and never falls back to AWS_* in the environment. The\n * provider chain checks the environment first, so exported staging keys would\n * quietly win over `--profile prod` and the production role would land in the\n * staging account.\n */\nexport async function iamFor(\n\tprofile?: string,\n\tendpoint?: string,\n): Promise<IAMClient> {\n\tconst config: IAMClientConfig = { region: 'us-east-1' };\n\tif (profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile });\n\t}\n\tif (endpoint) {\n\t\tconfig.endpoint = endpoint;\n\t\tconfig.credentials = { accessKeyId: 'test', secretAccessKey: 'test' };\n\t}\n\treturn new IAMClient(config);\n}\n\nexport async function deployGithubCommand(\n\toptions: DeployGithubOptions,\n\tdeps: { iam?: IAMClient; gh?: Gh; cwd?: string } = {},\n): Promise<{ roleArn?: string; repo: string }> {\n\tconst gh = deps.gh ?? defaultGh;\n\tconst { workspace } = await loadWorkspaceConfig(deps.cwd);\n\tassertDeployedStage(workspace.stages, options.stage);\n\n\tconst repo =\n\t\toptions.repo ??\n\t\tgh(['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner']);\n\tconst role = roleName(workspace.name, options.stage);\n\tconst policyArn = options.policyArn ?? DEFAULT_POLICY_ARN;\n\tconst keyPath = getKeyPath(options.stage, workspace.name);\n\tconst hasKey = existsSync(keyPath);\n\n\tlogger.log(`\\n🔐 GitHub → AWS for stage \"${options.stage}\"\\n`);\n\tlogger.log(` Repository: ${repo}`);\n\tlogger.log(` AWS profile: ${options.profile ?? '(default credentials)'}`);\n\tlogger.log(` Role: ${role}`);\n\tlogger.log(\n\t\t` Policy: ${policyArn}${options.policyArn ? '' : ' (default; --policy-arn to narrow)'}`,\n\t);\n\tlogger.log(` Trusted by: repo:${repo}:environment:${options.stage} only`);\n\tlogger.log(\n\t\t` Secrets key: ${hasKey ? keyPath : `none at ${keyPath} — run gkm secrets:init --stage ${options.stage} first`}`,\n\t);\n\n\tif (options.dryRun) {\n\t\tlogger.log('\\n --dry-run: nothing changed.\\n');\n\t\treturn { repo };\n\t}\n\n\tconst iam = deps.iam ?? (await iamFor(options.profile));\n\tconst providerArn = await ensureOidcProvider(iam).catch((error) => {\n\t\t// The first AWS call is where an expired SSO login surfaces; the SDK's\n\t\t// message does not say which profile, and this command knows.\n\t\tif (/SSO session/i.test(String(error?.message)) && options.profile) {\n\t\t\tthrow new SsoSessionExpired(options.profile);\n\t\t}\n\t\tthrow error;\n\t});\n\tconst roleArn = await ensureRole(\n\t\tiam,\n\t\trole,\n\t\ttrustPolicy(providerArn, repo, options.stage),\n\t\tpolicyArn,\n\t);\n\tlogger.log(`\\n ✓ AWS: ${roleArn}`);\n\n\t// The environment the generated deploy workflow runs the stage in.\n\tgh(['api', '--method', 'PUT', `repos/${repo}/environments/${options.stage}`]);\n\tgh([\n\t\t'variable',\n\t\t'set',\n\t\t'AWS_ROLE_ARN',\n\t\t'--env',\n\t\toptions.stage,\n\t\t'--repo',\n\t\trepo,\n\t\t'--body',\n\t\troleArn,\n\t]);\n\tlogger.log(` ✓ GitHub: environment \"${options.stage}\", AWS_ROLE_ARN`);\n\n\tif (hasKey) {\n\t\t// Through stdin, so the key is never an argument a process list shows.\n\t\tgh(\n\t\t\t[\n\t\t\t\t'secret',\n\t\t\t\t'set',\n\t\t\t\t'GKM_SECRETS_KEY',\n\t\t\t\t'--env',\n\t\t\t\toptions.stage,\n\t\t\t\t'--repo',\n\t\t\t\trepo,\n\t\t\t],\n\t\t\treadFileSync(keyPath, 'utf-8').trim(),\n\t\t);\n\t\tlogger.log(' ✓ GitHub: GKM_SECRETS_KEY');\n\t} else {\n\t\tlogger.log(\n\t\t\t` ⚠ No secrets key for \"${options.stage}\"; run gkm secrets:init --stage ${options.stage}, then this again.`,\n\t\t);\n\t}\n\n\tlogger.log(\n\t\t`\\n Protect it: add required reviewers to the \"${options.stage}\" environment in the repository settings.\\n`,\n\t);\n\treturn { roleArn, repo };\n}\n\n/** The profile's SSO login has lapsed; the fix is one command away. */\nexport class SsoSessionExpired extends Error {\n\tconstructor(readonly profile: string) {\n\t\tsuper(\n\t\t\t`The SSO session for profile \"${profile}\" has expired or is invalid. Run: aws sso login --profile ${profile}`,\n\t\t);\n\t\tthis.name = 'SsoSessionExpired';\n\t}\n}\n"],"mappings":"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"}
|
package/dist/github-DpMZurEK.mjs
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import "./discover-BYHQwQqu.mjs";
|
|
2
|
-
import { loadWorkspaceConfig } from "./config-DTsVjKZD.mjs";
|
|
3
|
-
import { assertDeployedStage } from "./workspace-CtnZnWsa.mjs";
|
|
4
|
-
import { getKeyPath } from "./keystore-TxeYM7an.mjs";
|
|
5
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
-
import { execFileSync } from "node:child_process";
|
|
7
|
-
import { AttachRolePolicyCommand, CreateOpenIDConnectProviderCommand, CreateRoleCommand, GetRoleCommand, IAMClient, ListOpenIDConnectProvidersCommand, UpdateAssumeRolePolicyCommand } from "@aws-sdk/client-iam";
|
|
8
|
-
|
|
9
|
-
//#region src/deploy/github.ts
|
|
10
|
-
const logger = console;
|
|
11
|
-
const GITHUB_OIDC_HOST = "token.actions.githubusercontent.com";
|
|
12
|
-
const AUDIENCE = "sts.amazonaws.com";
|
|
13
|
-
/**
|
|
14
|
-
* What SST needs to create a stack is most of AWS, so this is the default —
|
|
15
|
-
* said out loud in the output, and replaceable with `--policy-arn`.
|
|
16
|
-
*/
|
|
17
|
-
const DEFAULT_POLICY_ARN = "arn:aws:iam::aws:policy/AdministratorAccess";
|
|
18
|
-
const defaultGh = (args, input) => execFileSync("gh", args, {
|
|
19
|
-
encoding: "utf-8",
|
|
20
|
-
...input === void 0 ? {} : {
|
|
21
|
-
input,
|
|
22
|
-
stdio: [
|
|
23
|
-
"pipe",
|
|
24
|
-
"pipe",
|
|
25
|
-
"pipe"
|
|
26
|
-
]
|
|
27
|
-
}
|
|
28
|
-
}).trim();
|
|
29
|
-
/** The role a stage deploys as: `<project>-github-<stage>`, within IAM's 64. */
|
|
30
|
-
function roleName(project, stage) {
|
|
31
|
-
return `${project}-github-${stage}`.toLowerCase().replace(/[^a-z0-9+=,.@_-]/g, "-").slice(0, 64);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Who may assume the role: a workflow job running in this repository's
|
|
35
|
-
* `<stage>` environment, and nothing else — not another branch's job, not
|
|
36
|
-
* another environment's. That is what keeps a staging deploy from using the
|
|
37
|
-
* production role.
|
|
38
|
-
*/
|
|
39
|
-
function trustPolicy(providerArn, repo, stage) {
|
|
40
|
-
return JSON.stringify({
|
|
41
|
-
Version: "2012-10-17",
|
|
42
|
-
Statement: [{
|
|
43
|
-
Effect: "Allow",
|
|
44
|
-
Principal: { Federated: providerArn },
|
|
45
|
-
Action: "sts:AssumeRoleWithWebIdentity",
|
|
46
|
-
Condition: { StringEquals: {
|
|
47
|
-
[`${GITHUB_OIDC_HOST}:aud`]: AUDIENCE,
|
|
48
|
-
[`${GITHUB_OIDC_HOST}:sub`]: `repo:${repo}:environment:${stage}`
|
|
49
|
-
} }
|
|
50
|
-
}]
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
/** GitHub's OIDC provider in this account, created if it is not there. */
|
|
54
|
-
async function ensureOidcProvider(iam) {
|
|
55
|
-
const { OpenIDConnectProviderList = [] } = await iam.send(new ListOpenIDConnectProvidersCommand({}));
|
|
56
|
-
const existing = OpenIDConnectProviderList.find((p) => p.Arn?.endsWith(`oidc-provider/${GITHUB_OIDC_HOST}`))?.Arn;
|
|
57
|
-
if (existing) return existing;
|
|
58
|
-
const created = await iam.send(new CreateOpenIDConnectProviderCommand({
|
|
59
|
-
Url: `https://${GITHUB_OIDC_HOST}`,
|
|
60
|
-
ClientIDList: [AUDIENCE]
|
|
61
|
-
}));
|
|
62
|
-
return created.OpenIDConnectProviderArn;
|
|
63
|
-
}
|
|
64
|
-
/** The deploy role, created or brought back to this trust and policy. */
|
|
65
|
-
async function ensureRole(iam, name, trust, policyArn) {
|
|
66
|
-
let arn;
|
|
67
|
-
try {
|
|
68
|
-
const { Role } = await iam.send(new GetRoleCommand({ RoleName: name }));
|
|
69
|
-
await iam.send(new UpdateAssumeRolePolicyCommand({
|
|
70
|
-
RoleName: name,
|
|
71
|
-
PolicyDocument: trust
|
|
72
|
-
}));
|
|
73
|
-
arn = Role.Arn;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
if (error.name !== "NoSuchEntityException") throw error;
|
|
76
|
-
const { Role } = await iam.send(new CreateRoleCommand({
|
|
77
|
-
RoleName: name,
|
|
78
|
-
AssumeRolePolicyDocument: trust,
|
|
79
|
-
Description: "Deploys from GitHub Actions (gkm deploy:github)",
|
|
80
|
-
MaxSessionDuration: 3600 * 2
|
|
81
|
-
}));
|
|
82
|
-
arn = Role.Arn;
|
|
83
|
-
}
|
|
84
|
-
await iam.send(new AttachRolePolicyCommand({
|
|
85
|
-
RoleName: name,
|
|
86
|
-
PolicyArn: policyArn
|
|
87
|
-
}));
|
|
88
|
-
return arn;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* An IAM client for the stage's account.
|
|
92
|
-
*
|
|
93
|
-
* `fromIni` for a named profile, deliberately: it resolves exactly that
|
|
94
|
-
* profile — keys, assume-role, `credential_process` or SSO, whichever
|
|
95
|
-
* ~/.aws/config says — and never falls back to AWS_* in the environment. The
|
|
96
|
-
* provider chain checks the environment first, so exported staging keys would
|
|
97
|
-
* quietly win over `--profile prod` and the production role would land in the
|
|
98
|
-
* staging account.
|
|
99
|
-
*/
|
|
100
|
-
async function iamFor(profile, endpoint) {
|
|
101
|
-
const config = { region: "us-east-1" };
|
|
102
|
-
if (profile) {
|
|
103
|
-
const { fromIni } = await import("@aws-sdk/credential-providers");
|
|
104
|
-
config.credentials = fromIni({ profile });
|
|
105
|
-
}
|
|
106
|
-
if (endpoint) {
|
|
107
|
-
config.endpoint = endpoint;
|
|
108
|
-
config.credentials = {
|
|
109
|
-
accessKeyId: "test",
|
|
110
|
-
secretAccessKey: "test"
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return new IAMClient(config);
|
|
114
|
-
}
|
|
115
|
-
async function deployGithubCommand(options, deps = {}) {
|
|
116
|
-
const gh = deps.gh ?? defaultGh;
|
|
117
|
-
const { workspace } = await loadWorkspaceConfig(deps.cwd);
|
|
118
|
-
assertDeployedStage(workspace.stages, options.stage);
|
|
119
|
-
const repo = options.repo ?? gh([
|
|
120
|
-
"repo",
|
|
121
|
-
"view",
|
|
122
|
-
"--json",
|
|
123
|
-
"nameWithOwner",
|
|
124
|
-
"-q",
|
|
125
|
-
".nameWithOwner"
|
|
126
|
-
]);
|
|
127
|
-
const role = roleName(workspace.name, options.stage);
|
|
128
|
-
const policyArn = options.policyArn ?? DEFAULT_POLICY_ARN;
|
|
129
|
-
const keyPath = getKeyPath(options.stage, workspace.name);
|
|
130
|
-
const hasKey = existsSync(keyPath);
|
|
131
|
-
logger.log(`\n🔐 GitHub → AWS for stage "${options.stage}"\n`);
|
|
132
|
-
logger.log(` Repository: ${repo}`);
|
|
133
|
-
logger.log(` AWS profile: ${options.profile ?? "(default credentials)"}`);
|
|
134
|
-
logger.log(` Role: ${role}`);
|
|
135
|
-
logger.log(` Policy: ${policyArn}${options.policyArn ? "" : " (default; --policy-arn to narrow)"}`);
|
|
136
|
-
logger.log(` Trusted by: repo:${repo}:environment:${options.stage} only`);
|
|
137
|
-
logger.log(` Secrets key: ${hasKey ? keyPath : `none at ${keyPath} — run gkm secrets:init --stage ${options.stage} first`}`);
|
|
138
|
-
if (options.dryRun) {
|
|
139
|
-
logger.log("\n --dry-run: nothing changed.\n");
|
|
140
|
-
return { repo };
|
|
141
|
-
}
|
|
142
|
-
const iam = deps.iam ?? await iamFor(options.profile);
|
|
143
|
-
const providerArn = await ensureOidcProvider(iam).catch((error) => {
|
|
144
|
-
if (/SSO session/i.test(String(error?.message)) && options.profile) throw new SsoSessionExpired(options.profile);
|
|
145
|
-
throw error;
|
|
146
|
-
});
|
|
147
|
-
const roleArn = await ensureRole(iam, role, trustPolicy(providerArn, repo, options.stage), policyArn);
|
|
148
|
-
logger.log(`\n ✓ AWS: ${roleArn}`);
|
|
149
|
-
gh([
|
|
150
|
-
"api",
|
|
151
|
-
"--method",
|
|
152
|
-
"PUT",
|
|
153
|
-
`repos/${repo}/environments/${options.stage}`
|
|
154
|
-
]);
|
|
155
|
-
gh([
|
|
156
|
-
"variable",
|
|
157
|
-
"set",
|
|
158
|
-
"AWS_ROLE_ARN",
|
|
159
|
-
"--env",
|
|
160
|
-
options.stage,
|
|
161
|
-
"--repo",
|
|
162
|
-
repo,
|
|
163
|
-
"--body",
|
|
164
|
-
roleArn
|
|
165
|
-
]);
|
|
166
|
-
logger.log(` ✓ GitHub: environment "${options.stage}", AWS_ROLE_ARN`);
|
|
167
|
-
if (hasKey) {
|
|
168
|
-
gh([
|
|
169
|
-
"secret",
|
|
170
|
-
"set",
|
|
171
|
-
"GKM_SECRETS_KEY",
|
|
172
|
-
"--env",
|
|
173
|
-
options.stage,
|
|
174
|
-
"--repo",
|
|
175
|
-
repo
|
|
176
|
-
], readFileSync(keyPath, "utf-8").trim());
|
|
177
|
-
logger.log(" ✓ GitHub: GKM_SECRETS_KEY");
|
|
178
|
-
} else logger.log(` ⚠ No secrets key for "${options.stage}"; run gkm secrets:init --stage ${options.stage}, then this again.`);
|
|
179
|
-
logger.log(`\n Protect it: add required reviewers to the "${options.stage}" environment in the repository settings.\n`);
|
|
180
|
-
return {
|
|
181
|
-
roleArn,
|
|
182
|
-
repo
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
/** The profile's SSO login has lapsed; the fix is one command away. */
|
|
186
|
-
var SsoSessionExpired = class extends Error {
|
|
187
|
-
constructor(profile) {
|
|
188
|
-
super(`The SSO session for profile "${profile}" has expired or is invalid. Run: aws sso login --profile ${profile}`);
|
|
189
|
-
this.profile = profile;
|
|
190
|
-
this.name = "SsoSessionExpired";
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
//#endregion
|
|
195
|
-
export { deployGithubCommand };
|
|
196
|
-
//# sourceMappingURL=github-DpMZurEK.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"github-DpMZurEK.mjs","names":["defaultGh: Gh","project: string","stage: string","providerArn: string","repo: string","iam: IAMClient","name: string","trust: string","policyArn: string","arn: string","profile?: string","endpoint?: string","config: IAMClientConfig","options: DeployGithubOptions","deps: { iam?: IAMClient; gh?: Gh; cwd?: string }","profile: string"],"sources":["../src/deploy/github.ts"],"sourcesContent":["/**\n * `gkm deploy:github` — let GitHub Actions deploy one stage, with no keys.\n *\n * A stage usually lives in its own AWS account — staging in one, production in\n * another — so this runs once per stage, with that account's profile:\n *\n * gkm deploy:github --stage staging --profile acme-dev\n * gkm deploy:github --stage prod --profile acme-prod\n *\n * In the stage's account it makes sure GitHub's OIDC provider exists, and a\n * role that only this repository's `<stage>` environment can assume. On\n * GitHub it creates that environment and gives it what the generated deploy\n * workflow reads: `AWS_ROLE_ARN`, and the stage's secrets key as\n * `GKM_SECRETS_KEY`. Re-running it converges rather than duplicating.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport {\n\tAttachRolePolicyCommand,\n\tCreateOpenIDConnectProviderCommand,\n\tCreateRoleCommand,\n\tGetRoleCommand,\n\tIAMClient,\n\ttype IAMClientConfig,\n\tListOpenIDConnectProvidersCommand,\n\tUpdateAssumeRolePolicyCommand,\n} from '@aws-sdk/client-iam';\nimport { loadWorkspaceConfig } from '../config.js';\nimport { getKeyPath } from '../secrets/keystore.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\n\nconst logger = console;\n\nconst GITHUB_OIDC_HOST = 'token.actions.githubusercontent.com';\nconst AUDIENCE = 'sts.amazonaws.com';\n\n/**\n * What SST needs to create a stack is most of AWS, so this is the default —\n * said out loud in the output, and replaceable with `--policy-arn`.\n */\nexport const DEFAULT_POLICY_ARN = 'arn:aws:iam::aws:policy/AdministratorAccess';\n\nexport interface DeployGithubOptions {\n\tstage: string;\n\t/** The AWS profile for the stage's account. */\n\tprofile?: string;\n\t/** `owner/name`; defaults to the repository `gh` sees here. */\n\trepo?: string;\n\t/** The policy the deploy role gets. */\n\tpolicyArn?: string;\n\tdryRun?: boolean;\n}\n\n/** Runs `gh` with the given arguments and optional stdin, returning stdout. */\nexport type Gh = (args: string[], input?: string) => string;\n\nconst defaultGh: Gh = (args, input) =>\n\texecFileSync('gh', args, {\n\t\tencoding: 'utf-8',\n\t\t...(input === undefined\n\t\t\t? {}\n\t\t\t: { input, stdio: ['pipe', 'pipe', 'pipe'] as const }),\n\t}).trim();\n\n/** The role a stage deploys as: `<project>-github-<stage>`, within IAM's 64. */\nexport function roleName(project: string, stage: string): string {\n\treturn `${project}-github-${stage}`\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9+=,.@_-]/g, '-')\n\t\t.slice(0, 64);\n}\n\n/**\n * Who may assume the role: a workflow job running in this repository's\n * `<stage>` environment, and nothing else — not another branch's job, not\n * another environment's. That is what keeps a staging deploy from using the\n * production role.\n */\nexport function trustPolicy(\n\tproviderArn: string,\n\trepo: string,\n\tstage: string,\n): string {\n\treturn JSON.stringify({\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tPrincipal: { Federated: providerArn },\n\t\t\t\tAction: 'sts:AssumeRoleWithWebIdentity',\n\t\t\t\tCondition: {\n\t\t\t\t\tStringEquals: {\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:aud`]: AUDIENCE,\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:sub`]: `repo:${repo}:environment:${stage}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n}\n\n/** GitHub's OIDC provider in this account, created if it is not there. */\nexport async function ensureOidcProvider(iam: IAMClient): Promise<string> {\n\tconst { OpenIDConnectProviderList = [] } = await iam.send(\n\t\tnew ListOpenIDConnectProvidersCommand({}),\n\t);\n\tconst existing = OpenIDConnectProviderList.find((p) =>\n\t\tp.Arn?.endsWith(`oidc-provider/${GITHUB_OIDC_HOST}`),\n\t)?.Arn;\n\tif (existing) return existing;\n\n\tconst created = await iam.send(\n\t\tnew CreateOpenIDConnectProviderCommand({\n\t\t\tUrl: `https://${GITHUB_OIDC_HOST}`,\n\t\t\tClientIDList: [AUDIENCE],\n\t\t}),\n\t);\n\treturn created.OpenIDConnectProviderArn!;\n}\n\n/** The deploy role, created or brought back to this trust and policy. */\nexport async function ensureRole(\n\tiam: IAMClient,\n\tname: string,\n\ttrust: string,\n\tpolicyArn: string,\n): Promise<string> {\n\tlet arn: string;\n\ttry {\n\t\tconst { Role } = await iam.send(new GetRoleCommand({ RoleName: name }));\n\t\tawait iam.send(\n\t\t\tnew UpdateAssumeRolePolicyCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tPolicyDocument: trust,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t} catch (error) {\n\t\tif ((error as { name?: string }).name !== 'NoSuchEntityException') {\n\t\t\tthrow error;\n\t\t}\n\t\tconst { Role } = await iam.send(\n\t\t\tnew CreateRoleCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tAssumeRolePolicyDocument: trust,\n\t\t\t\tDescription: 'Deploys from GitHub Actions (gkm deploy:github)',\n\t\t\t\t// SST deploys can run long; the default hour is tight.\n\t\t\t\tMaxSessionDuration: 3600 * 2,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t}\n\n\t// Attaching an attached policy is a no-op, so this converges too.\n\tawait iam.send(\n\t\tnew AttachRolePolicyCommand({ RoleName: name, PolicyArn: policyArn }),\n\t);\n\treturn arn;\n}\n\n/**\n * An IAM client for the stage's account.\n *\n * `fromIni` for a named profile, deliberately: it resolves exactly that\n * profile — keys, assume-role, `credential_process` or SSO, whichever\n * ~/.aws/config says — and never falls back to AWS_* in the environment. The\n * provider chain checks the environment first, so exported staging keys would\n * quietly win over `--profile prod` and the production role would land in the\n * staging account.\n */\nexport async function iamFor(\n\tprofile?: string,\n\tendpoint?: string,\n): Promise<IAMClient> {\n\tconst config: IAMClientConfig = { region: 'us-east-1' };\n\tif (profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile });\n\t}\n\tif (endpoint) {\n\t\tconfig.endpoint = endpoint;\n\t\tconfig.credentials = { accessKeyId: 'test', secretAccessKey: 'test' };\n\t}\n\treturn new IAMClient(config);\n}\n\nexport async function deployGithubCommand(\n\toptions: DeployGithubOptions,\n\tdeps: { iam?: IAMClient; gh?: Gh; cwd?: string } = {},\n): Promise<{ roleArn?: string; repo: string }> {\n\tconst gh = deps.gh ?? defaultGh;\n\tconst { workspace } = await loadWorkspaceConfig(deps.cwd);\n\tassertDeployedStage(workspace.stages, options.stage);\n\n\tconst repo =\n\t\toptions.repo ??\n\t\tgh(['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner']);\n\tconst role = roleName(workspace.name, options.stage);\n\tconst policyArn = options.policyArn ?? DEFAULT_POLICY_ARN;\n\tconst keyPath = getKeyPath(options.stage, workspace.name);\n\tconst hasKey = existsSync(keyPath);\n\n\tlogger.log(`\\n🔐 GitHub → AWS for stage \"${options.stage}\"\\n`);\n\tlogger.log(` Repository: ${repo}`);\n\tlogger.log(` AWS profile: ${options.profile ?? '(default credentials)'}`);\n\tlogger.log(` Role: ${role}`);\n\tlogger.log(\n\t\t` Policy: ${policyArn}${options.policyArn ? '' : ' (default; --policy-arn to narrow)'}`,\n\t);\n\tlogger.log(` Trusted by: repo:${repo}:environment:${options.stage} only`);\n\tlogger.log(\n\t\t` Secrets key: ${hasKey ? keyPath : `none at ${keyPath} — run gkm secrets:init --stage ${options.stage} first`}`,\n\t);\n\n\tif (options.dryRun) {\n\t\tlogger.log('\\n --dry-run: nothing changed.\\n');\n\t\treturn { repo };\n\t}\n\n\tconst iam = deps.iam ?? (await iamFor(options.profile));\n\tconst providerArn = await ensureOidcProvider(iam).catch((error) => {\n\t\t// The first AWS call is where an expired SSO login surfaces; the SDK's\n\t\t// message does not say which profile, and this command knows.\n\t\tif (/SSO session/i.test(String(error?.message)) && options.profile) {\n\t\t\tthrow new SsoSessionExpired(options.profile);\n\t\t}\n\t\tthrow error;\n\t});\n\tconst roleArn = await ensureRole(\n\t\tiam,\n\t\trole,\n\t\ttrustPolicy(providerArn, repo, options.stage),\n\t\tpolicyArn,\n\t);\n\tlogger.log(`\\n ✓ AWS: ${roleArn}`);\n\n\t// The environment the generated deploy workflow runs the stage in.\n\tgh(['api', '--method', 'PUT', `repos/${repo}/environments/${options.stage}`]);\n\tgh([\n\t\t'variable',\n\t\t'set',\n\t\t'AWS_ROLE_ARN',\n\t\t'--env',\n\t\toptions.stage,\n\t\t'--repo',\n\t\trepo,\n\t\t'--body',\n\t\troleArn,\n\t]);\n\tlogger.log(` ✓ GitHub: environment \"${options.stage}\", AWS_ROLE_ARN`);\n\n\tif (hasKey) {\n\t\t// Through stdin, so the key is never an argument a process list shows.\n\t\tgh(\n\t\t\t[\n\t\t\t\t'secret',\n\t\t\t\t'set',\n\t\t\t\t'GKM_SECRETS_KEY',\n\t\t\t\t'--env',\n\t\t\t\toptions.stage,\n\t\t\t\t'--repo',\n\t\t\t\trepo,\n\t\t\t],\n\t\t\treadFileSync(keyPath, 'utf-8').trim(),\n\t\t);\n\t\tlogger.log(' ✓ GitHub: GKM_SECRETS_KEY');\n\t} else {\n\t\tlogger.log(\n\t\t\t` ⚠ No secrets key for \"${options.stage}\"; run gkm secrets:init --stage ${options.stage}, then this again.`,\n\t\t);\n\t}\n\n\tlogger.log(\n\t\t`\\n Protect it: add required reviewers to the \"${options.stage}\" environment in the repository settings.\\n`,\n\t);\n\treturn { roleArn, repo };\n}\n\n/** The profile's SSO login has lapsed; the fix is one command away. */\nexport class SsoSessionExpired extends Error {\n\tconstructor(readonly profile: string) {\n\t\tsuper(\n\t\t\t`The SSO session for profile \"${profile}\" has expired or is invalid. Run: aws sso login --profile ${profile}`,\n\t\t);\n\t\tthis.name = 'SsoSessionExpired';\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-BzJ7QJ9c.d.mts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"sourcesContent":[],"mappings":";;;;;;AASA;AAoBA;AAoBA;;;cAxCa;ACoHb;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;AAAwC,iBDjLxB,kBAAA,CCiLwB,SAAA,CAAA,EDjLO,SCiLP,CAAA,EAAA,MAAA;;;AAGlB;AA0DtB;AAA6B,iBD1Nb,iBAAA,CC0Na,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;;AA9I7B;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;;;;AAGsB;AA0DtB;;;;;AAGe;AA6Bf;AAmBA;AAwBA;AAaA;AAiBA;;;;AAGY;AAkCZ;AAmCA;AAAoC,iBA/TpB,eA+ToB,CAAA,oBA/TgB,UA+ThB,CAAA,CAAA,MAAA,EA9T3B,cA8T2B,CA9TZ,KA8TY,CAAA,CAAA,EA7TjC,uBA6TiC,CA7TT,KA6TS,CAAA;;;AAI3B;AAgDO,iBAnVA,kBAAA,CAqV2B,MAAA,EApVlC,eAoVkC,EAAA,GAAA,EAAA,MAAA,CAAA,EAlVxC,mBAkVwC;;;;;iBApS3B,wBAAA,SACP,yBAEN;;;;;iBA0Da,aAAA,SACP,YAAY,+BAElB;;;;;;;iBA6Ba,uBAAA,YACJ;;;;;;;;;;;;iBAkBI,iBAAA,YACJ;;;;;;;iBAuBI,iBAAA,YAA6B;;iBAa7B,iBAAA,SAA0B;;;;;iBAiB1B,eAAA,YACJ,uCAET;;;;;iBAkCa,gBAAA,YAA4B;;;;;;;;;;iBAmC5B,oBAAA,YACJ,2DAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDa,mBAAA;;cAEqB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-CfMjtdVC.d.cts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"sourcesContent":[],"mappings":";;;;;;AASA;AAoBA;AAoBA;;;cAxCa;ACoHb;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;AAAwC,iBDjLxB,kBAAA,CCiLwB,SAAA,CAAA,EDjLO,SCiLP,CAAA,EAAA,MAAA;;;AAGlB;AA0DtB;AAA6B,iBD1Nb,iBAAA,CC0Na,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;;AA9I7B;;;;;;;AAE0B;AA8B1B;;;;AAGsB;AA8CtB;;;;AAGsB;AA0DtB;;;;;AAGe;AA6Bf;AAmBA;AAwBA;AAaA;AAiBA;;;;AAGY;AAkCZ;AAmCA;AAAoC,iBA/TpB,eA+ToB,CAAA,oBA/TgB,UA+ThB,CAAA,CAAA,MAAA,EA9T3B,cA8T2B,CA9TZ,KA8TY,CAAA,CAAA,EA7TjC,uBA6TiC,CA7TT,KA6TS,CAAA;;;AAI3B;AAgDO,iBAnVA,kBAAA,CAqV2B,MAAA,EApVlC,eAoVkC,EAAA,GAAA,EAAA,MAAA,CAAA,EAlVxC,mBAkVwC;;;;;iBApS3B,wBAAA,SACP,yBAEN;;;;;iBA0Da,aAAA,SACP,YAAY,+BAElB;;;;;;;iBA6Ba,uBAAA,YACJ;;;;;;;;;;;;iBAkBI,iBAAA,YACJ;;;;;;;iBAuBI,iBAAA,YAA6B;;iBAa7B,iBAAA,SAA0B;;;;;iBAiB1B,eAAA,YACJ,uCAET;;;;;iBAkCa,gBAAA,YAA4B;;;;;;;;;;iBAmC5B,oBAAA,YACJ,2DAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDa,mBAAA;;cAEqB"}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
const node_fs = require_chunk.__toESM(require("node:fs"));
|
|
3
|
-
const node_path = require_chunk.__toESM(require("node:path"));
|
|
4
|
-
const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
|
|
5
|
-
const node_os = require_chunk.__toESM(require("node:os"));
|
|
6
|
-
const node_crypto = require_chunk.__toESM(require("node:crypto"));
|
|
7
|
-
|
|
8
|
-
//#region src/secrets/keystore.ts
|
|
9
|
-
/** Key length for AES-256 encryption */
|
|
10
|
-
const KEY_LENGTH = 32;
|
|
11
|
-
/**
|
|
12
|
-
* Get the keystore directory for a project.
|
|
13
|
-
* Keys are stored at ~/.gkm/{project-name}/
|
|
14
|
-
*
|
|
15
|
-
* @param projectName - Name of the project (defaults to current directory name)
|
|
16
|
-
* @returns Path to the keystore directory
|
|
17
|
-
*/
|
|
18
|
-
function getKeystoreDir(projectName) {
|
|
19
|
-
const name = projectName ?? (0, node_path.basename)(process.cwd());
|
|
20
|
-
return (0, node_path.join)((0, node_os.homedir)(), ".gkm", name);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Get the path to a stage's encryption key.
|
|
24
|
-
*
|
|
25
|
-
* @param stage - Stage name (e.g., 'development', 'production')
|
|
26
|
-
* @param projectName - Name of the project (defaults to current directory name)
|
|
27
|
-
* @returns Path to the key file
|
|
28
|
-
*/
|
|
29
|
-
function getKeyPath(stage, projectName) {
|
|
30
|
-
return (0, node_path.join)(getKeystoreDir(projectName), `${stage}.key`);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Generate a new encryption key for a stage.
|
|
34
|
-
* The key is stored at ~/.gkm/{project-name}/{stage}.key with restricted permissions.
|
|
35
|
-
*
|
|
36
|
-
* @param stage - Stage name
|
|
37
|
-
* @param projectName - Project name (defaults to current directory name)
|
|
38
|
-
* @returns The generated key as a hex string
|
|
39
|
-
*/
|
|
40
|
-
async function generateKey(stage, projectName) {
|
|
41
|
-
const keyDir = getKeystoreDir(projectName);
|
|
42
|
-
const keyPath = getKeyPath(stage, projectName);
|
|
43
|
-
await (0, node_fs_promises.mkdir)(keyDir, {
|
|
44
|
-
recursive: true,
|
|
45
|
-
mode: 448
|
|
46
|
-
});
|
|
47
|
-
const key = (0, node_crypto.randomBytes)(KEY_LENGTH).toString("hex");
|
|
48
|
-
await (0, node_fs_promises.writeFile)(keyPath, key, {
|
|
49
|
-
mode: 384,
|
|
50
|
-
encoding: "utf-8"
|
|
51
|
-
});
|
|
52
|
-
await (0, node_fs_promises.chmod)(keyPath, 384);
|
|
53
|
-
return key;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Read an encryption key for a stage.
|
|
57
|
-
*
|
|
58
|
-
* @param stage - Stage name
|
|
59
|
-
* @param projectName - Project name (defaults to current directory name)
|
|
60
|
-
* @returns The key as a hex string, or null if not found
|
|
61
|
-
*/
|
|
62
|
-
async function readKey(stage, projectName) {
|
|
63
|
-
const keyPath = getKeyPath(stage, projectName);
|
|
64
|
-
if (!(0, node_fs.existsSync)(keyPath)) return null;
|
|
65
|
-
const key = await (0, node_fs_promises.readFile)(keyPath, "utf-8");
|
|
66
|
-
return key.trim();
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Get or create a key for a stage.
|
|
70
|
-
* If the key already exists, it is returned. Otherwise, a new key is generated.
|
|
71
|
-
*
|
|
72
|
-
* @param stage - Stage name
|
|
73
|
-
* @param projectName - Project name (defaults to current directory name)
|
|
74
|
-
* @returns The key as a hex string
|
|
75
|
-
*/
|
|
76
|
-
async function getOrCreateKey(stage, projectName) {
|
|
77
|
-
const existingKey = await readKey(stage, projectName);
|
|
78
|
-
if (existingKey) return existingKey;
|
|
79
|
-
return generateKey(stage, projectName);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
//#endregion
|
|
83
|
-
Object.defineProperty(exports, 'getKeyPath', {
|
|
84
|
-
enumerable: true,
|
|
85
|
-
get: function () {
|
|
86
|
-
return getKeyPath;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
Object.defineProperty(exports, 'getOrCreateKey', {
|
|
90
|
-
enumerable: true,
|
|
91
|
-
get: function () {
|
|
92
|
-
return getOrCreateKey;
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
Object.defineProperty(exports, 'readKey', {
|
|
96
|
-
enumerable: true,
|
|
97
|
-
get: function () {
|
|
98
|
-
return readKey;
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
//# sourceMappingURL=keystore-C9rint2E.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keystore-C9rint2E.cjs","names":["projectName?: string","stage: string"],"sources":["../src/secrets/keystore.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { chmod, mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { basename, join } from 'node:path';\n\n/** Key length for AES-256 encryption */\nconst KEY_LENGTH = 32; // 256 bits\n\n/**\n * Get the keystore directory for a project.\n * Keys are stored at ~/.gkm/{project-name}/\n *\n * @param projectName - Name of the project (defaults to current directory name)\n * @returns Path to the keystore directory\n */\nexport function getKeystoreDir(projectName?: string): string {\n\tconst name = projectName ?? basename(process.cwd());\n\treturn join(homedir(), '.gkm', name);\n}\n\n/**\n * Get the path to a stage's encryption key.\n *\n * @param stage - Stage name (e.g., 'development', 'production')\n * @param projectName - Name of the project (defaults to current directory name)\n * @returns Path to the key file\n */\nexport function getKeyPath(stage: string, projectName?: string): string {\n\treturn join(getKeystoreDir(projectName), `${stage}.key`);\n}\n\n/**\n * Check if a key exists for a stage.\n */\nexport function keyExists(stage: string, projectName?: string): boolean {\n\treturn existsSync(getKeyPath(stage, projectName));\n}\n\n/**\n * Generate a new encryption key for a stage.\n * The key is stored at ~/.gkm/{project-name}/{stage}.key with restricted permissions.\n *\n * @param stage - Stage name\n * @param projectName - Project name (defaults to current directory name)\n * @returns The generated key as a hex string\n */\nexport async function generateKey(\n\tstage: string,\n\tprojectName?: string,\n): Promise<string> {\n\tconst keyDir = getKeystoreDir(projectName);\n\tconst keyPath = getKeyPath(stage, projectName);\n\n\t// Ensure keystore directory exists with restricted permissions\n\tawait mkdir(keyDir, { recursive: true, mode: 0o700 });\n\n\t// Generate random key\n\tconst key = randomBytes(KEY_LENGTH).toString('hex');\n\n\t// Write key with restricted permissions (owner read/write only)\n\tawait writeFile(keyPath, key, { mode: 0o600, encoding: 'utf-8' });\n\n\t// Ensure permissions are set correctly (in case file existed)\n\tawait chmod(keyPath, 0o600);\n\n\treturn key;\n}\n\n/**\n * Read an encryption key for a stage.\n *\n * @param stage - Stage name\n * @param projectName - Project name (defaults to current directory name)\n * @returns The key as a hex string, or null if not found\n */\nexport async function readKey(\n\tstage: string,\n\tprojectName?: string,\n): Promise<string | null> {\n\tconst keyPath = getKeyPath(stage, projectName);\n\n\tif (!existsSync(keyPath)) {\n\t\treturn null;\n\t}\n\n\tconst key = await readFile(keyPath, 'utf-8');\n\treturn key.trim();\n}\n\n/**\n * Read an encryption key for a stage, throwing if not found.\n */\nexport async function requireKey(\n\tstage: string,\n\tprojectName?: string,\n): Promise<string> {\n\tconst key = await readKey(stage, projectName);\n\n\tif (!key) {\n\t\tconst name = projectName ?? basename(process.cwd());\n\t\tthrow new Error(\n\t\t\t`Encryption key not found for stage \"${stage}\" in project \"${name}\". ` +\n\t\t\t\t`Expected key at: ${getKeyPath(stage, projectName)}`,\n\t\t);\n\t}\n\n\treturn key;\n}\n\n/**\n * Delete a key for a stage.\n */\nexport async function deleteKey(\n\tstage: string,\n\tprojectName?: string,\n): Promise<void> {\n\tconst keyPath = getKeyPath(stage, projectName);\n\n\tif (existsSync(keyPath)) {\n\t\tawait rm(keyPath);\n\t}\n}\n\n/**\n * Get or create a key for a stage.\n * If the key already exists, it is returned. Otherwise, a new key is generated.\n *\n * @param stage - Stage name\n * @param projectName - Project name (defaults to current directory name)\n * @returns The key as a hex string\n */\nexport async function getOrCreateKey(\n\tstage: string,\n\tprojectName?: string,\n): Promise<string> {\n\tconst existingKey = await readKey(stage, projectName);\n\n\tif (existingKey) {\n\t\treturn existingKey;\n\t}\n\n\treturn generateKey(stage, projectName);\n}\n"],"mappings":";;;;;;;;;AAOA,MAAM,aAAa;;;;;;;;AASnB,SAAgB,eAAeA,aAA8B;CAC5D,MAAM,OAAO,eAAe,wBAAS,QAAQ,KAAK,CAAC;AACnD,QAAO,oBAAK,sBAAS,EAAE,QAAQ,KAAK;AACpC;;;;;;;;AASD,SAAgB,WAAWC,OAAeD,aAA8B;AACvE,QAAO,oBAAK,eAAe,YAAY,GAAG,EAAE,MAAM,MAAM;AACxD;;;;;;;;;AAiBD,eAAsB,YACrBC,OACAD,aACkB;CAClB,MAAM,SAAS,eAAe,YAAY;CAC1C,MAAM,UAAU,WAAW,OAAO,YAAY;AAG9C,OAAM,4BAAM,QAAQ;EAAE,WAAW;EAAM,MAAM;CAAO,EAAC;CAGrD,MAAM,MAAM,6BAAY,WAAW,CAAC,SAAS,MAAM;AAGnD,OAAM,gCAAU,SAAS,KAAK;EAAE,MAAM;EAAO,UAAU;CAAS,EAAC;AAGjE,OAAM,4BAAM,SAAS,IAAM;AAE3B,QAAO;AACP;;;;;;;;AASD,eAAsB,QACrBC,OACAD,aACyB;CACzB,MAAM,UAAU,WAAW,OAAO,YAAY;AAE9C,MAAK,wBAAW,QAAQ,CACvB,QAAO;CAGR,MAAM,MAAM,MAAM,+BAAS,SAAS,QAAQ;AAC5C,QAAO,IAAI,MAAM;AACjB;;;;;;;;;AA4CD,eAAsB,eACrBC,OACAD,aACkB;CAClB,MAAM,cAAc,MAAM,QAAQ,OAAO,YAAY;AAErD,KAAI,YACH,QAAO;AAGR,QAAO,YAAY,OAAO,YAAY;AACtC"}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { basename, join } from "node:path";
|
|
3
|
-
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
-
import { homedir } from "node:os";
|
|
5
|
-
import { randomBytes } from "node:crypto";
|
|
6
|
-
|
|
7
|
-
//#region src/secrets/keystore.ts
|
|
8
|
-
/** Key length for AES-256 encryption */
|
|
9
|
-
const KEY_LENGTH = 32;
|
|
10
|
-
/**
|
|
11
|
-
* Get the keystore directory for a project.
|
|
12
|
-
* Keys are stored at ~/.gkm/{project-name}/
|
|
13
|
-
*
|
|
14
|
-
* @param projectName - Name of the project (defaults to current directory name)
|
|
15
|
-
* @returns Path to the keystore directory
|
|
16
|
-
*/
|
|
17
|
-
function getKeystoreDir(projectName) {
|
|
18
|
-
const name = projectName ?? basename(process.cwd());
|
|
19
|
-
return join(homedir(), ".gkm", name);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get the path to a stage's encryption key.
|
|
23
|
-
*
|
|
24
|
-
* @param stage - Stage name (e.g., 'development', 'production')
|
|
25
|
-
* @param projectName - Name of the project (defaults to current directory name)
|
|
26
|
-
* @returns Path to the key file
|
|
27
|
-
*/
|
|
28
|
-
function getKeyPath(stage, projectName) {
|
|
29
|
-
return join(getKeystoreDir(projectName), `${stage}.key`);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Generate a new encryption key for a stage.
|
|
33
|
-
* The key is stored at ~/.gkm/{project-name}/{stage}.key with restricted permissions.
|
|
34
|
-
*
|
|
35
|
-
* @param stage - Stage name
|
|
36
|
-
* @param projectName - Project name (defaults to current directory name)
|
|
37
|
-
* @returns The generated key as a hex string
|
|
38
|
-
*/
|
|
39
|
-
async function generateKey(stage, projectName) {
|
|
40
|
-
const keyDir = getKeystoreDir(projectName);
|
|
41
|
-
const keyPath = getKeyPath(stage, projectName);
|
|
42
|
-
await mkdir(keyDir, {
|
|
43
|
-
recursive: true,
|
|
44
|
-
mode: 448
|
|
45
|
-
});
|
|
46
|
-
const key = randomBytes(KEY_LENGTH).toString("hex");
|
|
47
|
-
await writeFile(keyPath, key, {
|
|
48
|
-
mode: 384,
|
|
49
|
-
encoding: "utf-8"
|
|
50
|
-
});
|
|
51
|
-
await chmod(keyPath, 384);
|
|
52
|
-
return key;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Read an encryption key for a stage.
|
|
56
|
-
*
|
|
57
|
-
* @param stage - Stage name
|
|
58
|
-
* @param projectName - Project name (defaults to current directory name)
|
|
59
|
-
* @returns The key as a hex string, or null if not found
|
|
60
|
-
*/
|
|
61
|
-
async function readKey(stage, projectName) {
|
|
62
|
-
const keyPath = getKeyPath(stage, projectName);
|
|
63
|
-
if (!existsSync(keyPath)) return null;
|
|
64
|
-
const key = await readFile(keyPath, "utf-8");
|
|
65
|
-
return key.trim();
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Get or create a key for a stage.
|
|
69
|
-
* If the key already exists, it is returned. Otherwise, a new key is generated.
|
|
70
|
-
*
|
|
71
|
-
* @param stage - Stage name
|
|
72
|
-
* @param projectName - Project name (defaults to current directory name)
|
|
73
|
-
* @returns The key as a hex string
|
|
74
|
-
*/
|
|
75
|
-
async function getOrCreateKey(stage, projectName) {
|
|
76
|
-
const existingKey = await readKey(stage, projectName);
|
|
77
|
-
if (existingKey) return existingKey;
|
|
78
|
-
return generateKey(stage, projectName);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
//#endregion
|
|
82
|
-
export { getKeyPath, getOrCreateKey, readKey };
|
|
83
|
-
//# sourceMappingURL=keystore-TxeYM7an.mjs.map
|