@geekmidas/cli 10.0.0-alpha.94 → 10.0.0-alpha.95

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.
Files changed (192) hide show
  1. package/dist/{GoDaddyProvider-BRZUWD8z.mjs → GoDaddyProvider-BwW51hPm.mjs} +3 -3
  2. package/dist/{GoDaddyProvider-BRZUWD8z.mjs.map → GoDaddyProvider-BwW51hPm.mjs.map} +1 -1
  3. package/dist/{GoDaddyProvider-DzguxU_a.cjs → GoDaddyProvider-C_DgIkMv.cjs} +3 -3
  4. package/dist/{GoDaddyProvider-DzguxU_a.cjs.map → GoDaddyProvider-C_DgIkMv.cjs.map} +1 -1
  5. package/dist/{HostingerProvider-Cjh_2Ml6.mjs → HostingerProvider-BNpS9aRJ.mjs} +2 -2
  6. package/dist/{HostingerProvider-Cjh_2Ml6.mjs.map → HostingerProvider-BNpS9aRJ.mjs.map} +1 -1
  7. package/dist/{HostingerProvider-OdQmKXE3.cjs → HostingerProvider-DR1iws1P.cjs} +2 -2
  8. package/dist/{HostingerProvider-OdQmKXE3.cjs.map → HostingerProvider-DR1iws1P.cjs.map} +1 -1
  9. package/dist/{LegacyStateStore-D50dgUPc.cjs → LegacyStateStore-BawjE_5n.cjs} +3 -3
  10. package/dist/{LegacyStateStore-D50dgUPc.cjs.map → LegacyStateStore-BawjE_5n.cjs.map} +1 -1
  11. package/dist/{LegacyStateStore-BQZb6-j2.mjs → LegacyStateStore-D5DarNA2.mjs} +3 -3
  12. package/dist/{LegacyStateStore-BQZb6-j2.mjs.map → LegacyStateStore-D5DarNA2.mjs.map} +1 -1
  13. package/dist/{LocalStateStore-EFBUjuMX.cjs → LocalStateStore-D8fu5WiF.cjs} +2 -2
  14. package/dist/{LocalStateStore-EFBUjuMX.cjs.map → LocalStateStore-D8fu5WiF.cjs.map} +1 -1
  15. package/dist/{LocalStateStore-BSaS2535.mjs → LocalStateStore-YjIqlgAz.mjs} +2 -2
  16. package/dist/{LocalStateStore-BSaS2535.mjs.map → LocalStateStore-YjIqlgAz.mjs.map} +1 -1
  17. package/dist/{S3StateStore-CrFq4UZU.mjs → S3StateStore-CjTAVsWh.mjs} +2 -2
  18. package/dist/{S3StateStore-CrFq4UZU.mjs.map → S3StateStore-CjTAVsWh.mjs.map} +1 -1
  19. package/dist/{S3StateStore-C5mv8To3.cjs → S3StateStore-Cm-v2IPI.cjs} +2 -2
  20. package/dist/{S3StateStore-C5mv8To3.cjs.map → S3StateStore-Cm-v2IPI.cjs.map} +1 -1
  21. package/dist/{SSMStateStore-DuZCH7_v.cjs → SSMStateStore-BS4BiZCN.cjs} +2 -2
  22. package/dist/{SSMStateStore-DuZCH7_v.cjs.map → SSMStateStore-BS4BiZCN.cjs.map} +1 -1
  23. package/dist/{SSMStateStore-D3Z6mZnA.mjs → SSMStateStore-BhtM6jOh.mjs} +2 -2
  24. package/dist/{SSMStateStore-D3Z6mZnA.mjs.map → SSMStateStore-BhtM6jOh.mjs.map} +1 -1
  25. package/dist/{add-DsVDdvon.cjs → add-D-3IKT7W.cjs} +22 -51
  26. package/dist/add-D-3IKT7W.cjs.map +1 -0
  27. package/dist/{add-C85isXFl.mjs → add-ylx8dejw.mjs} +21 -50
  28. package/dist/add-ylx8dejw.mjs.map +1 -0
  29. package/dist/{bundler-BEgUKc4j.cjs → bundler-CI3elfZS.cjs} +5 -5
  30. package/dist/{bundler-BEgUKc4j.cjs.map → bundler-CI3elfZS.cjs.map} +1 -1
  31. package/dist/{bundler-BSHog8CH.mjs → bundler-ywR3C1B_.mjs} +5 -5
  32. package/dist/{bundler-BSHog8CH.mjs.map → bundler-ywR3C1B_.mjs.map} +1 -1
  33. package/dist/{cli-BsFenyaf.mjs → cli-BCSuCfQk.mjs} +4 -4
  34. package/dist/{cli-BsFenyaf.mjs.map → cli-BCSuCfQk.mjs.map} +1 -1
  35. package/dist/{cli-BvBdv660.cjs → cli-Dewt2T21.cjs} +4 -4
  36. package/dist/{cli-BvBdv660.cjs.map → cli-Dewt2T21.cjs.map} +1 -1
  37. package/dist/{compose-D2RFYd_f.mjs → compose-C4js1JDv.mjs} +42 -46
  38. package/dist/compose-C4js1JDv.mjs.map +1 -0
  39. package/dist/{compose-Cd09gW-n.cjs → compose-Dd0XphvF.cjs} +59 -63
  40. package/dist/compose-Dd0XphvF.cjs.map +1 -0
  41. package/dist/{config-Ngesg4O8.d.mts → config-4yirvxS8.d.cts} +4 -4
  42. package/dist/{config-DvHNMoOp.d.cts.map → config-4yirvxS8.d.cts.map} +1 -1
  43. package/dist/{config-DvHNMoOp.d.cts → config-C8NPCn1l.d.mts} +4 -4
  44. package/dist/{config-Ngesg4O8.d.mts.map → config-C8NPCn1l.d.mts.map} +1 -1
  45. package/dist/config.d.cts +3 -3
  46. package/dist/config.d.mts +3 -3
  47. package/dist/{credentials-DpfnUvIR.mjs → credentials-B5N5yKk6.mjs} +4 -132
  48. package/dist/credentials-B5N5yKk6.mjs.map +1 -0
  49. package/dist/{credentials-D7XJypNd.cjs → credentials-Zqr3QQYB.cjs} +3 -173
  50. package/dist/credentials-Zqr3QQYB.cjs.map +1 -0
  51. package/dist/deploy/public.cjs +15 -14
  52. package/dist/deploy/public.cjs.map +1 -1
  53. package/dist/deploy/public.d.cts +5 -5
  54. package/dist/deploy/public.d.cts.map +1 -1
  55. package/dist/deploy/public.d.mts +5 -5
  56. package/dist/deploy/public.d.mts.map +1 -1
  57. package/dist/deploy/public.mjs +10 -9
  58. package/dist/deploy/public.mjs.map +1 -1
  59. package/dist/{providers-sTj-BG0S.mjs → deploy-B0drCD6s.mjs} +898 -123
  60. package/dist/deploy-B0drCD6s.mjs.map +1 -0
  61. package/dist/{providers-BFeP_mYw.cjs → deploy-Bw1FjX_x.cjs} +939 -134
  62. package/dist/deploy-Bw1FjX_x.cjs.map +1 -0
  63. package/dist/{discover-CTzOSGUF.d.cts → discover-BtFofyQB.d.cts} +2 -2
  64. package/dist/{discover-CTzOSGUF.d.cts.map → discover-BtFofyQB.d.cts.map} +1 -1
  65. package/dist/{discover-CihAtaoj.d.mts → discover-D-MdXZgm.d.mts} +2 -2
  66. package/dist/{discover-CihAtaoj.d.mts.map → discover-D-MdXZgm.d.mts.map} +1 -1
  67. package/dist/dns-Bmk7P9c2.cjs +663 -0
  68. package/dist/dns-Bmk7P9c2.cjs.map +1 -0
  69. package/dist/dns-CyMIq6to.cjs +55 -0
  70. package/dist/dns-CyMIq6to.cjs.map +1 -0
  71. package/dist/dns-X3oqEV4C.mjs +44 -0
  72. package/dist/dns-X3oqEV4C.mjs.map +1 -0
  73. package/dist/dns-idXfyCay.mjs +610 -0
  74. package/dist/dns-idXfyCay.mjs.map +1 -0
  75. package/dist/{dokploy-D_aat2Xj.mjs → dokploy-CZYxXeMa.mjs} +2 -2
  76. package/dist/{dokploy-D_aat2Xj.mjs.map → dokploy-CZYxXeMa.mjs.map} +1 -1
  77. package/dist/{dokploy-CV7GcobZ.cjs → dokploy-DaT0mgLU.cjs} +2 -2
  78. package/dist/{dokploy-CV7GcobZ.cjs.map → dokploy-DaT0mgLU.cjs.map} +1 -1
  79. package/dist/{encryption-_4qKqtTx.mjs → encryption-D0ucY4O7.mjs} +2 -2
  80. package/dist/{encryption-_4qKqtTx.mjs.map → encryption-D0ucY4O7.mjs.map} +1 -1
  81. package/dist/{encryption-DFcivJaO.cjs → encryption-Dp0IvLVX.cjs} +2 -2
  82. package/dist/{encryption-DFcivJaO.cjs.map → encryption-Dp0IvLVX.cjs.map} +1 -1
  83. package/dist/{engine-DPMHThkg.mjs → engine-BcuhnyQO.mjs} +13 -31
  84. package/dist/{engine-DPMHThkg.mjs.map → engine-BcuhnyQO.mjs.map} +1 -1
  85. package/dist/{engine-Bv-LZpmj.cjs → engine-WY6j_kvA.cjs} +17 -35
  86. package/dist/engine-WY6j_kvA.cjs.map +1 -0
  87. package/dist/{github-xsDT19im.mjs → github-DUGA57du.mjs} +4 -2
  88. package/dist/{github-xsDT19im.mjs.map → github-DUGA57du.mjs.map} +1 -1
  89. package/dist/{github-Br42NMrW.cjs → github-DgmW83OP.cjs} +8 -6
  90. package/dist/{github-Br42NMrW.cjs.map → github-DgmW83OP.cjs.map} +1 -1
  91. package/dist/{index-CwLvFqtH.d.cts → index-5eL8rM6H.d.mts} +2 -2
  92. package/dist/{index-BlpcClwM.d.mts.map → index-5eL8rM6H.d.mts.map} +1 -1
  93. package/dist/{index-BlpcClwM.d.mts → index-Dz-gyjm_.d.cts} +2 -2
  94. package/dist/{index-CwLvFqtH.d.cts.map → index-Dz-gyjm_.d.cts.map} +1 -1
  95. package/dist/index.cjs +53 -52
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.mjs +51 -50
  98. package/dist/index.mjs.map +1 -1
  99. package/dist/{local-B7Zv1NoA.mjs → local-BwC2v2Y8.mjs} +2 -2
  100. package/dist/{local-B7Zv1NoA.mjs.map → local-BwC2v2Y8.mjs.map} +1 -1
  101. package/dist/{local-OPC9BCZt.cjs → local-DNhnkugT.cjs} +3 -3
  102. package/dist/{local-OPC9BCZt.cjs.map → local-DNhnkugT.cjs.map} +1 -1
  103. package/dist/{migrate-SkWJotn5.cjs → migrate-BBcG1dhS.cjs} +2 -2
  104. package/dist/{migrate-SkWJotn5.cjs.map → migrate-BBcG1dhS.cjs.map} +1 -1
  105. package/dist/{migrate-DhvFPGLi.mjs → migrate-CZ-v5WV0.mjs} +2 -2
  106. package/dist/{migrate-DhvFPGLi.mjs.map → migrate-CZ-v5WV0.mjs.map} +1 -1
  107. package/dist/{migrate-B7evHv7O.mjs → migrate-D6PlNv2o.mjs} +2 -2
  108. package/dist/{migrate-B7evHv7O.mjs.map → migrate-D6PlNv2o.mjs.map} +1 -1
  109. package/dist/{migrate-D5jUz20_.cjs → migrate-afgRL3Hg.cjs} +2 -2
  110. package/dist/{migrate-D5jUz20_.cjs.map → migrate-afgRL3Hg.cjs.map} +1 -1
  111. package/dist/openapi.d.cts +1 -1
  112. package/dist/openapi.d.mts +1 -1
  113. package/dist/reconcile/public.d.cts +2 -2
  114. package/dist/reconcile/public.d.mts +2 -2
  115. package/dist/{resolve-CFEOtRsl.cjs → resolve-CFb4Navi.cjs} +4 -4
  116. package/dist/{resolve-CFEOtRsl.cjs.map → resolve-CFb4Navi.cjs.map} +1 -1
  117. package/dist/{resolve-Dyd1S2wn.mjs → resolve-DakDhr6Z.mjs} +4 -4
  118. package/dist/{resolve-Dyd1S2wn.mjs.map → resolve-DakDhr6Z.mjs.map} +1 -1
  119. package/dist/{rollback-D720SFhV.cjs → rollback-B-1dPP0m.cjs} +7 -8
  120. package/dist/{rollback-D720SFhV.cjs.map → rollback-B-1dPP0m.cjs.map} +1 -1
  121. package/dist/{rollback-NroNbGC0.mjs → rollback-B1TIpjdE.mjs} +6 -7
  122. package/dist/{rollback-NroNbGC0.mjs.map → rollback-B1TIpjdE.mjs.map} +1 -1
  123. package/dist/run-BJLIerMM.mjs +133 -0
  124. package/dist/run-BJLIerMM.mjs.map +1 -0
  125. package/dist/run-fVZ-rLnc.cjs +174 -0
  126. package/dist/run-fVZ-rLnc.cjs.map +1 -0
  127. package/dist/{runtime-VktAo_8B.d.cts → runtime-DUQdM-mW.d.cts} +2 -2
  128. package/dist/{runtime-BRCq6dQ7.d.mts.map → runtime-DUQdM-mW.d.cts.map} +1 -1
  129. package/dist/{runtime-BRCq6dQ7.d.mts → runtime-Vr6mleo2.d.mts} +2 -2
  130. package/dist/{runtime-VktAo_8B.d.cts.map → runtime-Vr6mleo2.d.mts.map} +1 -1
  131. package/dist/{sandbox-D1gd0iDz.d.cts → sandbox-BbJmh2rI.d.cts} +2 -2
  132. package/dist/{sandbox-D1gd0iDz.d.cts.map → sandbox-BbJmh2rI.d.cts.map} +1 -1
  133. package/dist/{sandbox-zHnRLCj0.d.mts → sandbox-DGOsMPMf.d.mts} +2 -2
  134. package/dist/{sandbox-zHnRLCj0.d.mts.map → sandbox-DGOsMPMf.d.mts.map} +1 -1
  135. package/dist/{secrets-DAvi_O9g.cjs → secrets-CPM0Qffe.cjs} +2 -2
  136. package/dist/{secrets-DAvi_O9g.cjs.map → secrets-CPM0Qffe.cjs.map} +1 -1
  137. package/dist/{secrets-CwLauUB_.mjs → secrets-oI9ClAPR.mjs} +2 -2
  138. package/dist/{secrets-CwLauUB_.mjs.map → secrets-oI9ClAPR.mjs.map} +1 -1
  139. package/dist/{seeds-BCg8X36S.cjs → seeds-CnXkgKUv.cjs} +192 -945
  140. package/dist/seeds-CnXkgKUv.cjs.map +1 -0
  141. package/dist/{seeds-CTxTZa-R.mjs → seeds-CoKkrSny.mjs} +156 -825
  142. package/dist/seeds-CoKkrSny.mjs.map +1 -0
  143. package/dist/{sniffer-DCcuzHz_.mjs → sniffer-CFRzIrby.mjs} +7 -7
  144. package/dist/{sniffer-DCcuzHz_.mjs.map → sniffer-CFRzIrby.mjs.map} +1 -1
  145. package/dist/{sniffer-C0z3NB2A.cjs → sniffer-vbiQ2Isn.cjs} +7 -7
  146. package/dist/{sniffer-C0z3NB2A.cjs.map → sniffer-vbiQ2Isn.cjs.map} +1 -1
  147. package/dist/{sst-DRDSDwOk.mjs → sst-CGdjHn2A.mjs} +4 -3
  148. package/dist/{sst-DRDSDwOk.mjs.map → sst-CGdjHn2A.mjs.map} +1 -1
  149. package/dist/{sst-DKNH243z.cjs → sst-DGuHDxVU.cjs} +5 -4
  150. package/dist/{sst-DKNH243z.cjs.map → sst-DGuHDxVU.cjs.map} +1 -1
  151. package/dist/{stack-B3fPDTBg.cjs → stack-1g57OfOw.cjs} +13 -51
  152. package/dist/stack-1g57OfOw.cjs.map +1 -0
  153. package/dist/{stack-NrdH5ngX.mjs → stack-B7O975TR.mjs} +13 -51
  154. package/dist/stack-B7O975TR.mjs.map +1 -0
  155. package/dist/{stages-veC4TcQe.mjs → stages-Bt4OggMm.mjs} +3 -2
  156. package/dist/{stages-veC4TcQe.mjs.map → stages-Bt4OggMm.mjs.map} +1 -1
  157. package/dist/{stages-CkqP1N4S.cjs → stages-BujUB4we.cjs} +4 -3
  158. package/dist/{stages-CkqP1N4S.cjs.map → stages-BujUB4we.cjs.map} +1 -1
  159. package/dist/target/public.cjs +1 -1
  160. package/dist/target/public.d.cts +2 -2
  161. package/dist/target/public.d.mts +2 -2
  162. package/dist/target/public.mjs +1 -1
  163. package/dist/{terminal-CkUYuAPd.cjs → terminal-CPHuH4S1.cjs} +2 -2
  164. package/dist/{terminal-CkUYuAPd.cjs.map → terminal-CPHuH4S1.cjs.map} +1 -1
  165. package/dist/{terminal-DAHs2Zko.mjs → terminal-iNmAXXjs.mjs} +2 -2
  166. package/dist/{terminal-DAHs2Zko.mjs.map → terminal-iNmAXXjs.mjs.map} +1 -1
  167. package/dist/{types-DMoaFrjg.d.mts → types-bkqVscdN.d.mts} +12 -3
  168. package/dist/types-bkqVscdN.d.mts.map +1 -0
  169. package/dist/{types-DXyaSmqu.d.cts → types-dipJRmKV.d.cts} +12 -3
  170. package/dist/types-dipJRmKV.d.cts.map +1 -0
  171. package/dist/workspace/index.d.cts +2 -2
  172. package/dist/workspace/index.d.mts +2 -2
  173. package/package.json +15 -15
  174. package/dist/add-C85isXFl.mjs.map +0 -1
  175. package/dist/add-DsVDdvon.cjs.map +0 -1
  176. package/dist/compose-Cd09gW-n.cjs.map +0 -1
  177. package/dist/compose-D2RFYd_f.mjs.map +0 -1
  178. package/dist/credentials-D7XJypNd.cjs.map +0 -1
  179. package/dist/credentials-DpfnUvIR.mjs.map +0 -1
  180. package/dist/deploy-C911Akkn.cjs +0 -670
  181. package/dist/deploy-C911Akkn.cjs.map +0 -1
  182. package/dist/deploy-CeJ5D0xn.mjs +0 -641
  183. package/dist/deploy-CeJ5D0xn.mjs.map +0 -1
  184. package/dist/engine-Bv-LZpmj.cjs.map +0 -1
  185. package/dist/providers-BFeP_mYw.cjs.map +0 -1
  186. package/dist/providers-sTj-BG0S.mjs.map +0 -1
  187. package/dist/seeds-BCg8X36S.cjs.map +0 -1
  188. package/dist/seeds-CTxTZa-R.mjs.map +0 -1
  189. package/dist/stack-B3fPDTBg.cjs.map +0 -1
  190. package/dist/stack-NrdH5ngX.mjs.map +0 -1
  191. package/dist/types-DMoaFrjg.d.mts.map +0 -1
  192. package/dist/types-DXyaSmqu.d.cts.map +0 -1
