@geekmidas/cli 10.0.0-alpha.122 → 10.0.0-alpha.124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EndpointGenerator-BDa6pPgE.cjs → EndpointGenerator-B2MUa4M2.cjs} +2 -2
- package/dist/{EndpointGenerator-BDa6pPgE.cjs.map → EndpointGenerator-B2MUa4M2.cjs.map} +1 -1
- package/dist/{EndpointGenerator-CP_z_E3e.mjs → EndpointGenerator-Z_BUTocT.mjs} +2 -2
- package/dist/{EndpointGenerator-CP_z_E3e.mjs.map → EndpointGenerator-Z_BUTocT.mjs.map} +1 -1
- package/dist/{GoDaddyProvider-BJ9j9mR7.cjs → GoDaddyProvider-0z5RAN1k.cjs} +3 -3
- package/dist/{GoDaddyProvider-BJ9j9mR7.cjs.map → GoDaddyProvider-0z5RAN1k.cjs.map} +1 -1
- package/dist/{GoDaddyProvider-wIKYdm7V.mjs → GoDaddyProvider-55x4o-4z.mjs} +3 -3
- package/dist/{GoDaddyProvider-wIKYdm7V.mjs.map → GoDaddyProvider-55x4o-4z.mjs.map} +1 -1
- package/dist/{HostingerProvider-BNpS9aRJ.mjs → HostingerProvider-Cjh_2Ml6.mjs} +2 -2
- package/dist/{HostingerProvider-BNpS9aRJ.mjs.map → HostingerProvider-Cjh_2Ml6.mjs.map} +1 -1
- package/dist/{HostingerProvider-DR1iws1P.cjs → HostingerProvider-OdQmKXE3.cjs} +2 -2
- package/dist/{HostingerProvider-DR1iws1P.cjs.map → HostingerProvider-OdQmKXE3.cjs.map} +1 -1
- package/dist/{LegacyStateStore-CkXUJP7i.mjs → LegacyStateStore-C-vumKSN.mjs} +3 -3
- package/dist/{LegacyStateStore-CkXUJP7i.mjs.map → LegacyStateStore-C-vumKSN.mjs.map} +1 -1
- package/dist/{LegacyStateStore-D1S87I_B.cjs → LegacyStateStore-DRpB-yC5.cjs} +3 -3
- package/dist/{LegacyStateStore-D1S87I_B.cjs.map → LegacyStateStore-DRpB-yC5.cjs.map} +1 -1
- package/dist/{LocalStateStore-DmXfpvu4.cjs → LocalStateStore-C3ummuDT.cjs} +2 -2
- package/dist/{LocalStateStore-DmXfpvu4.cjs.map → LocalStateStore-C3ummuDT.cjs.map} +1 -1
- package/dist/{LocalStateStore-BWoWeSq0.mjs → LocalStateStore-CtOjpV1w.mjs} +2 -2
- package/dist/{LocalStateStore-BWoWeSq0.mjs.map → LocalStateStore-CtOjpV1w.mjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-CsrukCE-.mjs → OpenApiTsGenerator-MtnMQL_g.mjs} +2 -2
- package/dist/{OpenApiTsGenerator-CsrukCE-.mjs.map → OpenApiTsGenerator-MtnMQL_g.mjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-FNhY7Ssz.cjs → OpenApiTsGenerator-t3_E98Fi.cjs} +2 -2
- package/dist/{OpenApiTsGenerator-FNhY7Ssz.cjs.map → OpenApiTsGenerator-t3_E98Fi.cjs.map} +1 -1
- package/dist/{S3StateStore-D19JSGE9.mjs → S3StateStore-BC4Jm3Tw.mjs} +2 -2
- package/dist/{S3StateStore-D19JSGE9.mjs.map → S3StateStore-BC4Jm3Tw.mjs.map} +1 -1
- package/dist/{S3StateStore-BEdsjjP4.cjs → S3StateStore-BeArp0aF.cjs} +2 -2
- package/dist/{S3StateStore-BEdsjjP4.cjs.map → S3StateStore-BeArp0aF.cjs.map} +1 -1
- package/dist/{SSMStateStore-7xKw0Zz9.mjs → SSMStateStore-Crl76aYZ.mjs} +2 -2
- package/dist/{SSMStateStore-7xKw0Zz9.mjs.map → SSMStateStore-Crl76aYZ.mjs.map} +1 -1
- package/dist/{SSMStateStore--2bcxoiH.cjs → SSMStateStore-DcstR6cW.cjs} +2 -2
- package/dist/{SSMStateStore--2bcxoiH.cjs.map → SSMStateStore-DcstR6cW.cjs.map} +1 -1
- package/dist/{SubscriberGenerator-C8CPxrCK.cjs → SubscriberGenerator-C3QTae-R.cjs} +237 -54
- package/dist/SubscriberGenerator-C3QTae-R.cjs.map +1 -0
- package/dist/{SubscriberGenerator-y3pncae_.mjs → SubscriberGenerator-COAVPgM-.mjs} +227 -56
- package/dist/SubscriberGenerator-COAVPgM-.mjs.map +1 -0
- package/dist/{add-DlFUKdjX.cjs → add-BFjb6mMq.cjs} +7 -7
- package/dist/{add-DlFUKdjX.cjs.map → add-BFjb6mMq.cjs.map} +1 -1
- package/dist/{add-Bu6FkaTn.mjs → add-CIjmgzkb.mjs} +6 -6
- package/dist/{add-Bu6FkaTn.mjs.map → add-CIjmgzkb.mjs.map} +1 -1
- package/dist/{bundler-Bg0lPDoi.cjs → bundler-CiUoIsku.cjs} +5 -5
- package/dist/{bundler-Bg0lPDoi.cjs.map → bundler-CiUoIsku.cjs.map} +1 -1
- package/dist/{bundler-CgE5XTyr.mjs → bundler-D6KFNpQk.mjs} +5 -5
- package/dist/{bundler-CgE5XTyr.mjs.map → bundler-D6KFNpQk.mjs.map} +1 -1
- package/dist/{cli-z5S3bHyK.mjs → cli-DNtSTtMc.mjs} +4 -4
- package/dist/{cli-z5S3bHyK.mjs.map → cli-DNtSTtMc.mjs.map} +1 -1
- package/dist/{cli-Cvjlnpon.cjs → cli-r4eUr98C.cjs} +4 -4
- package/dist/{cli-Cvjlnpon.cjs.map → cli-r4eUr98C.cjs.map} +1 -1
- package/dist/{compose-bKLAtHLj.cjs → compose-BfXXWJSp.cjs} +362 -59
- package/dist/compose-BfXXWJSp.cjs.map +1 -0
- package/dist/{compose-CgBPA44v.mjs → compose-DJvvmF3X.mjs} +336 -33
- package/dist/compose-DJvvmF3X.mjs.map +1 -0
- package/dist/{config-D48erO2j.d.mts → config-IgK6YaGp.d.cts} +3 -4
- package/dist/config-IgK6YaGp.d.cts.map +1 -0
- package/dist/{config-DHDtsQrB.d.cts → config-kE-p5hxq.d.mts} +3 -4
- package/dist/config-kE-p5hxq.d.mts.map +1 -0
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +2 -2
- package/dist/{credentialSchemas-B67WJOOm.cjs → credentialSchemas-AhIBuQxQ.cjs} +2 -2
- package/dist/{credentialSchemas-B67WJOOm.cjs.map → credentialSchemas-AhIBuQxQ.cjs.map} +1 -1
- package/dist/{credentialSchemas-DDOLRCLF.mjs → credentialSchemas-DLKbxYBy.mjs} +2 -2
- package/dist/{credentialSchemas-DDOLRCLF.mjs.map → credentialSchemas-DLKbxYBy.mjs.map} +1 -1
- package/dist/{credentials-Zqr3QQYB.cjs → credentials-D7XJypNd.cjs} +173 -3
- package/dist/credentials-D7XJypNd.cjs.map +1 -0
- package/dist/{credentials-B5N5yKk6.mjs → credentials-DpfnUvIR.mjs} +132 -4
- package/dist/credentials-DpfnUvIR.mjs.map +1 -0
- package/dist/deploy/public.cjs +16 -17
- package/dist/deploy/public.cjs.map +1 -1
- package/dist/deploy/public.d.cts +3 -5
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +3 -5
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +11 -12
- package/dist/deploy/public.mjs.map +1 -1
- package/dist/{deploy-CI85F6dr.cjs → deploy-BbI1UMh3.cjs} +477 -156
- package/dist/deploy-BbI1UMh3.cjs.map +1 -0
- package/dist/{deploy-Ddy8UBoE.mjs → deploy-CiRYwFmr.mjs} +456 -117
- package/dist/deploy-CiRYwFmr.mjs.map +1 -0
- package/dist/{discover-C5roJuc9.mjs → discover-BvJOVsYG.mjs} +66 -14
- package/dist/discover-BvJOVsYG.mjs.map +1 -0
- package/dist/{discover-DozUKs8f.cjs → discover-ojkcbxHw.cjs} +88 -12
- package/dist/discover-ojkcbxHw.cjs.map +1 -0
- package/dist/{dokploy-CiozgdKO.cjs → dokploy-C0aQrCgs.cjs} +2 -2
- package/dist/{dokploy-CiozgdKO.cjs.map → dokploy-C0aQrCgs.cjs.map} +1 -1
- package/dist/{dokploy-Boj1NSHV.mjs → dokploy-MM7c3IE0.mjs} +2 -2
- package/dist/{dokploy-Boj1NSHV.mjs.map → dokploy-MM7c3IE0.mjs.map} +1 -1
- package/dist/{drivers-DbjiYpW6.cjs → drivers-CQ32PB5w.cjs} +2 -2
- package/dist/{drivers-DbjiYpW6.cjs.map → drivers-CQ32PB5w.cjs.map} +1 -1
- package/dist/{drivers-BjGDYfnC.mjs → drivers-Chb5Akov.mjs} +2 -2
- package/dist/{drivers-BjGDYfnC.mjs.map → drivers-Chb5Akov.mjs.map} +1 -1
- package/dist/{eas-DCg41jKK.mjs → eas-1Ee6kql0.mjs} +2 -2
- package/dist/{eas-DCg41jKK.mjs.map → eas-1Ee6kql0.mjs.map} +1 -1
- package/dist/{eas-BmBjIFf_.cjs → eas-CJoys9yh.cjs} +2 -2
- package/dist/{eas-BmBjIFf_.cjs.map → eas-CJoys9yh.cjs.map} +1 -1
- package/dist/{emit-C1e8qD08.mjs → emit-CNpuV_6Q.mjs} +17 -1
- package/dist/emit-CNpuV_6Q.mjs.map +1 -0
- package/dist/{emit-Dmc1nvdS.cjs → emit-qvHxMV9b.cjs} +17 -1
- package/dist/emit-qvHxMV9b.cjs.map +1 -0
- package/dist/{encryption-QOQbGXgV.mjs → encryption-B8Bk1Mvu.mjs} +3 -3
- package/dist/{encryption-QOQbGXgV.mjs.map → encryption-B8Bk1Mvu.mjs.map} +1 -1
- package/dist/{encryption-CwLWV2ig.cjs → encryption-Bo9VlRnl.cjs} +3 -3
- package/dist/{encryption-CwLWV2ig.cjs.map → encryption-Bo9VlRnl.cjs.map} +1 -1
- package/dist/{engine-HVqo3mQu.mjs → engine-BuinpJfS.mjs} +7 -8
- package/dist/{engine-HVqo3mQu.mjs.map → engine-BuinpJfS.mjs.map} +1 -1
- package/dist/{engine-D7YNY3v7.cjs → engine-esxTxcIx.cjs} +10 -11
- package/dist/{engine-D7YNY3v7.cjs.map → engine-esxTxcIx.cjs.map} +1 -1
- package/dist/{github-CO8W9SDs.cjs → github-BEA4K3_X.cjs} +80 -47
- package/dist/github-BEA4K3_X.cjs.map +1 -0
- package/dist/{github-CQt3xc3o.mjs → github-BUlKJfOV.mjs} +78 -45
- package/dist/github-BUlKJfOV.mjs.map +1 -0
- package/dist/{googlePlay-Cfu17aEp.mjs → googlePlay-CK05QiTq.mjs} +4 -4
- package/dist/{googlePlay-Cfu17aEp.mjs.map → googlePlay-CK05QiTq.mjs.map} +1 -1
- package/dist/{googlePlay-DSuF6jbF.cjs → googlePlay-CiqAS2ma.cjs} +5 -5
- package/dist/{googlePlay-DSuF6jbF.cjs.map → googlePlay-CiqAS2ma.cjs.map} +1 -1
- package/dist/{index-8OfpOtSI.d.cts → index-4CO0HD27.d.cts} +2 -2
- package/dist/{index-8OfpOtSI.d.cts.map → index-4CO0HD27.d.cts.map} +1 -1
- package/dist/{index-Dpji6Bxq.d.mts → index-DhUf0B0m.d.mts} +2 -2
- package/dist/{index-Dpji6Bxq.d.mts.map → index-DhUf0B0m.d.mts.map} +1 -1
- package/dist/index.cjs +81 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +64 -65
- package/dist/index.mjs.map +1 -1
- package/dist/{local-BwC2v2Y8.mjs → local-B7Zv1NoA.mjs} +2 -2
- package/dist/{local-BwC2v2Y8.mjs.map → local-B7Zv1NoA.mjs.map} +1 -1
- package/dist/{local-DNhnkugT.cjs → local-OPC9BCZt.cjs} +3 -3
- package/dist/{local-DNhnkugT.cjs.map → local-OPC9BCZt.cjs.map} +1 -1
- package/dist/{migrate-CGkir5LM.mjs → migrate-BzCHT9qs.mjs} +3 -3
- package/dist/{migrate-CGkir5LM.mjs.map → migrate-BzCHT9qs.mjs.map} +1 -1
- package/dist/{migrate-CXsMaHbb.cjs → migrate-C-hmbjpG.cjs} +3 -3
- package/dist/{migrate-CXsMaHbb.cjs.map → migrate-C-hmbjpG.cjs.map} +1 -1
- package/dist/{migrate-Bkz8BGaZ.mjs → migrate-CnbvrVag.mjs} +4 -4
- package/dist/{migrate-Bkz8BGaZ.mjs.map → migrate-CnbvrVag.mjs.map} +1 -1
- package/dist/{migrate-dbAI2XF8.cjs → migrate-DeQJBexh.cjs} +4 -4
- package/dist/{migrate-dbAI2XF8.cjs.map → migrate-DeQJBexh.cjs.map} +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +3 -3
- package/dist/{publish-eUcWvSdP.mjs → publish-BISBrrqR.mjs} +2 -2
- package/dist/{publish-eUcWvSdP.mjs.map → publish-BISBrrqR.mjs.map} +1 -1
- package/dist/{publish-Bbd-2PI2.cjs → publish-DtSIB-hZ.cjs} +2 -2
- package/dist/{publish-Bbd-2PI2.cjs.map → publish-DtSIB-hZ.cjs.map} +1 -1
- package/dist/{ready-BOfogqzr.mjs → ready-DqsyadOs.mjs} +6 -6
- package/dist/{ready-BOfogqzr.mjs.map → ready-DqsyadOs.mjs.map} +1 -1
- package/dist/{ready-BFFP838V.cjs → ready-IVGu-q18.cjs} +6 -6
- package/dist/{ready-BFFP838V.cjs.map → ready-IVGu-q18.cjs.map} +1 -1
- package/dist/reconcile/public.cjs +2 -2
- package/dist/reconcile/public.d.cts +1 -2
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +1 -2
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +2 -2
- package/dist/{resolve-DSilYpzm.mjs → resolve-BT7fkPN5.mjs} +4 -4
- package/dist/{resolve-DSilYpzm.mjs.map → resolve-BT7fkPN5.mjs.map} +1 -1
- package/dist/{resolve-CyprRcQo.cjs → resolve-C7GKQcE4.cjs} +4 -4
- package/dist/{resolve-CyprRcQo.cjs.map → resolve-C7GKQcE4.cjs.map} +1 -1
- package/dist/{rollback-DfwsnwGO.cjs → rollback-BEiB-Pje.cjs} +7 -7
- package/dist/{rollback-DfwsnwGO.cjs.map → rollback-BEiB-Pje.cjs.map} +1 -1
- package/dist/{rollback-C4ri3h7i.mjs → rollback-DbP0KuDw.mjs} +7 -7
- package/dist/{rollback-C4ri3h7i.mjs.map → rollback-DbP0KuDw.mjs.map} +1 -1
- package/dist/{runtime-ACdfK59n.d.cts → runtime-BFJQNqwd.d.mts} +2 -2
- package/dist/{runtime-ACdfK59n.d.cts.map → runtime-BFJQNqwd.d.mts.map} +1 -1
- package/dist/{runtime-YyQuekxi.d.mts → runtime-BJO-FFef.d.cts} +2 -2
- package/dist/{runtime-YyQuekxi.d.mts.map → runtime-BJO-FFef.d.cts.map} +1 -1
- package/dist/{s3-DQXZdmCM.mjs → s3-B4FTQQkV.mjs} +2 -2
- package/dist/{s3-DQXZdmCM.mjs.map → s3-B4FTQQkV.mjs.map} +1 -1
- package/dist/{s3-CrPoA89T.cjs → s3-DwKLXwUT.cjs} +2 -2
- package/dist/{s3-CrPoA89T.cjs.map → s3-DwKLXwUT.cjs.map} +1 -1
- package/dist/sandbox/credentials-worker.cjs +2 -2
- package/dist/sandbox/credentials-worker.mjs +2 -2
- package/dist/sandbox/discover-worker.cjs +1 -1
- package/dist/sandbox/discover-worker.mjs +1 -1
- package/dist/sandbox/migrate-worker.cjs +1 -1
- package/dist/sandbox/migrate-worker.mjs +1 -1
- package/dist/{seeds-CFG-f24B.cjs → seeds-DOfxmDRO.cjs} +362 -34
- package/dist/seeds-DOfxmDRO.cjs.map +1 -0
- package/dist/{seeds-oY0qDqui.mjs → seeds-rG-Evfz9.mjs} +341 -31
- package/dist/seeds-rG-Evfz9.mjs.map +1 -0
- package/dist/{serverSetup-CQZt0OT6.cjs → serverSetup-CWWVcU6Y.cjs} +6 -6
- package/dist/{serverSetup-CQZt0OT6.cjs.map → serverSetup-CWWVcU6Y.cjs.map} +1 -1
- package/dist/{serverSetup-D8nngcNL.mjs → serverSetup-xGw1fxuZ.mjs} +6 -6
- package/dist/{serverSetup-D8nngcNL.mjs.map → serverSetup-xGw1fxuZ.mjs.map} +1 -1
- package/dist/{sniffer-BAmtXzou.cjs → sniffer-C7O9Pna_.cjs} +9 -9
- package/dist/{sniffer-BAmtXzou.cjs.map → sniffer-C7O9Pna_.cjs.map} +1 -1
- package/dist/{sniffer-Cgx608Tl.mjs → sniffer-DVPgfyHr.mjs} +9 -9
- package/dist/{sniffer-Cgx608Tl.mjs.map → sniffer-DVPgfyHr.mjs.map} +1 -1
- package/dist/{dns-CfEZHt7r.cjs → snsSubscriptions-CSkteK2J.cjs} +520 -3
- package/dist/snsSubscriptions-CSkteK2J.cjs.map +1 -0
- package/dist/{dns-BgxvvcQa.mjs → snsSubscriptions-CvBIGGp0.mjs} +431 -6
- package/dist/snsSubscriptions-CvBIGGp0.mjs.map +1 -0
- package/dist/{sst-C1pxbFEd.mjs → sst-CTqZZl1_.mjs} +3 -4
- package/dist/{sst-C1pxbFEd.mjs.map → sst-CTqZZl1_.mjs.map} +1 -1
- package/dist/{sst-B-Uz4cvm.cjs → sst-lEkBwzGc.cjs} +4 -5
- package/dist/{sst-B-Uz4cvm.cjs.map → sst-lEkBwzGc.cjs.map} +1 -1
- package/dist/{stage-BKDdQm65.mjs → stage-2EKpzPQ1.mjs} +6 -6
- package/dist/{stage-BKDdQm65.mjs.map → stage-2EKpzPQ1.mjs.map} +1 -1
- package/dist/{stage-CJysBXWB.cjs → stage-fRfFtLwj.cjs} +7 -7
- package/dist/{stage-CJysBXWB.cjs.map → stage-fRfFtLwj.cjs.map} +1 -1
- package/dist/{stages-D4SnG5yl.cjs → stages-B7mCWI_R.cjs} +2 -2
- package/dist/{stages-D4SnG5yl.cjs.map → stages-B7mCWI_R.cjs.map} +1 -1
- package/dist/{stages-Cb9rqRbN.mjs → stages-DSltTW2d.mjs} +2 -2
- package/dist/{stages-Cb9rqRbN.mjs.map → stages-DSltTW2d.mjs.map} +1 -1
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{terminal-CW_dWeTe.mjs → terminal-BAVrDhhN.mjs} +3 -3
- package/dist/{terminal-CW_dWeTe.mjs.map → terminal-BAVrDhhN.mjs.map} +1 -1
- package/dist/{terminal-DJlqcW_U.cjs → terminal-D1aeTkgv.cjs} +3 -3
- package/dist/{terminal-DJlqcW_U.cjs.map → terminal-D1aeTkgv.cjs.map} +1 -1
- package/dist/{types-HqVPddRK.d.mts → types-CFU2uvrz.d.cts} +263 -4
- package/dist/types-CFU2uvrz.d.cts.map +1 -0
- package/dist/{types-B6UXlEkf.d.cts → types-D3BeGucy.d.mts} +262 -5
- package/dist/types-D3BeGucy.d.mts.map +1 -0
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-BwqQnool.cjs → workspace-C82GLPnf.cjs} +8 -2
- package/dist/workspace-C82GLPnf.cjs.map +1 -0
- package/dist/{workspace-D1QbNd55.mjs → workspace-DUnnVjqC.mjs} +8 -2
- package/dist/workspace-DUnnVjqC.mjs.map +1 -0
- package/package.json +17 -16
- package/dist/SubscriberGenerator-C8CPxrCK.cjs.map +0 -1
- package/dist/SubscriberGenerator-y3pncae_.mjs.map +0 -1
- package/dist/compose-CgBPA44v.mjs.map +0 -1
- package/dist/compose-bKLAtHLj.cjs.map +0 -1
- package/dist/config-D48erO2j.d.mts.map +0 -1
- package/dist/config-DHDtsQrB.d.cts.map +0 -1
- package/dist/credentials-B5N5yKk6.mjs.map +0 -1
- package/dist/credentials-Zqr3QQYB.cjs.map +0 -1
- package/dist/deploy-CI85F6dr.cjs.map +0 -1
- package/dist/deploy-Ddy8UBoE.mjs.map +0 -1
- package/dist/discover-C5roJuc9.mjs.map +0 -1
- package/dist/discover-CSW_BMWa.d.cts +0 -125
- package/dist/discover-CSW_BMWa.d.cts.map +0 -1
- package/dist/discover-DozUKs8f.cjs.map +0 -1
- package/dist/discover-xtT7fgWg.d.mts +0 -125
- package/dist/discover-xtT7fgWg.d.mts.map +0 -1
- package/dist/dns-BgxvvcQa.mjs.map +0 -1
- package/dist/dns-CfEZHt7r.cjs.map +0 -1
- package/dist/emit-C1e8qD08.mjs.map +0 -1
- package/dist/emit-Dmc1nvdS.cjs.map +0 -1
- package/dist/github-CO8W9SDs.cjs.map +0 -1
- package/dist/github-CQt3xc3o.mjs.map +0 -1
- package/dist/run-BJLIerMM.mjs +0 -133
- package/dist/run-BJLIerMM.mjs.map +0 -1
- package/dist/run-fVZ-rLnc.cjs +0 -174
- package/dist/run-fVZ-rLnc.cjs.map +0 -1
- package/dist/sandbox-C4g1eG31.d.mts +0 -104
- package/dist/sandbox-C4g1eG31.d.mts.map +0 -1
- package/dist/sandbox-CdKgQ3XU.d.cts +0 -104
- package/dist/sandbox-CdKgQ3XU.d.cts.map +0 -1
- package/dist/seeds-CFG-f24B.cjs.map +0 -1
- package/dist/seeds-oY0qDqui.mjs.map +0 -1
- package/dist/types-B6UXlEkf.d.cts.map +0 -1
- package/dist/types-HqVPddRK.d.mts.map +0 -1
- package/dist/workspace-BwqQnool.cjs.map +0 -1
- package/dist/workspace-D1QbNd55.mjs.map +0 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import "./index-Dpji6Bxq.mjs";
|
|
1
|
+
import { Lt as Sandbox, Wt as GkmError, b as NormalizedAppConfig, r as GkmConfig, v as LoadedConfig, x as NormalizedWorkspace } from "./types-CFU2uvrz.cjs";
|
|
2
|
+
import "./index-4CO0HD27.cjs";
|
|
4
3
|
import { ConstructManifest } from "@geekmidas/manifest";
|
|
5
4
|
//#region src/dev/discovery.d.ts
|
|
6
5
|
/** Where an app is in its life. `stopped` is a server that exited on its own. */
|
|
@@ -266,4 +265,4 @@ interface WorkspaceAppInfo {
|
|
|
266
265
|
declare function loadWorkspaceAppInfo(cwd?: string): Promise<WorkspaceAppInfo>;
|
|
267
266
|
//#endregion
|
|
268
267
|
export { DiscoveredApp as C, DiscoveryResponse as D, DiscoveryEvent as E, DataApiKind as S, DiscoveredWorkspace as T, loadWorkspaceAppInfo as _, ConfigNotFound as a, parseModuleConfig as b, NotABackendApp as c, WorkspaceAppInfo as d, WorkspaceDeclaresNoConstructs as f, loadConfig as g, loadAppConfig as h, ConfigLoadFailed as i, NotInAnApp as l, findWorkspaceRoot as m, CONFIG_LOAD_TIMEOUT_MS as n, ConfigObjectNotSerializable as o, defineConfig as p, ConfigDiscoveryResult as r, LoadConfigOptions as s, AppConfigResult as t, ParsedModuleConfig as u, loadWorkspaceConfig as v, DiscoveredDataApi as w, AppStatus as x, loadWorkspaceSettings as y };
|
|
269
|
-
//# sourceMappingURL=config-
|
|
268
|
+
//# sourceMappingURL=config-IgK6YaGp.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-IgK6YaGp.d.cts","names":[],"sources":["../src/dev/discovery.ts","../src/config.ts"],"mappings":";;;;;KAqFY;;KAGA;;;;;;UAyBK;;EAEhB;;EAEA;;UA8BgB;EAChB,MAAM;;EAEN;;EAEA;;EAEA;;UAGgB;EAChB;EACA;EACA;;EAEA;EACA;EACA,QAAQ;EACR;;EAEA;EACA,UAAU;;UAGM;;EAEhB;EACA;EACA;EACA;EACA,UAAU;;EAEV,WAAW;EACX,MAAM;;;UAIU;EAChB;;EAEA;IAAQ;IAAa;;;EAErB;EACA,YAAY;;;KAID;EACP;EAAkB,UAAU;;EAC5B;EAAiD;;EAEnD;EACA;EACA,KAAK;;;;;;;;;;;;;;;;;;;;;iBCpJQ,aAAa,QAAQ,YAAY;UAIhC;EAChB;EACA;;;;;;;;;;;;;;;;;;;iBAoBe,kBACf,sBACA,uBACE;UAac;EAChB;EACA;;;;;;;;iBAgDe,kBAAkB;;cAKrB,uBAAuB;WACd;EAArB,YAAqB;;UAaL;;;;;;;;EAQhB,UAAU;;;;;EAKV;;;;;;;cAQY;;cAGA,yBAAyB;WAE3B;WACA;EAFV,YACU,oBACA;;;;;;;cAYE,oCAAoC;WAEtC;WACA;EAFV,YACU,oBACA;;;;;;;;iBA0GW,WACrB,eACE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCW,sBACrB,cACA,UAAS,oBACP,QAAQ;iBAKW,oBACrB,cACA,UAAS,oBACP,QAAQ;;;;;;;;cAmEE,sCAAsC;WAC7B;EAArB,YAAqB;;UAWL;EAChB;EACA,KAAK;EACL,WAAW;EACX,WAAW;EACX;EACA;;;cAqCY,mBAAmB;WAErB;WACA,MAAM,SAAS;EAFzB,YACU,aACA,MAAM,SAAS;;;;;;;;;;;;;;;iBAoCJ,cACrB,eACE,QAAQ;;cAkBE,uBAAuB;WACd;EAArB,YAAqB;;UAQL;;EAEhB;EACA,KAAK;EACL,WAAW;EACX;;;;;;;;;iBAUqB,qBACrB,eACE,QAAQ"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import "./index-8OfpOtSI.cjs";
|
|
1
|
+
import { Lt as Sandbox, Wt as GkmError, b as NormalizedAppConfig, r as GkmConfig, v as LoadedConfig, x as NormalizedWorkspace } from "./types-D3BeGucy.mjs";
|
|
2
|
+
import "./index-DhUf0B0m.mjs";
|
|
4
3
|
import { ConstructManifest } from "@geekmidas/manifest";
|
|
5
4
|
//#region src/dev/discovery.d.ts
|
|
6
5
|
/** Where an app is in its life. `stopped` is a server that exited on its own. */
|
|
@@ -266,4 +265,4 @@ interface WorkspaceAppInfo {
|
|
|
266
265
|
declare function loadWorkspaceAppInfo(cwd?: string): Promise<WorkspaceAppInfo>;
|
|
267
266
|
//#endregion
|
|
268
267
|
export { DiscoveredApp as C, DiscoveryResponse as D, DiscoveryEvent as E, DataApiKind as S, DiscoveredWorkspace as T, loadWorkspaceAppInfo as _, ConfigNotFound as a, parseModuleConfig as b, NotABackendApp as c, WorkspaceAppInfo as d, WorkspaceDeclaresNoConstructs as f, loadConfig as g, loadAppConfig as h, ConfigLoadFailed as i, NotInAnApp as l, findWorkspaceRoot as m, CONFIG_LOAD_TIMEOUT_MS as n, ConfigObjectNotSerializable as o, defineConfig as p, ConfigDiscoveryResult as r, LoadConfigOptions as s, AppConfigResult as t, ParsedModuleConfig as u, loadWorkspaceConfig as v, DiscoveredDataApi as w, AppStatus as x, loadWorkspaceSettings as y };
|
|
269
|
-
//# sourceMappingURL=config-
|
|
268
|
+
//# sourceMappingURL=config-kE-p5hxq.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-kE-p5hxq.d.mts","names":[],"sources":["../src/dev/discovery.ts","../src/config.ts"],"mappings":";;;;;KAqFY;;KAGA;;;;;;UAyBK;;EAEhB;;EAEA;;UA8BgB;EAChB,MAAM;;EAEN;;EAEA;;EAEA;;UAGgB;EAChB;EACA;EACA;;EAEA;EACA;EACA,QAAQ;EACR;;EAEA;EACA,UAAU;;UAGM;;EAEhB;EACA;EACA;EACA;EACA,UAAU;;EAEV,WAAW;EACX,MAAM;;;UAIU;EAChB;;EAEA;IAAQ;IAAa;;;EAErB;EACA,YAAY;;;KAID;EACP;EAAkB,UAAU;;EAC5B;EAAiD;;EAEnD;EACA;EACA,KAAK;;;;;;;;;;;;;;;;;;;;;iBCpJQ,aAAa,QAAQ,YAAY;UAIhC;EAChB;EACA;;;;;;;;;;;;;;;;;;;iBAoBe,kBACf,sBACA,uBACE;UAac;EAChB;EACA;;;;;;;;iBAgDe,kBAAkB;;cAKrB,uBAAuB;WACd;EAArB,YAAqB;;UAaL;;;;;;;;EAQhB,UAAU;;;;;EAKV;;;;;;;cAQY;;cAGA,yBAAyB;WAE3B;WACA;EAFV,YACU,oBACA;;;;;;;cAYE,oCAAoC;WAEtC;WACA;EAFV,YACU,oBACA;;;;;;;;iBA0GW,WACrB,eACE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCW,sBACrB,cACA,UAAS,oBACP,QAAQ;iBAKW,oBACrB,cACA,UAAS,oBACP,QAAQ;;;;;;;;cAmEE,sCAAsC;WAC7B;EAArB,YAAqB;;UAWL;EAChB;EACA,KAAK;EACL,WAAW;EACX,WAAW;EACX;EACA;;;cAqCY,mBAAmB;WAErB;WACA,MAAM,SAAS;EAFzB,YACU,aACA,MAAM,SAAS;;;;;;;;;;;;;;;iBAoCJ,cACrB,eACE,QAAQ;;cAkBE,uBAAuB;WACd;EAArB,YAAqB;;UAQL;;EAEhB;EACA,KAAK;EACL,WAAW;EACX;;;;;;;;;iBAUqB,qBACrB,eACE,QAAQ"}
|
package/dist/config.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_errors = require("./errors-DMC4Umsb.cjs");
|
|
3
|
-
const require_workspace = require("./workspace-
|
|
3
|
+
const require_workspace = require("./workspace-C82GLPnf.cjs");
|
|
4
4
|
const require_schemas = require("./schemas-BQ_v0lEX.cjs");
|
|
5
5
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
6
|
-
const require_discover = require("./discover-
|
|
6
|
+
const require_discover = require("./discover-ojkcbxHw.cjs");
|
|
7
7
|
const require_sandbox = require("./sandbox-CHv3OYXg.cjs");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
let node_fs = require("node:fs");
|
package/dist/config.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as WorkspaceConfig, m as DevConfig, r as GkmConfig, v as LoadedConfig } from "./types-
|
|
2
|
-
import { l as defineWorkspace } from "./index-
|
|
3
|
-
import { C as DiscoveredApp, D as DiscoveryResponse, E as DiscoveryEvent, S as DataApiKind, T as DiscoveredWorkspace, _ as loadWorkspaceAppInfo, a as ConfigNotFound, b as parseModuleConfig, c as NotABackendApp, d as WorkspaceAppInfo, f as WorkspaceDeclaresNoConstructs, g as loadConfig, h as loadAppConfig, i as ConfigLoadFailed, l as NotInAnApp, m as findWorkspaceRoot, n as CONFIG_LOAD_TIMEOUT_MS, o as ConfigObjectNotSerializable, p as defineConfig, r as ConfigDiscoveryResult, s as LoadConfigOptions, t as AppConfigResult, u as ParsedModuleConfig, v as loadWorkspaceConfig, w as DiscoveredDataApi, x as AppStatus, y as loadWorkspaceSettings } from "./config-
|
|
1
|
+
import { D as WorkspaceConfig, m as DevConfig, r as GkmConfig, v as LoadedConfig } from "./types-CFU2uvrz.cjs";
|
|
2
|
+
import { l as defineWorkspace } from "./index-4CO0HD27.cjs";
|
|
3
|
+
import { C as DiscoveredApp, D as DiscoveryResponse, E as DiscoveryEvent, S as DataApiKind, T as DiscoveredWorkspace, _ as loadWorkspaceAppInfo, a as ConfigNotFound, b as parseModuleConfig, c as NotABackendApp, d as WorkspaceAppInfo, f as WorkspaceDeclaresNoConstructs, g as loadConfig, h as loadAppConfig, i as ConfigLoadFailed, l as NotInAnApp, m as findWorkspaceRoot, n as CONFIG_LOAD_TIMEOUT_MS, o as ConfigObjectNotSerializable, p as defineConfig, r as ConfigDiscoveryResult, s as LoadConfigOptions, t as AppConfigResult, u as ParsedModuleConfig, v as loadWorkspaceConfig, w as DiscoveredDataApi, x as AppStatus, y as loadWorkspaceSettings } from "./config-IgK6YaGp.cjs";
|
|
4
4
|
export { AppConfigResult, type AppStatus, CONFIG_LOAD_TIMEOUT_MS, ConfigDiscoveryResult, ConfigLoadFailed, ConfigNotFound, ConfigObjectNotSerializable, type DataApiKind, type DevConfig, type DiscoveredApp, type DiscoveredDataApi, type DiscoveredWorkspace, type DiscoveryEvent, type DiscoveryResponse, type GkmConfig, LoadConfigOptions, type LoadedConfig, NotABackendApp, NotInAnApp, ParsedModuleConfig, WorkspaceAppInfo, type WorkspaceConfig, WorkspaceDeclaresNoConstructs, defineConfig, defineWorkspace, findWorkspaceRoot, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, loadWorkspaceSettings, parseModuleConfig };
|
package/dist/config.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as WorkspaceConfig, m as DevConfig, r as GkmConfig, v as LoadedConfig } from "./types-
|
|
2
|
-
import { l as defineWorkspace } from "./index-
|
|
3
|
-
import { C as DiscoveredApp, D as DiscoveryResponse, E as DiscoveryEvent, S as DataApiKind, T as DiscoveredWorkspace, _ as loadWorkspaceAppInfo, a as ConfigNotFound, b as parseModuleConfig, c as NotABackendApp, d as WorkspaceAppInfo, f as WorkspaceDeclaresNoConstructs, g as loadConfig, h as loadAppConfig, i as ConfigLoadFailed, l as NotInAnApp, m as findWorkspaceRoot, n as CONFIG_LOAD_TIMEOUT_MS, o as ConfigObjectNotSerializable, p as defineConfig, r as ConfigDiscoveryResult, s as LoadConfigOptions, t as AppConfigResult, u as ParsedModuleConfig, v as loadWorkspaceConfig, w as DiscoveredDataApi, x as AppStatus, y as loadWorkspaceSettings } from "./config-
|
|
1
|
+
import { D as WorkspaceConfig, m as DevConfig, r as GkmConfig, v as LoadedConfig } from "./types-D3BeGucy.mjs";
|
|
2
|
+
import { l as defineWorkspace } from "./index-DhUf0B0m.mjs";
|
|
3
|
+
import { C as DiscoveredApp, D as DiscoveryResponse, E as DiscoveryEvent, S as DataApiKind, T as DiscoveredWorkspace, _ as loadWorkspaceAppInfo, a as ConfigNotFound, b as parseModuleConfig, c as NotABackendApp, d as WorkspaceAppInfo, f as WorkspaceDeclaresNoConstructs, g as loadConfig, h as loadAppConfig, i as ConfigLoadFailed, l as NotInAnApp, m as findWorkspaceRoot, n as CONFIG_LOAD_TIMEOUT_MS, o as ConfigObjectNotSerializable, p as defineConfig, r as ConfigDiscoveryResult, s as LoadConfigOptions, t as AppConfigResult, u as ParsedModuleConfig, v as loadWorkspaceConfig, w as DiscoveredDataApi, x as AppStatus, y as loadWorkspaceSettings } from "./config-kE-p5hxq.mjs";
|
|
4
4
|
export { AppConfigResult, type AppStatus, CONFIG_LOAD_TIMEOUT_MS, ConfigDiscoveryResult, ConfigLoadFailed, ConfigNotFound, ConfigObjectNotSerializable, type DataApiKind, type DevConfig, type DiscoveredApp, type DiscoveredDataApi, type DiscoveredWorkspace, type DiscoveryEvent, type DiscoveryResponse, type GkmConfig, LoadConfigOptions, type LoadedConfig, NotABackendApp, NotInAnApp, ParsedModuleConfig, WorkspaceAppInfo, type WorkspaceConfig, WorkspaceDeclaresNoConstructs, defineConfig, defineWorkspace, findWorkspaceRoot, loadAppConfig, loadConfig, loadWorkspaceAppInfo, loadWorkspaceConfig, loadWorkspaceSettings, parseModuleConfig };
|
package/dist/config.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
|
|
2
|
-
import { a as allConstructGlobs, b as isWorkspaceConfig, d as getAppGkmConfig, l as defineWorkspace, m as processConfig } from "./workspace-
|
|
2
|
+
import { a as allConstructGlobs, b as isWorkspaceConfig, d as getAppGkmConfig, l as defineWorkspace, m as processConfig } from "./workspace-DUnnVjqC.mjs";
|
|
3
3
|
import { a as discriminatedUnion, c as literal, d as object, f as record, g as unknown, n as array, p as string } from "./schemas-BCwKKA42.mjs";
|
|
4
4
|
import { n as derivedApps } from "./derive-B4vDpzgP.mjs";
|
|
5
|
-
import { f as output, i as discover, l as runWorker } from "./discover-
|
|
5
|
+
import { f as output, i as discover, l as runWorker } from "./discover-BvJOVsYG.mjs";
|
|
6
6
|
import { i as activeSandbox } from "./sandbox-CbVB7uOD.mjs";
|
|
7
7
|
import { dirname, join, parse, resolve, sep } from "node:path";
|
|
8
8
|
import { existsSync, realpathSync } from "node:fs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_errors = require("./errors-DMC4Umsb.cjs");
|
|
2
2
|
const require_schemas = require("./schemas-BQ_v0lEX.cjs");
|
|
3
|
-
const require_discover = require("./discover-
|
|
3
|
+
const require_discover = require("./discover-ojkcbxHw.cjs");
|
|
4
4
|
const require_sandbox = require("./sandbox-CHv3OYXg.cjs");
|
|
5
5
|
let _geekmidas_manifest = require("@geekmidas/manifest");
|
|
6
6
|
let _geekmidas_constructs_credential = require("@geekmidas/constructs/credential");
|
|
@@ -269,4 +269,4 @@ Object.defineProperty(exports, "loadCredentialSchemas", {
|
|
|
269
269
|
}
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
-
//# sourceMappingURL=credentialSchemas-
|
|
272
|
+
//# sourceMappingURL=credentialSchemas-AhIBuQxQ.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentialSchemas-B67WJOOm.cjs","names":["provideKey","decodeCredentials","activeSandbox","runWorker","ConstructDiscoveryFailed","discover","GkmError"],"sources":["../src/secrets/credentialSchemas.ts"],"sourcesContent":["/**\n * A third party's credentials, checked against the schema of the construct\n * that reads them — before they are stored, and before a deploy builds\n * anything with them.\n *\n * The schema lives on the construct (`ExternalApi.credentialsSchema`,\n * `Credential.credentialsSchema`), which is the project's code. So the\n * constructs are loaded where a deploy loads them: in the run's sandbox when\n * there is one, here otherwise. What comes back is data only — each schema as\n * JSON Schema where it can say so, and `{ ok, issues }` for each value asked\n * about — because a live schema cannot cross an isolating sandbox. A value\n * asked about goes in as a secret file, never an argument, and no issue\n * carries it back: an issue is a path and a message.\n */\n\nimport { decodeCredentials } from '@geekmidas/constructs/credential';\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { z } from 'zod';\nimport { GkmError } from '../errors';\nimport {\n\tConstructDiscoveryFailed,\n\ttype ConstructSource,\n\tdiscover,\n} from '../reconcile/discover';\nimport { activeSandbox } from '../sandbox/sandbox';\nimport { runWorker } from '../sandbox/worker';\n\n/** One thing a schema refused: where in the value, and why. */\nexport interface CredentialIssue {\n\t/** Dotted, from the value's root — `apiKey`, `keys.0`; empty for the root. */\n\tpath: string;\n\tmessage: string;\n}\n\n/** What a candidate value came to. */\nexport interface CredentialCheck {\n\tok: boolean;\n\tissues: CredentialIssue[];\n}\n\n/** A construct's credentials key, and its schema as data. */\nexport interface CredentialSchemaInfo {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\t/**\n\t * The schema as JSON Schema, where the schema can say — zod's, or any\n\t * Standard JSON Schema. Absent otherwise: the value is asked for as JSON.\n\t */\n\tjsonSchema?: Record<string, unknown>;\n}\n\n/** What loading the constructs answers. */\nexport interface CredentialInspection {\n\tschemas: CredentialSchemaInfo[];\n\t/** Each value asked about, by key. */\n\tchecks: Record<string, CredentialCheck>;\n}\n\n/** A construct whose credentials have a schema. */\ninterface LiveCredential {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\tschema: StandardSchemaV1;\n}\n\n/** The credentials keys a manifest declares, by the construct that reads each. */\nexport function credentialKeys(\n\tmanifest: ConstructManifest,\n): { key: string; id: string; kind: 'external-api' | 'credential' }[] {\n\treturn Object.entries(manifest).flatMap(([id, declaration]) =>\n\t\tdeclaration.kind === 'external-api' || declaration.kind === 'credential'\n\t\t\t? [{ key: provideKey(id, 'credentials'), id, kind: declaration.kind }]\n\t\t\t: [],\n\t);\n}\n\n/** The constructs that read a third party's credentials, with their schemas. */\nexport function liveCredentials(\n\tmanifest: ConstructManifest,\n\tsources: Readonly<Record<string, ConstructSource>>,\n): LiveCredential[] {\n\treturn credentialKeys(manifest).flatMap(({ key, id, kind }) => {\n\t\tconst schema = (sources[id]?.construct as { credentialsSchema?: unknown })\n\t\t\t?.credentialsSchema;\n\t\treturn isStandardSchema(schema) ? [{ key, id, kind, schema }] : [];\n\t});\n}\n\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as StandardSchemaV1)['~standard']?.validate === 'function'\n\t);\n}\n\n/**\n * A schema as JSON Schema: through the Standard JSON Schema extension where\n * the schema has it, as zod 4's does, else zod's own converter — or nothing,\n * for a schema neither can describe.\n */\nexport function jsonSchemaOf(\n\tschema: StandardSchemaV1,\n): Record<string, unknown> | undefined {\n\tconst standard = schema['~standard'] as StandardSchemaV1['~standard'] & {\n\t\tjsonSchema?: {\n\t\t\tinput?: (options: { target: string }) => Record<string, unknown>;\n\t\t};\n\t};\n\ttry {\n\t\tconst described = standard.jsonSchema?.input?.({\n\t\t\ttarget: 'draft-2020-12',\n\t\t});\n\t\tif (described) return described;\n\t} catch {\n\t\t// A type JSON Schema cannot express: try zod's converter, then nothing.\n\t}\n\tif (typeof schema === 'object' && schema !== null && '_zod' in schema) {\n\t\ttry {\n\t\t\treturn z.toJSONSchema(schema as unknown as z.ZodType, {\n\t\t\t\tio: 'input',\n\t\t\t}) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** A stored value against its schema, read the way the construct reads it. */\nexport async function checkCredential(\n\tschema: StandardSchemaV1,\n\traw: string,\n): Promise<CredentialCheck> {\n\tconst result = await schema['~standard'].validate(decodeCredentials(raw));\n\tif (!result.issues) return { ok: true, issues: [] };\n\treturn {\n\t\tok: false,\n\t\tissues: result.issues.map((issue) => ({\n\t\t\tpath: (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.'),\n\t\t\tmessage: issue.message,\n\t\t})),\n\t};\n}\n\n/** What a set of live credentials says about some values: data only. */\nexport async function inspectLive(\n\tlive: readonly LiveCredential[],\n\tvalues: Readonly<Record<string, string>>,\n): Promise<CredentialInspection> {\n\tconst checks: Record<string, CredentialCheck> = {};\n\tfor (const credential of live) {\n\t\tconst value = values[credential.key];\n\t\tif (value === undefined) continue;\n\t\tchecks[credential.key] = await checkCredential(credential.schema, value);\n\t}\n\treturn {\n\t\tschemas: live.map(({ key, id, kind, schema }) => {\n\t\t\tconst jsonSchema = jsonSchemaOf(schema);\n\t\t\treturn { key, id, kind, ...(jsonSchema ? { jsonSchema } : {}) };\n\t\t}),\n\t\tchecks,\n\t};\n}\n\nexport interface InspectOptions {\n\t/** The workspace root. */\n\troot: string;\n\t/** Its construct globs. */\n\tpatterns: readonly string[];\n\t/** The values to check, by key. Only credentials keys are looked at. */\n\tvalues?: Readonly<Record<string, string>>;\n}\n\nconst Issue = z.object({ path: z.string(), message: z.string() });\n\n/** What the credentials worker answers. Checked: the worker ran project code. */\nconst CredentialsAnswer = z.discriminatedUnion('reason', [\n\tz.object({\n\t\treason: z.literal('inspected'),\n\t\tschemas: z.array(\n\t\t\tz.object({\n\t\t\t\tkey: z.string(),\n\t\t\t\tid: z.string(),\n\t\t\t\tkind: z.enum(['external-api', 'credential']),\n\t\t\t\tjsonSchema: z.record(z.string(), z.unknown()).optional(),\n\t\t\t}),\n\t\t),\n\t\tchecks: z.record(\n\t\t\tz.string(),\n\t\t\tz.object({ ok: z.boolean(), issues: z.array(Issue) }),\n\t\t),\n\t}),\n\tz.object({\n\t\treason: z.literal('failed'),\n\t\terror: z.object({ name: z.string(), message: z.string() }).loose(),\n\t}),\n]);\n\n/** How long loading the constructs to check credentials may take. */\nconst INSPECT_TIMEOUT_MS = 60_000;\n\n/**\n * The workspace's credential schemas, and what each of `values` comes to —\n * loaded in the run's sandbox when there is one, here otherwise.\n */\nexport async function inspectCredentials(\n\toptions: InspectOptions,\n): Promise<CredentialInspection> {\n\tconst sandbox = activeSandbox();\n\tif (!sandbox) {\n\t\treturn (await loadCredentialSchemasHere(options)).inspect(\n\t\t\toptions.values ?? {},\n\t\t);\n\t}\n\n\tconst secrets = Object.fromEntries(\n\t\tObject.entries(options.values ?? {}).filter(([key]) =>\n\t\t\tkey.endsWith('_CREDENTIALS'),\n\t\t),\n\t);\n\tconst { value } = await runWorker(sandbox, 'credentials check', {\n\t\tname: 'credentials-worker',\n\t\targs: [JSON.stringify({ patterns: options.patterns, cwd: options.root })],\n\t\tcwd: options.root,\n\t\ttimeoutMs: INSPECT_TIMEOUT_MS,\n\t\tschema: CredentialsAnswer,\n\t\t...(Object.keys(secrets).length > 0 ? { secrets } : {}),\n\t});\n\tif (value.reason === 'failed') {\n\t\tthrow new ConstructDiscoveryFailed(value.error.name, value.error.message);\n\t}\n\tconst { schemas, checks } = value;\n\treturn {\n\t\tschemas: schemas.map(({ jsonSchema, ...rest }) => ({\n\t\t\t...rest,\n\t\t\t...(jsonSchema ? { jsonSchema } : {}),\n\t\t})),\n\t\tchecks,\n\t};\n}\n\n/** The constructs loaded once, here, and asked about as often as needed. */\nasync function loadCredentialSchemasHere(options: InspectOptions): Promise<{\n\tinspect(\n\t\tvalues: Readonly<Record<string, string>>,\n\t): Promise<CredentialInspection>;\n}> {\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst manifest = await discover({\n\t\tpatterns: [...options.patterns],\n\t\tcwd: options.root,\n\t\tsources,\n\t});\n\tconst live = liveCredentials(manifest, sources);\n\treturn { inspect: (values) => inspectLive(live, values) };\n}\n\n/** The schemas, and a check of one candidate value at a time. */\nexport interface CredentialSchemas {\n\tschemas: CredentialSchemaInfo[];\n\t/** `raw` against `key`'s schema; ok for a key no schema describes. */\n\tcheck(key: string, raw: string): Promise<CredentialCheck>;\n}\n\n/**\n * The workspace's credential schemas, for a command that checks values one\n * at a time as they are typed. In-process the constructs are loaded once;\n * in a sandbox each check is a run of the worker.\n */\nexport async function loadCredentialSchemas(\n\toptions: Omit<InspectOptions, 'values'>,\n): Promise<CredentialSchemas> {\n\tconst here = activeSandbox()\n\t\t? undefined\n\t\t: await loadCredentialSchemasHere(options);\n\tconst inspect = (values: Readonly<Record<string, string>>) =>\n\t\there ? here.inspect(values) : inspectCredentials({ ...options, values });\n\n\tconst { schemas } = await inspect({});\n\treturn {\n\t\tschemas,\n\t\tasync check(key, raw) {\n\t\t\tif (!schemas.some((s) => s.key === key)) return { ok: true, issues: [] };\n\t\t\tconst { checks } = await inspect({ [key]: raw });\n\t\t\treturn checks[key] ?? { ok: true, issues: [] };\n\t\t},\n\t};\n}\n\n/** One stored credential its schema refuses. */\nexport interface InvalidCredential {\n\tkey: string;\n\tissues: CredentialIssue[];\n}\n\n/** An issue as the line that names it: `SHIPPING_CREDENTIALS.apiKey: …`. */\nexport function issueLine(key: string, issue: CredentialIssue): string {\n\treturn `${key}${issue.path ? `.${issue.path}` : ''}: ${issue.message}`;\n}\n\n/**\n * Credentials their construct's schema refuses — on their way into the\n * stage's secrets, or already there when a deploy reads them. The values are\n * never in the message: only where each is wrong, and why.\n */\nexport class CredentialsInvalid extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly invalid: readonly InvalidCredential[],\n\t\t/** Whether a value was being set (and was not saved), or deployed. */\n\t\treadonly during: 'set' | 'deploy',\n\t) {\n\t\tconst lines = invalid.flatMap(({ key, issues }) =>\n\t\t\tissues.map((issue) => ` ${issueLine(key, issue)}`),\n\t\t);\n\t\tconst keys = invalid.map((i) => i.key);\n\t\tsuper(\n\t\t\tduring === 'set'\n\t\t\t\t? `${keys.join(', ')} is not what its construct's schema describes, ` +\n\t\t\t\t\t\t`so nothing was saved:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set a value that matches, or let gkm ask for each field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`\n\t\t\t\t: `The stage '${stage}' holds ${keys.length === 1 ? 'a credential' : 'credentials'} ` +\n\t\t\t\t\t\t`${keys.length === 1 ? \"its construct's schema refuses\" : \"their constructs' schemas refuse\"}, ` +\n\t\t\t\t\t\t`and every app reading ${keys.length === 1 ? 'it' : 'them'} would fail ` +\n\t\t\t\t\t\t`as it starts:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set ${keys.length === 1 ? 'it' : 'them'} again, field by field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`,\n\t\t);\n\t\tthis.name = 'CredentialsInvalid';\n\t}\n}\n\n/**\n * Every credential the stage holds for a construct, against its schema —\n * before a deploy builds anything with one the app would refuse as it\n * starts. Loads nothing when the stage holds none.\n *\n * @throws {CredentialsInvalid} naming each key and every issue\n */\nexport async function assertStageCredentials(options: {\n\troot: string;\n\tpatterns: readonly string[];\n\tmanifest: ConstructManifest;\n\tstage: string;\n\tsupplied: Readonly<Record<string, string>>;\n}): Promise<void> {\n\tconst values = Object.fromEntries(\n\t\tcredentialKeys(options.manifest)\n\t\t\t.map(({ key }) => [key, options.supplied[key]] as const)\n\t\t\t.filter((entry): entry is [string, string] => entry[1] !== undefined),\n\t);\n\tif (Object.keys(values).length === 0) return;\n\n\tconst { checks } = await inspectCredentials({\n\t\troot: options.root,\n\t\tpatterns: options.patterns,\n\t\tvalues,\n\t});\n\tconst invalid = Object.entries(checks)\n\t\t.filter(([, check]) => !check.ok)\n\t\t.map(([key, check]) => ({ key, issues: check.issues }))\n\t\t.sort((a, b) => a.key.localeCompare(b.key));\n\tif (invalid.length > 0) {\n\t\tthrow new CredentialsInvalid(options.stage, invalid, 'deploy');\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"credentialSchemas-AhIBuQxQ.cjs","names":["provideKey","decodeCredentials","activeSandbox","runWorker","ConstructDiscoveryFailed","discover","GkmError"],"sources":["../src/secrets/credentialSchemas.ts"],"sourcesContent":["/**\n * A third party's credentials, checked against the schema of the construct\n * that reads them — before they are stored, and before a deploy builds\n * anything with them.\n *\n * The schema lives on the construct (`ExternalApi.credentialsSchema`,\n * `Credential.credentialsSchema`), which is the project's code. So the\n * constructs are loaded where a deploy loads them: in the run's sandbox when\n * there is one, here otherwise. What comes back is data only — each schema as\n * JSON Schema where it can say so, and `{ ok, issues }` for each value asked\n * about — because a live schema cannot cross an isolating sandbox. A value\n * asked about goes in as a secret file, never an argument, and no issue\n * carries it back: an issue is a path and a message.\n */\n\nimport { decodeCredentials } from '@geekmidas/constructs/credential';\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { z } from 'zod';\nimport { GkmError } from '../errors';\nimport {\n\tConstructDiscoveryFailed,\n\ttype ConstructSource,\n\tdiscover,\n} from '../reconcile/discover';\nimport { activeSandbox } from '../sandbox/sandbox';\nimport { runWorker } from '../sandbox/worker';\n\n/** One thing a schema refused: where in the value, and why. */\nexport interface CredentialIssue {\n\t/** Dotted, from the value's root — `apiKey`, `keys.0`; empty for the root. */\n\tpath: string;\n\tmessage: string;\n}\n\n/** What a candidate value came to. */\nexport interface CredentialCheck {\n\tok: boolean;\n\tissues: CredentialIssue[];\n}\n\n/** A construct's credentials key, and its schema as data. */\nexport interface CredentialSchemaInfo {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\t/**\n\t * The schema as JSON Schema, where the schema can say — zod's, or any\n\t * Standard JSON Schema. Absent otherwise: the value is asked for as JSON.\n\t */\n\tjsonSchema?: Record<string, unknown>;\n}\n\n/** What loading the constructs answers. */\nexport interface CredentialInspection {\n\tschemas: CredentialSchemaInfo[];\n\t/** Each value asked about, by key. */\n\tchecks: Record<string, CredentialCheck>;\n}\n\n/** A construct whose credentials have a schema. */\ninterface LiveCredential {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\tschema: StandardSchemaV1;\n}\n\n/** The credentials keys a manifest declares, by the construct that reads each. */\nexport function credentialKeys(\n\tmanifest: ConstructManifest,\n): { key: string; id: string; kind: 'external-api' | 'credential' }[] {\n\treturn Object.entries(manifest).flatMap(([id, declaration]) =>\n\t\tdeclaration.kind === 'external-api' || declaration.kind === 'credential'\n\t\t\t? [{ key: provideKey(id, 'credentials'), id, kind: declaration.kind }]\n\t\t\t: [],\n\t);\n}\n\n/** The constructs that read a third party's credentials, with their schemas. */\nexport function liveCredentials(\n\tmanifest: ConstructManifest,\n\tsources: Readonly<Record<string, ConstructSource>>,\n): LiveCredential[] {\n\treturn credentialKeys(manifest).flatMap(({ key, id, kind }) => {\n\t\tconst schema = (sources[id]?.construct as { credentialsSchema?: unknown })\n\t\t\t?.credentialsSchema;\n\t\treturn isStandardSchema(schema) ? [{ key, id, kind, schema }] : [];\n\t});\n}\n\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as StandardSchemaV1)['~standard']?.validate === 'function'\n\t);\n}\n\n/**\n * A schema as JSON Schema: through the Standard JSON Schema extension where\n * the schema has it, as zod 4's does, else zod's own converter — or nothing,\n * for a schema neither can describe.\n */\nexport function jsonSchemaOf(\n\tschema: StandardSchemaV1,\n): Record<string, unknown> | undefined {\n\tconst standard = schema['~standard'] as StandardSchemaV1['~standard'] & {\n\t\tjsonSchema?: {\n\t\t\tinput?: (options: { target: string }) => Record<string, unknown>;\n\t\t};\n\t};\n\ttry {\n\t\tconst described = standard.jsonSchema?.input?.({\n\t\t\ttarget: 'draft-2020-12',\n\t\t});\n\t\tif (described) return described;\n\t} catch {\n\t\t// A type JSON Schema cannot express: try zod's converter, then nothing.\n\t}\n\tif (typeof schema === 'object' && schema !== null && '_zod' in schema) {\n\t\ttry {\n\t\t\treturn z.toJSONSchema(schema as unknown as z.ZodType, {\n\t\t\t\tio: 'input',\n\t\t\t}) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** A stored value against its schema, read the way the construct reads it. */\nexport async function checkCredential(\n\tschema: StandardSchemaV1,\n\traw: string,\n): Promise<CredentialCheck> {\n\tconst result = await schema['~standard'].validate(decodeCredentials(raw));\n\tif (!result.issues) return { ok: true, issues: [] };\n\treturn {\n\t\tok: false,\n\t\tissues: result.issues.map((issue) => ({\n\t\t\tpath: (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.'),\n\t\t\tmessage: issue.message,\n\t\t})),\n\t};\n}\n\n/** What a set of live credentials says about some values: data only. */\nexport async function inspectLive(\n\tlive: readonly LiveCredential[],\n\tvalues: Readonly<Record<string, string>>,\n): Promise<CredentialInspection> {\n\tconst checks: Record<string, CredentialCheck> = {};\n\tfor (const credential of live) {\n\t\tconst value = values[credential.key];\n\t\tif (value === undefined) continue;\n\t\tchecks[credential.key] = await checkCredential(credential.schema, value);\n\t}\n\treturn {\n\t\tschemas: live.map(({ key, id, kind, schema }) => {\n\t\t\tconst jsonSchema = jsonSchemaOf(schema);\n\t\t\treturn { key, id, kind, ...(jsonSchema ? { jsonSchema } : {}) };\n\t\t}),\n\t\tchecks,\n\t};\n}\n\nexport interface InspectOptions {\n\t/** The workspace root. */\n\troot: string;\n\t/** Its construct globs. */\n\tpatterns: readonly string[];\n\t/** The values to check, by key. Only credentials keys are looked at. */\n\tvalues?: Readonly<Record<string, string>>;\n}\n\nconst Issue = z.object({ path: z.string(), message: z.string() });\n\n/** What the credentials worker answers. Checked: the worker ran project code. */\nconst CredentialsAnswer = z.discriminatedUnion('reason', [\n\tz.object({\n\t\treason: z.literal('inspected'),\n\t\tschemas: z.array(\n\t\t\tz.object({\n\t\t\t\tkey: z.string(),\n\t\t\t\tid: z.string(),\n\t\t\t\tkind: z.enum(['external-api', 'credential']),\n\t\t\t\tjsonSchema: z.record(z.string(), z.unknown()).optional(),\n\t\t\t}),\n\t\t),\n\t\tchecks: z.record(\n\t\t\tz.string(),\n\t\t\tz.object({ ok: z.boolean(), issues: z.array(Issue) }),\n\t\t),\n\t}),\n\tz.object({\n\t\treason: z.literal('failed'),\n\t\terror: z.object({ name: z.string(), message: z.string() }).loose(),\n\t}),\n]);\n\n/** How long loading the constructs to check credentials may take. */\nconst INSPECT_TIMEOUT_MS = 60_000;\n\n/**\n * The workspace's credential schemas, and what each of `values` comes to —\n * loaded in the run's sandbox when there is one, here otherwise.\n */\nexport async function inspectCredentials(\n\toptions: InspectOptions,\n): Promise<CredentialInspection> {\n\tconst sandbox = activeSandbox();\n\tif (!sandbox) {\n\t\treturn (await loadCredentialSchemasHere(options)).inspect(\n\t\t\toptions.values ?? {},\n\t\t);\n\t}\n\n\tconst secrets = Object.fromEntries(\n\t\tObject.entries(options.values ?? {}).filter(([key]) =>\n\t\t\tkey.endsWith('_CREDENTIALS'),\n\t\t),\n\t);\n\tconst { value } = await runWorker(sandbox, 'credentials check', {\n\t\tname: 'credentials-worker',\n\t\targs: [JSON.stringify({ patterns: options.patterns, cwd: options.root })],\n\t\tcwd: options.root,\n\t\ttimeoutMs: INSPECT_TIMEOUT_MS,\n\t\tschema: CredentialsAnswer,\n\t\t...(Object.keys(secrets).length > 0 ? { secrets } : {}),\n\t});\n\tif (value.reason === 'failed') {\n\t\tthrow new ConstructDiscoveryFailed(value.error.name, value.error.message);\n\t}\n\tconst { schemas, checks } = value;\n\treturn {\n\t\tschemas: schemas.map(({ jsonSchema, ...rest }) => ({\n\t\t\t...rest,\n\t\t\t...(jsonSchema ? { jsonSchema } : {}),\n\t\t})),\n\t\tchecks,\n\t};\n}\n\n/** The constructs loaded once, here, and asked about as often as needed. */\nasync function loadCredentialSchemasHere(options: InspectOptions): Promise<{\n\tinspect(\n\t\tvalues: Readonly<Record<string, string>>,\n\t): Promise<CredentialInspection>;\n}> {\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst manifest = await discover({\n\t\tpatterns: [...options.patterns],\n\t\tcwd: options.root,\n\t\tsources,\n\t});\n\tconst live = liveCredentials(manifest, sources);\n\treturn { inspect: (values) => inspectLive(live, values) };\n}\n\n/** The schemas, and a check of one candidate value at a time. */\nexport interface CredentialSchemas {\n\tschemas: CredentialSchemaInfo[];\n\t/** `raw` against `key`'s schema; ok for a key no schema describes. */\n\tcheck(key: string, raw: string): Promise<CredentialCheck>;\n}\n\n/**\n * The workspace's credential schemas, for a command that checks values one\n * at a time as they are typed. In-process the constructs are loaded once;\n * in a sandbox each check is a run of the worker.\n */\nexport async function loadCredentialSchemas(\n\toptions: Omit<InspectOptions, 'values'>,\n): Promise<CredentialSchemas> {\n\tconst here = activeSandbox()\n\t\t? undefined\n\t\t: await loadCredentialSchemasHere(options);\n\tconst inspect = (values: Readonly<Record<string, string>>) =>\n\t\there ? here.inspect(values) : inspectCredentials({ ...options, values });\n\n\tconst { schemas } = await inspect({});\n\treturn {\n\t\tschemas,\n\t\tasync check(key, raw) {\n\t\t\tif (!schemas.some((s) => s.key === key)) return { ok: true, issues: [] };\n\t\t\tconst { checks } = await inspect({ [key]: raw });\n\t\t\treturn checks[key] ?? { ok: true, issues: [] };\n\t\t},\n\t};\n}\n\n/** One stored credential its schema refuses. */\nexport interface InvalidCredential {\n\tkey: string;\n\tissues: CredentialIssue[];\n}\n\n/** An issue as the line that names it: `SHIPPING_CREDENTIALS.apiKey: …`. */\nexport function issueLine(key: string, issue: CredentialIssue): string {\n\treturn `${key}${issue.path ? `.${issue.path}` : ''}: ${issue.message}`;\n}\n\n/**\n * Credentials their construct's schema refuses — on their way into the\n * stage's secrets, or already there when a deploy reads them. The values are\n * never in the message: only where each is wrong, and why.\n */\nexport class CredentialsInvalid extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly invalid: readonly InvalidCredential[],\n\t\t/** Whether a value was being set (and was not saved), or deployed. */\n\t\treadonly during: 'set' | 'deploy',\n\t) {\n\t\tconst lines = invalid.flatMap(({ key, issues }) =>\n\t\t\tissues.map((issue) => ` ${issueLine(key, issue)}`),\n\t\t);\n\t\tconst keys = invalid.map((i) => i.key);\n\t\tsuper(\n\t\t\tduring === 'set'\n\t\t\t\t? `${keys.join(', ')} is not what its construct's schema describes, ` +\n\t\t\t\t\t\t`so nothing was saved:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set a value that matches, or let gkm ask for each field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`\n\t\t\t\t: `The stage '${stage}' holds ${keys.length === 1 ? 'a credential' : 'credentials'} ` +\n\t\t\t\t\t\t`${keys.length === 1 ? \"its construct's schema refuses\" : \"their constructs' schemas refuse\"}, ` +\n\t\t\t\t\t\t`and every app reading ${keys.length === 1 ? 'it' : 'them'} would fail ` +\n\t\t\t\t\t\t`as it starts:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set ${keys.length === 1 ? 'it' : 'them'} again, field by field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`,\n\t\t);\n\t\tthis.name = 'CredentialsInvalid';\n\t}\n}\n\n/**\n * Every credential the stage holds for a construct, against its schema —\n * before a deploy builds anything with one the app would refuse as it\n * starts. Loads nothing when the stage holds none.\n *\n * @throws {CredentialsInvalid} naming each key and every issue\n */\nexport async function assertStageCredentials(options: {\n\troot: string;\n\tpatterns: readonly string[];\n\tmanifest: ConstructManifest;\n\tstage: string;\n\tsupplied: Readonly<Record<string, string>>;\n}): Promise<void> {\n\tconst values = Object.fromEntries(\n\t\tcredentialKeys(options.manifest)\n\t\t\t.map(({ key }) => [key, options.supplied[key]] as const)\n\t\t\t.filter((entry): entry is [string, string] => entry[1] !== undefined),\n\t);\n\tif (Object.keys(values).length === 0) return;\n\n\tconst { checks } = await inspectCredentials({\n\t\troot: options.root,\n\t\tpatterns: options.patterns,\n\t\tvalues,\n\t});\n\tconst invalid = Object.entries(checks)\n\t\t.filter(([, check]) => !check.ok)\n\t\t.map(([key, check]) => ({ key, issues: check.issues }))\n\t\t.sort((a, b) => a.key.localeCompare(b.key));\n\tif (invalid.length > 0) {\n\t\tthrow new CredentialsInvalid(options.stage, invalid, 'deploy');\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
|
|
2
2
|
import { a as discriminatedUnion, c as literal, d as object, f as record, g as unknown, n as array, p as string, r as boolean, t as _enum, v as toJSONSchema } from "./schemas-BCwKKA42.mjs";
|
|
3
|
-
import { i as discover, l as runWorker, t as ConstructDiscoveryFailed } from "./discover-
|
|
3
|
+
import { i as discover, l as runWorker, t as ConstructDiscoveryFailed } from "./discover-BvJOVsYG.mjs";
|
|
4
4
|
import { i as activeSandbox } from "./sandbox-CbVB7uOD.mjs";
|
|
5
5
|
import { provideKey } from "@geekmidas/manifest";
|
|
6
6
|
import { decodeCredentials } from "@geekmidas/constructs/credential";
|
|
@@ -234,4 +234,4 @@ async function assertStageCredentials(options) {
|
|
|
234
234
|
//#endregion
|
|
235
235
|
export { liveCredentials as a, issueLine as i, assertStageCredentials as n, loadCredentialSchemas as o, inspectLive as r, CredentialsInvalid as t };
|
|
236
236
|
|
|
237
|
-
//# sourceMappingURL=credentialSchemas-
|
|
237
|
+
//# sourceMappingURL=credentialSchemas-DLKbxYBy.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentialSchemas-DDOLRCLF.mjs","names":["z.toJSONSchema","z.object","z.string","z.discriminatedUnion","z.literal","z.array","z.enum","z.record","z.unknown","z.boolean"],"sources":["../src/secrets/credentialSchemas.ts"],"sourcesContent":["/**\n * A third party's credentials, checked against the schema of the construct\n * that reads them — before they are stored, and before a deploy builds\n * anything with them.\n *\n * The schema lives on the construct (`ExternalApi.credentialsSchema`,\n * `Credential.credentialsSchema`), which is the project's code. So the\n * constructs are loaded where a deploy loads them: in the run's sandbox when\n * there is one, here otherwise. What comes back is data only — each schema as\n * JSON Schema where it can say so, and `{ ok, issues }` for each value asked\n * about — because a live schema cannot cross an isolating sandbox. A value\n * asked about goes in as a secret file, never an argument, and no issue\n * carries it back: an issue is a path and a message.\n */\n\nimport { decodeCredentials } from '@geekmidas/constructs/credential';\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { z } from 'zod';\nimport { GkmError } from '../errors';\nimport {\n\tConstructDiscoveryFailed,\n\ttype ConstructSource,\n\tdiscover,\n} from '../reconcile/discover';\nimport { activeSandbox } from '../sandbox/sandbox';\nimport { runWorker } from '../sandbox/worker';\n\n/** One thing a schema refused: where in the value, and why. */\nexport interface CredentialIssue {\n\t/** Dotted, from the value's root — `apiKey`, `keys.0`; empty for the root. */\n\tpath: string;\n\tmessage: string;\n}\n\n/** What a candidate value came to. */\nexport interface CredentialCheck {\n\tok: boolean;\n\tissues: CredentialIssue[];\n}\n\n/** A construct's credentials key, and its schema as data. */\nexport interface CredentialSchemaInfo {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\t/**\n\t * The schema as JSON Schema, where the schema can say — zod's, or any\n\t * Standard JSON Schema. Absent otherwise: the value is asked for as JSON.\n\t */\n\tjsonSchema?: Record<string, unknown>;\n}\n\n/** What loading the constructs answers. */\nexport interface CredentialInspection {\n\tschemas: CredentialSchemaInfo[];\n\t/** Each value asked about, by key. */\n\tchecks: Record<string, CredentialCheck>;\n}\n\n/** A construct whose credentials have a schema. */\ninterface LiveCredential {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\tschema: StandardSchemaV1;\n}\n\n/** The credentials keys a manifest declares, by the construct that reads each. */\nexport function credentialKeys(\n\tmanifest: ConstructManifest,\n): { key: string; id: string; kind: 'external-api' | 'credential' }[] {\n\treturn Object.entries(manifest).flatMap(([id, declaration]) =>\n\t\tdeclaration.kind === 'external-api' || declaration.kind === 'credential'\n\t\t\t? [{ key: provideKey(id, 'credentials'), id, kind: declaration.kind }]\n\t\t\t: [],\n\t);\n}\n\n/** The constructs that read a third party's credentials, with their schemas. */\nexport function liveCredentials(\n\tmanifest: ConstructManifest,\n\tsources: Readonly<Record<string, ConstructSource>>,\n): LiveCredential[] {\n\treturn credentialKeys(manifest).flatMap(({ key, id, kind }) => {\n\t\tconst schema = (sources[id]?.construct as { credentialsSchema?: unknown })\n\t\t\t?.credentialsSchema;\n\t\treturn isStandardSchema(schema) ? [{ key, id, kind, schema }] : [];\n\t});\n}\n\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as StandardSchemaV1)['~standard']?.validate === 'function'\n\t);\n}\n\n/**\n * A schema as JSON Schema: through the Standard JSON Schema extension where\n * the schema has it, as zod 4's does, else zod's own converter — or nothing,\n * for a schema neither can describe.\n */\nexport function jsonSchemaOf(\n\tschema: StandardSchemaV1,\n): Record<string, unknown> | undefined {\n\tconst standard = schema['~standard'] as StandardSchemaV1['~standard'] & {\n\t\tjsonSchema?: {\n\t\t\tinput?: (options: { target: string }) => Record<string, unknown>;\n\t\t};\n\t};\n\ttry {\n\t\tconst described = standard.jsonSchema?.input?.({\n\t\t\ttarget: 'draft-2020-12',\n\t\t});\n\t\tif (described) return described;\n\t} catch {\n\t\t// A type JSON Schema cannot express: try zod's converter, then nothing.\n\t}\n\tif (typeof schema === 'object' && schema !== null && '_zod' in schema) {\n\t\ttry {\n\t\t\treturn z.toJSONSchema(schema as unknown as z.ZodType, {\n\t\t\t\tio: 'input',\n\t\t\t}) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** A stored value against its schema, read the way the construct reads it. */\nexport async function checkCredential(\n\tschema: StandardSchemaV1,\n\traw: string,\n): Promise<CredentialCheck> {\n\tconst result = await schema['~standard'].validate(decodeCredentials(raw));\n\tif (!result.issues) return { ok: true, issues: [] };\n\treturn {\n\t\tok: false,\n\t\tissues: result.issues.map((issue) => ({\n\t\t\tpath: (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.'),\n\t\t\tmessage: issue.message,\n\t\t})),\n\t};\n}\n\n/** What a set of live credentials says about some values: data only. */\nexport async function inspectLive(\n\tlive: readonly LiveCredential[],\n\tvalues: Readonly<Record<string, string>>,\n): Promise<CredentialInspection> {\n\tconst checks: Record<string, CredentialCheck> = {};\n\tfor (const credential of live) {\n\t\tconst value = values[credential.key];\n\t\tif (value === undefined) continue;\n\t\tchecks[credential.key] = await checkCredential(credential.schema, value);\n\t}\n\treturn {\n\t\tschemas: live.map(({ key, id, kind, schema }) => {\n\t\t\tconst jsonSchema = jsonSchemaOf(schema);\n\t\t\treturn { key, id, kind, ...(jsonSchema ? { jsonSchema } : {}) };\n\t\t}),\n\t\tchecks,\n\t};\n}\n\nexport interface InspectOptions {\n\t/** The workspace root. */\n\troot: string;\n\t/** Its construct globs. */\n\tpatterns: readonly string[];\n\t/** The values to check, by key. Only credentials keys are looked at. */\n\tvalues?: Readonly<Record<string, string>>;\n}\n\nconst Issue = z.object({ path: z.string(), message: z.string() });\n\n/** What the credentials worker answers. Checked: the worker ran project code. */\nconst CredentialsAnswer = z.discriminatedUnion('reason', [\n\tz.object({\n\t\treason: z.literal('inspected'),\n\t\tschemas: z.array(\n\t\t\tz.object({\n\t\t\t\tkey: z.string(),\n\t\t\t\tid: z.string(),\n\t\t\t\tkind: z.enum(['external-api', 'credential']),\n\t\t\t\tjsonSchema: z.record(z.string(), z.unknown()).optional(),\n\t\t\t}),\n\t\t),\n\t\tchecks: z.record(\n\t\t\tz.string(),\n\t\t\tz.object({ ok: z.boolean(), issues: z.array(Issue) }),\n\t\t),\n\t}),\n\tz.object({\n\t\treason: z.literal('failed'),\n\t\terror: z.object({ name: z.string(), message: z.string() }).loose(),\n\t}),\n]);\n\n/** How long loading the constructs to check credentials may take. */\nconst INSPECT_TIMEOUT_MS = 60_000;\n\n/**\n * The workspace's credential schemas, and what each of `values` comes to —\n * loaded in the run's sandbox when there is one, here otherwise.\n */\nexport async function inspectCredentials(\n\toptions: InspectOptions,\n): Promise<CredentialInspection> {\n\tconst sandbox = activeSandbox();\n\tif (!sandbox) {\n\t\treturn (await loadCredentialSchemasHere(options)).inspect(\n\t\t\toptions.values ?? {},\n\t\t);\n\t}\n\n\tconst secrets = Object.fromEntries(\n\t\tObject.entries(options.values ?? {}).filter(([key]) =>\n\t\t\tkey.endsWith('_CREDENTIALS'),\n\t\t),\n\t);\n\tconst { value } = await runWorker(sandbox, 'credentials check', {\n\t\tname: 'credentials-worker',\n\t\targs: [JSON.stringify({ patterns: options.patterns, cwd: options.root })],\n\t\tcwd: options.root,\n\t\ttimeoutMs: INSPECT_TIMEOUT_MS,\n\t\tschema: CredentialsAnswer,\n\t\t...(Object.keys(secrets).length > 0 ? { secrets } : {}),\n\t});\n\tif (value.reason === 'failed') {\n\t\tthrow new ConstructDiscoveryFailed(value.error.name, value.error.message);\n\t}\n\tconst { schemas, checks } = value;\n\treturn {\n\t\tschemas: schemas.map(({ jsonSchema, ...rest }) => ({\n\t\t\t...rest,\n\t\t\t...(jsonSchema ? { jsonSchema } : {}),\n\t\t})),\n\t\tchecks,\n\t};\n}\n\n/** The constructs loaded once, here, and asked about as often as needed. */\nasync function loadCredentialSchemasHere(options: InspectOptions): Promise<{\n\tinspect(\n\t\tvalues: Readonly<Record<string, string>>,\n\t): Promise<CredentialInspection>;\n}> {\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst manifest = await discover({\n\t\tpatterns: [...options.patterns],\n\t\tcwd: options.root,\n\t\tsources,\n\t});\n\tconst live = liveCredentials(manifest, sources);\n\treturn { inspect: (values) => inspectLive(live, values) };\n}\n\n/** The schemas, and a check of one candidate value at a time. */\nexport interface CredentialSchemas {\n\tschemas: CredentialSchemaInfo[];\n\t/** `raw` against `key`'s schema; ok for a key no schema describes. */\n\tcheck(key: string, raw: string): Promise<CredentialCheck>;\n}\n\n/**\n * The workspace's credential schemas, for a command that checks values one\n * at a time as they are typed. In-process the constructs are loaded once;\n * in a sandbox each check is a run of the worker.\n */\nexport async function loadCredentialSchemas(\n\toptions: Omit<InspectOptions, 'values'>,\n): Promise<CredentialSchemas> {\n\tconst here = activeSandbox()\n\t\t? undefined\n\t\t: await loadCredentialSchemasHere(options);\n\tconst inspect = (values: Readonly<Record<string, string>>) =>\n\t\there ? here.inspect(values) : inspectCredentials({ ...options, values });\n\n\tconst { schemas } = await inspect({});\n\treturn {\n\t\tschemas,\n\t\tasync check(key, raw) {\n\t\t\tif (!schemas.some((s) => s.key === key)) return { ok: true, issues: [] };\n\t\t\tconst { checks } = await inspect({ [key]: raw });\n\t\t\treturn checks[key] ?? { ok: true, issues: [] };\n\t\t},\n\t};\n}\n\n/** One stored credential its schema refuses. */\nexport interface InvalidCredential {\n\tkey: string;\n\tissues: CredentialIssue[];\n}\n\n/** An issue as the line that names it: `SHIPPING_CREDENTIALS.apiKey: …`. */\nexport function issueLine(key: string, issue: CredentialIssue): string {\n\treturn `${key}${issue.path ? `.${issue.path}` : ''}: ${issue.message}`;\n}\n\n/**\n * Credentials their construct's schema refuses — on their way into the\n * stage's secrets, or already there when a deploy reads them. The values are\n * never in the message: only where each is wrong, and why.\n */\nexport class CredentialsInvalid extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly invalid: readonly InvalidCredential[],\n\t\t/** Whether a value was being set (and was not saved), or deployed. */\n\t\treadonly during: 'set' | 'deploy',\n\t) {\n\t\tconst lines = invalid.flatMap(({ key, issues }) =>\n\t\t\tissues.map((issue) => ` ${issueLine(key, issue)}`),\n\t\t);\n\t\tconst keys = invalid.map((i) => i.key);\n\t\tsuper(\n\t\t\tduring === 'set'\n\t\t\t\t? `${keys.join(', ')} is not what its construct's schema describes, ` +\n\t\t\t\t\t\t`so nothing was saved:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set a value that matches, or let gkm ask for each field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`\n\t\t\t\t: `The stage '${stage}' holds ${keys.length === 1 ? 'a credential' : 'credentials'} ` +\n\t\t\t\t\t\t`${keys.length === 1 ? \"its construct's schema refuses\" : \"their constructs' schemas refuse\"}, ` +\n\t\t\t\t\t\t`and every app reading ${keys.length === 1 ? 'it' : 'them'} would fail ` +\n\t\t\t\t\t\t`as it starts:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set ${keys.length === 1 ? 'it' : 'them'} again, field by field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`,\n\t\t);\n\t\tthis.name = 'CredentialsInvalid';\n\t}\n}\n\n/**\n * Every credential the stage holds for a construct, against its schema —\n * before a deploy builds anything with one the app would refuse as it\n * starts. Loads nothing when the stage holds none.\n *\n * @throws {CredentialsInvalid} naming each key and every issue\n */\nexport async function assertStageCredentials(options: {\n\troot: string;\n\tpatterns: readonly string[];\n\tmanifest: ConstructManifest;\n\tstage: string;\n\tsupplied: Readonly<Record<string, string>>;\n}): Promise<void> {\n\tconst values = Object.fromEntries(\n\t\tcredentialKeys(options.manifest)\n\t\t\t.map(({ key }) => [key, options.supplied[key]] as const)\n\t\t\t.filter((entry): entry is [string, string] => entry[1] !== undefined),\n\t);\n\tif (Object.keys(values).length === 0) return;\n\n\tconst { checks } = await inspectCredentials({\n\t\troot: options.root,\n\t\tpatterns: options.patterns,\n\t\tvalues,\n\t});\n\tconst invalid = Object.entries(checks)\n\t\t.filter(([, check]) => !check.ok)\n\t\t.map(([key, check]) => ({ key, issues: check.issues }))\n\t\t.sort((a, b) => a.key.localeCompare(b.key));\n\tif (invalid.length > 0) {\n\t\tthrow new CredentialsInvalid(options.stage, invalid, 'deploy');\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"credentialSchemas-DLKbxYBy.mjs","names":["z.toJSONSchema","z.object","z.string","z.discriminatedUnion","z.literal","z.array","z.enum","z.record","z.unknown","z.boolean"],"sources":["../src/secrets/credentialSchemas.ts"],"sourcesContent":["/**\n * A third party's credentials, checked against the schema of the construct\n * that reads them — before they are stored, and before a deploy builds\n * anything with them.\n *\n * The schema lives on the construct (`ExternalApi.credentialsSchema`,\n * `Credential.credentialsSchema`), which is the project's code. So the\n * constructs are loaded where a deploy loads them: in the run's sandbox when\n * there is one, here otherwise. What comes back is data only — each schema as\n * JSON Schema where it can say so, and `{ ok, issues }` for each value asked\n * about — because a live schema cannot cross an isolating sandbox. A value\n * asked about goes in as a secret file, never an argument, and no issue\n * carries it back: an issue is a path and a message.\n */\n\nimport { decodeCredentials } from '@geekmidas/constructs/credential';\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { z } from 'zod';\nimport { GkmError } from '../errors';\nimport {\n\tConstructDiscoveryFailed,\n\ttype ConstructSource,\n\tdiscover,\n} from '../reconcile/discover';\nimport { activeSandbox } from '../sandbox/sandbox';\nimport { runWorker } from '../sandbox/worker';\n\n/** One thing a schema refused: where in the value, and why. */\nexport interface CredentialIssue {\n\t/** Dotted, from the value's root — `apiKey`, `keys.0`; empty for the root. */\n\tpath: string;\n\tmessage: string;\n}\n\n/** What a candidate value came to. */\nexport interface CredentialCheck {\n\tok: boolean;\n\tissues: CredentialIssue[];\n}\n\n/** A construct's credentials key, and its schema as data. */\nexport interface CredentialSchemaInfo {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\t/**\n\t * The schema as JSON Schema, where the schema can say — zod's, or any\n\t * Standard JSON Schema. Absent otherwise: the value is asked for as JSON.\n\t */\n\tjsonSchema?: Record<string, unknown>;\n}\n\n/** What loading the constructs answers. */\nexport interface CredentialInspection {\n\tschemas: CredentialSchemaInfo[];\n\t/** Each value asked about, by key. */\n\tchecks: Record<string, CredentialCheck>;\n}\n\n/** A construct whose credentials have a schema. */\ninterface LiveCredential {\n\tkey: string;\n\tid: string;\n\tkind: 'external-api' | 'credential';\n\tschema: StandardSchemaV1;\n}\n\n/** The credentials keys a manifest declares, by the construct that reads each. */\nexport function credentialKeys(\n\tmanifest: ConstructManifest,\n): { key: string; id: string; kind: 'external-api' | 'credential' }[] {\n\treturn Object.entries(manifest).flatMap(([id, declaration]) =>\n\t\tdeclaration.kind === 'external-api' || declaration.kind === 'credential'\n\t\t\t? [{ key: provideKey(id, 'credentials'), id, kind: declaration.kind }]\n\t\t\t: [],\n\t);\n}\n\n/** The constructs that read a third party's credentials, with their schemas. */\nexport function liveCredentials(\n\tmanifest: ConstructManifest,\n\tsources: Readonly<Record<string, ConstructSource>>,\n): LiveCredential[] {\n\treturn credentialKeys(manifest).flatMap(({ key, id, kind }) => {\n\t\tconst schema = (sources[id]?.construct as { credentialsSchema?: unknown })\n\t\t\t?.credentialsSchema;\n\t\treturn isStandardSchema(schema) ? [{ key, id, kind, schema }] : [];\n\t});\n}\n\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as StandardSchemaV1)['~standard']?.validate === 'function'\n\t);\n}\n\n/**\n * A schema as JSON Schema: through the Standard JSON Schema extension where\n * the schema has it, as zod 4's does, else zod's own converter — or nothing,\n * for a schema neither can describe.\n */\nexport function jsonSchemaOf(\n\tschema: StandardSchemaV1,\n): Record<string, unknown> | undefined {\n\tconst standard = schema['~standard'] as StandardSchemaV1['~standard'] & {\n\t\tjsonSchema?: {\n\t\t\tinput?: (options: { target: string }) => Record<string, unknown>;\n\t\t};\n\t};\n\ttry {\n\t\tconst described = standard.jsonSchema?.input?.({\n\t\t\ttarget: 'draft-2020-12',\n\t\t});\n\t\tif (described) return described;\n\t} catch {\n\t\t// A type JSON Schema cannot express: try zod's converter, then nothing.\n\t}\n\tif (typeof schema === 'object' && schema !== null && '_zod' in schema) {\n\t\ttry {\n\t\t\treturn z.toJSONSchema(schema as unknown as z.ZodType, {\n\t\t\t\tio: 'input',\n\t\t\t}) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** A stored value against its schema, read the way the construct reads it. */\nexport async function checkCredential(\n\tschema: StandardSchemaV1,\n\traw: string,\n): Promise<CredentialCheck> {\n\tconst result = await schema['~standard'].validate(decodeCredentials(raw));\n\tif (!result.issues) return { ok: true, issues: [] };\n\treturn {\n\t\tok: false,\n\t\tissues: result.issues.map((issue) => ({\n\t\t\tpath: (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.'),\n\t\t\tmessage: issue.message,\n\t\t})),\n\t};\n}\n\n/** What a set of live credentials says about some values: data only. */\nexport async function inspectLive(\n\tlive: readonly LiveCredential[],\n\tvalues: Readonly<Record<string, string>>,\n): Promise<CredentialInspection> {\n\tconst checks: Record<string, CredentialCheck> = {};\n\tfor (const credential of live) {\n\t\tconst value = values[credential.key];\n\t\tif (value === undefined) continue;\n\t\tchecks[credential.key] = await checkCredential(credential.schema, value);\n\t}\n\treturn {\n\t\tschemas: live.map(({ key, id, kind, schema }) => {\n\t\t\tconst jsonSchema = jsonSchemaOf(schema);\n\t\t\treturn { key, id, kind, ...(jsonSchema ? { jsonSchema } : {}) };\n\t\t}),\n\t\tchecks,\n\t};\n}\n\nexport interface InspectOptions {\n\t/** The workspace root. */\n\troot: string;\n\t/** Its construct globs. */\n\tpatterns: readonly string[];\n\t/** The values to check, by key. Only credentials keys are looked at. */\n\tvalues?: Readonly<Record<string, string>>;\n}\n\nconst Issue = z.object({ path: z.string(), message: z.string() });\n\n/** What the credentials worker answers. Checked: the worker ran project code. */\nconst CredentialsAnswer = z.discriminatedUnion('reason', [\n\tz.object({\n\t\treason: z.literal('inspected'),\n\t\tschemas: z.array(\n\t\t\tz.object({\n\t\t\t\tkey: z.string(),\n\t\t\t\tid: z.string(),\n\t\t\t\tkind: z.enum(['external-api', 'credential']),\n\t\t\t\tjsonSchema: z.record(z.string(), z.unknown()).optional(),\n\t\t\t}),\n\t\t),\n\t\tchecks: z.record(\n\t\t\tz.string(),\n\t\t\tz.object({ ok: z.boolean(), issues: z.array(Issue) }),\n\t\t),\n\t}),\n\tz.object({\n\t\treason: z.literal('failed'),\n\t\terror: z.object({ name: z.string(), message: z.string() }).loose(),\n\t}),\n]);\n\n/** How long loading the constructs to check credentials may take. */\nconst INSPECT_TIMEOUT_MS = 60_000;\n\n/**\n * The workspace's credential schemas, and what each of `values` comes to —\n * loaded in the run's sandbox when there is one, here otherwise.\n */\nexport async function inspectCredentials(\n\toptions: InspectOptions,\n): Promise<CredentialInspection> {\n\tconst sandbox = activeSandbox();\n\tif (!sandbox) {\n\t\treturn (await loadCredentialSchemasHere(options)).inspect(\n\t\t\toptions.values ?? {},\n\t\t);\n\t}\n\n\tconst secrets = Object.fromEntries(\n\t\tObject.entries(options.values ?? {}).filter(([key]) =>\n\t\t\tkey.endsWith('_CREDENTIALS'),\n\t\t),\n\t);\n\tconst { value } = await runWorker(sandbox, 'credentials check', {\n\t\tname: 'credentials-worker',\n\t\targs: [JSON.stringify({ patterns: options.patterns, cwd: options.root })],\n\t\tcwd: options.root,\n\t\ttimeoutMs: INSPECT_TIMEOUT_MS,\n\t\tschema: CredentialsAnswer,\n\t\t...(Object.keys(secrets).length > 0 ? { secrets } : {}),\n\t});\n\tif (value.reason === 'failed') {\n\t\tthrow new ConstructDiscoveryFailed(value.error.name, value.error.message);\n\t}\n\tconst { schemas, checks } = value;\n\treturn {\n\t\tschemas: schemas.map(({ jsonSchema, ...rest }) => ({\n\t\t\t...rest,\n\t\t\t...(jsonSchema ? { jsonSchema } : {}),\n\t\t})),\n\t\tchecks,\n\t};\n}\n\n/** The constructs loaded once, here, and asked about as often as needed. */\nasync function loadCredentialSchemasHere(options: InspectOptions): Promise<{\n\tinspect(\n\t\tvalues: Readonly<Record<string, string>>,\n\t): Promise<CredentialInspection>;\n}> {\n\tconst sources: Record<string, ConstructSource> = {};\n\tconst manifest = await discover({\n\t\tpatterns: [...options.patterns],\n\t\tcwd: options.root,\n\t\tsources,\n\t});\n\tconst live = liveCredentials(manifest, sources);\n\treturn { inspect: (values) => inspectLive(live, values) };\n}\n\n/** The schemas, and a check of one candidate value at a time. */\nexport interface CredentialSchemas {\n\tschemas: CredentialSchemaInfo[];\n\t/** `raw` against `key`'s schema; ok for a key no schema describes. */\n\tcheck(key: string, raw: string): Promise<CredentialCheck>;\n}\n\n/**\n * The workspace's credential schemas, for a command that checks values one\n * at a time as they are typed. In-process the constructs are loaded once;\n * in a sandbox each check is a run of the worker.\n */\nexport async function loadCredentialSchemas(\n\toptions: Omit<InspectOptions, 'values'>,\n): Promise<CredentialSchemas> {\n\tconst here = activeSandbox()\n\t\t? undefined\n\t\t: await loadCredentialSchemasHere(options);\n\tconst inspect = (values: Readonly<Record<string, string>>) =>\n\t\there ? here.inspect(values) : inspectCredentials({ ...options, values });\n\n\tconst { schemas } = await inspect({});\n\treturn {\n\t\tschemas,\n\t\tasync check(key, raw) {\n\t\t\tif (!schemas.some((s) => s.key === key)) return { ok: true, issues: [] };\n\t\t\tconst { checks } = await inspect({ [key]: raw });\n\t\t\treturn checks[key] ?? { ok: true, issues: [] };\n\t\t},\n\t};\n}\n\n/** One stored credential its schema refuses. */\nexport interface InvalidCredential {\n\tkey: string;\n\tissues: CredentialIssue[];\n}\n\n/** An issue as the line that names it: `SHIPPING_CREDENTIALS.apiKey: …`. */\nexport function issueLine(key: string, issue: CredentialIssue): string {\n\treturn `${key}${issue.path ? `.${issue.path}` : ''}: ${issue.message}`;\n}\n\n/**\n * Credentials their construct's schema refuses — on their way into the\n * stage's secrets, or already there when a deploy reads them. The values are\n * never in the message: only where each is wrong, and why.\n */\nexport class CredentialsInvalid extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly invalid: readonly InvalidCredential[],\n\t\t/** Whether a value was being set (and was not saved), or deployed. */\n\t\treadonly during: 'set' | 'deploy',\n\t) {\n\t\tconst lines = invalid.flatMap(({ key, issues }) =>\n\t\t\tissues.map((issue) => ` ${issueLine(key, issue)}`),\n\t\t);\n\t\tconst keys = invalid.map((i) => i.key);\n\t\tsuper(\n\t\t\tduring === 'set'\n\t\t\t\t? `${keys.join(', ')} is not what its construct's schema describes, ` +\n\t\t\t\t\t\t`so nothing was saved:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set a value that matches, or let gkm ask for each field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`\n\t\t\t\t: `The stage '${stage}' holds ${keys.length === 1 ? 'a credential' : 'credentials'} ` +\n\t\t\t\t\t\t`${keys.length === 1 ? \"its construct's schema refuses\" : \"their constructs' schemas refuse\"}, ` +\n\t\t\t\t\t\t`and every app reading ${keys.length === 1 ? 'it' : 'them'} would fail ` +\n\t\t\t\t\t\t`as it starts:\\n\\n${lines.join('\\n')}\\n\\n` +\n\t\t\t\t\t\t`Set ${keys.length === 1 ? 'it' : 'them'} again, field by field: ` +\n\t\t\t\t\t\t`gkm secrets:add --stage ${stage}`,\n\t\t);\n\t\tthis.name = 'CredentialsInvalid';\n\t}\n}\n\n/**\n * Every credential the stage holds for a construct, against its schema —\n * before a deploy builds anything with one the app would refuse as it\n * starts. Loads nothing when the stage holds none.\n *\n * @throws {CredentialsInvalid} naming each key and every issue\n */\nexport async function assertStageCredentials(options: {\n\troot: string;\n\tpatterns: readonly string[];\n\tmanifest: ConstructManifest;\n\tstage: string;\n\tsupplied: Readonly<Record<string, string>>;\n}): Promise<void> {\n\tconst values = Object.fromEntries(\n\t\tcredentialKeys(options.manifest)\n\t\t\t.map(({ key }) => [key, options.supplied[key]] as const)\n\t\t\t.filter((entry): entry is [string, string] => entry[1] !== undefined),\n\t);\n\tif (Object.keys(values).length === 0) return;\n\n\tconst { checks } = await inspectCredentials({\n\t\troot: options.root,\n\t\tpatterns: options.patterns,\n\t\tvalues,\n\t});\n\tconst invalid = Object.entries(checks)\n\t\t.filter(([, check]) => !check.ok)\n\t\t.map(([key, check]) => ({ key, issues: check.issues }))\n\t\t.sort((a, b) => a.key.localeCompare(b.key));\n\tif (invalid.length > 0) {\n\t\tthrow new CredentialsInvalid(options.stage, invalid, 'deploy');\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
const require_errors = require("./errors-DMC4Umsb.cjs");
|
|
2
|
-
const require_run = require("./run-fVZ-rLnc.cjs");
|
|
3
2
|
let node_path = require("node:path");
|
|
4
3
|
let node_fs = require("node:fs");
|
|
5
4
|
let node_fs_promises = require("node:fs/promises");
|
|
5
|
+
let node_os = require("node:os");
|
|
6
|
+
let node_child_process = require("node:child_process");
|
|
7
|
+
//#region src/home.ts
|
|
8
|
+
/**
|
|
9
|
+
* Where the CLI keeps what belongs to a person rather than a project: stage
|
|
10
|
+
* keys and stored provider credentials.
|
|
11
|
+
*
|
|
12
|
+
* `GKM_HOME` names it, so a CI job, a shared build runner or a test can give
|
|
13
|
+
* every run its own instead of reaching into whoever's home directory the
|
|
14
|
+
* process happens to have. Unset, it is `~/.gkm`, where it has always been.
|
|
15
|
+
*/
|
|
16
|
+
/** The environment variable that moves the CLI's home. */
|
|
17
|
+
const GKM_HOME_ENV = "GKM_HOME";
|
|
18
|
+
/** The CLI's home: `GKM_HOME` if set, else `~/.gkm`. */
|
|
19
|
+
function gkmHome(env = process.env) {
|
|
20
|
+
const configured = env[GKM_HOME_ENV];
|
|
21
|
+
return configured ? (0, node_path.resolve)(configured) : (0, node_path.join)((0, node_os.homedir)(), ".gkm");
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
6
24
|
//#region src/auth/credentials.ts
|
|
7
25
|
/**
|
|
8
26
|
* Get the path to the credentials directory
|
|
9
27
|
*/
|
|
10
28
|
function getCredentialsDir(options) {
|
|
11
29
|
if (options?.home) return options.home;
|
|
12
|
-
return options?.root ? (0, node_path.join)(options.root, ".gkm") :
|
|
30
|
+
return options?.root ? (0, node_path.join)(options.root, ".gkm") : gkmHome();
|
|
13
31
|
}
|
|
14
32
|
/**
|
|
15
33
|
* Get the path to the credentials file
|
|
@@ -146,6 +164,116 @@ async function removeGoDaddyCredentials(options) {
|
|
|
146
164
|
return true;
|
|
147
165
|
}
|
|
148
166
|
//#endregion
|
|
167
|
+
//#region src/run.ts
|
|
168
|
+
/**
|
|
169
|
+
* Start a program with an argument array, never a shell string.
|
|
170
|
+
*
|
|
171
|
+
* `gkm build`, `gkm docker` and `gkm deploy` pass values that come from the
|
|
172
|
+
* workspace — image refs, tags, build args, package names — to `docker` and
|
|
173
|
+
* `turbo`. Joined into a string and handed to a shell, a package named
|
|
174
|
+
* `x;curl …|sh` or a tag holding `$(…)` became part of the command line, which
|
|
175
|
+
* matters most where the CLI builds a repository it didn't write: a CI job for a
|
|
176
|
+
* fork, a shared build runner. Here every value reaches the program as one
|
|
177
|
+
* `argv` element, whatever it contains.
|
|
178
|
+
*/
|
|
179
|
+
/** Long enough for a cold image build; short enough that a hung one ends. */
|
|
180
|
+
const DEFAULT_TIMEOUT_MS = 18e5;
|
|
181
|
+
/** How long a timed-out child has to exit on SIGTERM before it is killed. */
|
|
182
|
+
const KILL_GRACE_MS = 5e3;
|
|
183
|
+
/** The command line as a person would read it — for messages, never to run. */
|
|
184
|
+
function display(command, args) {
|
|
185
|
+
return [command, ...args].join(" ");
|
|
186
|
+
}
|
|
187
|
+
/** The program ran and exited unsuccessfully; its own output said why. */
|
|
188
|
+
var CommandFailed = class extends Error {
|
|
189
|
+
command;
|
|
190
|
+
args;
|
|
191
|
+
exitCode;
|
|
192
|
+
signal;
|
|
193
|
+
constructor(command, args, exitCode, signal) {
|
|
194
|
+
super(`\`${display(command, args)}\` ${exitCode === null ? `was stopped by ${signal ?? "a signal"}` : `exited with code ${exitCode}`}. Its output above says why; run it by hand to see it again.`);
|
|
195
|
+
this.command = command;
|
|
196
|
+
this.args = args;
|
|
197
|
+
this.exitCode = exitCode;
|
|
198
|
+
this.signal = signal;
|
|
199
|
+
this.name = "CommandFailed";
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
/** The program ran past its timeout and was killed. */
|
|
203
|
+
var CommandTimedOut = class extends Error {
|
|
204
|
+
command;
|
|
205
|
+
args;
|
|
206
|
+
timeoutMs;
|
|
207
|
+
constructor(command, args, timeoutMs) {
|
|
208
|
+
super(`\`${display(command, args)}\` was still running after ${Math.round(timeoutMs / 1e3)}s and was stopped. Check what it was waiting on — a registry, the Docker daemon, a prompt — and run it again.`);
|
|
209
|
+
this.command = command;
|
|
210
|
+
this.args = args;
|
|
211
|
+
this.timeoutMs = timeoutMs;
|
|
212
|
+
this.name = "CommandTimedOut";
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Run `command` with `args`, resolving when it exits 0.
|
|
217
|
+
*
|
|
218
|
+
* Rejects with {@link CommandFailed} on any other exit, {@link CommandTimedOut}
|
|
219
|
+
* once `timeoutMs` passes (after the child is gone), and with the spawn error
|
|
220
|
+
* itself when the program cannot be started at all — `ENOENT` already names it.
|
|
221
|
+
*/
|
|
222
|
+
async function run(command, args, options = {}) {
|
|
223
|
+
await spawnChild(command, args, options, false);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* {@link run}, resolving with what the program wrote to stdout — for a value
|
|
227
|
+
* the CLI reads back, such as the digest `docker inspect` reports. stderr still
|
|
228
|
+
* reaches the terminal, so a failure explains itself the same way.
|
|
229
|
+
*/
|
|
230
|
+
function runOutput(command, args, options = {}) {
|
|
231
|
+
return spawnChild(command, args, options, true);
|
|
232
|
+
}
|
|
233
|
+
function spawnChild(command, args, options, capture) {
|
|
234
|
+
const { timeoutMs = DEFAULT_TIMEOUT_MS, ...spawnOptions } = options;
|
|
235
|
+
return new Promise((resolve, reject) => {
|
|
236
|
+
const child = (0, node_child_process.spawn)(command, [...args], {
|
|
237
|
+
stdio: "inherit",
|
|
238
|
+
...spawnOptions,
|
|
239
|
+
...capture ? { stdio: [
|
|
240
|
+
"ignore",
|
|
241
|
+
"pipe",
|
|
242
|
+
"inherit"
|
|
243
|
+
] } : {},
|
|
244
|
+
shell: false
|
|
245
|
+
});
|
|
246
|
+
let stdout = "";
|
|
247
|
+
child.stdout?.on("data", (chunk) => {
|
|
248
|
+
stdout += chunk.toString();
|
|
249
|
+
});
|
|
250
|
+
let timedOut = false;
|
|
251
|
+
let killer;
|
|
252
|
+
const timer = setTimeout(() => {
|
|
253
|
+
timedOut = true;
|
|
254
|
+
child.kill("SIGTERM");
|
|
255
|
+
killer = setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS);
|
|
256
|
+
killer.unref?.();
|
|
257
|
+
}, timeoutMs);
|
|
258
|
+
timer.unref?.();
|
|
259
|
+
const settle = () => {
|
|
260
|
+
clearTimeout(timer);
|
|
261
|
+
if (killer) clearTimeout(killer);
|
|
262
|
+
};
|
|
263
|
+
child.on("error", (error) => {
|
|
264
|
+
settle();
|
|
265
|
+
reject(spawnOptions.signal?.aborted ? spawnOptions.signal.reason : error);
|
|
266
|
+
});
|
|
267
|
+
child.on("close", (code, signal) => {
|
|
268
|
+
settle();
|
|
269
|
+
if (spawnOptions.signal?.aborted) reject(spawnOptions.signal.reason);
|
|
270
|
+
else if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));
|
|
271
|
+
else if (code === 0) resolve(stdout);
|
|
272
|
+
else reject(new CommandFailed(command, args, code, signal));
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
149
277
|
//#region src/deploy/credentials.ts
|
|
150
278
|
/**
|
|
151
279
|
* How a deploy gets the credentials it acts with.
|
|
@@ -262,6 +390,30 @@ function storedCredentials(options = {}) {
|
|
|
262
390
|
} };
|
|
263
391
|
}
|
|
264
392
|
//#endregion
|
|
393
|
+
Object.defineProperty(exports, "CommandFailed", {
|
|
394
|
+
enumerable: true,
|
|
395
|
+
get: function() {
|
|
396
|
+
return CommandFailed;
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
Object.defineProperty(exports, "CommandTimedOut", {
|
|
400
|
+
enumerable: true,
|
|
401
|
+
get: function() {
|
|
402
|
+
return CommandTimedOut;
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
Object.defineProperty(exports, "DEFAULT_TIMEOUT_MS", {
|
|
406
|
+
enumerable: true,
|
|
407
|
+
get: function() {
|
|
408
|
+
return DEFAULT_TIMEOUT_MS;
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
Object.defineProperty(exports, "GKM_HOME_ENV", {
|
|
412
|
+
enumerable: true,
|
|
413
|
+
get: function() {
|
|
414
|
+
return GKM_HOME_ENV;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
265
417
|
Object.defineProperty(exports, "MissingCredential", {
|
|
266
418
|
enumerable: true,
|
|
267
419
|
get: function() {
|
|
@@ -304,6 +456,12 @@ Object.defineProperty(exports, "getHostingerToken", {
|
|
|
304
456
|
return getHostingerToken;
|
|
305
457
|
}
|
|
306
458
|
});
|
|
459
|
+
Object.defineProperty(exports, "gkmHome", {
|
|
460
|
+
enumerable: true,
|
|
461
|
+
get: function() {
|
|
462
|
+
return gkmHome;
|
|
463
|
+
}
|
|
464
|
+
});
|
|
307
465
|
Object.defineProperty(exports, "readCredentials", {
|
|
308
466
|
enumerable: true,
|
|
309
467
|
get: function() {
|
|
@@ -322,6 +480,18 @@ Object.defineProperty(exports, "removeGoDaddyCredentials", {
|
|
|
322
480
|
return removeGoDaddyCredentials;
|
|
323
481
|
}
|
|
324
482
|
});
|
|
483
|
+
Object.defineProperty(exports, "run", {
|
|
484
|
+
enumerable: true,
|
|
485
|
+
get: function() {
|
|
486
|
+
return run;
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
Object.defineProperty(exports, "runOutput", {
|
|
490
|
+
enumerable: true,
|
|
491
|
+
get: function() {
|
|
492
|
+
return runOutput;
|
|
493
|
+
}
|
|
494
|
+
});
|
|
325
495
|
Object.defineProperty(exports, "storeDokployCredentials", {
|
|
326
496
|
enumerable: true,
|
|
327
497
|
get: function() {
|
|
@@ -347,4 +517,4 @@ Object.defineProperty(exports, "storedCredentials", {
|
|
|
347
517
|
}
|
|
348
518
|
});
|
|
349
519
|
|
|
350
|
-
//# sourceMappingURL=credentials-
|
|
520
|
+
//# sourceMappingURL=credentials-D7XJypNd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-D7XJypNd.cjs","names":["resolve","join","homedir","join","existsSync","readFile","writeFile","spawn","GkmError"],"sources":["../src/home.ts","../src/auth/credentials.ts","../src/run.ts","../src/deploy/credentials.ts"],"sourcesContent":["/**\n * Where the CLI keeps what belongs to a person rather than a project: stage\n * keys and stored provider credentials.\n *\n * `GKM_HOME` names it, so a CI job, a shared build runner or a test can give\n * every run its own instead of reaching into whoever's home directory the\n * process happens to have. Unset, it is `~/.gkm`, where it has always been.\n */\n\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\n/** The environment variable that moves the CLI's home. */\nexport const GKM_HOME_ENV = 'GKM_HOME';\n\n/** The CLI's home: `GKM_HOME` if set, else `~/.gkm`. */\nexport function gkmHome(env: NodeJS.ProcessEnv = process.env): string {\n\tconst configured = env[GKM_HOME_ENV];\n\treturn configured ? resolve(configured) : join(homedir(), '.gkm');\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { readFile, unlink, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { gkmHome } from '../home';\n\n/**\n * Stored credentials for various services\n */\nexport interface StoredCredentials {\n\tdokploy?: {\n\t\t/** API token */\n\t\ttoken: string;\n\t\t/** Dokploy endpoint URL */\n\t\tendpoint: string;\n\t\t/** Registry ID in Dokploy (for Docker image pulls) */\n\t\tregistryId?: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n\thostinger?: {\n\t\t/** API token from hpanel.hostinger.com/profile/api */\n\t\ttoken: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n\tgodaddy?: {\n\t\t/** A Personal Access Token, scoped to domains.dns:update */\n\t\ttoken: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n}\n\n/**\n * Options for credential operations\n */\nexport interface CredentialOptions {\n\t/**\n\t * A directory whose `.gkm` holds the credentials. Default: the CLI's home\n\t * (`GKM_HOME`, else `~/.gkm`).\n\t */\n\troot?: string;\n\t/** The CLI's home itself, holding `credentials.json`. Wins over `root`. */\n\thome?: string;\n}\n\n/**\n * Get the path to the credentials directory\n */\nexport function getCredentialsDir(options?: CredentialOptions): string {\n\tif (options?.home) return options.home;\n\treturn options?.root ? join(options.root, '.gkm') : gkmHome();\n}\n\n/**\n * Get the path to the credentials file\n */\nexport function getCredentialsPath(options?: CredentialOptions): string {\n\treturn join(getCredentialsDir(options), 'credentials.json');\n}\n\n/**\n * Ensure the credentials directory exists\n */\nfunction ensureCredentialsDir(options?: CredentialOptions): void {\n\tconst dir = getCredentialsDir(options);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Read stored credentials from disk\n */\nexport async function readCredentials(\n\toptions?: CredentialOptions,\n): Promise<StoredCredentials> {\n\tconst path = getCredentialsPath(options);\n\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst content = await readFile(path, 'utf-8');\n\t\treturn JSON.parse(content) as StoredCredentials;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/**\n * Write credentials to disk\n */\nexport async function writeCredentials(\n\tcredentials: StoredCredentials,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tensureCredentialsDir(options);\n\tconst path = getCredentialsPath(options);\n\n\tawait writeFile(path, JSON.stringify(credentials, null, 2), {\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n/**\n * Store Dokploy credentials\n */\nexport async function storeDokployCredentials(\n\ttoken: string,\n\tendpoint: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.dokploy = {\n\t\ttoken,\n\t\tendpoint,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Dokploy credentials\n */\nexport async function getDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<{\n\ttoken: string;\n\tendpoint: string;\n\tregistryId?: string;\n} | null> {\n\tconst credentials = await readCredentials(options);\n\n\t// The environment first, and each half independently.\n\t//\n\t// `getDokployToken` has always read `DOKPLOY_API_TOKEN` while this — the\n\t// function the deploy path actually calls — read only the file. So a CI job\n\t// given the token as a secret had a token and nowhere to send it, and the\n\t// only way through was committing a credentials file or running an\n\t// interactive login on the runner.\n\t//\n\t// Read separately rather than as a pair because they arrive separately: a\n\t// token is a secret and belongs in the environment, while an endpoint is\n\t// configuration and usually belongs in `deploy.dokploy.endpoint`. Requiring\n\t// both from the same place is what made either one useless alone.\n\tconst token = process.env.DOKPLOY_API_TOKEN ?? credentials.dokploy?.token;\n\tconst endpoint =\n\t\tprocess.env.DOKPLOY_ENDPOINT ?? credentials.dokploy?.endpoint;\n\n\tif (!token || !endpoint) return null;\n\n\treturn {\n\t\ttoken,\n\t\tendpoint: endpoint.replace(/\\/$/, ''),\n\t\t...(credentials.dokploy?.registryId\n\t\t\t? { registryId: credentials.dokploy.registryId }\n\t\t\t: {}),\n\t};\n}\n\n/**\n * Remove Dokploy credentials\n */\nexport async function removeDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.dokploy;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n\n/**\n * Remove all stored credentials\n */\nexport async function removeAllCredentials(\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst path = getCredentialsPath(options);\n\n\tif (existsSync(path)) {\n\t\tawait unlink(path);\n\t}\n}\n\n/**\n * Get Dokploy API token, checking stored credentials first, then environment\n */\nexport async function getDokployToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.DOKPLOY_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst stored = await getDokployCredentials(options);\n\tif (stored) {\n\t\treturn stored.token;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get Dokploy endpoint from stored credentials\n */\nexport async function getDokployEndpoint(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.endpoint ?? null;\n}\n\n/**\n * Store Dokploy registry ID\n */\nexport async function storeDokployRegistryId(\n\tregistryId: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found. Run \"gkm login --service dokploy\" first.',\n\t\t);\n\t}\n\n\tcredentials.dokploy.registryId = registryId;\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get Dokploy registry ID from stored credentials\n */\nexport async function getDokployRegistryId(\n\toptions?: CredentialOptions,\n): Promise<string | undefined> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.registryId ?? undefined;\n}\n\n// ============================================\n// Hostinger credentials\n// ============================================\n\n/**\n * Store Hostinger API token\n *\n * @param token - API token from hpanel.hostinger.com/profile/api\n */\nexport async function storeHostingerToken(\n\ttoken: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.hostinger = {\n\t\ttoken,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Hostinger API token\n *\n * Checks environment variable first (HOSTINGER_API_TOKEN),\n * then falls back to stored credentials.\n */\nexport async function getHostingerToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.HOSTINGER_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst credentials = await readCredentials(options);\n\treturn credentials.hostinger?.token ?? null;\n}\n\n/**\n * Remove Hostinger credentials\n */\nexport async function removeHostingerCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.hostinger) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.hostinger;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n\n// ============================================\n// GoDaddy credentials\n// ============================================\n\n/**\n * Store a GoDaddy Personal Access Token.\n */\nexport async function storeGoDaddyToken(\n\ttoken: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.godaddy = {\n\t\ttoken,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Remove GoDaddy credentials\n */\nexport async function removeGoDaddyCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.godaddy) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.godaddy;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n","/**\n * Start a program with an argument array, never a shell string.\n *\n * `gkm build`, `gkm docker` and `gkm deploy` pass values that come from the\n * workspace — image refs, tags, build args, package names — to `docker` and\n * `turbo`. Joined into a string and handed to a shell, a package named\n * `x;curl …|sh` or a tag holding `$(…)` became part of the command line, which\n * matters most where the CLI builds a repository it didn't write: a CI job for a\n * fork, a shared build runner. Here every value reaches the program as one\n * `argv` element, whatever it contains.\n */\n\nimport { type SpawnOptions, spawn } from 'node:child_process';\n\n/** Long enough for a cold image build; short enough that a hung one ends. */\nexport const DEFAULT_TIMEOUT_MS = 30 * 60_000;\n\n/** How long a timed-out child has to exit on SIGTERM before it is killed. */\nconst KILL_GRACE_MS = 5_000;\n\nexport interface RunOptions {\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tstdio?: SpawnOptions['stdio'];\n\t/** Kill the child after this long. Defaults to {@link DEFAULT_TIMEOUT_MS}. */\n\ttimeoutMs?: number;\n\t/**\n\t * Kills the child when aborted, and rejects with the signal's reason — the\n\t * same as a stopped deploy's other calls.\n\t */\n\tsignal?: AbortSignal;\n}\n\n/** The command line as a person would read it — for messages, never to run. */\nfunction display(command: string, args: readonly string[]): string {\n\treturn [command, ...args].join(' ');\n}\n\n/** The program ran and exited unsuccessfully; its own output said why. */\nexport class CommandFailed extends Error {\n\tconstructor(\n\t\treadonly command: string,\n\t\treadonly args: readonly string[],\n\t\treadonly exitCode: number | null,\n\t\treadonly signal: NodeJS.Signals | null,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${display(command, args)}\\` ${exitCode === null ? `was stopped by ${signal ?? 'a signal'}` : `exited with code ${exitCode}`}. Its output above says why; run it by hand to see it again.`,\n\t\t);\n\t\tthis.name = 'CommandFailed';\n\t}\n}\n\n/** The program ran past its timeout and was killed. */\nexport class CommandTimedOut extends Error {\n\tconstructor(\n\t\treadonly command: string,\n\t\treadonly args: readonly string[],\n\t\treadonly timeoutMs: number,\n\t) {\n\t\tsuper(\n\t\t\t`\\`${display(command, args)}\\` was still running after ${Math.round(timeoutMs / 1000)}s and was stopped. Check what it was waiting on — a registry, the Docker daemon, a prompt — and run it again.`,\n\t\t);\n\t\tthis.name = 'CommandTimedOut';\n\t}\n}\n\n/**\n * Run `command` with `args`, resolving when it exits 0.\n *\n * Rejects with {@link CommandFailed} on any other exit, {@link CommandTimedOut}\n * once `timeoutMs` passes (after the child is gone), and with the spawn error\n * itself when the program cannot be started at all — `ENOENT` already names it.\n */\nexport async function run(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: RunOptions = {},\n): Promise<void> {\n\tawait spawnChild(command, args, options, false);\n}\n\n/**\n * {@link run}, resolving with what the program wrote to stdout — for a value\n * the CLI reads back, such as the digest `docker inspect` reports. stderr still\n * reaches the terminal, so a failure explains itself the same way.\n */\nexport function runOutput(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: Omit<RunOptions, 'stdio'> = {},\n): Promise<string> {\n\treturn spawnChild(command, args, options, true);\n}\n\nfunction spawnChild(\n\tcommand: string,\n\targs: readonly string[],\n\toptions: RunOptions,\n\tcapture: boolean,\n): Promise<string> {\n\tconst { timeoutMs = DEFAULT_TIMEOUT_MS, ...spawnOptions } = options;\n\n\treturn new Promise<string>((resolve, reject) => {\n\t\tconst child = spawn(command, [...args], {\n\t\t\tstdio: 'inherit',\n\t\t\t...spawnOptions,\n\t\t\t...(capture ? { stdio: ['ignore', 'pipe', 'inherit'] } : {}),\n\t\t\tshell: false,\n\t\t});\n\n\t\tlet stdout = '';\n\t\tchild.stdout?.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString();\n\t\t});\n\n\t\tlet timedOut = false;\n\t\tlet killer: NodeJS.Timeout | undefined;\n\t\tconst timer = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\t// A child that ignores SIGTERM would hold the deploy open forever.\n\t\t\tkiller = setTimeout(() => child.kill('SIGKILL'), KILL_GRACE_MS);\n\t\t\tkiller.unref?.();\n\t\t}, timeoutMs);\n\t\ttimer.unref?.();\n\n\t\tconst settle = () => {\n\t\t\tclearTimeout(timer);\n\t\t\tif (killer) clearTimeout(killer);\n\t\t};\n\n\t\tchild.on('error', (error) => {\n\t\t\tsettle();\n\t\t\t// Node reports an abort as its own `AbortError`; the caller asked\n\t\t\t// with a reason, and that is what it should get back.\n\t\t\treject(spawnOptions.signal?.aborted ? spawnOptions.signal.reason : error);\n\t\t});\n\n\t\tchild.on('close', (code: number | null, signal: NodeJS.Signals | null) => {\n\t\t\tsettle();\n\t\t\tif (spawnOptions.signal?.aborted) reject(spawnOptions.signal.reason);\n\t\t\telse if (timedOut) reject(new CommandTimedOut(command, args, timeoutMs));\n\t\t\telse if (code === 0) resolve(stdout);\n\t\t\telse reject(new CommandFailed(command, args, code, signal));\n\t\t});\n\t});\n}\n","/**\n * How a deploy gets the credentials it acts with.\n *\n * `deploy()` never prompts and never reads a terminal: it asks a\n * `CredentialProvider` and, when the provider has nothing, stops with\n * `MissingCredential` naming what it needed and how to supply it. Whether to\n * ask a person, read a vault or fail is the caller's decision — `gkm deploy`\n * prompts at a terminal and stores what was typed; a CI job sets the\n * environment; a host passes its own provider.\n */\n\nimport { readCredentials } from '../auth/credentials';\nimport { GkmError } from '../errors';\n\n/**\n * What each kind of credential is asked for with, and what it is.\n *\n * A target that needs a kind the CLI does not know declares it by augmenting\n * this interface, and lists it in its `credentials`:\n *\n * ```ts\n * declare module '@geekmidas/cli/target' {\n * interface CredentialKinds {\n * fly: { request: { org: string }; value: { token: string } };\n * }\n * }\n * ```\n */\nexport interface CredentialKinds {\n\t/** The Dokploy API a stage deploys through. */\n\tdokploy: {\n\t\t/** `deploy.dokploy.endpoint`, when the config names one. */\n\t\trequest: { endpoint?: string };\n\t\tvalue: { endpoint: string; token: string };\n\t};\n\t/**\n\t * A container registry login, for Dokploy to pull with. Asked for only when\n\t * Dokploy has no registry for `deploy.registry` and one has to be\n\t * created.\n\t */\n\tregistry: {\n\t\t/** `deploy.registry`. */\n\t\trequest: { url: string };\n\t\tvalue: { username: string; password: string };\n\t};\n\t/**\n\t * The AWS account a stage deploys to, for the SST target's `sst deploy`.\n\t * Handed to that one command's environment and to nothing else.\n\t */\n\taws: {\n\t\t/** The stage, for a provider that keeps one account per stage. */\n\t\trequest: { stage: string };\n\t\tvalue: AwsCredential;\n\t};\n\t/**\n\t * A GoDaddy Personal Access Token, for a `dns` domain whose provider is\n\t * `godaddy`. Read on the machine that writes the records — never the\n\t * server's.\n\t */\n\tgodaddy: {\n\t\trequest: Record<never, never>;\n\t\tvalue: GoDaddyCredential;\n\t};\n\t/**\n\t * A Hostinger API token, for a `dns` domain whose provider is\n\t * `hostinger`. Like GoDaddy's, read where the records are written.\n\t */\n\thostinger: {\n\t\trequest: Record<never, never>;\n\t\tvalue: HostingerCredential;\n\t};\n}\n\n/** A Hostinger API token, from hpanel.hostinger.com/profile/api. */\nexport interface HostingerCredential {\n\ttoken: string;\n}\n\n/** A GoDaddy Personal Access Token, sent as `Authorization: Bearer <token>`. */\nexport interface GoDaddyCredential {\n\ttoken: string;\n}\n\n/**\n * Who to act as on AWS: a named profile, or keys.\n *\n * Never both. Given both, every AWS SDK takes the keys and ignores the\n * profile, so `--profile prod` with staging's keys still exported would deploy\n * production's stack into staging's account — the reason `secretsStoreFor`\n * resolves a named profile on its own, and why this cannot express the mix.\n */\nexport type AwsCredential =\n\t| {\n\t\t\t/** A profile in `~/.aws/config` — keys, SSO, an assumed role. */\n\t\t\tprofile: string;\n\t\t\tregion?: string;\n\t }\n\t| {\n\t\t\taccessKeyId: string;\n\t\t\tsecretAccessKey: string;\n\t\t\t/** Present for temporary keys: an assumed role, GitHub's OIDC. */\n\t\t\tsessionToken?: string;\n\t\t\tregion?: string;\n\t };\n\nexport type CredentialKind = keyof CredentialKinds;\n\n/** What a deploy asks a provider for. */\nexport type CredentialRequest<K extends CredentialKind = CredentialKind> = {\n\t[P in K]: { kind: P } & CredentialKinds[P]['request'];\n}[K];\n\n/** What a provider answers with. */\nexport type Credential<K extends CredentialKind> = CredentialKinds[K]['value'];\n\nexport interface CredentialProvider {\n\t/**\n\t * The credential `request` asks for, or `undefined` when this provider has\n\t * none — the deploy then raises {@link MissingCredential}.\n\t */\n\tget<K extends CredentialKind>(\n\t\trequest: CredentialRequest<K>,\n\t\toptions?: { signal?: AbortSignal },\n\t): Promise<Credential<K> | undefined>;\n}\n\n/**\n * How to supply each kind the CLI knows, for the error that says it is\n * missing. A target's own kinds are its to explain.\n */\nconst HOW_TO_PROVIDE: Partial<Record<CredentialKind, string>> = {\n\tdokploy:\n\t\t\"Set DOKPLOY_API_TOKEN (and DOKPLOY_ENDPOINT, or deploy.dokploy.endpoint in gkm.config.ts), run `gkm login --provider dokploy`, or pass them through the deploy's CredentialProvider.\",\n\tregistry:\n\t\t'Add the registry in Dokploy (Settings → Docker Registry) and set deploy.dokploy.registryId, set DOCKER_REGISTRY_USERNAME and DOCKER_REGISTRY_PASSWORD, or run `gkm deploy` at a terminal to be asked for them.',\n\tgodaddy:\n\t\t'Set GODADDY_API_TOKEN to a Personal Access Token scoped to domains.dns:update (create one in the GoDaddy developer dashboard), or run `gkm login --provider godaddy`.',\n\thostinger:\n\t\t'Set HOSTINGER_API_TOKEN to a token from hpanel.hostinger.com/profile/api, or run `gkm login --provider hostinger`.',\n\taws: \"Set AWS_PROFILE to the stage account's profile, or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (and AWS_SESSION_TOKEN) — in CI, the keys aws-actions/configure-aws-credentials exports — or pass them through the deploy's CredentialProvider.\",\n};\n\n/** A deploy needed a credential, and its provider had none. */\nexport class MissingCredential extends GkmError {\n\tconstructor(\n\t\treadonly kind: CredentialKind,\n\t\t/** What it was for: the Dokploy endpoint or the registry URL. */\n\t\treadonly target: string | undefined,\n\t\t/** How to supply it. */\n\t\treadonly howToProvide: string = HOW_TO_PROVIDE[kind] ??\n\t\t\t\"Pass it through the deploy's CredentialProvider.\",\n\t) {\n\t\tconst what =\n\t\t\tkind === 'dokploy'\n\t\t\t\t? `No Dokploy credentials${target ? ` for ${target}` : ''}.`\n\t\t\t\t: kind === 'registry'\n\t\t\t\t\t? `Dokploy has no registry for ${target ?? 'the configured registry'}, and there are no credentials to create one with.`\n\t\t\t\t\t: kind === 'aws'\n\t\t\t\t\t\t? `No AWS credentials${target ? ` for the \"${target}\" stage` : ''}.`\n\t\t\t\t\t\t: kind === 'godaddy'\n\t\t\t\t\t\t\t? `No GoDaddy API token${target ? ` for ${target}` : ''}.`\n\t\t\t\t\t\t\t: kind === 'hostinger'\n\t\t\t\t\t\t\t\t? `No Hostinger API token${target ? ` for ${target}` : ''}.`\n\t\t\t\t\t\t\t\t: `No \"${String(kind)}\" credentials${target ? ` for ${target}` : ''}.`;\n\t\tsuper(`${what} ${howToProvide}`);\n\t\tthis.name = 'MissingCredential';\n\t}\n}\n\n/** Whatever was asked for, from the first provider that has it. */\nexport function chainCredentials(\n\t...providers: CredentialProvider[]\n): CredentialProvider {\n\treturn {\n\t\tasync get(request, options) {\n\t\t\tfor (const provider of providers) {\n\t\t\t\tconst found = await provider.get(request, options);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nexport interface StoredCredentialsOptions {\n\t/** Where to read the variables from. Defaults to `process.env`. */\n\tenv?: NodeJS.ProcessEnv;\n\t/**\n\t * The CLI's home, whose `credentials.json` holds stored logins. Defaults\n\t * to `GKM_HOME`, else `~/.gkm`.\n\t */\n\thome?: string;\n}\n\n/**\n * Credentials from the environment, then from what `gkm login` stored. What\n * `deploy()` uses when it is handed no provider.\n *\n * - Dokploy: `DOKPLOY_API_TOKEN` / `DOKPLOY_ENDPOINT`, each falling back to\n * the stored login, and the endpoint finally to `deploy.dokploy.endpoint`.\n * Each half is read on its own: a token is a secret and belongs in the\n * environment, an endpoint is configuration and belongs in the config.\n * - Registry: `DOCKER_REGISTRY_USERNAME` / `DOCKER_REGISTRY_PASSWORD`.\n * - AWS: `AWS_PROFILE` when it is set, and then nothing else; otherwise\n * `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN`. The\n * profile winning is `secretsStoreFor`'s rule: a profile is a choice of\n * account someone made, exported keys may be left over from another.\n * Read here, by name, and handed only to the command that deploys — the\n * sandbox every other step runs in passes no `AWS_*` on.\n */\nexport function storedCredentials(\n\toptions: StoredCredentialsOptions = {},\n): CredentialProvider {\n\tconst env = options.env ?? process.env;\n\n\treturn {\n\t\tasync get(asked) {\n\t\t\t// The union, so a switch on `kind` narrows it: `K` itself never is.\n\t\t\tconst request = asked as CredentialRequest;\n\t\t\tswitch (request.kind) {\n\t\t\t\tcase 'dokploy': {\n\t\t\t\t\tconst stored = (\n\t\t\t\t\t\tawait readCredentials(\n\t\t\t\t\t\t\toptions.home ? { home: options.home } : undefined,\n\t\t\t\t\t\t)\n\t\t\t\t\t).dokploy;\n\t\t\t\t\tconst token = env.DOKPLOY_API_TOKEN ?? stored?.token;\n\t\t\t\t\tconst endpoint =\n\t\t\t\t\t\tenv.DOKPLOY_ENDPOINT ?? stored?.endpoint ?? request.endpoint;\n\t\t\t\t\tif (!token || !endpoint) return undefined;\n\t\t\t\t\treturn { endpoint: endpoint.replace(/\\/$/, ''), token } as never;\n\t\t\t\t}\n\t\t\t\tcase 'registry': {\n\t\t\t\t\tconst username = env.DOCKER_REGISTRY_USERNAME;\n\t\t\t\t\tconst password = env.DOCKER_REGISTRY_PASSWORD;\n\t\t\t\t\tif (!username || !password) return undefined;\n\t\t\t\t\treturn { username, password } as never;\n\t\t\t\t}\n\t\t\t\tcase 'godaddy': {\n\t\t\t\t\t// The environment first, then the stored login.\n\t\t\t\t\tconst token =\n\t\t\t\t\t\tenv.GODADDY_API_TOKEN ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait readCredentials(\n\t\t\t\t\t\t\t\toptions.home ? { home: options.home } : undefined,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).godaddy?.token;\n\t\t\t\t\tif (!token) return undefined;\n\t\t\t\t\treturn { token } as never;\n\t\t\t\t}\n\t\t\t\tcase 'hostinger': {\n\t\t\t\t\tconst token =\n\t\t\t\t\t\tenv.HOSTINGER_API_TOKEN ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait readCredentials(\n\t\t\t\t\t\t\t\toptions.home ? { home: options.home } : undefined,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).hostinger?.token;\n\t\t\t\t\tif (!token) return undefined;\n\t\t\t\t\treturn { token } as never;\n\t\t\t\t}\n\t\t\t\tcase 'aws': {\n\t\t\t\t\tconst region = env.AWS_REGION ?? env.AWS_DEFAULT_REGION;\n\t\t\t\t\tconst where = region ? { region } : {};\n\t\t\t\t\tif (env.AWS_PROFILE) {\n\t\t\t\t\t\treturn { profile: env.AWS_PROFILE, ...where } as never;\n\t\t\t\t\t}\n\t\t\t\t\tconst accessKeyId = env.AWS_ACCESS_KEY_ID;\n\t\t\t\t\tconst secretAccessKey = env.AWS_SECRET_ACCESS_KEY;\n\t\t\t\t\tif (!accessKeyId || !secretAccessKey) return undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\taccessKeyId,\n\t\t\t\t\t\tsecretAccessKey,\n\t\t\t\t\t\t...(env.AWS_SESSION_TOKEN\n\t\t\t\t\t\t\t? { sessionToken: env.AWS_SESSION_TOKEN }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t...where,\n\t\t\t\t\t} as never;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// A kind a target declared: nothing stored here can answer it.\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|