@@ -1,10 +1,11 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
3
- import { i as CommandFailed, t as MissingCredential } from "./credentials-DpfnUvIR.mjs";
3
+ import { t as CommandFailed } from "./run-BJLIerMM.mjs";
4
+ import { t as MissingCredential } from "./credentials-B5N5yKk6.mjs";
4
5
  import { i as activeSandbox } from "./sandbox-CbVB7uOD.mjs";
5
6
  import { t as appKey } from "./derive-B4vDpzgP.mjs";
6
7
  import { t as defineTarget } from "./define-6poNqm5O.mjs";
7
- import { t as LocalSandbox } from "./local-B7Zv1NoA.mjs";
8
+ import { t as LocalSandbox } from "./local-BwC2v2Y8.mjs";
8
9
  import { n as detectPackageManager } from "./utils-D_fxUqvU.mjs";
9
10
  import { join } from "node:path";
10
11
  import { existsSync } from "node:fs";
@@ -437,4 +438,4 @@ const sstTarget = createSstTarget();
437
438
  //#endregion
438
439
  export { SurfacesUnhealthy as i, sst_exports as n, SstOutputsUnreadable as r, SstConfigNotFound as t };
439
440
 
440
- //# sourceMappingURL=sst-DRDSDwOk.mjs.map
441
+ //# sourceMappingURL=sst-CGdjHn2A.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sst-DRDSDwOk.mjs","names":[],"sources":["../src/target/sst/health.ts","../src/target/sst/outputs.ts","../src/target/sst/index.ts"],"sourcesContent":["/**\n * Whether a released surface answers.\n *\n * The paths are the ones the local stack's healthchecks use\n * (`reconcile/apps.ts`): an API's `/health`, a site's `/`. A surface is\n * asked a few times, because a fresh deploy can take a moment to answer — a\n * Lambda's first start, a distribution still settling — and healthy means a\n * 2xx, after redirects.\n */\n\nimport { GkmError } from '../../errors';\nimport type { TargetEvent } from '../types';\n\nexport interface HealthCheckOptions {\n\t/** How many times a surface is asked before it counts as down. */\n\tattempts: number;\n\t/** The wait between two attempts. */\n\tdelayMs: number;\n\t/** How long one request may take. */\n\ttimeoutMs: number;\n\tsignal: AbortSignal;\n\temit: (event: TargetEvent) => void;\n}\n\n/** Surfaces that never answered healthy. */\nexport class SurfacesUnhealthy extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** Each surface that failed, with the last thing it answered. */\n\t\treadonly surfaces: readonly {\n\t\t\tapp: string;\n\t\t\turl: string;\n\t\t\tstatus?: number;\n\t\t\terror?: string;\n\t\t}[],\n\t) {\n\t\tconst lines = surfaces.map(\n\t\t\t({ app, url, status, error }) =>\n\t\t\t\t` - ${app}: ${url} → ${status ?? error ?? 'no answer'}`,\n\t\t);\n\t\tsuper(\n\t\t\t`The \"${stage}\" stage was deployed, but ${surfaces.length === 1 ? 'a surface does' : 'surfaces do'} not answer healthy:\\n${lines.join('\\n')}\\nCheck its logs in CloudWatch, fix it, and deploy again.`,\n\t\t);\n\t\tthis.name = 'SurfacesUnhealthy';\n\t}\n}\n\n/** `path` under `base`, keeping any path `base` already has. */\nexport function healthUrl(base: string, path: string): string {\n\tconst root = base.endsWith('/') ? base : `${base}/`;\n\treturn new URL(path.replace(/^\\//, ''), root).toString();\n}\n\n/**\n * Ask `url` until it answers 2xx or the attempts run out, emitting\n * `health.checked` for each. Resolves with the last answer.\n */\nexport async function checkHealth(\n\tapp: string,\n\turl: string,\n\toptions: HealthCheckOptions,\n): Promise<{ healthy: boolean; status?: number; error?: string }> {\n\tlet last: { healthy: boolean; status?: number; error?: string } = {\n\t\thealthy: false,\n\t};\n\tfor (let attempt = 1; attempt <= options.attempts; attempt++) {\n\t\toptions.signal.throwIfAborted();\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tredirect: 'follow',\n\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\toptions.signal,\n\t\t\t\t\tAbortSignal.timeout(options.timeoutMs),\n\t\t\t\t]),\n\t\t\t});\n\t\t\t// Drained, so the connection is not held open by an unread body.\n\t\t\tawait response.arrayBuffer().catch(() => undefined);\n\t\t\tlast = { healthy: response.ok, status: response.status };\n\t\t} catch (error) {\n\t\t\t// The run being stopped is not the surface being down.\n\t\t\toptions.signal.throwIfAborted();\n\t\t\tlast = {\n\t\t\t\thealthy: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t\toptions.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp,\n\t\t\turl,\n\t\t\thealthy: last.healthy,\n\t\t\t...(last.status !== undefined ? { status: last.status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (last.healthy) return last;\n\t\tif (attempt < options.attempts) await wait(options.delayMs, options.signal);\n\t}\n\treturn last;\n}\n\nfunction wait(ms: number, signal: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal.removeEventListener('abort', stop);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst stop = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal.reason);\n\t\t};\n\t\tsignal.addEventListener('abort', stop, { once: true });\n\t});\n}\n","/**\n * The surface URLs an `sst deploy` reports.\n *\n * SST writes whatever `run()` in `sst.config.ts` returns to\n * `.sst/outputs.json` after every successful deploy — `{\"Api\": \"https://…\"}`.\n * What `run()` returns is the project's to write, so this reads it leniently:\n * nested objects are walked, anything that is not an http(s) URL is ignored,\n * and an output names a surface by its id in any casing, with or without a\n * `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { GkmError } from '../../errors';\n\n/** Where SST leaves the last successful deploy's outputs, under the project. */\nexport const SST_OUTPUTS_FILE = join('.sst', 'outputs.json');\n\n/** `.sst/outputs.json` is there, and is not JSON. */\nexport class SstOutputsUnreadable extends GkmError {\n\tconstructor(\n\t\treadonly path: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \\`sst deploy\\`; delete it and deploy again.`,\n\t\t);\n\t\tthis.name = 'SstOutputsUnreadable';\n\t}\n}\n\n/**\n * Remove what an earlier deploy wrote, so the outputs read after this one\n * are this one's — not another stage's, deployed from the same checkout.\n */\nexport async function clearOutputs(cwd: string): Promise<void> {\n\tawait rm(join(cwd, SST_OUTPUTS_FILE), { force: true });\n}\n\n/** The deploy's outputs, or `{}` when it wrote none. */\nexport async function readOutputs(cwd: string): Promise<unknown> {\n\tconst path = join(cwd, SST_OUTPUTS_FILE);\n\tif (!existsSync(path)) return {};\n\ttry {\n\t\treturn JSON.parse(await readFile(path, 'utf8'));\n\t} catch (error) {\n\t\tthrow new SstOutputsUnreadable(\n\t\t\tpath,\n\t\t\terror instanceof Error ? error.message : String(error),\n\t\t);\n\t}\n}\n\n/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */\nfunction urlsIn(\n\tvalue: unknown,\n\tpath: string[] = [],\n\tfound: { path: string[]; url: string }[] = [],\n): { path: string[]; url: string }[] {\n\tif (typeof value === 'string') {\n\t\tif (isHttpUrl(value)) found.push({ path, url: value });\n\t} else if (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\turlsIn(child, [...path, key], found);\n\t\t}\n\t}\n\treturn found;\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst { protocol } = new URL(value);\n\t\treturn protocol === 'http:' || protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * The app an output's key path names, kebab-cased as app keys are: its last\n * segment, without a `url` suffix — or its parent's, when the last segment\n * is only `url`. Exact names are tried first, so an app called `api-url`\n * still finds `ApiUrl`.\n */\nfunction namesOf(path: string[]): string[] {\n\tconst names: string[] = [];\n\tfor (const segment of [...path].reverse()) {\n\t\tconst name = kebabCase(segment);\n\t\tnames.push(name);\n\t\tconst bare = name.replace(/-?url$/, '');\n\t\tif (bare) {\n\t\t\tnames.push(bare);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn names;\n}\n\n/**\n * Each app's URL from the outputs, for the apps given. An app no output\n * names is left out.\n */\nexport function surfaceUrls(\n\toutputs: unknown,\n\tapps: readonly string[],\n): Record<string, string> {\n\tconst found = urlsIn(outputs);\n\tconst urls: Record<string, string> = {};\n\tfor (const app of apps) {\n\t\t// An exact name beats a stripped one, wherever each is in the file.\n\t\tconst exact = found.find(({ path }) => namesOf(path)[0] === app);\n\t\tconst loose = found.find(({ path }) => namesOf(path).includes(app));\n\t\tconst match = exact ?? loose;\n\t\tif (match) urls[app] = match.url;\n\t}\n\treturn urls;\n}\n","/**\n * The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`\n * provisions it, and the surfaces SST reports are health-checked.\n *\n * `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads\n * `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What\n * the target adds is the run around the two commands — the lock, the events,\n * verification, and credentials kept where they belong.\n *\n * Both commands run in the sandbox: the build executes the project's code,\n * and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second\n * needs AWS, so the AWS credential goes into that one command's environment\n * and nowhere else — not the build's, not the process the deploy runs in.\n * What `sst deploy` needs beyond them, the sandbox already passes: `PATH`\n * for node and the package manager, and `HOME`, under which SST keeps its\n * toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK\n * finds `~/.aws` for a profile. Its state — the Pulumi backend and the\n * passphrase — is in the stage's own account, reached with that credential.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\ttype AwsCredential,\n\tMissingCredential,\n} from '../../deploy/credentials';\nimport type { DeployResult } from '../../deploy/types';\nimport { GkmError } from '../../errors';\nimport { detectPackageManager, type PackageManager } from '../../init/utils';\nimport { CommandFailed } from '../../run';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { activeSandbox, type Sandbox } from '../../sandbox/sandbox';\nimport { appKey } from '../../workspace/derive';\nimport { defineTarget } from '../define';\nimport type { DeployPhaseContext, DeployTarget } from '../types';\nimport { checkHealth, healthUrl, SurfacesUnhealthy } from './health';\nimport { clearOutputs, readOutputs, surfaceUrls } from './outputs';\n\nexport { SurfacesUnhealthy } from './health';\nexport { SST_OUTPUTS_FILE, SstOutputsUnreadable } from './outputs';\n\n/** A cold build of every handler and site. */\nconst BUILD_TIMEOUT_MS = 30 * 60_000;\n/**\n * A first deploy creates CloudFront distributions and, with a database, a\n * VPC and an RDS instance — each of which alone can take a quarter of an hour.\n */\nconst DEPLOY_TIMEOUT_MS = 90 * 60_000;\n\n/** The workspace has no `sst.config.ts` for `sst deploy` to run. */\nexport class SstConfigNotFound extends GkmError {\n\tconstructor(readonly cwd: string) {\n\t\tsuper(\n\t\t\t`No sst.config.ts in ${cwd}. The sst target runs \\`sst deploy\\` at the workspace root: scaffold one with \\`gkm init --deploy sst\\` and copy its sst.config.ts, or deploy through another target with --target.`,\n\t\t);\n\t\tthis.name = 'SstConfigNotFound';\n\t}\n}\n\n/** What the phases hand on. */\nexport interface SstRun {\n\tsandbox: Sandbox;\n\tpm: PackageManager;\n\taws: AwsCredential;\n\t/** The apps SST deploys this run: `ctx.apps` without the skipped. */\n\tapps: string[];\n\t/** Each app's URL, from the deploy's outputs. */\n\turls: Record<string, string>;\n}\n\nexport interface SstTargetOptions {\n\t/** How often, and how patiently, `verify` asks each surface. */\n\thealth?: { attempts?: number; delayMs?: number; timeoutMs?: number };\n}\n\n/**\n * The project's own copy of `bin`, through its package manager — never one\n * `npx` would download, which would be code nobody installed.\n */\nexport function projectCommand(\n\tpm: PackageManager,\n\tbin: string,\n\targs: readonly string[],\n): [command: string, args: string[]] {\n\tswitch (pm) {\n\t\tcase 'pnpm':\n\t\t\treturn ['pnpm', ['exec', bin, ...args]];\n\t\tcase 'yarn':\n\t\t\treturn ['yarn', [bin, ...args]];\n\t\tcase 'bun':\n\t\t\treturn ['bunx', [bin, ...args]];\n\t\tcase 'npm':\n\t\t\treturn ['npx', ['--no-install', bin, ...args]];\n\t}\n}\n\n/**\n * The variables `credential` is to the AWS SDK and to SST.\n *\n * A profile is passed alone: given keys too, every SDK would take the keys.\n */\nexport function awsEnv(credential: AwsCredential): Record<string, string> {\n\tconst region: Record<string, string> = credential.region\n\t\t? { AWS_REGION: credential.region, AWS_DEFAULT_REGION: credential.region }\n\t\t: {};\n\tif ('profile' in credential) {\n\t\treturn { AWS_PROFILE: credential.profile, ...region };\n\t}\n\treturn {\n\t\tAWS_ACCESS_KEY_ID: credential.accessKeyId,\n\t\tAWS_SECRET_ACCESS_KEY: credential.secretAccessKey,\n\t\t...(credential.sessionToken\n\t\t\t? { AWS_SESSION_TOKEN: credential.sessionToken }\n\t\t\t: {}),\n\t\t...region,\n\t};\n}\n\n/**\n * `env` without any `AWS_*`, so a host sandbox that passes some cannot put\n * a second account beside the one the credential names.\n */\nfunction withoutAws(\n\tenv: Readonly<Record<string, string>>,\n): Record<string, string> {\n\treturn Object.fromEntries(\n\t\tObject.entries(env).filter(([name]) => !name.startsWith('AWS_')),\n\t);\n}\n\n/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */\nfunction kindsOf(manifest: ConstructManifest): Map<string, string> {\n\treturn new Map(\n\t\tObject.entries(manifest).map(([id, declaration]) => [\n\t\t\tappKey(id),\n\t\t\tdeclaration.kind,\n\t\t]),\n\t);\n}\n\nasync function exec(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n\t[command, args]: [string, string[]],\n\toptions: { env: Record<string, string>; timeoutMs: number },\n): Promise<void> {\n\tconst result = await run.sandbox.exec(command, args, {\n\t\tcwd: ctx.cwd,\n\t\tenv: options.env,\n\t\ttimeoutMs: options.timeoutMs,\n\t\toutput: ctx.childOutput,\n\t\tsignal: ctx.signal,\n\t});\n\tif (result.exitCode !== 0) {\n\t\tthrow new CommandFailed(\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tresult.exitCode,\n\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t);\n\t}\n}\n\n/** The `sst` target, with its health checks tuned — for tests and hosts. */\nexport function createSstTarget(\n\toptions: SstTargetOptions = {},\n): DeployTarget<undefined, SstRun> {\n\tconst health = {\n\t\tattempts: options.health?.attempts ?? 6,\n\t\tdelayMs: options.health?.delayMs ?? 5_000,\n\t\ttimeoutMs: options.health?.timeoutMs ?? 10_000,\n\t};\n\n\treturn defineTarget<undefined, SstRun>({\n\t\tname: 'sst',\n\t\truntime: 'aws',\n\t\t// SST keeps no previous release to return to; migrations run in the\n\t\t// stack, as `fromManifest` provisions the database; and nothing here\n\t\t// builds an image.\n\t\tcapabilities: { rollback: false, migrations: 'target', images: false },\n\t\tcredentials: ['aws'],\n\n\t\tasync validate(ctx) {\n\t\t\tif (!existsSync(join(ctx.cwd, 'sst.config.ts'))) {\n\t\t\t\tthrow new SstConfigNotFound(ctx.cwd);\n\t\t\t}\n\n\t\t\tconst aws = await ctx.credentials.get(\n\t\t\t\t{ kind: 'aws', stage: ctx.stage },\n\t\t\t\t{ signal: ctx.signal },\n\t\t\t);\n\t\t\tif (!aws) throw new MissingCredential('aws', ctx.stage);\n\t\t\tif (!('profile' in aws)) {\n\t\t\t\tctx.secrets.mask(aws.secretAccessKey);\n\t\t\t\tif (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);\n\t\t\t}\n\n\t\t\t// A mobile app ships through its own store's toolchain.\n\t\t\tfor (const app of ctx.apps) {\n\t\t\t\tif (ctx.workspace.apps[app]?.type === 'mobile') {\n\t\t\t\t\tctx.skip(app, 'mobile apps deploy through their own toolchain');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst skipped = new Set(ctx.skipped.map(({ app }) => app));\n\t\t\tconst apps = ctx.apps.filter((app) => !skipped.has(app));\n\n\t\t\tctx.logger.info(\n\t\t\t\t`\\n🚀 Deploying \"${ctx.workspace.name}\" to the \"${ctx.stage}\" stage with SST`,\n\t\t\t);\n\t\t\tctx.logger.info(\n\t\t\t\t` AWS: ${'profile' in aws ? `profile \"${aws.profile}\"` : 'access keys'}`,\n\t\t\t);\n\t\t\t// `sst deploy` takes the whole stack: there is no deploying one app.\n\t\t\tconst deployable = Object.values(ctx.workspace.apps).filter(\n\t\t\t\t(app) => app.type !== 'mobile',\n\t\t\t).length;\n\t\t\tif (apps.length < deployable) {\n\t\t\t\tctx.logger.warn(\n\t\t\t\t\t` sst deploy deploys every construct of the stage, not only ${apps.join(', ')}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),\n\t\t\t\tpm: detectPackageManager(ctx.cwd),\n\t\t\t\taws,\n\t\t\t\tapps,\n\t\t\t\turls: {},\n\t\t\t};\n\t\t},\n\n\t\tasync plan(ctx, run) {\n\t\t\tconst kinds = kindsOf(ctx.manifest);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'resource.planned',\n\t\t\t\t\tkey: `application:${app}`,\n\t\t\t\t\tresourceType: kinds.get(app) ?? 'application',\n\t\t\t\t\taction: 'ensure',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst [build, buildArgs] = buildCommand(ctx, run);\n\t\t\tconst [deploy, deployArgs] = deployCommand(ctx, run);\n\t\t\tctx.logger.info(` Would run: ${[build, ...buildArgs].join(' ')}`);\n\t\t\tctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(' ')}`);\n\t\t},\n\n\t\tasync build(ctx, run) {\n\t\t\tctx.logger.info('\\n📦 Building the manifest SST deploys');\n\t\t\t// No credential: the build runs the project's code and needs none.\n\t\t\tawait exec(ctx, run, buildCommand(ctx, run), {\n\t\t\t\tenv: { ...run.sandbox.env },\n\t\t\t\ttimeoutMs: BUILD_TIMEOUT_MS,\n\t\t\t});\n\t\t},\n\n\t\tasync release(ctx, run) {\n\t\t\tctx.logger.info(`\\n☁️ sst deploy --stage ${ctx.stage}`);\n\t\t\tawait clearOutputs(ctx.cwd);\n\t\t\tawait exec(ctx, run, deployCommand(ctx, run), {\n\t\t\t\tenv: { ...withoutAws(run.sandbox.env), ...awsEnv(run.aws) },\n\t\t\t\ttimeoutMs: DEPLOY_TIMEOUT_MS,\n\t\t\t});\n\n\t\t\trun.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'app.deployed',\n\t\t\t\t\tapp,\n\t\t\t\t\tapplicationId: ctx.name(app),\n\t\t\t\t\t// SST builds no image a registry holds.\n\t\t\t\t\timageRef: '',\n\t\t\t\t\turl: run.urls[app] ?? '',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tasync verify(ctx, run) {\n\t\t\tconst unhealthy: SurfacesUnhealthy['surfaces'][number][] = [];\n\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tconst base = run.urls[app];\n\t\t\t\tif (!base) {\n\t\t\t\t\tctx.logger.warn(\n\t\t\t\t\t\t` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A surface — a `rest-api` — is the backend app it derives.\n\t\t\t\tconst backend = ctx.workspace.apps[app]?.type === 'backend';\n\t\t\t\tconst url = healthUrl(base, backend ? '/health' : '/');\n\t\t\t\tconst answer = await checkHealth(app, url, {\n\t\t\t\t\t...health,\n\t\t\t\t\tsignal: ctx.signal,\n\t\t\t\t\temit: ctx.emit,\n\t\t\t\t});\n\t\t\t\tif (answer.healthy) {\n\t\t\t\t\tctx.logger.info(` ✓ ${app}: ${url}`);\n\t\t\t\t} else {\n\t\t\t\t\tunhealthy.push({\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t...(answer.status !== undefined ? { status: answer.status } : {}),\n\t\t\t\t\t\t...(answer.error ? { error: answer.error } : {}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unhealthy.length > 0) {\n\t\t\t\tthrow new SurfacesUnhealthy(ctx.stage, unhealthy);\n\t\t\t}\n\t\t},\n\n\t\tresult(ctx, run): DeployResult {\n\t\t\treturn {\n\t\t\t\tapps: run.apps.map((appName) => ({\n\t\t\t\t\tappName,\n\t\t\t\t\ttype: ctx.workspace.apps[appName]?.type ?? 'backend',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\t...(run.urls[appName] ? { url: run.urls[appName] } : {}),\n\t\t\t\t})),\n\t\t\t\tprojectId: '',\n\t\t\t\tenvironmentId: '',\n\t\t\t\tsuccessCount: ctx.dryRun ? 0 : run.apps.length,\n\t\t\t\tfailedCount: 0,\n\t\t\t\tstage: ctx.stage,\n\t\t\t\tidentity: ctx.identity.key,\n\t\t\t\ttag: ctx.tag,\n\t\t\t\tdryRun: ctx.dryRun,\n\t\t\t\tskipped: [...ctx.skipped],\n\t\t\t\turls: { ...run.urls },\n\t\t\t\tchanges: [],\n\t\t\t};\n\t\t},\n\t});\n}\n\nfunction buildCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'gkm', [\n\t\t'build',\n\t\t'--provider',\n\t\t'aws',\n\t\t'--stage',\n\t\tctx.stage,\n\t]);\n}\n\nfunction deployCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'sst', ['deploy', '--stage', ctx.stage]);\n}\n\nexport const sstTarget = createSstTarget();\n"],"mappings":"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"}
1
+ {"version":3,"file":"sst-CGdjHn2A.mjs","names":[],"sources":["../src/target/sst/health.ts","../src/target/sst/outputs.ts","../src/target/sst/index.ts"],"sourcesContent":["/**\n * Whether a released surface answers.\n *\n * The paths are the ones the local stack's healthchecks use\n * (`reconcile/apps.ts`): an API's `/health`, a site's `/`. A surface is\n * asked a few times, because a fresh deploy can take a moment to answer — a\n * Lambda's first start, a distribution still settling — and healthy means a\n * 2xx, after redirects.\n */\n\nimport { GkmError } from '../../errors';\nimport type { TargetEvent } from '../types';\n\nexport interface HealthCheckOptions {\n\t/** How many times a surface is asked before it counts as down. */\n\tattempts: number;\n\t/** The wait between two attempts. */\n\tdelayMs: number;\n\t/** How long one request may take. */\n\ttimeoutMs: number;\n\tsignal: AbortSignal;\n\temit: (event: TargetEvent) => void;\n}\n\n/** Surfaces that never answered healthy. */\nexport class SurfacesUnhealthy extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** Each surface that failed, with the last thing it answered. */\n\t\treadonly surfaces: readonly {\n\t\t\tapp: string;\n\t\t\turl: string;\n\t\t\tstatus?: number;\n\t\t\terror?: string;\n\t\t}[],\n\t) {\n\t\tconst lines = surfaces.map(\n\t\t\t({ app, url, status, error }) =>\n\t\t\t\t` - ${app}: ${url} → ${status ?? error ?? 'no answer'}`,\n\t\t);\n\t\tsuper(\n\t\t\t`The \"${stage}\" stage was deployed, but ${surfaces.length === 1 ? 'a surface does' : 'surfaces do'} not answer healthy:\\n${lines.join('\\n')}\\nCheck its logs in CloudWatch, fix it, and deploy again.`,\n\t\t);\n\t\tthis.name = 'SurfacesUnhealthy';\n\t}\n}\n\n/** `path` under `base`, keeping any path `base` already has. */\nexport function healthUrl(base: string, path: string): string {\n\tconst root = base.endsWith('/') ? base : `${base}/`;\n\treturn new URL(path.replace(/^\\//, ''), root).toString();\n}\n\n/**\n * Ask `url` until it answers 2xx or the attempts run out, emitting\n * `health.checked` for each. Resolves with the last answer.\n */\nexport async function checkHealth(\n\tapp: string,\n\turl: string,\n\toptions: HealthCheckOptions,\n): Promise<{ healthy: boolean; status?: number; error?: string }> {\n\tlet last: { healthy: boolean; status?: number; error?: string } = {\n\t\thealthy: false,\n\t};\n\tfor (let attempt = 1; attempt <= options.attempts; attempt++) {\n\t\toptions.signal.throwIfAborted();\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tredirect: 'follow',\n\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\toptions.signal,\n\t\t\t\t\tAbortSignal.timeout(options.timeoutMs),\n\t\t\t\t]),\n\t\t\t});\n\t\t\t// Drained, so the connection is not held open by an unread body.\n\t\t\tawait response.arrayBuffer().catch(() => undefined);\n\t\t\tlast = { healthy: response.ok, status: response.status };\n\t\t} catch (error) {\n\t\t\t// The run being stopped is not the surface being down.\n\t\t\toptions.signal.throwIfAborted();\n\t\t\tlast = {\n\t\t\t\thealthy: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t\toptions.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp,\n\t\t\turl,\n\t\t\thealthy: last.healthy,\n\t\t\t...(last.status !== undefined ? { status: last.status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (last.healthy) return last;\n\t\tif (attempt < options.attempts) await wait(options.delayMs, options.signal);\n\t}\n\treturn last;\n}\n\nfunction wait(ms: number, signal: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal.removeEventListener('abort', stop);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst stop = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal.reason);\n\t\t};\n\t\tsignal.addEventListener('abort', stop, { once: true });\n\t});\n}\n","/**\n * The surface URLs an `sst deploy` reports.\n *\n * SST writes whatever `run()` in `sst.config.ts` returns to\n * `.sst/outputs.json` after every successful deploy — `{\"Api\": \"https://…\"}`.\n * What `run()` returns is the project's to write, so this reads it leniently:\n * nested objects are walked, anything that is not an http(s) URL is ignored,\n * and an output names a surface by its id in any casing, with or without a\n * `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { GkmError } from '../../errors';\n\n/** Where SST leaves the last successful deploy's outputs, under the project. */\nexport const SST_OUTPUTS_FILE = join('.sst', 'outputs.json');\n\n/** `.sst/outputs.json` is there, and is not JSON. */\nexport class SstOutputsUnreadable extends GkmError {\n\tconstructor(\n\t\treadonly path: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \\`sst deploy\\`; delete it and deploy again.`,\n\t\t);\n\t\tthis.name = 'SstOutputsUnreadable';\n\t}\n}\n\n/**\n * Remove what an earlier deploy wrote, so the outputs read after this one\n * are this one's — not another stage's, deployed from the same checkout.\n */\nexport async function clearOutputs(cwd: string): Promise<void> {\n\tawait rm(join(cwd, SST_OUTPUTS_FILE), { force: true });\n}\n\n/** The deploy's outputs, or `{}` when it wrote none. */\nexport async function readOutputs(cwd: string): Promise<unknown> {\n\tconst path = join(cwd, SST_OUTPUTS_FILE);\n\tif (!existsSync(path)) return {};\n\ttry {\n\t\treturn JSON.parse(await readFile(path, 'utf8'));\n\t} catch (error) {\n\t\tthrow new SstOutputsUnreadable(\n\t\t\tpath,\n\t\t\terror instanceof Error ? error.message : String(error),\n\t\t);\n\t}\n}\n\n/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */\nfunction urlsIn(\n\tvalue: unknown,\n\tpath: string[] = [],\n\tfound: { path: string[]; url: string }[] = [],\n): { path: string[]; url: string }[] {\n\tif (typeof value === 'string') {\n\t\tif (isHttpUrl(value)) found.push({ path, url: value });\n\t} else if (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\turlsIn(child, [...path, key], found);\n\t\t}\n\t}\n\treturn found;\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst { protocol } = new URL(value);\n\t\treturn protocol === 'http:' || protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * The app an output's key path names, kebab-cased as app keys are: its last\n * segment, without a `url` suffix — or its parent's, when the last segment\n * is only `url`. Exact names are tried first, so an app called `api-url`\n * still finds `ApiUrl`.\n */\nfunction namesOf(path: string[]): string[] {\n\tconst names: string[] = [];\n\tfor (const segment of [...path].reverse()) {\n\t\tconst name = kebabCase(segment);\n\t\tnames.push(name);\n\t\tconst bare = name.replace(/-?url$/, '');\n\t\tif (bare) {\n\t\t\tnames.push(bare);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn names;\n}\n\n/**\n * Each app's URL from the outputs, for the apps given. An app no output\n * names is left out.\n */\nexport function surfaceUrls(\n\toutputs: unknown,\n\tapps: readonly string[],\n): Record<string, string> {\n\tconst found = urlsIn(outputs);\n\tconst urls: Record<string, string> = {};\n\tfor (const app of apps) {\n\t\t// An exact name beats a stripped one, wherever each is in the file.\n\t\tconst exact = found.find(({ path }) => namesOf(path)[0] === app);\n\t\tconst loose = found.find(({ path }) => namesOf(path).includes(app));\n\t\tconst match = exact ?? loose;\n\t\tif (match) urls[app] = match.url;\n\t}\n\treturn urls;\n}\n","/**\n * The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`\n * provisions it, and the surfaces SST reports are health-checked.\n *\n * `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads\n * `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What\n * the target adds is the run around the two commands — the lock, the events,\n * verification, and credentials kept where they belong.\n *\n * Both commands run in the sandbox: the build executes the project's code,\n * and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second\n * needs AWS, so the AWS credential goes into that one command's environment\n * and nowhere else — not the build's, not the process the deploy runs in.\n * What `sst deploy` needs beyond them, the sandbox already passes: `PATH`\n * for node and the package manager, and `HOME`, under which SST keeps its\n * toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK\n * finds `~/.aws` for a profile. Its state — the Pulumi backend and the\n * passphrase — is in the stage's own account, reached with that credential.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\ttype AwsCredential,\n\tMissingCredential,\n} from '../../deploy/credentials';\nimport type { DeployResult } from '../../deploy/types';\nimport { GkmError } from '../../errors';\nimport { detectPackageManager, type PackageManager } from '../../init/utils';\nimport { CommandFailed } from '../../run';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { activeSandbox, type Sandbox } from '../../sandbox/sandbox';\nimport { appKey } from '../../workspace/derive';\nimport { defineTarget } from '../define';\nimport type { DeployPhaseContext, DeployTarget } from '../types';\nimport { checkHealth, healthUrl, SurfacesUnhealthy } from './health';\nimport { clearOutputs, readOutputs, surfaceUrls } from './outputs';\n\nexport { SurfacesUnhealthy } from './health';\nexport { SST_OUTPUTS_FILE, SstOutputsUnreadable } from './outputs';\n\n/** A cold build of every handler and site. */\nconst BUILD_TIMEOUT_MS = 30 * 60_000;\n/**\n * A first deploy creates CloudFront distributions and, with a database, a\n * VPC and an RDS instance — each of which alone can take a quarter of an hour.\n */\nconst DEPLOY_TIMEOUT_MS = 90 * 60_000;\n\n/** The workspace has no `sst.config.ts` for `sst deploy` to run. */\nexport class SstConfigNotFound extends GkmError {\n\tconstructor(readonly cwd: string) {\n\t\tsuper(\n\t\t\t`No sst.config.ts in ${cwd}. The sst target runs \\`sst deploy\\` at the workspace root: scaffold one with \\`gkm init --deploy sst\\` and copy its sst.config.ts, or deploy through another target with --target.`,\n\t\t);\n\t\tthis.name = 'SstConfigNotFound';\n\t}\n}\n\n/** What the phases hand on. */\nexport interface SstRun {\n\tsandbox: Sandbox;\n\tpm: PackageManager;\n\taws: AwsCredential;\n\t/** The apps SST deploys this run: `ctx.apps` without the skipped. */\n\tapps: string[];\n\t/** Each app's URL, from the deploy's outputs. */\n\turls: Record<string, string>;\n}\n\nexport interface SstTargetOptions {\n\t/** How often, and how patiently, `verify` asks each surface. */\n\thealth?: { attempts?: number; delayMs?: number; timeoutMs?: number };\n}\n\n/**\n * The project's own copy of `bin`, through its package manager — never one\n * `npx` would download, which would be code nobody installed.\n */\nexport function projectCommand(\n\tpm: PackageManager,\n\tbin: string,\n\targs: readonly string[],\n): [command: string, args: string[]] {\n\tswitch (pm) {\n\t\tcase 'pnpm':\n\t\t\treturn ['pnpm', ['exec', bin, ...args]];\n\t\tcase 'yarn':\n\t\t\treturn ['yarn', [bin, ...args]];\n\t\tcase 'bun':\n\t\t\treturn ['bunx', [bin, ...args]];\n\t\tcase 'npm':\n\t\t\treturn ['npx', ['--no-install', bin, ...args]];\n\t}\n}\n\n/**\n * The variables `credential` is to the AWS SDK and to SST.\n *\n * A profile is passed alone: given keys too, every SDK would take the keys.\n */\nexport function awsEnv(credential: AwsCredential): Record<string, string> {\n\tconst region: Record<string, string> = credential.region\n\t\t? { AWS_REGION: credential.region, AWS_DEFAULT_REGION: credential.region }\n\t\t: {};\n\tif ('profile' in credential) {\n\t\treturn { AWS_PROFILE: credential.profile, ...region };\n\t}\n\treturn {\n\t\tAWS_ACCESS_KEY_ID: credential.accessKeyId,\n\t\tAWS_SECRET_ACCESS_KEY: credential.secretAccessKey,\n\t\t...(credential.sessionToken\n\t\t\t? { AWS_SESSION_TOKEN: credential.sessionToken }\n\t\t\t: {}),\n\t\t...region,\n\t};\n}\n\n/**\n * `env` without any `AWS_*`, so a host sandbox that passes some cannot put\n * a second account beside the one the credential names.\n */\nfunction withoutAws(\n\tenv: Readonly<Record<string, string>>,\n): Record<string, string> {\n\treturn Object.fromEntries(\n\t\tObject.entries(env).filter(([name]) => !name.startsWith('AWS_')),\n\t);\n}\n\n/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */\nfunction kindsOf(manifest: ConstructManifest): Map<string, string> {\n\treturn new Map(\n\t\tObject.entries(manifest).map(([id, declaration]) => [\n\t\t\tappKey(id),\n\t\t\tdeclaration.kind,\n\t\t]),\n\t);\n}\n\nasync function exec(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n\t[command, args]: [string, string[]],\n\toptions: { env: Record<string, string>; timeoutMs: number },\n): Promise<void> {\n\tconst result = await run.sandbox.exec(command, args, {\n\t\tcwd: ctx.cwd,\n\t\tenv: options.env,\n\t\ttimeoutMs: options.timeoutMs,\n\t\toutput: ctx.childOutput,\n\t\tsignal: ctx.signal,\n\t});\n\tif (result.exitCode !== 0) {\n\t\tthrow new CommandFailed(\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tresult.exitCode,\n\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t);\n\t}\n}\n\n/** The `sst` target, with its health checks tuned — for tests and hosts. */\nexport function createSstTarget(\n\toptions: SstTargetOptions = {},\n): DeployTarget<undefined, SstRun> {\n\tconst health = {\n\t\tattempts: options.health?.attempts ?? 6,\n\t\tdelayMs: options.health?.delayMs ?? 5_000,\n\t\ttimeoutMs: options.health?.timeoutMs ?? 10_000,\n\t};\n\n\treturn defineTarget<undefined, SstRun>({\n\t\tname: 'sst',\n\t\truntime: 'aws',\n\t\t// SST keeps no previous release to return to; migrations run in the\n\t\t// stack, as `fromManifest` provisions the database; and nothing here\n\t\t// builds an image.\n\t\tcapabilities: { rollback: false, migrations: 'target', images: false },\n\t\tcredentials: ['aws'],\n\n\t\tasync validate(ctx) {\n\t\t\tif (!existsSync(join(ctx.cwd, 'sst.config.ts'))) {\n\t\t\t\tthrow new SstConfigNotFound(ctx.cwd);\n\t\t\t}\n\n\t\t\tconst aws = await ctx.credentials.get(\n\t\t\t\t{ kind: 'aws', stage: ctx.stage },\n\t\t\t\t{ signal: ctx.signal },\n\t\t\t);\n\t\t\tif (!aws) throw new MissingCredential('aws', ctx.stage);\n\t\t\tif (!('profile' in aws)) {\n\t\t\t\tctx.secrets.mask(aws.secretAccessKey);\n\t\t\t\tif (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);\n\t\t\t}\n\n\t\t\t// A mobile app ships through its own store's toolchain.\n\t\t\tfor (const app of ctx.apps) {\n\t\t\t\tif (ctx.workspace.apps[app]?.type === 'mobile') {\n\t\t\t\t\tctx.skip(app, 'mobile apps deploy through their own toolchain');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst skipped = new Set(ctx.skipped.map(({ app }) => app));\n\t\t\tconst apps = ctx.apps.filter((app) => !skipped.has(app));\n\n\t\t\tctx.logger.info(\n\t\t\t\t`\\n🚀 Deploying \"${ctx.workspace.name}\" to the \"${ctx.stage}\" stage with SST`,\n\t\t\t);\n\t\t\tctx.logger.info(\n\t\t\t\t` AWS: ${'profile' in aws ? `profile \"${aws.profile}\"` : 'access keys'}`,\n\t\t\t);\n\t\t\t// `sst deploy` takes the whole stack: there is no deploying one app.\n\t\t\tconst deployable = Object.values(ctx.workspace.apps).filter(\n\t\t\t\t(app) => app.type !== 'mobile',\n\t\t\t).length;\n\t\t\tif (apps.length < deployable) {\n\t\t\t\tctx.logger.warn(\n\t\t\t\t\t` sst deploy deploys every construct of the stage, not only ${apps.join(', ')}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),\n\t\t\t\tpm: detectPackageManager(ctx.cwd),\n\t\t\t\taws,\n\t\t\t\tapps,\n\t\t\t\turls: {},\n\t\t\t};\n\t\t},\n\n\t\tasync plan(ctx, run) {\n\t\t\tconst kinds = kindsOf(ctx.manifest);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'resource.planned',\n\t\t\t\t\tkey: `application:${app}`,\n\t\t\t\t\tresourceType: kinds.get(app) ?? 'application',\n\t\t\t\t\taction: 'ensure',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst [build, buildArgs] = buildCommand(ctx, run);\n\t\t\tconst [deploy, deployArgs] = deployCommand(ctx, run);\n\t\t\tctx.logger.info(` Would run: ${[build, ...buildArgs].join(' ')}`);\n\t\t\tctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(' ')}`);\n\t\t},\n\n\t\tasync build(ctx, run) {\n\t\t\tctx.logger.info('\\n📦 Building the manifest SST deploys');\n\t\t\t// No credential: the build runs the project's code and needs none.\n\t\t\tawait exec(ctx, run, buildCommand(ctx, run), {\n\t\t\t\tenv: { ...run.sandbox.env },\n\t\t\t\ttimeoutMs: BUILD_TIMEOUT_MS,\n\t\t\t});\n\t\t},\n\n\t\tasync release(ctx, run) {\n\t\t\tctx.logger.info(`\\n☁️ sst deploy --stage ${ctx.stage}`);\n\t\t\tawait clearOutputs(ctx.cwd);\n\t\t\tawait exec(ctx, run, deployCommand(ctx, run), {\n\t\t\t\tenv: { ...withoutAws(run.sandbox.env), ...awsEnv(run.aws) },\n\t\t\t\ttimeoutMs: DEPLOY_TIMEOUT_MS,\n\t\t\t});\n\n\t\t\trun.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'app.deployed',\n\t\t\t\t\tapp,\n\t\t\t\t\tapplicationId: ctx.name(app),\n\t\t\t\t\t// SST builds no image a registry holds.\n\t\t\t\t\timageRef: '',\n\t\t\t\t\turl: run.urls[app] ?? '',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tasync verify(ctx, run) {\n\t\t\tconst unhealthy: SurfacesUnhealthy['surfaces'][number][] = [];\n\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tconst base = run.urls[app];\n\t\t\t\tif (!base) {\n\t\t\t\t\tctx.logger.warn(\n\t\t\t\t\t\t` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A surface — a `rest-api` — is the backend app it derives.\n\t\t\t\tconst backend = ctx.workspace.apps[app]?.type === 'backend';\n\t\t\t\tconst url = healthUrl(base, backend ? '/health' : '/');\n\t\t\t\tconst answer = await checkHealth(app, url, {\n\t\t\t\t\t...health,\n\t\t\t\t\tsignal: ctx.signal,\n\t\t\t\t\temit: ctx.emit,\n\t\t\t\t});\n\t\t\t\tif (answer.healthy) {\n\t\t\t\t\tctx.logger.info(` ✓ ${app}: ${url}`);\n\t\t\t\t} else {\n\t\t\t\t\tunhealthy.push({\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t...(answer.status !== undefined ? { status: answer.status } : {}),\n\t\t\t\t\t\t...(answer.error ? { error: answer.error } : {}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unhealthy.length > 0) {\n\t\t\t\tthrow new SurfacesUnhealthy(ctx.stage, unhealthy);\n\t\t\t}\n\t\t},\n\n\t\tresult(ctx, run): DeployResult {\n\t\t\treturn {\n\t\t\t\tapps: run.apps.map((appName) => ({\n\t\t\t\t\tappName,\n\t\t\t\t\ttype: ctx.workspace.apps[appName]?.type ?? 'backend',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\t...(run.urls[appName] ? { url: run.urls[appName] } : {}),\n\t\t\t\t})),\n\t\t\t\tprojectId: '',\n\t\t\t\tenvironmentId: '',\n\t\t\t\tsuccessCount: ctx.dryRun ? 0 : run.apps.length,\n\t\t\t\tfailedCount: 0,\n\t\t\t\tstage: ctx.stage,\n\t\t\t\tidentity: ctx.identity.key,\n\t\t\t\ttag: ctx.tag,\n\t\t\t\tdryRun: ctx.dryRun,\n\t\t\t\tskipped: [...ctx.skipped],\n\t\t\t\turls: { ...run.urls },\n\t\t\t\tchanges: [],\n\t\t\t};\n\t\t},\n\t});\n}\n\nfunction buildCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'gkm', [\n\t\t'build',\n\t\t'--provider',\n\t\t'aws',\n\t\t'--stage',\n\t\tctx.stage,\n\t]);\n}\n\nfunction deployCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'sst', ['deploy', '--stage', ctx.stage]);\n}\n\nexport const sstTarget = createSstTarget();\n"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
2
  const require_errors = require("./errors-DMC4Umsb.cjs");
3
- const require_credentials = require("./credentials-D7XJypNd.cjs");
3
+ const require_run = require("./run-fVZ-rLnc.cjs");
4
+ const require_credentials = require("./credentials-Zqr3QQYB.cjs");
4
5
  const require_sandbox = require("./sandbox-CHv3OYXg.cjs");
5
6
  const require_derive = require("./derive-DAbo49sm.cjs");
6
7
  const require_define = require("./define-crmMcXFS.cjs");
7
- const require_local = require("./local-OPC9BCZt.cjs");
8
+ const require_local = require("./local-DNhnkugT.cjs");
8
9
  const require_utils = require("./utils-D2Nk1Nv2.cjs");
9
10
  let node_path = require("node:path");
10
11
  let node_fs = require("node:fs");
@@ -287,7 +288,7 @@ async function exec(ctx, run, [command, args], options) {
287
288
  output: ctx.childOutput,
288
289
  signal: ctx.signal
289
290
  });
290
- if (result.exitCode !== 0) throw new require_credentials.CommandFailed(command, args, result.exitCode, result.signal);
291
+ if (result.exitCode !== 0) throw new require_run.CommandFailed(command, args, result.exitCode, result.signal);
291
292
  }
292
293
  /** The `sst` target, with its health checks tuned — for tests and hosts. */
293
294
  function createSstTarget(options = {}) {
@@ -460,4 +461,4 @@ Object.defineProperty(exports, "sst_exports", {
460
461
  }
461
462
  });
462
463
 
463
- //# sourceMappingURL=sst-DKNH243z.cjs.map
464
+ //# sourceMappingURL=sst-DGuHDxVU.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sst-DKNH243z.cjs","names":["GkmError","join","GkmError","rm","existsSync","readFile","kebabCase","GkmError","appKey","CommandFailed","defineTarget","existsSync","join","MissingCredential","activeSandbox","LocalSandbox","detectPackageManager"],"sources":["../src/target/sst/health.ts","../src/target/sst/outputs.ts","../src/target/sst/index.ts"],"sourcesContent":["/**\n * Whether a released surface answers.\n *\n * The paths are the ones the local stack's healthchecks use\n * (`reconcile/apps.ts`): an API's `/health`, a site's `/`. A surface is\n * asked a few times, because a fresh deploy can take a moment to answer — a\n * Lambda's first start, a distribution still settling — and healthy means a\n * 2xx, after redirects.\n */\n\nimport { GkmError } from '../../errors';\nimport type { TargetEvent } from '../types';\n\nexport interface HealthCheckOptions {\n\t/** How many times a surface is asked before it counts as down. */\n\tattempts: number;\n\t/** The wait between two attempts. */\n\tdelayMs: number;\n\t/** How long one request may take. */\n\ttimeoutMs: number;\n\tsignal: AbortSignal;\n\temit: (event: TargetEvent) => void;\n}\n\n/** Surfaces that never answered healthy. */\nexport class SurfacesUnhealthy extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** Each surface that failed, with the last thing it answered. */\n\t\treadonly surfaces: readonly {\n\t\t\tapp: string;\n\t\t\turl: string;\n\t\t\tstatus?: number;\n\t\t\terror?: string;\n\t\t}[],\n\t) {\n\t\tconst lines = surfaces.map(\n\t\t\t({ app, url, status, error }) =>\n\t\t\t\t` - ${app}: ${url} → ${status ?? error ?? 'no answer'}`,\n\t\t);\n\t\tsuper(\n\t\t\t`The \"${stage}\" stage was deployed, but ${surfaces.length === 1 ? 'a surface does' : 'surfaces do'} not answer healthy:\\n${lines.join('\\n')}\\nCheck its logs in CloudWatch, fix it, and deploy again.`,\n\t\t);\n\t\tthis.name = 'SurfacesUnhealthy';\n\t}\n}\n\n/** `path` under `base`, keeping any path `base` already has. */\nexport function healthUrl(base: string, path: string): string {\n\tconst root = base.endsWith('/') ? base : `${base}/`;\n\treturn new URL(path.replace(/^\\//, ''), root).toString();\n}\n\n/**\n * Ask `url` until it answers 2xx or the attempts run out, emitting\n * `health.checked` for each. Resolves with the last answer.\n */\nexport async function checkHealth(\n\tapp: string,\n\turl: string,\n\toptions: HealthCheckOptions,\n): Promise<{ healthy: boolean; status?: number; error?: string }> {\n\tlet last: { healthy: boolean; status?: number; error?: string } = {\n\t\thealthy: false,\n\t};\n\tfor (let attempt = 1; attempt <= options.attempts; attempt++) {\n\t\toptions.signal.throwIfAborted();\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tredirect: 'follow',\n\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\toptions.signal,\n\t\t\t\t\tAbortSignal.timeout(options.timeoutMs),\n\t\t\t\t]),\n\t\t\t});\n\t\t\t// Drained, so the connection is not held open by an unread body.\n\t\t\tawait response.arrayBuffer().catch(() => undefined);\n\t\t\tlast = { healthy: response.ok, status: response.status };\n\t\t} catch (error) {\n\t\t\t// The run being stopped is not the surface being down.\n\t\t\toptions.signal.throwIfAborted();\n\t\t\tlast = {\n\t\t\t\thealthy: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t\toptions.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp,\n\t\t\turl,\n\t\t\thealthy: last.healthy,\n\t\t\t...(last.status !== undefined ? { status: last.status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (last.healthy) return last;\n\t\tif (attempt < options.attempts) await wait(options.delayMs, options.signal);\n\t}\n\treturn last;\n}\n\nfunction wait(ms: number, signal: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal.removeEventListener('abort', stop);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst stop = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal.reason);\n\t\t};\n\t\tsignal.addEventListener('abort', stop, { once: true });\n\t});\n}\n","/**\n * The surface URLs an `sst deploy` reports.\n *\n * SST writes whatever `run()` in `sst.config.ts` returns to\n * `.sst/outputs.json` after every successful deploy — `{\"Api\": \"https://…\"}`.\n * What `run()` returns is the project's to write, so this reads it leniently:\n * nested objects are walked, anything that is not an http(s) URL is ignored,\n * and an output names a surface by its id in any casing, with or without a\n * `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { GkmError } from '../../errors';\n\n/** Where SST leaves the last successful deploy's outputs, under the project. */\nexport const SST_OUTPUTS_FILE = join('.sst', 'outputs.json');\n\n/** `.sst/outputs.json` is there, and is not JSON. */\nexport class SstOutputsUnreadable extends GkmError {\n\tconstructor(\n\t\treadonly path: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \\`sst deploy\\`; delete it and deploy again.`,\n\t\t);\n\t\tthis.name = 'SstOutputsUnreadable';\n\t}\n}\n\n/**\n * Remove what an earlier deploy wrote, so the outputs read after this one\n * are this one's — not another stage's, deployed from the same checkout.\n */\nexport async function clearOutputs(cwd: string): Promise<void> {\n\tawait rm(join(cwd, SST_OUTPUTS_FILE), { force: true });\n}\n\n/** The deploy's outputs, or `{}` when it wrote none. */\nexport async function readOutputs(cwd: string): Promise<unknown> {\n\tconst path = join(cwd, SST_OUTPUTS_FILE);\n\tif (!existsSync(path)) return {};\n\ttry {\n\t\treturn JSON.parse(await readFile(path, 'utf8'));\n\t} catch (error) {\n\t\tthrow new SstOutputsUnreadable(\n\t\t\tpath,\n\t\t\terror instanceof Error ? error.message : String(error),\n\t\t);\n\t}\n}\n\n/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */\nfunction urlsIn(\n\tvalue: unknown,\n\tpath: string[] = [],\n\tfound: { path: string[]; url: string }[] = [],\n): { path: string[]; url: string }[] {\n\tif (typeof value === 'string') {\n\t\tif (isHttpUrl(value)) found.push({ path, url: value });\n\t} else if (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\turlsIn(child, [...path, key], found);\n\t\t}\n\t}\n\treturn found;\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst { protocol } = new URL(value);\n\t\treturn protocol === 'http:' || protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * The app an output's key path names, kebab-cased as app keys are: its last\n * segment, without a `url` suffix — or its parent's, when the last segment\n * is only `url`. Exact names are tried first, so an app called `api-url`\n * still finds `ApiUrl`.\n */\nfunction namesOf(path: string[]): string[] {\n\tconst names: string[] = [];\n\tfor (const segment of [...path].reverse()) {\n\t\tconst name = kebabCase(segment);\n\t\tnames.push(name);\n\t\tconst bare = name.replace(/-?url$/, '');\n\t\tif (bare) {\n\t\t\tnames.push(bare);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn names;\n}\n\n/**\n * Each app's URL from the outputs, for the apps given. An app no output\n * names is left out.\n */\nexport function surfaceUrls(\n\toutputs: unknown,\n\tapps: readonly string[],\n): Record<string, string> {\n\tconst found = urlsIn(outputs);\n\tconst urls: Record<string, string> = {};\n\tfor (const app of apps) {\n\t\t// An exact name beats a stripped one, wherever each is in the file.\n\t\tconst exact = found.find(({ path }) => namesOf(path)[0] === app);\n\t\tconst loose = found.find(({ path }) => namesOf(path).includes(app));\n\t\tconst match = exact ?? loose;\n\t\tif (match) urls[app] = match.url;\n\t}\n\treturn urls;\n}\n","/**\n * The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`\n * provisions it, and the surfaces SST reports are health-checked.\n *\n * `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads\n * `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What\n * the target adds is the run around the two commands — the lock, the events,\n * verification, and credentials kept where they belong.\n *\n * Both commands run in the sandbox: the build executes the project's code,\n * and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second\n * needs AWS, so the AWS credential goes into that one command's environment\n * and nowhere else — not the build's, not the process the deploy runs in.\n * What `sst deploy` needs beyond them, the sandbox already passes: `PATH`\n * for node and the package manager, and `HOME`, under which SST keeps its\n * toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK\n * finds `~/.aws` for a profile. Its state — the Pulumi backend and the\n * passphrase — is in the stage's own account, reached with that credential.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\ttype AwsCredential,\n\tMissingCredential,\n} from '../../deploy/credentials';\nimport type { DeployResult } from '../../deploy/types';\nimport { GkmError } from '../../errors';\nimport { detectPackageManager, type PackageManager } from '../../init/utils';\nimport { CommandFailed } from '../../run';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { activeSandbox, type Sandbox } from '../../sandbox/sandbox';\nimport { appKey } from '../../workspace/derive';\nimport { defineTarget } from '../define';\nimport type { DeployPhaseContext, DeployTarget } from '../types';\nimport { checkHealth, healthUrl, SurfacesUnhealthy } from './health';\nimport { clearOutputs, readOutputs, surfaceUrls } from './outputs';\n\nexport { SurfacesUnhealthy } from './health';\nexport { SST_OUTPUTS_FILE, SstOutputsUnreadable } from './outputs';\n\n/** A cold build of every handler and site. */\nconst BUILD_TIMEOUT_MS = 30 * 60_000;\n/**\n * A first deploy creates CloudFront distributions and, with a database, a\n * VPC and an RDS instance — each of which alone can take a quarter of an hour.\n */\nconst DEPLOY_TIMEOUT_MS = 90 * 60_000;\n\n/** The workspace has no `sst.config.ts` for `sst deploy` to run. */\nexport class SstConfigNotFound extends GkmError {\n\tconstructor(readonly cwd: string) {\n\t\tsuper(\n\t\t\t`No sst.config.ts in ${cwd}. The sst target runs \\`sst deploy\\` at the workspace root: scaffold one with \\`gkm init --deploy sst\\` and copy its sst.config.ts, or deploy through another target with --target.`,\n\t\t);\n\t\tthis.name = 'SstConfigNotFound';\n\t}\n}\n\n/** What the phases hand on. */\nexport interface SstRun {\n\tsandbox: Sandbox;\n\tpm: PackageManager;\n\taws: AwsCredential;\n\t/** The apps SST deploys this run: `ctx.apps` without the skipped. */\n\tapps: string[];\n\t/** Each app's URL, from the deploy's outputs. */\n\turls: Record<string, string>;\n}\n\nexport interface SstTargetOptions {\n\t/** How often, and how patiently, `verify` asks each surface. */\n\thealth?: { attempts?: number; delayMs?: number; timeoutMs?: number };\n}\n\n/**\n * The project's own copy of `bin`, through its package manager — never one\n * `npx` would download, which would be code nobody installed.\n */\nexport function projectCommand(\n\tpm: PackageManager,\n\tbin: string,\n\targs: readonly string[],\n): [command: string, args: string[]] {\n\tswitch (pm) {\n\t\tcase 'pnpm':\n\t\t\treturn ['pnpm', ['exec', bin, ...args]];\n\t\tcase 'yarn':\n\t\t\treturn ['yarn', [bin, ...args]];\n\t\tcase 'bun':\n\t\t\treturn ['bunx', [bin, ...args]];\n\t\tcase 'npm':\n\t\t\treturn ['npx', ['--no-install', bin, ...args]];\n\t}\n}\n\n/**\n * The variables `credential` is to the AWS SDK and to SST.\n *\n * A profile is passed alone: given keys too, every SDK would take the keys.\n */\nexport function awsEnv(credential: AwsCredential): Record<string, string> {\n\tconst region: Record<string, string> = credential.region\n\t\t? { AWS_REGION: credential.region, AWS_DEFAULT_REGION: credential.region }\n\t\t: {};\n\tif ('profile' in credential) {\n\t\treturn { AWS_PROFILE: credential.profile, ...region };\n\t}\n\treturn {\n\t\tAWS_ACCESS_KEY_ID: credential.accessKeyId,\n\t\tAWS_SECRET_ACCESS_KEY: credential.secretAccessKey,\n\t\t...(credential.sessionToken\n\t\t\t? { AWS_SESSION_TOKEN: credential.sessionToken }\n\t\t\t: {}),\n\t\t...region,\n\t};\n}\n\n/**\n * `env` without any `AWS_*`, so a host sandbox that passes some cannot put\n * a second account beside the one the credential names.\n */\nfunction withoutAws(\n\tenv: Readonly<Record<string, string>>,\n): Record<string, string> {\n\treturn Object.fromEntries(\n\t\tObject.entries(env).filter(([name]) => !name.startsWith('AWS_')),\n\t);\n}\n\n/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */\nfunction kindsOf(manifest: ConstructManifest): Map<string, string> {\n\treturn new Map(\n\t\tObject.entries(manifest).map(([id, declaration]) => [\n\t\t\tappKey(id),\n\t\t\tdeclaration.kind,\n\t\t]),\n\t);\n}\n\nasync function exec(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n\t[command, args]: [string, string[]],\n\toptions: { env: Record<string, string>; timeoutMs: number },\n): Promise<void> {\n\tconst result = await run.sandbox.exec(command, args, {\n\t\tcwd: ctx.cwd,\n\t\tenv: options.env,\n\t\ttimeoutMs: options.timeoutMs,\n\t\toutput: ctx.childOutput,\n\t\tsignal: ctx.signal,\n\t});\n\tif (result.exitCode !== 0) {\n\t\tthrow new CommandFailed(\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tresult.exitCode,\n\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t);\n\t}\n}\n\n/** The `sst` target, with its health checks tuned — for tests and hosts. */\nexport function createSstTarget(\n\toptions: SstTargetOptions = {},\n): DeployTarget<undefined, SstRun> {\n\tconst health = {\n\t\tattempts: options.health?.attempts ?? 6,\n\t\tdelayMs: options.health?.delayMs ?? 5_000,\n\t\ttimeoutMs: options.health?.timeoutMs ?? 10_000,\n\t};\n\n\treturn defineTarget<undefined, SstRun>({\n\t\tname: 'sst',\n\t\truntime: 'aws',\n\t\t// SST keeps no previous release to return to; migrations run in the\n\t\t// stack, as `fromManifest` provisions the database; and nothing here\n\t\t// builds an image.\n\t\tcapabilities: { rollback: false, migrations: 'target', images: false },\n\t\tcredentials: ['aws'],\n\n\t\tasync validate(ctx) {\n\t\t\tif (!existsSync(join(ctx.cwd, 'sst.config.ts'))) {\n\t\t\t\tthrow new SstConfigNotFound(ctx.cwd);\n\t\t\t}\n\n\t\t\tconst aws = await ctx.credentials.get(\n\t\t\t\t{ kind: 'aws', stage: ctx.stage },\n\t\t\t\t{ signal: ctx.signal },\n\t\t\t);\n\t\t\tif (!aws) throw new MissingCredential('aws', ctx.stage);\n\t\t\tif (!('profile' in aws)) {\n\t\t\t\tctx.secrets.mask(aws.secretAccessKey);\n\t\t\t\tif (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);\n\t\t\t}\n\n\t\t\t// A mobile app ships through its own store's toolchain.\n\t\t\tfor (const app of ctx.apps) {\n\t\t\t\tif (ctx.workspace.apps[app]?.type === 'mobile') {\n\t\t\t\t\tctx.skip(app, 'mobile apps deploy through their own toolchain');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst skipped = new Set(ctx.skipped.map(({ app }) => app));\n\t\t\tconst apps = ctx.apps.filter((app) => !skipped.has(app));\n\n\t\t\tctx.logger.info(\n\t\t\t\t`\\n🚀 Deploying \"${ctx.workspace.name}\" to the \"${ctx.stage}\" stage with SST`,\n\t\t\t);\n\t\t\tctx.logger.info(\n\t\t\t\t` AWS: ${'profile' in aws ? `profile \"${aws.profile}\"` : 'access keys'}`,\n\t\t\t);\n\t\t\t// `sst deploy` takes the whole stack: there is no deploying one app.\n\t\t\tconst deployable = Object.values(ctx.workspace.apps).filter(\n\t\t\t\t(app) => app.type !== 'mobile',\n\t\t\t).length;\n\t\t\tif (apps.length < deployable) {\n\t\t\t\tctx.logger.warn(\n\t\t\t\t\t` sst deploy deploys every construct of the stage, not only ${apps.join(', ')}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),\n\t\t\t\tpm: detectPackageManager(ctx.cwd),\n\t\t\t\taws,\n\t\t\t\tapps,\n\t\t\t\turls: {},\n\t\t\t};\n\t\t},\n\n\t\tasync plan(ctx, run) {\n\t\t\tconst kinds = kindsOf(ctx.manifest);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'resource.planned',\n\t\t\t\t\tkey: `application:${app}`,\n\t\t\t\t\tresourceType: kinds.get(app) ?? 'application',\n\t\t\t\t\taction: 'ensure',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst [build, buildArgs] = buildCommand(ctx, run);\n\t\t\tconst [deploy, deployArgs] = deployCommand(ctx, run);\n\t\t\tctx.logger.info(` Would run: ${[build, ...buildArgs].join(' ')}`);\n\t\t\tctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(' ')}`);\n\t\t},\n\n\t\tasync build(ctx, run) {\n\t\t\tctx.logger.info('\\n📦 Building the manifest SST deploys');\n\t\t\t// No credential: the build runs the project's code and needs none.\n\t\t\tawait exec(ctx, run, buildCommand(ctx, run), {\n\t\t\t\tenv: { ...run.sandbox.env },\n\t\t\t\ttimeoutMs: BUILD_TIMEOUT_MS,\n\t\t\t});\n\t\t},\n\n\t\tasync release(ctx, run) {\n\t\t\tctx.logger.info(`\\n☁️ sst deploy --stage ${ctx.stage}`);\n\t\t\tawait clearOutputs(ctx.cwd);\n\t\t\tawait exec(ctx, run, deployCommand(ctx, run), {\n\t\t\t\tenv: { ...withoutAws(run.sandbox.env), ...awsEnv(run.aws) },\n\t\t\t\ttimeoutMs: DEPLOY_TIMEOUT_MS,\n\t\t\t});\n\n\t\t\trun.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'app.deployed',\n\t\t\t\t\tapp,\n\t\t\t\t\tapplicationId: ctx.name(app),\n\t\t\t\t\t// SST builds no image a registry holds.\n\t\t\t\t\timageRef: '',\n\t\t\t\t\turl: run.urls[app] ?? '',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tasync verify(ctx, run) {\n\t\t\tconst unhealthy: SurfacesUnhealthy['surfaces'][number][] = [];\n\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tconst base = run.urls[app];\n\t\t\t\tif (!base) {\n\t\t\t\t\tctx.logger.warn(\n\t\t\t\t\t\t` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A surface — a `rest-api` — is the backend app it derives.\n\t\t\t\tconst backend = ctx.workspace.apps[app]?.type === 'backend';\n\t\t\t\tconst url = healthUrl(base, backend ? '/health' : '/');\n\t\t\t\tconst answer = await checkHealth(app, url, {\n\t\t\t\t\t...health,\n\t\t\t\t\tsignal: ctx.signal,\n\t\t\t\t\temit: ctx.emit,\n\t\t\t\t});\n\t\t\t\tif (answer.healthy) {\n\t\t\t\t\tctx.logger.info(` ✓ ${app}: ${url}`);\n\t\t\t\t} else {\n\t\t\t\t\tunhealthy.push({\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t...(answer.status !== undefined ? { status: answer.status } : {}),\n\t\t\t\t\t\t...(answer.error ? { error: answer.error } : {}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unhealthy.length > 0) {\n\t\t\t\tthrow new SurfacesUnhealthy(ctx.stage, unhealthy);\n\t\t\t}\n\t\t},\n\n\t\tresult(ctx, run): DeployResult {\n\t\t\treturn {\n\t\t\t\tapps: run.apps.map((appName) => ({\n\t\t\t\t\tappName,\n\t\t\t\t\ttype: ctx.workspace.apps[appName]?.type ?? 'backend',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\t...(run.urls[appName] ? { url: run.urls[appName] } : {}),\n\t\t\t\t})),\n\t\t\t\tprojectId: '',\n\t\t\t\tenvironmentId: '',\n\t\t\t\tsuccessCount: ctx.dryRun ? 0 : run.apps.length,\n\t\t\t\tfailedCount: 0,\n\t\t\t\tstage: ctx.stage,\n\t\t\t\tidentity: ctx.identity.key,\n\t\t\t\ttag: ctx.tag,\n\t\t\t\tdryRun: ctx.dryRun,\n\t\t\t\tskipped: [...ctx.skipped],\n\t\t\t\turls: { ...run.urls },\n\t\t\t\tchanges: [],\n\t\t\t};\n\t\t},\n\t});\n}\n\nfunction buildCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'gkm', [\n\t\t'build',\n\t\t'--provider',\n\t\t'aws',\n\t\t'--stage',\n\t\tctx.stage,\n\t]);\n}\n\nfunction deployCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'sst', ['deploy', '--stage', ctx.stage]);\n}\n\nexport const sstTarget = createSstTarget();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyBA,IAAa,oBAAb,cAAuCA,eAAAA,SAAS;CAErC;CAEA;CAHV,YACC,OAEA,UAMC;EACD,MAAM,QAAQ,SAAS,KACrB,EAAE,KAAK,KAAK,QAAQ,YACpB,OAAO,IAAI,IAAI,IAAI,KAAK,UAAU,SAAS,aAC7C;EACA,MACC,QAAQ,MAAM,4BAA4B,SAAS,WAAW,IAAI,mBAAmB,cAAc,wBAAwB,MAAM,KAAK,IAAI,EAAE,0DAC7I;EAfS,KAAA,QAAA;EAEA,KAAA,WAAA;EAcT,KAAK,OAAO;CACb;AACD;;AAGA,SAAgB,UAAU,MAAc,MAAsB;CAC7D,MAAM,OAAO,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,KAAK;CACjD,OAAO,IAAI,IAAI,KAAK,QAAQ,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AACxD;;;;;AAMA,eAAsB,YACrB,KACA,KACA,SACiE;CACjE,IAAI,OAA8D,EACjE,SAAS,MACV;CACA,KAAK,IAAI,UAAU,GAAG,WAAW,QAAQ,UAAU,WAAW;EAC7D,QAAQ,OAAO,eAAe;EAC9B,IAAI;GACH,MAAM,WAAW,MAAM,MAAM,KAAK;IACjC,UAAU;IACV,QAAQ,YAAY,IAAI,CACvB,QAAQ,QACR,YAAY,QAAQ,QAAQ,SAAS,CACtC,CAAC;GACF,CAAC;GAED,MAAM,SAAS,YAAY,CAAC,CAAC,YAAY,KAAA,CAAS;GAClD,OAAO;IAAE,SAAS,SAAS;IAAI,QAAQ,SAAS;GAAO;EACxD,SAAS,OAAO;GAEf,QAAQ,OAAO,eAAe;GAC9B,OAAO;IACN,SAAS;IACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAC7D;EACD;EACA,QAAQ,KAAK;GACZ,MAAM;GACN;GACA;GACA,SAAS,KAAK;GACd,GAAI,KAAK,WAAW,KAAA,IAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D;EACD,CAAC;EACD,IAAI,KAAK,SAAS,OAAO;EACzB,IAAI,UAAU,QAAQ,UAAU,MAAM,KAAK,QAAQ,SAAS,QAAQ,MAAM;CAC3E;CACA,OAAO;AACR;AAEA,SAAS,KAAK,IAAY,QAAoC;CAC7D,IAAI,MAAM,GAAG,OAAO,QAAQ,QAAQ;CACpC,OAAO,IAAI,SAAS,SAAS,WAAW;EACvC,MAAM,QAAQ,iBAAiB;GAC9B,OAAO,oBAAoB,SAAS,IAAI;GACxC,QAAQ;EACT,GAAG,EAAE;EACL,MAAM,aAAa;GAClB,aAAa,KAAK;GAClB,OAAO,OAAO,MAAM;EACrB;EACA,OAAO,iBAAiB,SAAS,MAAM,EAAE,MAAM,KAAK,CAAC;CACtD,CAAC;AACF;;;;;;;;;;;;;;AC/FA,MAAa,oBAAA,GAAmBC,UAAAA,KAAAA,CAAK,QAAQ,cAAc;;AAG3D,IAAa,uBAAb,cAA0CC,eAAAA,SAAS;CAExC;CACA;CAFV,YACC,MACA,QACC;EACD,MACC,mCAAmC,KAAK,IAAI,OAAO,kFACpD;EALS,KAAA,OAAA;EACA,KAAA,SAAA;EAKT,KAAK,OAAO;CACb;AACD;;;;;AAMA,eAAsB,aAAa,KAA4B;CAC9D,OAAA,GAAMC,iBAAAA,GAAAA,EAAAA,GAAGF,UAAAA,KAAAA,CAAK,KAAK,gBAAgB,GAAG,EAAE,OAAO,KAAK,CAAC;AACtD;;AAGA,eAAsB,YAAY,KAA+B;CAChE,MAAM,QAAA,GAAOA,UAAAA,KAAAA,CAAK,KAAK,gBAAgB;CACvC,IAAI,EAAA,GAACG,QAAAA,WAAAA,CAAW,IAAI,GAAG,OAAO,CAAC;CAC/B,IAAI;EACH,OAAO,KAAK,MAAM,OAAA,GAAMC,iBAAAA,SAAAA,CAAS,MAAM,MAAM,CAAC;CAC/C,SAAS,OAAO;EACf,MAAM,IAAI,qBACT,MACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACtD;CACD;AACD;;AAGA,SAAS,OACR,OACA,OAAiB,CAAC,GAClB,QAA2C,CAAC,GACR;CACpC,IAAI,OAAO,UAAU,UAChB;MAAA,UAAU,KAAK,GAAG,MAAM,KAAK;GAAE;GAAM,KAAK;EAAM,CAAC;CAAA,OAC/C,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GACpE,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC9C,OAAO,OAAO,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK;CAGrC,OAAO;AACR;AAEA,SAAS,UAAU,OAAwB;CAC1C,IAAI;EACH,MAAM,EAAE,aAAa,IAAI,IAAI,KAAK;EAClC,OAAO,aAAa,WAAW,aAAa;CAC7C,QAAQ;EACP,OAAO;CACR;AACD;;;;;;;AAQA,SAAS,QAAQ,MAA0B;CAC1C,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,GAAG;EAC1C,MAAM,QAAA,GAAOC,oBAAAA,UAAAA,CAAU,OAAO;EAC9B,MAAM,KAAK,IAAI;EACf,MAAM,OAAO,KAAK,QAAQ,UAAU,EAAE;EACtC,IAAI,MAAM;GACT,MAAM,KAAK,IAAI;GACf;EACD;CACD;CACA,OAAO;AACR;;;;;AAMA,SAAgB,YACf,SACA,MACyB;CACzB,MAAM,QAAQ,OAAO,OAAO;CAC5B,MAAM,OAA+B,CAAC;CACtC,KAAK,MAAM,OAAO,MAAM;EAEvB,MAAM,QAAQ,MAAM,MAAM,EAAE,WAAW,QAAQ,IAAI,CAAC,CAAC,OAAO,GAAG;EAC/D,MAAM,QAAQ,MAAM,MAAM,EAAE,WAAW,QAAQ,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC;EAClE,MAAM,QAAQ,SAAS;EACvB,IAAI,OAAO,KAAK,OAAO,MAAM;CAC9B;CACA,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3EA,MAAM,mBAAmB;;;;;AAKzB,MAAM,oBAAoB;;AAG1B,IAAa,oBAAb,cAAuCC,eAAAA,SAAS;CAC1B;CAArB,YAAY,KAAsB;EACjC,MACC,uBAAuB,IAAI,oLAC5B;EAHoB,KAAA,MAAA;EAIpB,KAAK,OAAO;CACb;AACD;;;;;AAsBA,SAAgB,eACf,IACA,KACA,MACoC;CACpC,QAAQ,IAAR;EACC,KAAK,QACJ,OAAO,CAAC,QAAQ;GAAC;GAAQ;GAAK,GAAG;EAAI,CAAC;EACvC,KAAK,QACJ,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;EAC/B,KAAK,OACJ,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;EAC/B,KAAK,OACJ,OAAO,CAAC,OAAO;GAAC;GAAgB;GAAK,GAAG;EAAI,CAAC;CAC/C;AACD;;;;;;AAOA,SAAgB,OAAO,YAAmD;CACzE,MAAM,SAAiC,WAAW,SAC/C;EAAE,YAAY,WAAW;EAAQ,oBAAoB,WAAW;CAAO,IACvE,CAAC;CACJ,IAAI,aAAa,YAChB,OAAO;EAAE,aAAa,WAAW;EAAS,GAAG;CAAO;CAErD,OAAO;EACN,mBAAmB,WAAW;EAC9B,uBAAuB,WAAW;EAClC,GAAI,WAAW,eACZ,EAAE,mBAAmB,WAAW,aAAa,IAC7C,CAAC;EACJ,GAAG;CACJ;AACD;;;;;AAMA,SAAS,WACR,KACyB;CACzB,OAAO,OAAO,YACb,OAAO,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,WAAW,MAAM,CAAC,CAChE;AACD;;AAGA,SAAS,QAAQ,UAAkD;CAClE,OAAO,IAAI,IACV,OAAO,QAAQ,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,iBAAiB,CACnDC,eAAAA,OAAO,EAAE,GACT,YAAY,IACb,CAAC,CACF;AACD;AAEA,eAAe,KACd,KACA,KACA,CAAC,SAAS,OACV,SACgB;CAChB,MAAM,SAAS,MAAM,IAAI,QAAQ,KAAK,SAAS,MAAM;EACpD,KAAK,IAAI;EACT,KAAK,QAAQ;EACb,WAAW,QAAQ;EACnB,QAAQ,IAAI;EACZ,QAAQ,IAAI;CACb,CAAC;CACD,IAAI,OAAO,aAAa,GACvB,MAAM,IAAIC,oBAAAA,cACT,SACA,MACA,OAAO,UACP,OAAO,MACR;AAEF;;AAGA,SAAgB,gBACf,UAA4B,CAAC,GACK;CAClC,MAAM,SAAS;EACd,UAAU,QAAQ,QAAQ,YAAY;EACtC,SAAS,QAAQ,QAAQ,WAAW;EACpC,WAAW,QAAQ,QAAQ,aAAa;CACzC;CAEA,OAAOC,eAAAA,aAAgC;EACtC,MAAM;EACN,SAAS;EAIT,cAAc;GAAE,UAAU;GAAO,YAAY;GAAU,QAAQ;EAAM;EACrE,aAAa,CAAC,KAAK;EAEnB,MAAM,SAAS,KAAK;GACnB,IAAI,EAAA,GAACC,QAAAA,WAAAA,EAAAA,GAAWC,UAAAA,KAAAA,CAAK,IAAI,KAAK,eAAe,CAAC,GAC7C,MAAM,IAAI,kBAAkB,IAAI,GAAG;GAGpC,MAAM,MAAM,MAAM,IAAI,YAAY,IACjC;IAAE,MAAM;IAAO,OAAO,IAAI;GAAM,GAChC,EAAE,QAAQ,IAAI,OAAO,CACtB;GACA,IAAI,CAAC,KAAK,MAAM,IAAIC,oBAAAA,kBAAkB,OAAO,IAAI,KAAK;GACtD,IAAI,EAAE,aAAa,MAAM;IACxB,IAAI,QAAQ,KAAK,IAAI,eAAe;IACpC,IAAI,IAAI,cAAc,IAAI,QAAQ,KAAK,IAAI,YAAY;GACxD;GAGA,KAAK,MAAM,OAAO,IAAI,MACrB,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,SAAS,UACrC,IAAI,KAAK,KAAK,gDAAgD;GAGhE,MAAM,UAAU,IAAI,IAAI,IAAI,QAAQ,KAAK,EAAE,UAAU,GAAG,CAAC;GACzD,MAAM,OAAO,IAAI,KAAK,QAAQ,QAAQ,CAAC,QAAQ,IAAI,GAAG,CAAC;GAEvD,IAAI,OAAO,KACV,mBAAmB,IAAI,UAAU,KAAK,YAAY,IAAI,MAAM,iBAC7D;GACA,IAAI,OAAO,KACV,WAAW,aAAa,MAAM,YAAY,IAAI,QAAQ,KAAK,eAC5D;GAEA,MAAM,aAAa,OAAO,OAAO,IAAI,UAAU,IAAI,CAAC,CAAC,QACnD,QAAQ,IAAI,SAAS,QACvB,CAAC,CAAC;GACF,IAAI,KAAK,SAAS,YACjB,IAAI,OAAO,KACV,gEAAgE,KAAK,KAAK,IAAI,EAAE,EACjF;GAGD,OAAO;IACN,SAASC,gBAAAA,cAAc,KAAK,IAAIC,cAAAA,aAAa,EAAE,MAAM,IAAI,IAAI,CAAC;IAC9D,IAAIC,cAAAA,qBAAqB,IAAI,GAAG;IAChC;IACA;IACA,MAAM,CAAC;GACR;EACD;EAEA,MAAM,KAAK,KAAK,KAAK;GACpB,MAAM,QAAQ,QAAQ,IAAI,QAAQ;GAClC,KAAK,MAAM,OAAO,IAAI,MACrB,IAAI,KAAK;IACR,MAAM;IACN,KAAK,eAAe;IACpB,cAAc,MAAM,IAAI,GAAG,KAAK;IAChC,QAAQ;GACT,CAAC;GAEF,MAAM,CAAC,OAAO,aAAa,aAAa,KAAK,GAAG;GAChD,MAAM,CAAC,QAAQ,cAAc,cAAc,KAAK,GAAG;GACnD,IAAI,OAAO,KAAK,iBAAiB,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,KAAK,GAAG,GAAG;GAClE,IAAI,OAAO,KAAK,iBAAiB,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,KAAK,GAAG,GAAG;EACrE;EAEA,MAAM,MAAM,KAAK,KAAK;GACrB,IAAI,OAAO,KAAK,wCAAwC;GAExD,MAAM,KAAK,KAAK,KAAK,aAAa,KAAK,GAAG,GAAG;IAC5C,KAAK,EAAE,GAAG,IAAI,QAAQ,IAAI;IAC1B,WAAW;GACZ,CAAC;EACF;EAEA,MAAM,QAAQ,KAAK,KAAK;GACvB,IAAI,OAAO,KAAK,4BAA4B,IAAI,OAAO;GACvD,MAAM,aAAa,IAAI,GAAG;GAC1B,MAAM,KAAK,KAAK,KAAK,cAAc,KAAK,GAAG,GAAG;IAC7C,KAAK;KAAE,GAAG,WAAW,IAAI,QAAQ,GAAG;KAAG,GAAG,OAAO,IAAI,GAAG;IAAE;IAC1D,WAAW;GACZ,CAAC;GAED,IAAI,OAAO,YAAY,MAAM,YAAY,IAAI,GAAG,GAAG,IAAI,IAAI;GAC3D,KAAK,MAAM,OAAO,IAAI,MACrB,IAAI,KAAK;IACR,MAAM;IACN;IACA,eAAe,IAAI,KAAK,GAAG;IAE3B,UAAU;IACV,KAAK,IAAI,KAAK,QAAQ;GACvB,CAAC;EAEH;EAEA,MAAM,OAAO,KAAK,KAAK;GACtB,MAAM,YAAqD,CAAC;GAE5D,KAAK,MAAM,OAAO,IAAI,MAAM;IAC3B,MAAM,OAAO,IAAI,KAAK;IACtB,IAAI,CAAC,MAAM;KACV,IAAI,OAAO,KACV,mBAAmB,IAAI,sFAAsF,IAAI,oCAClH;KACA;IACD;IAGA,MAAM,MAAM,UAAU,MADN,IAAI,UAAU,KAAK,IAAI,EAAE,SAAS,YACZ,YAAY,GAAG;IACrD,MAAM,SAAS,MAAM,YAAY,KAAK,KAAK;KAC1C,GAAG;KACH,QAAQ,IAAI;KACZ,MAAM,IAAI;IACX,CAAC;IACD,IAAI,OAAO,SACV,IAAI,OAAO,KAAK,QAAQ,IAAI,IAAI,KAAK;SAErC,UAAU,KAAK;KACd;KACA;KACA,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;KAC/D,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;IAC/C,CAAC;GAEH;GAEA,IAAI,UAAU,SAAS,GACtB,MAAM,IAAI,kBAAkB,IAAI,OAAO,SAAS;EAElD;EAEA,OAAO,KAAK,KAAmB;GAC9B,OAAO;IACN,MAAM,IAAI,KAAK,KAAK,aAAa;KAChC;KACA,MAAM,IAAI,UAAU,KAAK,QAAQ,EAAE,QAAQ;KAC3C,SAAS;KACT,GAAI,IAAI,KAAK,WAAW,EAAE,KAAK,IAAI,KAAK,SAAS,IAAI,CAAC;IACvD,EAAE;IACF,WAAW;IACX,eAAe;IACf,cAAc,IAAI,SAAS,IAAI,IAAI,KAAK;IACxC,aAAa;IACb,OAAO,IAAI;IACX,UAAU,IAAI,SAAS;IACvB,KAAK,IAAI;IACT,QAAQ,IAAI;IACZ,SAAS,CAAC,GAAG,IAAI,OAAO;IACxB,MAAM,EAAE,GAAG,IAAI,KAAK;IACpB,SAAS,CAAC;GACX;EACD;CACD,CAAC;AACF;AAEA,SAAS,aACR,KACA,KACqB;CACrB,OAAO,eAAe,IAAI,IAAI,OAAO;EACpC;EACA;EACA;EACA;EACA,IAAI;CACL,CAAC;AACF;AAEA,SAAS,cACR,KACA,KACqB;CACrB,OAAO,eAAe,IAAI,IAAI,OAAO;EAAC;EAAU;EAAW,IAAI;CAAK,CAAC;AACtE;AAEA,MAAa,YAAY,gBAAgB"}
1
+ {"version":3,"file":"sst-DGuHDxVU.cjs","names":["GkmError","join","GkmError","rm","existsSync","readFile","kebabCase","GkmError","appKey","CommandFailed","defineTarget","existsSync","join","MissingCredential","activeSandbox","LocalSandbox","detectPackageManager"],"sources":["../src/target/sst/health.ts","../src/target/sst/outputs.ts","../src/target/sst/index.ts"],"sourcesContent":["/**\n * Whether a released surface answers.\n *\n * The paths are the ones the local stack's healthchecks use\n * (`reconcile/apps.ts`): an API's `/health`, a site's `/`. A surface is\n * asked a few times, because a fresh deploy can take a moment to answer — a\n * Lambda's first start, a distribution still settling — and healthy means a\n * 2xx, after redirects.\n */\n\nimport { GkmError } from '../../errors';\nimport type { TargetEvent } from '../types';\n\nexport interface HealthCheckOptions {\n\t/** How many times a surface is asked before it counts as down. */\n\tattempts: number;\n\t/** The wait between two attempts. */\n\tdelayMs: number;\n\t/** How long one request may take. */\n\ttimeoutMs: number;\n\tsignal: AbortSignal;\n\temit: (event: TargetEvent) => void;\n}\n\n/** Surfaces that never answered healthy. */\nexport class SurfacesUnhealthy extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** Each surface that failed, with the last thing it answered. */\n\t\treadonly surfaces: readonly {\n\t\t\tapp: string;\n\t\t\turl: string;\n\t\t\tstatus?: number;\n\t\t\terror?: string;\n\t\t}[],\n\t) {\n\t\tconst lines = surfaces.map(\n\t\t\t({ app, url, status, error }) =>\n\t\t\t\t` - ${app}: ${url} → ${status ?? error ?? 'no answer'}`,\n\t\t);\n\t\tsuper(\n\t\t\t`The \"${stage}\" stage was deployed, but ${surfaces.length === 1 ? 'a surface does' : 'surfaces do'} not answer healthy:\\n${lines.join('\\n')}\\nCheck its logs in CloudWatch, fix it, and deploy again.`,\n\t\t);\n\t\tthis.name = 'SurfacesUnhealthy';\n\t}\n}\n\n/** `path` under `base`, keeping any path `base` already has. */\nexport function healthUrl(base: string, path: string): string {\n\tconst root = base.endsWith('/') ? base : `${base}/`;\n\treturn new URL(path.replace(/^\\//, ''), root).toString();\n}\n\n/**\n * Ask `url` until it answers 2xx or the attempts run out, emitting\n * `health.checked` for each. Resolves with the last answer.\n */\nexport async function checkHealth(\n\tapp: string,\n\turl: string,\n\toptions: HealthCheckOptions,\n): Promise<{ healthy: boolean; status?: number; error?: string }> {\n\tlet last: { healthy: boolean; status?: number; error?: string } = {\n\t\thealthy: false,\n\t};\n\tfor (let attempt = 1; attempt <= options.attempts; attempt++) {\n\t\toptions.signal.throwIfAborted();\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tredirect: 'follow',\n\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\toptions.signal,\n\t\t\t\t\tAbortSignal.timeout(options.timeoutMs),\n\t\t\t\t]),\n\t\t\t});\n\t\t\t// Drained, so the connection is not held open by an unread body.\n\t\t\tawait response.arrayBuffer().catch(() => undefined);\n\t\t\tlast = { healthy: response.ok, status: response.status };\n\t\t} catch (error) {\n\t\t\t// The run being stopped is not the surface being down.\n\t\t\toptions.signal.throwIfAborted();\n\t\t\tlast = {\n\t\t\t\thealthy: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t\toptions.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp,\n\t\t\turl,\n\t\t\thealthy: last.healthy,\n\t\t\t...(last.status !== undefined ? { status: last.status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (last.healthy) return last;\n\t\tif (attempt < options.attempts) await wait(options.delayMs, options.signal);\n\t}\n\treturn last;\n}\n\nfunction wait(ms: number, signal: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal.removeEventListener('abort', stop);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst stop = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal.reason);\n\t\t};\n\t\tsignal.addEventListener('abort', stop, { once: true });\n\t});\n}\n","/**\n * The surface URLs an `sst deploy` reports.\n *\n * SST writes whatever `run()` in `sst.config.ts` returns to\n * `.sst/outputs.json` after every successful deploy — `{\"Api\": \"https://…\"}`.\n * What `run()` returns is the project's to write, so this reads it leniently:\n * nested objects are walked, anything that is not an http(s) URL is ignored,\n * and an output names a surface by its id in any casing, with or without a\n * `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { GkmError } from '../../errors';\n\n/** Where SST leaves the last successful deploy's outputs, under the project. */\nexport const SST_OUTPUTS_FILE = join('.sst', 'outputs.json');\n\n/** `.sst/outputs.json` is there, and is not JSON. */\nexport class SstOutputsUnreadable extends GkmError {\n\tconstructor(\n\t\treadonly path: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \\`sst deploy\\`; delete it and deploy again.`,\n\t\t);\n\t\tthis.name = 'SstOutputsUnreadable';\n\t}\n}\n\n/**\n * Remove what an earlier deploy wrote, so the outputs read after this one\n * are this one's — not another stage's, deployed from the same checkout.\n */\nexport async function clearOutputs(cwd: string): Promise<void> {\n\tawait rm(join(cwd, SST_OUTPUTS_FILE), { force: true });\n}\n\n/** The deploy's outputs, or `{}` when it wrote none. */\nexport async function readOutputs(cwd: string): Promise<unknown> {\n\tconst path = join(cwd, SST_OUTPUTS_FILE);\n\tif (!existsSync(path)) return {};\n\ttry {\n\t\treturn JSON.parse(await readFile(path, 'utf8'));\n\t} catch (error) {\n\t\tthrow new SstOutputsUnreadable(\n\t\t\tpath,\n\t\t\terror instanceof Error ? error.message : String(error),\n\t\t);\n\t}\n}\n\n/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */\nfunction urlsIn(\n\tvalue: unknown,\n\tpath: string[] = [],\n\tfound: { path: string[]; url: string }[] = [],\n): { path: string[]; url: string }[] {\n\tif (typeof value === 'string') {\n\t\tif (isHttpUrl(value)) found.push({ path, url: value });\n\t} else if (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\turlsIn(child, [...path, key], found);\n\t\t}\n\t}\n\treturn found;\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst { protocol } = new URL(value);\n\t\treturn protocol === 'http:' || protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * The app an output's key path names, kebab-cased as app keys are: its last\n * segment, without a `url` suffix — or its parent's, when the last segment\n * is only `url`. Exact names are tried first, so an app called `api-url`\n * still finds `ApiUrl`.\n */\nfunction namesOf(path: string[]): string[] {\n\tconst names: string[] = [];\n\tfor (const segment of [...path].reverse()) {\n\t\tconst name = kebabCase(segment);\n\t\tnames.push(name);\n\t\tconst bare = name.replace(/-?url$/, '');\n\t\tif (bare) {\n\t\t\tnames.push(bare);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn names;\n}\n\n/**\n * Each app's URL from the outputs, for the apps given. An app no output\n * names is left out.\n */\nexport function surfaceUrls(\n\toutputs: unknown,\n\tapps: readonly string[],\n): Record<string, string> {\n\tconst found = urlsIn(outputs);\n\tconst urls: Record<string, string> = {};\n\tfor (const app of apps) {\n\t\t// An exact name beats a stripped one, wherever each is in the file.\n\t\tconst exact = found.find(({ path }) => namesOf(path)[0] === app);\n\t\tconst loose = found.find(({ path }) => namesOf(path).includes(app));\n\t\tconst match = exact ?? loose;\n\t\tif (match) urls[app] = match.url;\n\t}\n\treturn urls;\n}\n","/**\n * The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`\n * provisions it, and the surfaces SST reports are health-checked.\n *\n * `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads\n * `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What\n * the target adds is the run around the two commands — the lock, the events,\n * verification, and credentials kept where they belong.\n *\n * Both commands run in the sandbox: the build executes the project's code,\n * and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second\n * needs AWS, so the AWS credential goes into that one command's environment\n * and nowhere else — not the build's, not the process the deploy runs in.\n * What `sst deploy` needs beyond them, the sandbox already passes: `PATH`\n * for node and the package manager, and `HOME`, under which SST keeps its\n * toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK\n * finds `~/.aws` for a profile. Its state — the Pulumi backend and the\n * passphrase — is in the stage's own account, reached with that credential.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\ttype AwsCredential,\n\tMissingCredential,\n} from '../../deploy/credentials';\nimport type { DeployResult } from '../../deploy/types';\nimport { GkmError } from '../../errors';\nimport { detectPackageManager, type PackageManager } from '../../init/utils';\nimport { CommandFailed } from '../../run';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { activeSandbox, type Sandbox } from '../../sandbox/sandbox';\nimport { appKey } from '../../workspace/derive';\nimport { defineTarget } from '../define';\nimport type { DeployPhaseContext, DeployTarget } from '../types';\nimport { checkHealth, healthUrl, SurfacesUnhealthy } from './health';\nimport { clearOutputs, readOutputs, surfaceUrls } from './outputs';\n\nexport { SurfacesUnhealthy } from './health';\nexport { SST_OUTPUTS_FILE, SstOutputsUnreadable } from './outputs';\n\n/** A cold build of every handler and site. */\nconst BUILD_TIMEOUT_MS = 30 * 60_000;\n/**\n * A first deploy creates CloudFront distributions and, with a database, a\n * VPC and an RDS instance — each of which alone can take a quarter of an hour.\n */\nconst DEPLOY_TIMEOUT_MS = 90 * 60_000;\n\n/** The workspace has no `sst.config.ts` for `sst deploy` to run. */\nexport class SstConfigNotFound extends GkmError {\n\tconstructor(readonly cwd: string) {\n\t\tsuper(\n\t\t\t`No sst.config.ts in ${cwd}. The sst target runs \\`sst deploy\\` at the workspace root: scaffold one with \\`gkm init --deploy sst\\` and copy its sst.config.ts, or deploy through another target with --target.`,\n\t\t);\n\t\tthis.name = 'SstConfigNotFound';\n\t}\n}\n\n/** What the phases hand on. */\nexport interface SstRun {\n\tsandbox: Sandbox;\n\tpm: PackageManager;\n\taws: AwsCredential;\n\t/** The apps SST deploys this run: `ctx.apps` without the skipped. */\n\tapps: string[];\n\t/** Each app's URL, from the deploy's outputs. */\n\turls: Record<string, string>;\n}\n\nexport interface SstTargetOptions {\n\t/** How often, and how patiently, `verify` asks each surface. */\n\thealth?: { attempts?: number; delayMs?: number; timeoutMs?: number };\n}\n\n/**\n * The project's own copy of `bin`, through its package manager — never one\n * `npx` would download, which would be code nobody installed.\n */\nexport function projectCommand(\n\tpm: PackageManager,\n\tbin: string,\n\targs: readonly string[],\n): [command: string, args: string[]] {\n\tswitch (pm) {\n\t\tcase 'pnpm':\n\t\t\treturn ['pnpm', ['exec', bin, ...args]];\n\t\tcase 'yarn':\n\t\t\treturn ['yarn', [bin, ...args]];\n\t\tcase 'bun':\n\t\t\treturn ['bunx', [bin, ...args]];\n\t\tcase 'npm':\n\t\t\treturn ['npx', ['--no-install', bin, ...args]];\n\t}\n}\n\n/**\n * The variables `credential` is to the AWS SDK and to SST.\n *\n * A profile is passed alone: given keys too, every SDK would take the keys.\n */\nexport function awsEnv(credential: AwsCredential): Record<string, string> {\n\tconst region: Record<string, string> = credential.region\n\t\t? { AWS_REGION: credential.region, AWS_DEFAULT_REGION: credential.region }\n\t\t: {};\n\tif ('profile' in credential) {\n\t\treturn { AWS_PROFILE: credential.profile, ...region };\n\t}\n\treturn {\n\t\tAWS_ACCESS_KEY_ID: credential.accessKeyId,\n\t\tAWS_SECRET_ACCESS_KEY: credential.secretAccessKey,\n\t\t...(credential.sessionToken\n\t\t\t? { AWS_SESSION_TOKEN: credential.sessionToken }\n\t\t\t: {}),\n\t\t...region,\n\t};\n}\n\n/**\n * `env` without any `AWS_*`, so a host sandbox that passes some cannot put\n * a second account beside the one the credential names.\n */\nfunction withoutAws(\n\tenv: Readonly<Record<string, string>>,\n): Record<string, string> {\n\treturn Object.fromEntries(\n\t\tObject.entries(env).filter(([name]) => !name.startsWith('AWS_')),\n\t);\n}\n\n/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */\nfunction kindsOf(manifest: ConstructManifest): Map<string, string> {\n\treturn new Map(\n\t\tObject.entries(manifest).map(([id, declaration]) => [\n\t\t\tappKey(id),\n\t\t\tdeclaration.kind,\n\t\t]),\n\t);\n}\n\nasync function exec(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n\t[command, args]: [string, string[]],\n\toptions: { env: Record<string, string>; timeoutMs: number },\n): Promise<void> {\n\tconst result = await run.sandbox.exec(command, args, {\n\t\tcwd: ctx.cwd,\n\t\tenv: options.env,\n\t\ttimeoutMs: options.timeoutMs,\n\t\toutput: ctx.childOutput,\n\t\tsignal: ctx.signal,\n\t});\n\tif (result.exitCode !== 0) {\n\t\tthrow new CommandFailed(\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tresult.exitCode,\n\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t);\n\t}\n}\n\n/** The `sst` target, with its health checks tuned — for tests and hosts. */\nexport function createSstTarget(\n\toptions: SstTargetOptions = {},\n): DeployTarget<undefined, SstRun> {\n\tconst health = {\n\t\tattempts: options.health?.attempts ?? 6,\n\t\tdelayMs: options.health?.delayMs ?? 5_000,\n\t\ttimeoutMs: options.health?.timeoutMs ?? 10_000,\n\t};\n\n\treturn defineTarget<undefined, SstRun>({\n\t\tname: 'sst',\n\t\truntime: 'aws',\n\t\t// SST keeps no previous release to return to; migrations run in the\n\t\t// stack, as `fromManifest` provisions the database; and nothing here\n\t\t// builds an image.\n\t\tcapabilities: { rollback: false, migrations: 'target', images: false },\n\t\tcredentials: ['aws'],\n\n\t\tasync validate(ctx) {\n\t\t\tif (!existsSync(join(ctx.cwd, 'sst.config.ts'))) {\n\t\t\t\tthrow new SstConfigNotFound(ctx.cwd);\n\t\t\t}\n\n\t\t\tconst aws = await ctx.credentials.get(\n\t\t\t\t{ kind: 'aws', stage: ctx.stage },\n\t\t\t\t{ signal: ctx.signal },\n\t\t\t);\n\t\t\tif (!aws) throw new MissingCredential('aws', ctx.stage);\n\t\t\tif (!('profile' in aws)) {\n\t\t\t\tctx.secrets.mask(aws.secretAccessKey);\n\t\t\t\tif (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);\n\t\t\t}\n\n\t\t\t// A mobile app ships through its own store's toolchain.\n\t\t\tfor (const app of ctx.apps) {\n\t\t\t\tif (ctx.workspace.apps[app]?.type === 'mobile') {\n\t\t\t\t\tctx.skip(app, 'mobile apps deploy through their own toolchain');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst skipped = new Set(ctx.skipped.map(({ app }) => app));\n\t\t\tconst apps = ctx.apps.filter((app) => !skipped.has(app));\n\n\t\t\tctx.logger.info(\n\t\t\t\t`\\n🚀 Deploying \"${ctx.workspace.name}\" to the \"${ctx.stage}\" stage with SST`,\n\t\t\t);\n\t\t\tctx.logger.info(\n\t\t\t\t` AWS: ${'profile' in aws ? `profile \"${aws.profile}\"` : 'access keys'}`,\n\t\t\t);\n\t\t\t// `sst deploy` takes the whole stack: there is no deploying one app.\n\t\t\tconst deployable = Object.values(ctx.workspace.apps).filter(\n\t\t\t\t(app) => app.type !== 'mobile',\n\t\t\t).length;\n\t\t\tif (apps.length < deployable) {\n\t\t\t\tctx.logger.warn(\n\t\t\t\t\t` sst deploy deploys every construct of the stage, not only ${apps.join(', ')}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),\n\t\t\t\tpm: detectPackageManager(ctx.cwd),\n\t\t\t\taws,\n\t\t\t\tapps,\n\t\t\t\turls: {},\n\t\t\t};\n\t\t},\n\n\t\tasync plan(ctx, run) {\n\t\t\tconst kinds = kindsOf(ctx.manifest);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'resource.planned',\n\t\t\t\t\tkey: `application:${app}`,\n\t\t\t\t\tresourceType: kinds.get(app) ?? 'application',\n\t\t\t\t\taction: 'ensure',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst [build, buildArgs] = buildCommand(ctx, run);\n\t\t\tconst [deploy, deployArgs] = deployCommand(ctx, run);\n\t\t\tctx.logger.info(` Would run: ${[build, ...buildArgs].join(' ')}`);\n\t\t\tctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(' ')}`);\n\t\t},\n\n\t\tasync build(ctx, run) {\n\t\t\tctx.logger.info('\\n📦 Building the manifest SST deploys');\n\t\t\t// No credential: the build runs the project's code and needs none.\n\t\t\tawait exec(ctx, run, buildCommand(ctx, run), {\n\t\t\t\tenv: { ...run.sandbox.env },\n\t\t\t\ttimeoutMs: BUILD_TIMEOUT_MS,\n\t\t\t});\n\t\t},\n\n\t\tasync release(ctx, run) {\n\t\t\tctx.logger.info(`\\n☁️ sst deploy --stage ${ctx.stage}`);\n\t\t\tawait clearOutputs(ctx.cwd);\n\t\t\tawait exec(ctx, run, deployCommand(ctx, run), {\n\t\t\t\tenv: { ...withoutAws(run.sandbox.env), ...awsEnv(run.aws) },\n\t\t\t\ttimeoutMs: DEPLOY_TIMEOUT_MS,\n\t\t\t});\n\n\t\t\trun.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'app.deployed',\n\t\t\t\t\tapp,\n\t\t\t\t\tapplicationId: ctx.name(app),\n\t\t\t\t\t// SST builds no image a registry holds.\n\t\t\t\t\timageRef: '',\n\t\t\t\t\turl: run.urls[app] ?? '',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tasync verify(ctx, run) {\n\t\t\tconst unhealthy: SurfacesUnhealthy['surfaces'][number][] = [];\n\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tconst base = run.urls[app];\n\t\t\t\tif (!base) {\n\t\t\t\t\tctx.logger.warn(\n\t\t\t\t\t\t` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A surface — a `rest-api` — is the backend app it derives.\n\t\t\t\tconst backend = ctx.workspace.apps[app]?.type === 'backend';\n\t\t\t\tconst url = healthUrl(base, backend ? '/health' : '/');\n\t\t\t\tconst answer = await checkHealth(app, url, {\n\t\t\t\t\t...health,\n\t\t\t\t\tsignal: ctx.signal,\n\t\t\t\t\temit: ctx.emit,\n\t\t\t\t});\n\t\t\t\tif (answer.healthy) {\n\t\t\t\t\tctx.logger.info(` ✓ ${app}: ${url}`);\n\t\t\t\t} else {\n\t\t\t\t\tunhealthy.push({\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t...(answer.status !== undefined ? { status: answer.status } : {}),\n\t\t\t\t\t\t...(answer.error ? { error: answer.error } : {}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unhealthy.length > 0) {\n\t\t\t\tthrow new SurfacesUnhealthy(ctx.stage, unhealthy);\n\t\t\t}\n\t\t},\n\n\t\tresult(ctx, run): DeployResult {\n\t\t\treturn {\n\t\t\t\tapps: run.apps.map((appName) => ({\n\t\t\t\t\tappName,\n\t\t\t\t\ttype: ctx.workspace.apps[appName]?.type ?? 'backend',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\t...(run.urls[appName] ? { url: run.urls[appName] } : {}),\n\t\t\t\t})),\n\t\t\t\tprojectId: '',\n\t\t\t\tenvironmentId: '',\n\t\t\t\tsuccessCount: ctx.dryRun ? 0 : run.apps.length,\n\t\t\t\tfailedCount: 0,\n\t\t\t\tstage: ctx.stage,\n\t\t\t\tidentity: ctx.identity.key,\n\t\t\t\ttag: ctx.tag,\n\t\t\t\tdryRun: ctx.dryRun,\n\t\t\t\tskipped: [...ctx.skipped],\n\t\t\t\turls: { ...run.urls },\n\t\t\t\tchanges: [],\n\t\t\t};\n\t\t},\n\t});\n}\n\nfunction buildCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'gkm', [\n\t\t'build',\n\t\t'--provider',\n\t\t'aws',\n\t\t'--stage',\n\t\tctx.stage,\n\t]);\n}\n\nfunction deployCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'sst', ['deploy', '--stage', ctx.stage]);\n}\n\nexport const sstTarget = createSstTarget();\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
2
  const require_errors = require("./errors-DMC4Umsb.cjs");
3
3
  const require_derive = require("./derive-DAbo49sm.cjs");
4
4
  const require_workspace = require("./workspace-cSyi5nb1.cjs");
5
- const require_seeds = require("./seeds-BCg8X36S.cjs");
5
+ const require_seeds = require("./seeds-CnXkgKUv.cjs");
6
6
  const require_SubscriberGenerator = require("./SubscriberGenerator-Dvz7EzqK.cjs");
7
7
  let node_path = require("node:path");
8
8
  let _geekmidas_manifest = require("@geekmidas/manifest");
@@ -681,12 +681,6 @@ function composeStack(input) {
681
681
  }
682
682
  if (resource.kind === "external-api") owners.set((0, _geekmidas_manifest.provideKey)(resource.id, "credentials"), resource);
683
683
  }
684
- const reads = /* @__PURE__ */ new Map();
685
- for (const app of apps) {
686
- const site = manifest[app.id];
687
- reads.set(app.name, site?.kind === "site" ? Object.values((0, _geekmidas_manifest.publicEnvFor)(site, manifest)) : [...require_seeds.appEnvKeys(manifest, app.name, input.runnables) ?? []]);
688
- }
689
- for (const worker of workers) reads.set(worker.name, [...require_seeds.workerEnvKeys(manifest, worker.id, input.runnables) ?? []]);
690
684
  const domain = workspace.domains?.[stage];
691
685
  const telemetry = require_workspace.resolveStageTelemetry({
692
686
  ...workspace.deploy?.telemetry ? { telemetry: workspace.deploy.telemetry } : {},
@@ -714,17 +708,17 @@ function composeStack(input) {
714
708
  missing: [],
715
709
  minio: plan.resources.filter((r) => r.kind === "objects").map((r) => r.id),
716
710
  mailpit: plan.resources.filter((r) => r.kind === "email").map((r) => r.id)
717
- } : (() => {
718
- require_seeds.assertStageProvidersEnabled(workspace, manifest, stage);
719
- return require_seeds.assertExternalServices({
720
- stage,
721
- declarations: serviceDeclarations(plan, reads, owners),
722
- supplied: custom,
723
- allow: input.allowDevServices === true,
724
- ...domain ? { domain } : {},
725
- providers: require_seeds.stageProviderNotes(workspace, stage)
726
- });
727
- })();
711
+ } : require_seeds.externalServices({
712
+ stage,
713
+ declarations: require_seeds.stageServiceDeclarations({
714
+ manifest,
715
+ ...input.runnables ? { runnables: input.runnables } : {}
716
+ }),
717
+ supplied: custom,
718
+ allow: input.allowDevServices === true,
719
+ ...domain ? { domain } : {},
720
+ providers: require_seeds.stageProviderNotes(workspace, stage)
721
+ });
728
722
  const redis = require_seeds.stackRedis({
729
723
  plan,
730
724
  stage,
@@ -993,38 +987,6 @@ function composeStack(input) {
993
987
  ...redis ? { redis } : {}
994
988
  };
995
989
  }
996
- /**
997
- * The mail and storage constructs a deployed stage's apps read, with who
998
- * reads each — and every file server's bucket, which serves it whether or
999
- * not an app reads it directly.
1000
- */
1001
- function serviceDeclarations(plan, reads, owners) {
1002
- const byId = new Map(plan.resources.map((r) => [r.id, r]));
1003
- const readers = /* @__PURE__ */ new Map();
1004
- const add = (id, app) => {
1005
- const set = readers.get(id) ?? /* @__PURE__ */ new Set();
1006
- if (app) set.add(app);
1007
- readers.set(id, set);
1008
- };
1009
- for (const [app, keys] of reads) for (const key of keys) {
1010
- const owner = owners.get(key);
1011
- if (!owner || !SERVICE_KINDS[owner.kind]) continue;
1012
- if (owner.kind === "email" && key.endsWith("_INBOX_URL")) continue;
1013
- add(owner.id, app);
1014
- if (owner.kind === "file-server" && owner.of) add(owner.of);
1015
- }
1016
- return [...readers].flatMap(([id, apps]) => {
1017
- const resource = byId.get(id);
1018
- const kind = resource && SERVICE_KINDS[resource.kind];
1019
- if (!resource || !kind) return [];
1020
- return [{
1021
- id,
1022
- kind,
1023
- ...resource.of ? { of: resource.of } : {},
1024
- apps: [...apps].sort()
1025
- }];
1026
- });
1027
- }
1028
990
  /** The stack's MinIO's value for one of the S3 client's keys. */
1029
991
  function storageValue(key, storage) {
1030
992
  if (!storage) return void 0;
@@ -1343,4 +1305,4 @@ Object.defineProperty(exports, "traefikStaticFile", {
1343
1305
  }
1344
1306
  });
1345
1307
 
1346
- //# sourceMappingURL=stack-B3fPDTBg.cjs.map
1308
+ //# sourceMappingURL=stack-1g57OfOw.cjs.map