@geekmidas/cli 10.0.0-alpha.124 → 10.0.0-alpha.125

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 (228) hide show
  1. package/dist/{EndpointGenerator-B2MUa4M2.cjs → EndpointGenerator-BGxf9jWE.cjs} +8 -4
  2. package/dist/{EndpointGenerator-B2MUa4M2.cjs.map → EndpointGenerator-BGxf9jWE.cjs.map} +1 -1
  3. package/dist/{EndpointGenerator-Z_BUTocT.mjs → EndpointGenerator-errMeldx.mjs} +8 -4
  4. package/dist/{EndpointGenerator-Z_BUTocT.mjs.map → EndpointGenerator-errMeldx.mjs.map} +1 -1
  5. package/dist/{GoDaddyProvider-55x4o-4z.mjs → GoDaddyProvider-BN1dODm9.mjs} +2 -2
  6. package/dist/{GoDaddyProvider-55x4o-4z.mjs.map → GoDaddyProvider-BN1dODm9.mjs.map} +1 -1
  7. package/dist/{GoDaddyProvider-0z5RAN1k.cjs → GoDaddyProvider-BTdtqhI_.cjs} +2 -2
  8. package/dist/{GoDaddyProvider-0z5RAN1k.cjs.map → GoDaddyProvider-BTdtqhI_.cjs.map} +1 -1
  9. package/dist/{LegacyStateStore-DRpB-yC5.cjs → LegacyStateStore-C2S8TGwx.cjs} +3 -3
  10. package/dist/{LegacyStateStore-DRpB-yC5.cjs.map → LegacyStateStore-C2S8TGwx.cjs.map} +1 -1
  11. package/dist/{LegacyStateStore-C-vumKSN.mjs → LegacyStateStore-DgXmuG87.mjs} +3 -3
  12. package/dist/{LegacyStateStore-C-vumKSN.mjs.map → LegacyStateStore-DgXmuG87.mjs.map} +1 -1
  13. package/dist/{LocalStateStore-C3ummuDT.cjs → LocalStateStore-CaJw9H-3.cjs} +2 -2
  14. package/dist/{LocalStateStore-C3ummuDT.cjs.map → LocalStateStore-CaJw9H-3.cjs.map} +1 -1
  15. package/dist/{LocalStateStore-CtOjpV1w.mjs → LocalStateStore-ojY_BiMK.mjs} +2 -2
  16. package/dist/{LocalStateStore-CtOjpV1w.mjs.map → LocalStateStore-ojY_BiMK.mjs.map} +1 -1
  17. package/dist/{OpenApiTsGenerator-MtnMQL_g.mjs → OpenApiTsGenerator-W_HRXH1X.mjs} +2 -2
  18. package/dist/{OpenApiTsGenerator-MtnMQL_g.mjs.map → OpenApiTsGenerator-W_HRXH1X.mjs.map} +1 -1
  19. package/dist/{OpenApiTsGenerator-t3_E98Fi.cjs → OpenApiTsGenerator-cQgtxWQo.cjs} +2 -2
  20. package/dist/{OpenApiTsGenerator-t3_E98Fi.cjs.map → OpenApiTsGenerator-cQgtxWQo.cjs.map} +1 -1
  21. package/dist/{S3StateStore-BC4Jm3Tw.mjs → S3StateStore-BSPkxhrx.mjs} +2 -2
  22. package/dist/{S3StateStore-BC4Jm3Tw.mjs.map → S3StateStore-BSPkxhrx.mjs.map} +1 -1
  23. package/dist/{S3StateStore-BeArp0aF.cjs → S3StateStore-BqugXIcb.cjs} +2 -2
  24. package/dist/{S3StateStore-BeArp0aF.cjs.map → S3StateStore-BqugXIcb.cjs.map} +1 -1
  25. package/dist/{SSMStateStore-DcstR6cW.cjs → SSMStateStore-B0OsuT_k.cjs} +2 -2
  26. package/dist/{SSMStateStore-DcstR6cW.cjs.map → SSMStateStore-B0OsuT_k.cjs.map} +1 -1
  27. package/dist/{SSMStateStore-Crl76aYZ.mjs → SSMStateStore-DM85OiH0.mjs} +2 -2
  28. package/dist/{SSMStateStore-Crl76aYZ.mjs.map → SSMStateStore-DM85OiH0.mjs.map} +1 -1
  29. package/dist/{SubscriberGenerator-C3QTae-R.cjs → SubscriberGenerator-BDUp7OeY.cjs} +3 -3
  30. package/dist/SubscriberGenerator-BDUp7OeY.cjs.map +1 -0
  31. package/dist/{SubscriberGenerator-COAVPgM-.mjs → SubscriberGenerator-ocQ2yj0K.mjs} +3 -3
  32. package/dist/{SubscriberGenerator-C3QTae-R.cjs.map → SubscriberGenerator-ocQ2yj0K.mjs.map} +1 -1
  33. package/dist/{add-CIjmgzkb.mjs → add-C7ZBXIzM.mjs} +6 -6
  34. package/dist/{add-CIjmgzkb.mjs.map → add-C7ZBXIzM.mjs.map} +1 -1
  35. package/dist/{add-BFjb6mMq.cjs → add-CrxvmSpq.cjs} +6 -6
  36. package/dist/{add-BFjb6mMq.cjs.map → add-CrxvmSpq.cjs.map} +1 -1
  37. package/dist/{bundler-CiUoIsku.cjs → bundler-DVUXW95p.cjs} +5 -5
  38. package/dist/{bundler-CiUoIsku.cjs.map → bundler-DVUXW95p.cjs.map} +1 -1
  39. package/dist/{bundler-D6KFNpQk.mjs → bundler-DpZ9uBGN.mjs} +5 -5
  40. package/dist/{bundler-D6KFNpQk.mjs.map → bundler-DpZ9uBGN.mjs.map} +1 -1
  41. package/dist/{cli-r4eUr98C.cjs → cli-BMRhE6cZ.cjs} +3 -3
  42. package/dist/{cli-r4eUr98C.cjs.map → cli-BMRhE6cZ.cjs.map} +1 -1
  43. package/dist/{cli-DNtSTtMc.mjs → cli-BWfYyy1k.mjs} +3 -3
  44. package/dist/{cli-DNtSTtMc.mjs.map → cli-BWfYyy1k.mjs.map} +1 -1
  45. package/dist/{compose-DJvvmF3X.mjs → compose-BFmdLig3.mjs} +232 -36
  46. package/dist/compose-BFmdLig3.mjs.map +1 -0
  47. package/dist/{compose-BfXXWJSp.cjs → compose-Bqcy0lqo.cjs} +232 -36
  48. package/dist/compose-Bqcy0lqo.cjs.map +1 -0
  49. package/dist/{config-IgK6YaGp.d.cts → config-CdytFgSR.d.cts} +3 -3
  50. package/dist/{config-IgK6YaGp.d.cts.map → config-CdytFgSR.d.cts.map} +1 -1
  51. package/dist/{config-kE-p5hxq.d.mts → config-_y1FGBWR.d.mts} +3 -3
  52. package/dist/{config-kE-p5hxq.d.mts.map → config-_y1FGBWR.d.mts.map} +1 -1
  53. package/dist/config.cjs +2 -2
  54. package/dist/config.d.cts +3 -3
  55. package/dist/config.d.mts +3 -3
  56. package/dist/config.mjs +2 -2
  57. package/dist/{credentialSchemas-AhIBuQxQ.cjs → credentialSchemas-DFxvGEwa.cjs} +2 -2
  58. package/dist/{credentialSchemas-AhIBuQxQ.cjs.map → credentialSchemas-DFxvGEwa.cjs.map} +1 -1
  59. package/dist/{credentialSchemas-DLKbxYBy.mjs → credentialSchemas-DaMpt-Dx.mjs} +2 -2
  60. package/dist/{credentialSchemas-DLKbxYBy.mjs.map → credentialSchemas-DaMpt-Dx.mjs.map} +1 -1
  61. package/dist/deploy/public.cjs +8 -8
  62. package/dist/deploy/public.d.cts +3 -3
  63. package/dist/deploy/public.d.cts.map +1 -1
  64. package/dist/deploy/public.d.mts +3 -3
  65. package/dist/deploy/public.d.mts.map +1 -1
  66. package/dist/deploy/public.mjs +8 -8
  67. package/dist/{deploy-CiRYwFmr.mjs → deploy-D8pUA9Y0.mjs} +797 -25
  68. package/dist/deploy-D8pUA9Y0.mjs.map +1 -0
  69. package/dist/{deploy-BbI1UMh3.cjs → deploy-DVrNjX1X.cjs} +796 -24
  70. package/dist/deploy-DVrNjX1X.cjs.map +1 -0
  71. package/dist/{discover-BvJOVsYG.mjs → discover-CzGM5P3p.mjs} +71 -1
  72. package/dist/discover-CzGM5P3p.mjs.map +1 -0
  73. package/dist/{discover-ojkcbxHw.cjs → discover-DL6h-J97.cjs} +71 -1
  74. package/dist/discover-DL6h-J97.cjs.map +1 -0
  75. package/dist/{dokploy-MM7c3IE0.mjs → dokploy-CzDGNB6A.mjs} +2 -2
  76. package/dist/{dokploy-MM7c3IE0.mjs.map → dokploy-CzDGNB6A.mjs.map} +1 -1
  77. package/dist/{dokploy-C0aQrCgs.cjs → dokploy-TtK6Zyl3.cjs} +2 -2
  78. package/dist/{dokploy-C0aQrCgs.cjs.map → dokploy-TtK6Zyl3.cjs.map} +1 -1
  79. package/dist/{drivers-Chb5Akov.mjs → drivers-C-VqMtld.mjs} +2 -2
  80. package/dist/{drivers-Chb5Akov.mjs.map → drivers-C-VqMtld.mjs.map} +1 -1
  81. package/dist/{drivers-CQ32PB5w.cjs → drivers-L29WvE95.cjs} +2 -2
  82. package/dist/{drivers-CQ32PB5w.cjs.map → drivers-L29WvE95.cjs.map} +1 -1
  83. package/dist/{eas-CJoys9yh.cjs → eas-D3clzkni.cjs} +2 -2
  84. package/dist/{eas-CJoys9yh.cjs.map → eas-D3clzkni.cjs.map} +1 -1
  85. package/dist/{eas-1Ee6kql0.mjs → eas-DaobzDks.mjs} +2 -2
  86. package/dist/{eas-1Ee6kql0.mjs.map → eas-DaobzDks.mjs.map} +1 -1
  87. package/dist/{emit-qvHxMV9b.cjs → emit-CYloptRS.cjs} +18 -1
  88. package/dist/emit-CYloptRS.cjs.map +1 -0
  89. package/dist/{emit-CNpuV_6Q.mjs → emit-CiJGdy_f.mjs} +18 -1
  90. package/dist/emit-CiJGdy_f.mjs.map +1 -0
  91. package/dist/{encryption-Bo9VlRnl.cjs → encryption-DBkIFiR2.cjs} +3 -3
  92. package/dist/{encryption-Bo9VlRnl.cjs.map → encryption-DBkIFiR2.cjs.map} +1 -1
  93. package/dist/{encryption-B8Bk1Mvu.mjs → encryption-DV31gEY8.mjs} +3 -3
  94. package/dist/{encryption-B8Bk1Mvu.mjs.map → encryption-DV31gEY8.mjs.map} +1 -1
  95. package/dist/{engine-BuinpJfS.mjs → engine-CFOR9h6X.mjs} +138 -13
  96. package/dist/engine-CFOR9h6X.mjs.map +1 -0
  97. package/dist/{engine-esxTxcIx.cjs → engine-CuZUGbEh.cjs} +138 -13
  98. package/dist/engine-CuZUGbEh.cjs.map +1 -0
  99. package/dist/{github-BEA4K3_X.cjs → github-CsvtWSBW.cjs} +41 -6
  100. package/dist/github-CsvtWSBW.cjs.map +1 -0
  101. package/dist/{github-BUlKJfOV.mjs → github-Nep8pI4_.mjs} +41 -6
  102. package/dist/github-Nep8pI4_.mjs.map +1 -0
  103. package/dist/{googlePlay-CiqAS2ma.cjs → googlePlay-C-UfBXJU.cjs} +3 -3
  104. package/dist/{googlePlay-CiqAS2ma.cjs.map → googlePlay-C-UfBXJU.cjs.map} +1 -1
  105. package/dist/{googlePlay-CK05QiTq.mjs → googlePlay-lF7Atm_N.mjs} +3 -3
  106. package/dist/{googlePlay-CK05QiTq.mjs.map → googlePlay-lF7Atm_N.mjs.map} +1 -1
  107. package/dist/{index-DhUf0B0m.d.mts → index-DrkV7N5w.d.mts} +2 -2
  108. package/dist/{index-4CO0HD27.d.cts.map → index-DrkV7N5w.d.mts.map} +1 -1
  109. package/dist/{index-4CO0HD27.d.cts → index-yaXZ9m-J.d.cts} +2 -2
  110. package/dist/{index-DhUf0B0m.d.mts.map → index-yaXZ9m-J.d.cts.map} +1 -1
  111. package/dist/index.cjs +147 -65
  112. package/dist/index.cjs.map +1 -1
  113. package/dist/index.mjs +147 -65
  114. package/dist/index.mjs.map +1 -1
  115. package/dist/{migrate-DeQJBexh.cjs → migrate-Dp3GhFnf.cjs} +4 -4
  116. package/dist/{migrate-DeQJBexh.cjs.map → migrate-Dp3GhFnf.cjs.map} +1 -1
  117. package/dist/{migrate-CnbvrVag.mjs → migrate-NfbPVhi9.mjs} +4 -4
  118. package/dist/{migrate-CnbvrVag.mjs.map → migrate-NfbPVhi9.mjs.map} +1 -1
  119. package/dist/{migrate-BzCHT9qs.mjs → migrate-_sBX0pve.mjs} +3 -3
  120. package/dist/{migrate-BzCHT9qs.mjs.map → migrate-_sBX0pve.mjs.map} +1 -1
  121. package/dist/{migrate-C-hmbjpG.cjs → migrate-hlNKNWmg.cjs} +3 -3
  122. package/dist/{migrate-C-hmbjpG.cjs.map → migrate-hlNKNWmg.cjs.map} +1 -1
  123. package/dist/openapi.cjs +3 -3
  124. package/dist/openapi.d.cts +1 -1
  125. package/dist/openapi.d.mts +1 -1
  126. package/dist/openapi.mjs +3 -3
  127. package/dist/{publish-BISBrrqR.mjs → publish-BuUVaZVy.mjs} +2 -2
  128. package/dist/{publish-BISBrrqR.mjs.map → publish-BuUVaZVy.mjs.map} +1 -1
  129. package/dist/{publish-DtSIB-hZ.cjs → publish-ZOo4xEuZ.cjs} +2 -2
  130. package/dist/{publish-DtSIB-hZ.cjs.map → publish-ZOo4xEuZ.cjs.map} +1 -1
  131. package/dist/{ready-DqsyadOs.mjs → ready-Ca883OvY.mjs} +6 -6
  132. package/dist/{ready-DqsyadOs.mjs.map → ready-Ca883OvY.mjs.map} +1 -1
  133. package/dist/{ready-IVGu-q18.cjs → ready-qnqp6JAY.cjs} +6 -6
  134. package/dist/{ready-IVGu-q18.cjs.map → ready-qnqp6JAY.cjs.map} +1 -1
  135. package/dist/reconcile/public.cjs +2 -2
  136. package/dist/reconcile/public.d.cts +1 -1
  137. package/dist/reconcile/public.d.cts.map +1 -1
  138. package/dist/reconcile/public.d.mts +1 -1
  139. package/dist/reconcile/public.d.mts.map +1 -1
  140. package/dist/reconcile/public.mjs +2 -2
  141. package/dist/{resolve-BT7fkPN5.mjs → resolve-BCU9pYDx.mjs} +3 -3
  142. package/dist/{resolve-BT7fkPN5.mjs.map → resolve-BCU9pYDx.mjs.map} +1 -1
  143. package/dist/{resolve-C7GKQcE4.cjs → resolve-C9QqOl5t.cjs} +3 -3
  144. package/dist/{resolve-C7GKQcE4.cjs.map → resolve-C9QqOl5t.cjs.map} +1 -1
  145. package/dist/{rollback-BEiB-Pje.cjs → rollback-CTWdDBgB.cjs} +5 -5
  146. package/dist/{rollback-BEiB-Pje.cjs.map → rollback-CTWdDBgB.cjs.map} +1 -1
  147. package/dist/{rollback-DbP0KuDw.mjs → rollback-CWyyTQ0B.mjs} +5 -5
  148. package/dist/{rollback-DbP0KuDw.mjs.map → rollback-CWyyTQ0B.mjs.map} +1 -1
  149. package/dist/{runtime-BFJQNqwd.d.mts → runtime-DCkfI2E7.d.mts} +2 -2
  150. package/dist/{runtime-BFJQNqwd.d.mts.map → runtime-DCkfI2E7.d.mts.map} +1 -1
  151. package/dist/{runtime-BJO-FFef.d.cts → runtime-Ie4znWIB.d.cts} +2 -2
  152. package/dist/{runtime-BJO-FFef.d.cts.map → runtime-Ie4znWIB.d.cts.map} +1 -1
  153. package/dist/{s3-B4FTQQkV.mjs → s3-BZzSnker.mjs} +2 -2
  154. package/dist/{s3-B4FTQQkV.mjs.map → s3-BZzSnker.mjs.map} +1 -1
  155. package/dist/{s3-DwKLXwUT.cjs → s3-pqgmCTOq.cjs} +2 -2
  156. package/dist/{s3-DwKLXwUT.cjs.map → s3-pqgmCTOq.cjs.map} +1 -1
  157. package/dist/sandbox/credentials-worker.cjs +2 -2
  158. package/dist/sandbox/credentials-worker.mjs +2 -2
  159. package/dist/sandbox/discover-worker.cjs +1 -1
  160. package/dist/sandbox/discover-worker.mjs +1 -1
  161. package/dist/sandbox/migrate-worker.cjs +1 -1
  162. package/dist/sandbox/migrate-worker.mjs +1 -1
  163. package/dist/{seeds-rG-Evfz9.mjs → seeds-CK7w79VC.mjs} +516 -39
  164. package/dist/seeds-CK7w79VC.mjs.map +1 -0
  165. package/dist/{seeds-DOfxmDRO.cjs → seeds-CPEcmoPn.cjs} +599 -38
  166. package/dist/seeds-CPEcmoPn.cjs.map +1 -0
  167. package/dist/{serverSetup-xGw1fxuZ.mjs → serverSetup-BAPNuNEX.mjs} +6 -6
  168. package/dist/{serverSetup-xGw1fxuZ.mjs.map → serverSetup-BAPNuNEX.mjs.map} +1 -1
  169. package/dist/{serverSetup-CWWVcU6Y.cjs → serverSetup-C6t6Vtt7.cjs} +6 -6
  170. package/dist/{serverSetup-CWWVcU6Y.cjs.map → serverSetup-C6t6Vtt7.cjs.map} +1 -1
  171. package/dist/{sniffer-C7O9Pna_.cjs → sniffer-DdX_WN_-.cjs} +8 -8
  172. package/dist/{sniffer-C7O9Pna_.cjs.map → sniffer-DdX_WN_-.cjs.map} +1 -1
  173. package/dist/{sniffer-DVPgfyHr.mjs → sniffer-g9v7cqDN.mjs} +8 -8
  174. package/dist/{sniffer-DVPgfyHr.mjs.map → sniffer-g9v7cqDN.mjs.map} +1 -1
  175. package/dist/{snsSubscriptions-CSkteK2J.cjs → snsSubscriptions-5Cqww8S7.cjs} +15 -3
  176. package/dist/snsSubscriptions-5Cqww8S7.cjs.map +1 -0
  177. package/dist/{snsSubscriptions-CvBIGGp0.mjs → snsSubscriptions-BmYeeTH8.mjs} +4 -4
  178. package/dist/snsSubscriptions-BmYeeTH8.mjs.map +1 -0
  179. package/dist/{stage-2EKpzPQ1.mjs → stage-C-I2dVw1.mjs} +6 -6
  180. package/dist/{stage-2EKpzPQ1.mjs.map → stage-C-I2dVw1.mjs.map} +1 -1
  181. package/dist/{stage-fRfFtLwj.cjs → stage-CUE5pMmw.cjs} +6 -6
  182. package/dist/{stage-fRfFtLwj.cjs.map → stage-CUE5pMmw.cjs.map} +1 -1
  183. package/dist/{stages-B7mCWI_R.cjs → stages-3yUZaZeA.cjs} +2 -2
  184. package/dist/{stages-B7mCWI_R.cjs.map → stages-3yUZaZeA.cjs.map} +1 -1
  185. package/dist/{stages-DSltTW2d.mjs → stages-DTTv0NZW.mjs} +2 -2
  186. package/dist/{stages-DSltTW2d.mjs.map → stages-DTTv0NZW.mjs.map} +1 -1
  187. package/dist/target/public.cjs +1 -1
  188. package/dist/target/public.d.cts +2 -2
  189. package/dist/target/public.d.mts +2 -2
  190. package/dist/target/public.mjs +1 -1
  191. package/dist/{terminal-D1aeTkgv.cjs → terminal-PKhPAajN.cjs} +2 -2
  192. package/dist/{terminal-D1aeTkgv.cjs.map → terminal-PKhPAajN.cjs.map} +1 -1
  193. package/dist/{terminal-BAVrDhhN.mjs → terminal-bqY33lpN.mjs} +2 -2
  194. package/dist/{terminal-BAVrDhhN.mjs.map → terminal-bqY33lpN.mjs.map} +1 -1
  195. package/dist/{types-CFU2uvrz.d.cts → types-Bmjs4jZV.d.mts} +8 -2
  196. package/dist/{types-D3BeGucy.d.mts.map → types-Bmjs4jZV.d.mts.map} +1 -1
  197. package/dist/{types-D3BeGucy.d.mts → types-D0IsQxES.d.cts} +9 -1
  198. package/dist/{types-CFU2uvrz.d.cts.map → types-D0IsQxES.d.cts.map} +1 -1
  199. package/dist/vitest.cjs +1 -1
  200. package/dist/vitest.mjs +1 -1
  201. package/dist/workspace/index.cjs +1 -1
  202. package/dist/workspace/index.d.cts +2 -2
  203. package/dist/workspace/index.d.mts +2 -2
  204. package/dist/workspace/index.mjs +1 -1
  205. package/dist/{workspace-DUnnVjqC.mjs → workspace-DBHF9Gba.mjs} +5 -3
  206. package/dist/workspace-DBHF9Gba.mjs.map +1 -0
  207. package/dist/{workspace-C82GLPnf.cjs → workspace-Du4Afb03.cjs} +5 -3
  208. package/dist/workspace-Du4Afb03.cjs.map +1 -0
  209. package/package.json +17 -15
  210. package/dist/SubscriberGenerator-COAVPgM-.mjs.map +0 -1
  211. package/dist/compose-BfXXWJSp.cjs.map +0 -1
  212. package/dist/compose-DJvvmF3X.mjs.map +0 -1
  213. package/dist/deploy-BbI1UMh3.cjs.map +0 -1
  214. package/dist/deploy-CiRYwFmr.mjs.map +0 -1
  215. package/dist/discover-BvJOVsYG.mjs.map +0 -1
  216. package/dist/discover-ojkcbxHw.cjs.map +0 -1
  217. package/dist/emit-CNpuV_6Q.mjs.map +0 -1
  218. package/dist/emit-qvHxMV9b.cjs.map +0 -1
  219. package/dist/engine-BuinpJfS.mjs.map +0 -1
  220. package/dist/engine-esxTxcIx.cjs.map +0 -1
  221. package/dist/github-BEA4K3_X.cjs.map +0 -1
  222. package/dist/github-BUlKJfOV.mjs.map +0 -1
  223. package/dist/seeds-DOfxmDRO.cjs.map +0 -1
  224. package/dist/seeds-rG-Evfz9.mjs.map +0 -1
  225. package/dist/snsSubscriptions-CSkteK2J.cjs.map +0 -1
  226. package/dist/snsSubscriptions-CvBIGGp0.mjs.map +0 -1
  227. package/dist/workspace-C82GLPnf.cjs.map +0 -1
  228. package/dist/workspace-DUnnVjqC.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-C7GKQcE4.cjs","names":["GkmError","join","existsSync","realpathSync","dirname","readFileSync","pathToFileURL","GkmError","builtinTarget","configuredTarget","UnknownDeployTarget","configurableBuiltins","GkmError","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","isDeployTarget"],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { GkmError } from '../errors';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport { GkmError } from '../errors';\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst implementation = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\n}\n","/**\n * From a target's name to the target.\n *\n * In this order, the first that has the name wins:\n *\n * 1. the host's own targets — what a program calling `deploy()` passes\n * 2. the built-ins — `dokploy`, `compose`, `sst`\n * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either\n * with options\n *\n * Built-ins come before the config so that a dependency cannot take over\n * `dokploy` by being listed under its name. A name nothing has is\n * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a\n * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody\n * has claimed can be claimed by anyone, and a deploy would then run their\n * code with the stage's credentials. A target is installed and named.\n */\n\nimport { GkmError } from '../errors';\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tDeployTargetNotYetSupported,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { isDeployTarget } from './define';\nimport { importPackage } from './package';\nimport { declaredRuntime } from './runtime';\nimport type {\n\tAnyDeployTarget,\n\tDeployRuntime,\n\tDeployTargetEntry,\n\tTargetOptionsIssue,\n} from './types';\n\n/** Where a target came from. */\nexport type TargetSourceKind = 'host' | 'builtin' | 'config';\n\nexport interface ResolvedTarget {\n\t/** The name it was asked for by. */\n\tname: string;\n\ttarget: AnyDeployTarget;\n\tsource: TargetSourceKind;\n\t/** Its options as written in the config, before its schema parsed them. */\n\toptions: unknown;\n}\n\nexport interface ResolveTargetOptions {\n\t/** The workspace whose `deploy.targets` is consulted. */\n\tworkspace: {\n\t\troot: string;\n\t\tdeploy?: { targets?: Record<string, DeployTargetEntry> } | undefined;\n\t};\n\t/** The host's targets, consulted first. */\n\thost?: Record<string, AnyDeployTarget>;\n\t/** The stage being deployed, for what to do instead of a refused target. */\n\tstage: string;\n}\n\n/** A target package whose default export is not a target. */\nexport class TargetPackageInvalid extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names \"${packageName}\", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`,\n\t\t);\n\t\tthis.name = 'TargetPackageInvalid';\n\t}\n}\n\n/** A `deploy.targets` entry that is not a target, a package name or a pair. */\nexport class TargetEntryInvalid extends GkmError {\n\tconstructor(readonly target: string) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`,\n\t\t);\n\t\tthis.name = 'TargetEntryInvalid';\n\t}\n}\n\n/** A target whose `runtime` is not the one its package declares. */\nexport class TargetRuntimeMismatch extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly declared: DeployRuntime,\n\t\treadonly actual: DeployRuntime,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" runs on \"${actual}\", but ${packageName}'s package.json declares gkm.runtime \"${declared}\". gkm dev and gkm build chose backends for \"${declared}\", so the two must agree — fix the package.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeMismatch';\n\t}\n}\n\n/** Options a target's schema rejected. */\nexport class InvalidTargetOptions extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly issues: readonly TargetOptionsIssue[],\n\t) {\n\t\tconst lines = issues.map((issue) => {\n\t\t\tconst path = (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.');\n\t\t\treturn ` - ${path ? `${path}: ` : ''}${issue.message}`;\n\t\t});\n\t\tsuper(\n\t\t\t`The options for deploy target \"${target}\" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\\n${lines.join('\\n')}`,\n\t\t);\n\t\tthis.name = 'InvalidTargetOptions';\n\t}\n}\n\n/** The built-ins `gkm deploy` deploys through, loaded only when used. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<AnyDeployTarget>> = {\n\tdokploy: async () => (await import('./dokploy')).dokployTarget,\n\tcompose: async () => (await import('./compose/index')).composeTarget(),\n\tsst: async () => (await import('./sst/index')).sstTarget,\n};\n\n/** The target `name` means, in this workspace, for this host. */\nexport async function resolveTarget(\n\tname: string,\n\t{ workspace, host, stage }: ResolveTargetOptions,\n): Promise<ResolvedTarget> {\n\tif (host && Object.hasOwn(host, name)) {\n\t\treturn { name, target: host[name]!, source: 'host', options: undefined };\n\t}\n\n\tconst builtin = builtinTarget(name);\n\tif (builtin) {\n\t\tconst load = BUILTIN_LOADERS[name];\n\t\tif (builtin.status !== 'available' || !load) {\n\t\t\tthrow new DeployTargetNotYetSupported(name, builtin.instead?.(stage));\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\ttarget: await load(),\n\t\t\tsource: 'builtin',\n\t\t\toptions: undefined,\n\t\t};\n\t}\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst [implementation, options] = Array.isArray(entry)\n\t\t? (entry as readonly [unknown, unknown])\n\t\t: [entry, undefined];\n\n\tif (typeof implementation === 'string') {\n\t\t// Before the import: a package that does not say where it runs is\n\t\t// refused without running any of its code.\n\t\tconst declared = declaredRuntime(name, implementation, workspace.root);\n\t\tconst loaded = await importPackage(name, implementation, workspace.root);\n\t\tconst target = loaded.default;\n\t\tif (!isDeployTarget(target)) {\n\t\t\tthrow new TargetPackageInvalid(name, implementation);\n\t\t}\n\t\tif (target.runtime !== declared) {\n\t\t\tthrow new TargetRuntimeMismatch(\n\t\t\t\tname,\n\t\t\t\timplementation,\n\t\t\t\tdeclared,\n\t\t\t\ttarget.runtime,\n\t\t\t);\n\t\t}\n\t\treturn { name, target, source: 'config', options };\n\t}\n\n\tif (!isDeployTarget(implementation)) throw new TargetEntryInvalid(name);\n\treturn { name, target: implementation, source: 'config', options };\n}\n\n/** The target's options, parsed by its schema. */\nexport async function parseTargetOptions(\n\tresolved: ResolvedTarget,\n): Promise<unknown> {\n\tconst { name, target, options } = resolved;\n\tif (!target.options) {\n\t\tif (options !== undefined) {\n\t\t\tthrow new InvalidTargetOptions(name, [\n\t\t\t\t{ message: 'this target takes no options' },\n\t\t\t]);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst result = await target.options['~standard'].validate(options);\n\tif (result.issues) throw new InvalidTargetOptions(name, result.issues);\n\treturn result.value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolve-C9QqOl5t.cjs","names":["GkmError","join","existsSync","realpathSync","dirname","readFileSync","pathToFileURL","GkmError","builtinTarget","configuredTarget","UnknownDeployTarget","configurableBuiltins","GkmError","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","isDeployTarget"],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { GkmError } from '../errors';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport { GkmError } from '../errors';\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst implementation = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\n}\n","/**\n * From a target's name to the target.\n *\n * In this order, the first that has the name wins:\n *\n * 1. the host's own targets — what a program calling `deploy()` passes\n * 2. the built-ins — `dokploy`, `compose`, `sst`\n * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either\n * with options\n *\n * Built-ins come before the config so that a dependency cannot take over\n * `dokploy` by being listed under its name. A name nothing has is\n * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a\n * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody\n * has claimed can be claimed by anyone, and a deploy would then run their\n * code with the stage's credentials. A target is installed and named.\n */\n\nimport { GkmError } from '../errors';\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tDeployTargetNotYetSupported,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { isDeployTarget } from './define';\nimport { importPackage } from './package';\nimport { declaredRuntime } from './runtime';\nimport type {\n\tAnyDeployTarget,\n\tDeployRuntime,\n\tDeployTargetEntry,\n\tTargetOptionsIssue,\n} from './types';\n\n/** Where a target came from. */\nexport type TargetSourceKind = 'host' | 'builtin' | 'config';\n\nexport interface ResolvedTarget {\n\t/** The name it was asked for by. */\n\tname: string;\n\ttarget: AnyDeployTarget;\n\tsource: TargetSourceKind;\n\t/** Its options as written in the config, before its schema parsed them. */\n\toptions: unknown;\n}\n\nexport interface ResolveTargetOptions {\n\t/** The workspace whose `deploy.targets` is consulted. */\n\tworkspace: {\n\t\troot: string;\n\t\tdeploy?: { targets?: Record<string, DeployTargetEntry> } | undefined;\n\t};\n\t/** The host's targets, consulted first. */\n\thost?: Record<string, AnyDeployTarget>;\n\t/** The stage being deployed, for what to do instead of a refused target. */\n\tstage: string;\n}\n\n/** A target package whose default export is not a target. */\nexport class TargetPackageInvalid extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names \"${packageName}\", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`,\n\t\t);\n\t\tthis.name = 'TargetPackageInvalid';\n\t}\n}\n\n/** A `deploy.targets` entry that is not a target, a package name or a pair. */\nexport class TargetEntryInvalid extends GkmError {\n\tconstructor(readonly target: string) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`,\n\t\t);\n\t\tthis.name = 'TargetEntryInvalid';\n\t}\n}\n\n/** A target whose `runtime` is not the one its package declares. */\nexport class TargetRuntimeMismatch extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly declared: DeployRuntime,\n\t\treadonly actual: DeployRuntime,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" runs on \"${actual}\", but ${packageName}'s package.json declares gkm.runtime \"${declared}\". gkm dev and gkm build chose backends for \"${declared}\", so the two must agree — fix the package.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeMismatch';\n\t}\n}\n\n/** Options a target's schema rejected. */\nexport class InvalidTargetOptions extends GkmError {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly issues: readonly TargetOptionsIssue[],\n\t) {\n\t\tconst lines = issues.map((issue) => {\n\t\t\tconst path = (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.');\n\t\t\treturn ` - ${path ? `${path}: ` : ''}${issue.message}`;\n\t\t});\n\t\tsuper(\n\t\t\t`The options for deploy target \"${target}\" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\\n${lines.join('\\n')}`,\n\t\t);\n\t\tthis.name = 'InvalidTargetOptions';\n\t}\n}\n\n/** The built-ins `gkm deploy` deploys through, loaded only when used. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<AnyDeployTarget>> = {\n\tdokploy: async () => (await import('./dokploy')).dokployTarget,\n\tcompose: async () => (await import('./compose/index')).composeTarget(),\n\tsst: async () => (await import('./sst/index')).sstTarget,\n};\n\n/** The target `name` means, in this workspace, for this host. */\nexport async function resolveTarget(\n\tname: string,\n\t{ workspace, host, stage }: ResolveTargetOptions,\n): Promise<ResolvedTarget> {\n\tif (host && Object.hasOwn(host, name)) {\n\t\treturn { name, target: host[name]!, source: 'host', options: undefined };\n\t}\n\n\tconst builtin = builtinTarget(name);\n\tif (builtin) {\n\t\tconst load = BUILTIN_LOADERS[name];\n\t\tif (builtin.status !== 'available' || !load) {\n\t\t\tthrow new DeployTargetNotYetSupported(name, builtin.instead?.(stage));\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\ttarget: await load(),\n\t\t\tsource: 'builtin',\n\t\t\toptions: undefined,\n\t\t};\n\t}\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst [implementation, options] = Array.isArray(entry)\n\t\t? (entry as readonly [unknown, unknown])\n\t\t: [entry, undefined];\n\n\tif (typeof implementation === 'string') {\n\t\t// Before the import: a package that does not say where it runs is\n\t\t// refused without running any of its code.\n\t\tconst declared = declaredRuntime(name, implementation, workspace.root);\n\t\tconst loaded = await importPackage(name, implementation, workspace.root);\n\t\tconst target = loaded.default;\n\t\tif (!isDeployTarget(target)) {\n\t\t\tthrow new TargetPackageInvalid(name, implementation);\n\t\t}\n\t\tif (target.runtime !== declared) {\n\t\t\tthrow new TargetRuntimeMismatch(\n\t\t\t\tname,\n\t\t\t\timplementation,\n\t\t\t\tdeclared,\n\t\t\t\ttarget.runtime,\n\t\t\t);\n\t\t}\n\t\treturn { name, target, source: 'config', options };\n\t}\n\n\tif (!isDeployTarget(implementation)) throw new TargetEntryInvalid(name);\n\treturn { name, target: implementation, source: 'config', options };\n}\n\n/** The target's options, parsed by its schema. */\nexport async function parseTargetOptions(\n\tresolved: ResolvedTarget,\n): Promise<unknown> {\n\tconst { name, target, options } = resolved;\n\tif (!target.options) {\n\t\tif (options !== undefined) {\n\t\t\tthrow new InvalidTargetOptions(name, [\n\t\t\t\t{ message: 'this target takes no options' },\n\t\t\t]);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst result = await target.options['~standard'].validate(options);\n\tif (result.issues) throw new InvalidTargetOptions(name, result.issues);\n\treturn result.value;\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
2
  const require_errors = require("./errors-DMC4Umsb.cjs");
3
3
  const require_credentials = require("./credentials-D7XJypNd.cjs");
4
- const require_workspace = require("./workspace-C82GLPnf.cjs");
5
- const require_seeds = require("./seeds-DOfxmDRO.cjs");
4
+ const require_workspace = require("./workspace-Du4Afb03.cjs");
5
+ const require_seeds = require("./seeds-CPEcmoPn.cjs");
6
6
  const require_sandbox = require("./sandbox-CHv3OYXg.cjs");
7
7
  const require_config = require("./config.cjs");
8
8
  const require_local = require("./local-OPC9BCZt.cjs");
9
- const require_sniffer = require("./sniffer-C7O9Pna_.cjs");
10
- const require_engine = require("./engine-esxTxcIx.cjs");
9
+ const require_sniffer = require("./sniffer-DdX_WN_-.cjs");
10
+ const require_engine = require("./engine-CuZUGbEh.cjs");
11
11
  let node_path = require("node:path");
12
12
  //#region src/target/dokploy/rollback.ts
13
13
  /**
@@ -162,4 +162,4 @@ Object.defineProperty(exports, "rollback_exports", {
162
162
  }
163
163
  });
164
164
 
165
- //# sourceMappingURL=rollback-BEiB-Pje.cjs.map
165
+ //# sourceMappingURL=rollback-CTWdDBgB.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback-BEiB-Pje.cjs","names":["GkmError","storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","asDokployState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport {\n\tassertStateOutlivesRun,\n\tcreateStateStore,\n} from '../../deploy/StateStore';\nimport {\n\tasDokployState,\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { GkmError } from '../../errors';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends GkmError {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\t\tassertStateOutlivesRun(workspace, input.stage, 'deploy:rollback');\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t\tnamespace: workspace.deploy?.namespace,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(\n\t\t\t\tstore,\n\t\t\t\tinput.stage,\n\t\t\t\t() => createEmptyState(input.stage, '', ''),\n\t\t\t\tasDokployState,\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rollback-CTWdDBgB.cjs","names":["GkmError","storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","asDokployState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport {\n\tassertStateOutlivesRun,\n\tcreateStateStore,\n} from '../../deploy/StateStore';\nimport {\n\tasDokployState,\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { GkmError } from '../../errors';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends GkmError {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\t\tassertStateOutlivesRun(workspace, input.stage, 'deploy:rollback');\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t\tnamespace: workspace.deploy?.namespace,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(\n\t\t\t\tstore,\n\t\t\t\tinput.stage,\n\t\t\t\t() => createEmptyState(input.stage, '', ''),\n\t\t\t\tasDokployState,\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
3
3
  import { r as storedCredentials } from "./credentials-DpfnUvIR.mjs";
4
- import { N as assertDeployedStage } from "./workspace-DUnnVjqC.mjs";
5
- import { C as recordRollback, _ as asDokployState, d as DeployJournal, y as createEmptyState } from "./seeds-rG-Evfz9.mjs";
4
+ import { N as assertDeployedStage } from "./workspace-DBHF9Gba.mjs";
5
+ import { C as recordRollback, _ as asDokployState, d as DeployJournal, y as createEmptyState } from "./seeds-CK7w79VC.mjs";
6
6
  import { c as withSandbox } from "./sandbox-CbVB7uOD.mjs";
7
7
  import { findWorkspaceRoot, loadWorkspaceConfig } from "./config.mjs";
8
8
  import { t as LocalSandbox } from "./local-B7Zv1NoA.mjs";
9
- import { S as createStateStore, v as assertStateOutlivesRun } from "./sniffer-DVPgfyHr.mjs";
10
- import { i as dokployApi, l as restoreImage, p as verifySettings } from "./engine-BuinpJfS.mjs";
9
+ import { S as createStateStore, v as assertStateOutlivesRun } from "./sniffer-g9v7cqDN.mjs";
10
+ import { i as dokployApi, l as restoreImage, p as verifySettings } from "./engine-CFOR9h6X.mjs";
11
11
  import { resolve } from "node:path";
12
12
  //#region src/target/dokploy/rollback.ts
13
13
  /**
@@ -133,4 +133,4 @@ async function rollbackStage(input) {
133
133
  //#endregion
134
134
  export { rollback_exports as a, rollbackStage as i, RollbackNeedsApp as n, StageNeverDeployed as r, NothingToRollBack as t };
135
135
 
136
- //# sourceMappingURL=rollback-DbP0KuDw.mjs.map
136
+ //# sourceMappingURL=rollback-CWyyTQ0B.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback-DbP0KuDw.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport {\n\tassertStateOutlivesRun,\n\tcreateStateStore,\n} from '../../deploy/StateStore';\nimport {\n\tasDokployState,\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { GkmError } from '../../errors';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends GkmError {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\t\tassertStateOutlivesRun(workspace, input.stage, 'deploy:rollback');\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t\tnamespace: workspace.deploy?.namespace,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(\n\t\t\t\tstore,\n\t\t\t\tinput.stage,\n\t\t\t\t() => createEmptyState(input.stage, '', ''),\n\t\t\t\tasDokployState,\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rollback-CWyyTQ0B.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport {\n\tassertStateOutlivesRun,\n\tcreateStateStore,\n} from '../../deploy/StateStore';\nimport {\n\tasDokployState,\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { GkmError } from '../../errors';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends GkmError {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\t\tassertStateOutlivesRun(workspace, input.stage, 'deploy:rollback');\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t\tnamespace: workspace.deploy?.namespace,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(\n\t\t\t\tstore,\n\t\t\t\tinput.stage,\n\t\t\t\t() => createEmptyState(input.stage, '', ''),\n\t\t\t\tasDokployState,\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { K as DeployRuntime, Wt as GkmError, et as TargetOptionsIssue } from "./types-D3BeGucy.mjs";
1
+ import { K as DeployRuntime, Wt as GkmError, et as TargetOptionsIssue } from "./types-Bmjs4jZV.mjs";
2
2
  //#region src/target/builtins.d.ts
3
3
  /** A target name that is neither built in nor in `deploy.targets`. */
4
4
  declare class UnknownDeployTarget extends GkmError {
@@ -79,4 +79,4 @@ declare class TargetRuntimeUndeclared extends GkmError {
79
79
  }
80
80
  //#endregion
81
81
  export { TargetRuntimeMismatch as a, DeployTargetNotYetSupported as c, TargetPackageInvalid as i, UnknownDeployTarget as l, InvalidTargetOptions as n, ProviderRemoved as o, TargetEntryInvalid as r, TargetPackageNotFound as s, TargetRuntimeUndeclared as t };
82
- //# sourceMappingURL=runtime-BFJQNqwd.d.mts.map
82
+ //# sourceMappingURL=runtime-DCkfI2E7.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-BFJQNqwd.d.mts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cAgEa,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
1
+ {"version":3,"file":"runtime-DCkfI2E7.d.mts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cAgEa,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
@@ -1,4 +1,4 @@
1
- import { K as DeployRuntime, Wt as GkmError, et as TargetOptionsIssue } from "./types-CFU2uvrz.cjs";
1
+ import { K as DeployRuntime, Wt as GkmError, et as TargetOptionsIssue } from "./types-D0IsQxES.cjs";
2
2
  //#region src/target/builtins.d.ts
3
3
  /** A target name that is neither built in nor in `deploy.targets`. */
4
4
  declare class UnknownDeployTarget extends GkmError {
@@ -79,4 +79,4 @@ declare class TargetRuntimeUndeclared extends GkmError {
79
79
  }
80
80
  //#endregion
81
81
  export { TargetRuntimeMismatch as a, DeployTargetNotYetSupported as c, TargetPackageInvalid as i, UnknownDeployTarget as l, InvalidTargetOptions as n, ProviderRemoved as o, TargetEntryInvalid as r, TargetPackageNotFound as s, TargetRuntimeUndeclared as t };
82
- //# sourceMappingURL=runtime-BJO-FFef.d.cts.map
82
+ //# sourceMappingURL=runtime-Ie4znWIB.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-BJO-FFef.d.cts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cAgEa,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
1
+ {"version":3,"file":"runtime-Ie4znWIB.d.cts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cAgEa,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
@@ -1,5 +1,5 @@
1
1
  import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
2
- import { lt as s3SecretsKey } from "./workspace-DUnnVjqC.mjs";
2
+ import { lt as s3SecretsKey } from "./workspace-DBHF9Gba.mjs";
3
3
  import { a as findProjectBucket, i as ensureProjectBucket, o as projectBucketName, r as callerAccountId } from "./projectBucket-C_DN4WzF.mjs";
4
4
  import { r as withStageCredentials, t as awsClientConfig } from "./awsStore-Bx5nCFnS.mjs";
5
5
  import { GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
@@ -212,4 +212,4 @@ var S3SecretsStore = class {
212
212
  //#endregion
213
213
  export { S3SecretsStore };
214
214
 
215
- //# sourceMappingURL=s3-B4FTQQkV.mjs.map
215
+ //# sourceMappingURL=s3-BZzSnker.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"s3-B4FTQQkV.mjs","names":[],"sources":["../src/secrets/s3.ts"],"sourcesContent":["/**\n * A stage's secrets in S3: one object per stage,\n * `<prefix>/<project>/<stage>/secrets.json`, in the project bucket beside the\n * deploy state (`providers/projectBucket.ts`) — or in a bucket the config\n * names, which must exist.\n *\n * Encrypted at rest with SSE-S3, asked for on every write although the\n * project bucket defaults to it, so no KMS key is another place to keep. The\n * bucket's versioning keeps every past document. Unlike an SSM parameter\n * there is no size to outgrow.\n *\n * The project bucket is created by the first write, never by a read: a stage\n * whose bucket or object does not exist yet has no secrets. Every write is\n * conditional — `If-Match` on the ETag this store last read for the stage,\n * `If-None-Match: *` when it read none — so two `secrets:set` runs at once\n * cannot each overwrite the other's key: the second is refused with\n * {@link StageSecretsChanged}.\n */\n\nimport {\n\tGetObjectCommand,\n\tHeadObjectCommand,\n\tPutObjectCommand,\n\tS3Client,\n\ttype S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport { STSClient } from '@aws-sdk/client-sts';\nimport type { DeployIdentity } from '../deploy/identity.js';\nimport { GkmError } from '../errors';\nimport {\n\tcallerAccountId,\n\tensureProjectBucket,\n\tfindProjectBucket,\n\tprojectBucketName,\n} from '../providers/projectBucket.js';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\twithStageCredentials,\n} from './awsStore.js';\nimport { s3SecretsKey } from './providers.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface S3SecretsStoreOptions extends AwsStoreOptions {\n\t/** The deploy identity: the project bucket's name and its tag. */\n\tidentity: Pick<DeployIdentity, 'scope' | 'key'>;\n\t/** A bucket that exists; omitted, the project bucket. */\n\tbucket?: string;\n\t/** Key prefix inside the bucket, without a trailing slash. */\n\tprefix: string;\n\t/** For tests: credentials to use instead of the default chain. */\n\tcredentials?: S3ClientConfig['credentials'];\n}\n\n/**\n * Another run wrote the stage's secrets after this one read them. Nothing was\n * written: the change is to be made again, on top of theirs.\n */\nexport class StageSecretsChanged extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** `s3://<bucket>/<key>` */\n\t\treadonly location: string,\n\t) {\n\t\tsuper(\n\t\t\t`The secrets for stage \"${stage}\" at ${location} changed after this command read them — ` +\n\t\t\t\t'another secrets command or deploy wrote them first. Nothing was written; run the command ' +\n\t\t\t\t'again to make the change on top of theirs.',\n\t\t);\n\t\tthis.name = 'StageSecretsChanged';\n\t}\n}\n\ninterface S3Failure {\n\tname?: string;\n\t$metadata?: { httpStatusCode?: number };\n}\n\n/** A conditional write that lost: the object is not what the write assumed. */\nfunction lostRace(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'PreconditionFailed' ||\n\t\tname === 'ConditionalRequestConflict' ||\n\t\t$metadata?.httpStatusCode === 412 ||\n\t\t$metadata?.httpStatusCode === 409\n\t);\n}\n\nfunction notFound(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'NoSuchKey' ||\n\t\tname === 'NotFound' ||\n\t\t$metadata?.httpStatusCode === 404\n\t);\n}\n\nexport class S3SecretsStore implements SecretsStore {\n\treadonly name = 's3';\n\n\tprivate clients?: { s3: S3Client; sts: STSClient };\n\t/** The bucket's name, once known. */\n\tprivate bucketName?: string;\n\t/** Whether the bucket is known to exist. */\n\tprivate exists = false;\n\t/** The ETag each stage was last read at — null: read, and not there. */\n\tprivate readonly etags = new Map<string, string | null>();\n\n\tconstructor(private readonly options: S3SecretsStoreOptions) {\n\t\tif (options.bucket) {\n\t\t\tthis.bucketName = options.bucket;\n\t\t\tthis.exists = true;\n\t\t}\n\t}\n\n\t/** The bucket's name; the project bucket's is known after the first call. */\n\tget bucket(): string {\n\t\treturn (\n\t\t\tthis.bucketName ??\n\t\t\tprojectBucketName(this.options.identity.scope, '<account id>')\n\t\t);\n\t}\n\n\t/** Where a stage's secrets are kept: `s3://<bucket>/<key>`. */\n\tlocation(stage: string): string {\n\t\treturn `s3://${this.bucket}/${this.key(stage)}`;\n\t}\n\n\tprivate key(stage: string): string {\n\t\treturn s3SecretsKey(this.options.prefix, this.options.project, stage);\n\t}\n\n\tprivate async client(): Promise<{ s3: S3Client; sts: STSClient }> {\n\t\tif (this.clients) return this.clients;\n\t\tconst base = await awsClientConfig(this.options);\n\t\tconst endpoint =\n\t\t\tbase.endpoint ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL_S3 ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL;\n\t\tconst credentials = this.options.credentials ?? base.credentials;\n\t\tthis.clients = {\n\t\t\ts3: new S3Client({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(endpoint ? { endpoint, forcePathStyle: true } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t\tsts: new STSClient({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(base.endpoint ? { endpoint: base.endpoint } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t};\n\t\treturn this.clients;\n\t}\n\n\t/** One AWS call, a missing or expired credential refused by name. */\n\tprivate call<T>(\n\t\tstage: string,\n\t\taccess: 'read' | 'write',\n\t\trun: () => Promise<T>,\n\t): Promise<T> {\n\t\treturn withStageCredentials(\n\t\t\t{ stage, store: this.name, profile: this.options.profile, access },\n\t\t\trun,\n\t\t);\n\t}\n\n\t/**\n\t * The bucket, or null for a project bucket that does not exist yet and is\n\t * not to be created (a read).\n\t */\n\tprivate async use(\n\t\tstage: string,\n\t\tcreate: boolean,\n\t): Promise<{ s3: S3Client; bucket: string | null }> {\n\t\tconst { s3, sts } = await this.client();\n\t\tif (this.exists) return { s3, bucket: this.bucketName! };\n\t\tconst access = create ? 'write' : 'read';\n\t\tthis.bucketName ??= projectBucketName(\n\t\t\tthis.options.identity.scope,\n\t\t\tawait this.call(stage, access, () => callerAccountId(sts)),\n\t\t);\n\t\tconst bucket = this.bucketName;\n\t\tif (create) {\n\t\t\tawait this.call(stage, access, () =>\n\t\t\t\tensureProjectBucket(s3, {\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion: this.options.region,\n\t\t\t\t\tidentity: this.options.identity,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (\n\t\t\t(await this.call(stage, access, () => findProjectBucket(s3, bucket))) ===\n\t\t\t'none'\n\t\t) {\n\t\t\treturn { s3, bucket: null };\n\t\t}\n\t\tthis.exists = true;\n\t\treturn { s3, bucket };\n\t}\n\n\t/**\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * read it with, or they have expired\n\t */\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst { s3, bucket } = await this.use(stage, false);\n\t\tif (!bucket) {\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tconst response = await this.call(stage, 'read', () =>\n\t\t\t\ts3.send(new GetObjectCommand({ Bucket: bucket, Key: this.key(stage) })),\n\t\t\t);\n\t\t\tconst body = await (\n\t\t\t\tresponse.Body as {\n\t\t\t\t\ttransformToString(encoding: string): Promise<string>;\n\t\t\t\t}\n\t\t\t).transformToString('utf-8');\n\t\t\tthis.remember(stage, response.ETag);\n\t\t\treturn JSON.parse(body) as StageSecrets;\n\t\t} catch (error) {\n\t\t\tif (!notFound(error)) throw error;\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Replace the stage's secrets — on the condition that they are still what\n\t * this store last read. A stage never read here is replaced as it is now.\n\t *\n\t * @throws {StageSecretsChanged} when another run wrote them in between\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * write it with, or they have expired\n\t */\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst { s3, bucket } = await this.use(stage, true);\n\t\tconst Bucket = bucket!;\n\t\tconst Key = this.key(stage);\n\t\tconst expected = this.etags.has(stage)\n\t\t\t? (this.etags.get(stage) ?? null)\n\t\t\t: await this.currentEtag(s3, stage, Bucket, Key);\n\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(\n\t\t\t\t\tnew PutObjectCommand({\n\t\t\t\t\t\tBucket,\n\t\t\t\t\t\tKey,\n\t\t\t\t\t\tBody: JSON.stringify(secrets),\n\t\t\t\t\t\tContentType: 'application/json',\n\t\t\t\t\t\tServerSideEncryption: 'AES256',\n\t\t\t\t\t\t...(expected === null\n\t\t\t\t\t\t\t? { IfNoneMatch: '*' }\n\t\t\t\t\t\t\t: { IfMatch: expected }),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.remember(stage, ETag);\n\t\t} catch (error) {\n\t\t\tif (lostRace(error)) {\n\t\t\t\tthis.etags.delete(stage);\n\t\t\t\tthrow new StageSecretsChanged(stage, `s3://${Bucket}/${Key}`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * The ETag the stage is now at. Some S3-compatible servers answer without\n\t * one: then nothing is remembered, and the next write asks for it first.\n\t */\n\tprivate remember(stage: string, etag: string | undefined): void {\n\t\tif (etag) this.etags.set(stage, etag);\n\t\telse this.etags.delete(stage);\n\t}\n\n\tprivate async currentEtag(\n\t\ts3: S3Client,\n\t\tstage: string,\n\t\tBucket: string,\n\t\tKey: string,\n\t): Promise<string | null> {\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(new HeadObjectCommand({ Bucket, Key })),\n\t\t\t);\n\t\t\treturn ETag ?? null;\n\t\t} catch (error) {\n\t\t\tif (notFound(error)) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"s3-BZzSnker.mjs","names":[],"sources":["../src/secrets/s3.ts"],"sourcesContent":["/**\n * A stage's secrets in S3: one object per stage,\n * `<prefix>/<project>/<stage>/secrets.json`, in the project bucket beside the\n * deploy state (`providers/projectBucket.ts`) — or in a bucket the config\n * names, which must exist.\n *\n * Encrypted at rest with SSE-S3, asked for on every write although the\n * project bucket defaults to it, so no KMS key is another place to keep. The\n * bucket's versioning keeps every past document. Unlike an SSM parameter\n * there is no size to outgrow.\n *\n * The project bucket is created by the first write, never by a read: a stage\n * whose bucket or object does not exist yet has no secrets. Every write is\n * conditional — `If-Match` on the ETag this store last read for the stage,\n * `If-None-Match: *` when it read none — so two `secrets:set` runs at once\n * cannot each overwrite the other's key: the second is refused with\n * {@link StageSecretsChanged}.\n */\n\nimport {\n\tGetObjectCommand,\n\tHeadObjectCommand,\n\tPutObjectCommand,\n\tS3Client,\n\ttype S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport { STSClient } from '@aws-sdk/client-sts';\nimport type { DeployIdentity } from '../deploy/identity.js';\nimport { GkmError } from '../errors';\nimport {\n\tcallerAccountId,\n\tensureProjectBucket,\n\tfindProjectBucket,\n\tprojectBucketName,\n} from '../providers/projectBucket.js';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\twithStageCredentials,\n} from './awsStore.js';\nimport { s3SecretsKey } from './providers.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface S3SecretsStoreOptions extends AwsStoreOptions {\n\t/** The deploy identity: the project bucket's name and its tag. */\n\tidentity: Pick<DeployIdentity, 'scope' | 'key'>;\n\t/** A bucket that exists; omitted, the project bucket. */\n\tbucket?: string;\n\t/** Key prefix inside the bucket, without a trailing slash. */\n\tprefix: string;\n\t/** For tests: credentials to use instead of the default chain. */\n\tcredentials?: S3ClientConfig['credentials'];\n}\n\n/**\n * Another run wrote the stage's secrets after this one read them. Nothing was\n * written: the change is to be made again, on top of theirs.\n */\nexport class StageSecretsChanged extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** `s3://<bucket>/<key>` */\n\t\treadonly location: string,\n\t) {\n\t\tsuper(\n\t\t\t`The secrets for stage \"${stage}\" at ${location} changed after this command read them — ` +\n\t\t\t\t'another secrets command or deploy wrote them first. Nothing was written; run the command ' +\n\t\t\t\t'again to make the change on top of theirs.',\n\t\t);\n\t\tthis.name = 'StageSecretsChanged';\n\t}\n}\n\ninterface S3Failure {\n\tname?: string;\n\t$metadata?: { httpStatusCode?: number };\n}\n\n/** A conditional write that lost: the object is not what the write assumed. */\nfunction lostRace(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'PreconditionFailed' ||\n\t\tname === 'ConditionalRequestConflict' ||\n\t\t$metadata?.httpStatusCode === 412 ||\n\t\t$metadata?.httpStatusCode === 409\n\t);\n}\n\nfunction notFound(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'NoSuchKey' ||\n\t\tname === 'NotFound' ||\n\t\t$metadata?.httpStatusCode === 404\n\t);\n}\n\nexport class S3SecretsStore implements SecretsStore {\n\treadonly name = 's3';\n\n\tprivate clients?: { s3: S3Client; sts: STSClient };\n\t/** The bucket's name, once known. */\n\tprivate bucketName?: string;\n\t/** Whether the bucket is known to exist. */\n\tprivate exists = false;\n\t/** The ETag each stage was last read at — null: read, and not there. */\n\tprivate readonly etags = new Map<string, string | null>();\n\n\tconstructor(private readonly options: S3SecretsStoreOptions) {\n\t\tif (options.bucket) {\n\t\t\tthis.bucketName = options.bucket;\n\t\t\tthis.exists = true;\n\t\t}\n\t}\n\n\t/** The bucket's name; the project bucket's is known after the first call. */\n\tget bucket(): string {\n\t\treturn (\n\t\t\tthis.bucketName ??\n\t\t\tprojectBucketName(this.options.identity.scope, '<account id>')\n\t\t);\n\t}\n\n\t/** Where a stage's secrets are kept: `s3://<bucket>/<key>`. */\n\tlocation(stage: string): string {\n\t\treturn `s3://${this.bucket}/${this.key(stage)}`;\n\t}\n\n\tprivate key(stage: string): string {\n\t\treturn s3SecretsKey(this.options.prefix, this.options.project, stage);\n\t}\n\n\tprivate async client(): Promise<{ s3: S3Client; sts: STSClient }> {\n\t\tif (this.clients) return this.clients;\n\t\tconst base = await awsClientConfig(this.options);\n\t\tconst endpoint =\n\t\t\tbase.endpoint ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL_S3 ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL;\n\t\tconst credentials = this.options.credentials ?? base.credentials;\n\t\tthis.clients = {\n\t\t\ts3: new S3Client({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(endpoint ? { endpoint, forcePathStyle: true } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t\tsts: new STSClient({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(base.endpoint ? { endpoint: base.endpoint } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t};\n\t\treturn this.clients;\n\t}\n\n\t/** One AWS call, a missing or expired credential refused by name. */\n\tprivate call<T>(\n\t\tstage: string,\n\t\taccess: 'read' | 'write',\n\t\trun: () => Promise<T>,\n\t): Promise<T> {\n\t\treturn withStageCredentials(\n\t\t\t{ stage, store: this.name, profile: this.options.profile, access },\n\t\t\trun,\n\t\t);\n\t}\n\n\t/**\n\t * The bucket, or null for a project bucket that does not exist yet and is\n\t * not to be created (a read).\n\t */\n\tprivate async use(\n\t\tstage: string,\n\t\tcreate: boolean,\n\t): Promise<{ s3: S3Client; bucket: string | null }> {\n\t\tconst { s3, sts } = await this.client();\n\t\tif (this.exists) return { s3, bucket: this.bucketName! };\n\t\tconst access = create ? 'write' : 'read';\n\t\tthis.bucketName ??= projectBucketName(\n\t\t\tthis.options.identity.scope,\n\t\t\tawait this.call(stage, access, () => callerAccountId(sts)),\n\t\t);\n\t\tconst bucket = this.bucketName;\n\t\tif (create) {\n\t\t\tawait this.call(stage, access, () =>\n\t\t\t\tensureProjectBucket(s3, {\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion: this.options.region,\n\t\t\t\t\tidentity: this.options.identity,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (\n\t\t\t(await this.call(stage, access, () => findProjectBucket(s3, bucket))) ===\n\t\t\t'none'\n\t\t) {\n\t\t\treturn { s3, bucket: null };\n\t\t}\n\t\tthis.exists = true;\n\t\treturn { s3, bucket };\n\t}\n\n\t/**\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * read it with, or they have expired\n\t */\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst { s3, bucket } = await this.use(stage, false);\n\t\tif (!bucket) {\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tconst response = await this.call(stage, 'read', () =>\n\t\t\t\ts3.send(new GetObjectCommand({ Bucket: bucket, Key: this.key(stage) })),\n\t\t\t);\n\t\t\tconst body = await (\n\t\t\t\tresponse.Body as {\n\t\t\t\t\ttransformToString(encoding: string): Promise<string>;\n\t\t\t\t}\n\t\t\t).transformToString('utf-8');\n\t\t\tthis.remember(stage, response.ETag);\n\t\t\treturn JSON.parse(body) as StageSecrets;\n\t\t} catch (error) {\n\t\t\tif (!notFound(error)) throw error;\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Replace the stage's secrets — on the condition that they are still what\n\t * this store last read. A stage never read here is replaced as it is now.\n\t *\n\t * @throws {StageSecretsChanged} when another run wrote them in between\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * write it with, or they have expired\n\t */\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst { s3, bucket } = await this.use(stage, true);\n\t\tconst Bucket = bucket!;\n\t\tconst Key = this.key(stage);\n\t\tconst expected = this.etags.has(stage)\n\t\t\t? (this.etags.get(stage) ?? null)\n\t\t\t: await this.currentEtag(s3, stage, Bucket, Key);\n\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(\n\t\t\t\t\tnew PutObjectCommand({\n\t\t\t\t\t\tBucket,\n\t\t\t\t\t\tKey,\n\t\t\t\t\t\tBody: JSON.stringify(secrets),\n\t\t\t\t\t\tContentType: 'application/json',\n\t\t\t\t\t\tServerSideEncryption: 'AES256',\n\t\t\t\t\t\t...(expected === null\n\t\t\t\t\t\t\t? { IfNoneMatch: '*' }\n\t\t\t\t\t\t\t: { IfMatch: expected }),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.remember(stage, ETag);\n\t\t} catch (error) {\n\t\t\tif (lostRace(error)) {\n\t\t\t\tthis.etags.delete(stage);\n\t\t\t\tthrow new StageSecretsChanged(stage, `s3://${Bucket}/${Key}`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * The ETag the stage is now at. Some S3-compatible servers answer without\n\t * one: then nothing is remembered, and the next write asks for it first.\n\t */\n\tprivate remember(stage: string, etag: string | undefined): void {\n\t\tif (etag) this.etags.set(stage, etag);\n\t\telse this.etags.delete(stage);\n\t}\n\n\tprivate async currentEtag(\n\t\ts3: S3Client,\n\t\tstage: string,\n\t\tBucket: string,\n\t\tKey: string,\n\t): Promise<string | null> {\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(new HeadObjectCommand({ Bucket, Key })),\n\t\t\t);\n\t\t\treturn ETag ?? null;\n\t\t} catch (error) {\n\t\t\tif (notFound(error)) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_errors = require("./errors-DMC4Umsb.cjs");
2
- const require_workspace = require("./workspace-C82GLPnf.cjs");
2
+ const require_workspace = require("./workspace-Du4Afb03.cjs");
3
3
  const require_projectBucket = require("./projectBucket-BBbQ1lHF.cjs");
4
4
  const require_awsStore = require("./awsStore-u3ehhMoY.cjs");
5
5
  let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
@@ -212,4 +212,4 @@ var S3SecretsStore = class {
212
212
  //#endregion
213
213
  exports.S3SecretsStore = S3SecretsStore;
214
214
 
215
- //# sourceMappingURL=s3-DwKLXwUT.cjs.map
215
+ //# sourceMappingURL=s3-pqgmCTOq.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"s3-DwKLXwUT.cjs","names":["GkmError","projectBucketName","s3SecretsKey","awsClientConfig","S3Client","STSClient","withStageCredentials","callerAccountId","ensureProjectBucket","findProjectBucket","GetObjectCommand","PutObjectCommand","HeadObjectCommand"],"sources":["../src/secrets/s3.ts"],"sourcesContent":["/**\n * A stage's secrets in S3: one object per stage,\n * `<prefix>/<project>/<stage>/secrets.json`, in the project bucket beside the\n * deploy state (`providers/projectBucket.ts`) — or in a bucket the config\n * names, which must exist.\n *\n * Encrypted at rest with SSE-S3, asked for on every write although the\n * project bucket defaults to it, so no KMS key is another place to keep. The\n * bucket's versioning keeps every past document. Unlike an SSM parameter\n * there is no size to outgrow.\n *\n * The project bucket is created by the first write, never by a read: a stage\n * whose bucket or object does not exist yet has no secrets. Every write is\n * conditional — `If-Match` on the ETag this store last read for the stage,\n * `If-None-Match: *` when it read none — so two `secrets:set` runs at once\n * cannot each overwrite the other's key: the second is refused with\n * {@link StageSecretsChanged}.\n */\n\nimport {\n\tGetObjectCommand,\n\tHeadObjectCommand,\n\tPutObjectCommand,\n\tS3Client,\n\ttype S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport { STSClient } from '@aws-sdk/client-sts';\nimport type { DeployIdentity } from '../deploy/identity.js';\nimport { GkmError } from '../errors';\nimport {\n\tcallerAccountId,\n\tensureProjectBucket,\n\tfindProjectBucket,\n\tprojectBucketName,\n} from '../providers/projectBucket.js';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\twithStageCredentials,\n} from './awsStore.js';\nimport { s3SecretsKey } from './providers.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface S3SecretsStoreOptions extends AwsStoreOptions {\n\t/** The deploy identity: the project bucket's name and its tag. */\n\tidentity: Pick<DeployIdentity, 'scope' | 'key'>;\n\t/** A bucket that exists; omitted, the project bucket. */\n\tbucket?: string;\n\t/** Key prefix inside the bucket, without a trailing slash. */\n\tprefix: string;\n\t/** For tests: credentials to use instead of the default chain. */\n\tcredentials?: S3ClientConfig['credentials'];\n}\n\n/**\n * Another run wrote the stage's secrets after this one read them. Nothing was\n * written: the change is to be made again, on top of theirs.\n */\nexport class StageSecretsChanged extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** `s3://<bucket>/<key>` */\n\t\treadonly location: string,\n\t) {\n\t\tsuper(\n\t\t\t`The secrets for stage \"${stage}\" at ${location} changed after this command read them — ` +\n\t\t\t\t'another secrets command or deploy wrote them first. Nothing was written; run the command ' +\n\t\t\t\t'again to make the change on top of theirs.',\n\t\t);\n\t\tthis.name = 'StageSecretsChanged';\n\t}\n}\n\ninterface S3Failure {\n\tname?: string;\n\t$metadata?: { httpStatusCode?: number };\n}\n\n/** A conditional write that lost: the object is not what the write assumed. */\nfunction lostRace(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'PreconditionFailed' ||\n\t\tname === 'ConditionalRequestConflict' ||\n\t\t$metadata?.httpStatusCode === 412 ||\n\t\t$metadata?.httpStatusCode === 409\n\t);\n}\n\nfunction notFound(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'NoSuchKey' ||\n\t\tname === 'NotFound' ||\n\t\t$metadata?.httpStatusCode === 404\n\t);\n}\n\nexport class S3SecretsStore implements SecretsStore {\n\treadonly name = 's3';\n\n\tprivate clients?: { s3: S3Client; sts: STSClient };\n\t/** The bucket's name, once known. */\n\tprivate bucketName?: string;\n\t/** Whether the bucket is known to exist. */\n\tprivate exists = false;\n\t/** The ETag each stage was last read at — null: read, and not there. */\n\tprivate readonly etags = new Map<string, string | null>();\n\n\tconstructor(private readonly options: S3SecretsStoreOptions) {\n\t\tif (options.bucket) {\n\t\t\tthis.bucketName = options.bucket;\n\t\t\tthis.exists = true;\n\t\t}\n\t}\n\n\t/** The bucket's name; the project bucket's is known after the first call. */\n\tget bucket(): string {\n\t\treturn (\n\t\t\tthis.bucketName ??\n\t\t\tprojectBucketName(this.options.identity.scope, '<account id>')\n\t\t);\n\t}\n\n\t/** Where a stage's secrets are kept: `s3://<bucket>/<key>`. */\n\tlocation(stage: string): string {\n\t\treturn `s3://${this.bucket}/${this.key(stage)}`;\n\t}\n\n\tprivate key(stage: string): string {\n\t\treturn s3SecretsKey(this.options.prefix, this.options.project, stage);\n\t}\n\n\tprivate async client(): Promise<{ s3: S3Client; sts: STSClient }> {\n\t\tif (this.clients) return this.clients;\n\t\tconst base = await awsClientConfig(this.options);\n\t\tconst endpoint =\n\t\t\tbase.endpoint ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL_S3 ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL;\n\t\tconst credentials = this.options.credentials ?? base.credentials;\n\t\tthis.clients = {\n\t\t\ts3: new S3Client({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(endpoint ? { endpoint, forcePathStyle: true } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t\tsts: new STSClient({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(base.endpoint ? { endpoint: base.endpoint } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t};\n\t\treturn this.clients;\n\t}\n\n\t/** One AWS call, a missing or expired credential refused by name. */\n\tprivate call<T>(\n\t\tstage: string,\n\t\taccess: 'read' | 'write',\n\t\trun: () => Promise<T>,\n\t): Promise<T> {\n\t\treturn withStageCredentials(\n\t\t\t{ stage, store: this.name, profile: this.options.profile, access },\n\t\t\trun,\n\t\t);\n\t}\n\n\t/**\n\t * The bucket, or null for a project bucket that does not exist yet and is\n\t * not to be created (a read).\n\t */\n\tprivate async use(\n\t\tstage: string,\n\t\tcreate: boolean,\n\t): Promise<{ s3: S3Client; bucket: string | null }> {\n\t\tconst { s3, sts } = await this.client();\n\t\tif (this.exists) return { s3, bucket: this.bucketName! };\n\t\tconst access = create ? 'write' : 'read';\n\t\tthis.bucketName ??= projectBucketName(\n\t\t\tthis.options.identity.scope,\n\t\t\tawait this.call(stage, access, () => callerAccountId(sts)),\n\t\t);\n\t\tconst bucket = this.bucketName;\n\t\tif (create) {\n\t\t\tawait this.call(stage, access, () =>\n\t\t\t\tensureProjectBucket(s3, {\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion: this.options.region,\n\t\t\t\t\tidentity: this.options.identity,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (\n\t\t\t(await this.call(stage, access, () => findProjectBucket(s3, bucket))) ===\n\t\t\t'none'\n\t\t) {\n\t\t\treturn { s3, bucket: null };\n\t\t}\n\t\tthis.exists = true;\n\t\treturn { s3, bucket };\n\t}\n\n\t/**\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * read it with, or they have expired\n\t */\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst { s3, bucket } = await this.use(stage, false);\n\t\tif (!bucket) {\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tconst response = await this.call(stage, 'read', () =>\n\t\t\t\ts3.send(new GetObjectCommand({ Bucket: bucket, Key: this.key(stage) })),\n\t\t\t);\n\t\t\tconst body = await (\n\t\t\t\tresponse.Body as {\n\t\t\t\t\ttransformToString(encoding: string): Promise<string>;\n\t\t\t\t}\n\t\t\t).transformToString('utf-8');\n\t\t\tthis.remember(stage, response.ETag);\n\t\t\treturn JSON.parse(body) as StageSecrets;\n\t\t} catch (error) {\n\t\t\tif (!notFound(error)) throw error;\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Replace the stage's secrets — on the condition that they are still what\n\t * this store last read. A stage never read here is replaced as it is now.\n\t *\n\t * @throws {StageSecretsChanged} when another run wrote them in between\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * write it with, or they have expired\n\t */\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst { s3, bucket } = await this.use(stage, true);\n\t\tconst Bucket = bucket!;\n\t\tconst Key = this.key(stage);\n\t\tconst expected = this.etags.has(stage)\n\t\t\t? (this.etags.get(stage) ?? null)\n\t\t\t: await this.currentEtag(s3, stage, Bucket, Key);\n\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(\n\t\t\t\t\tnew PutObjectCommand({\n\t\t\t\t\t\tBucket,\n\t\t\t\t\t\tKey,\n\t\t\t\t\t\tBody: JSON.stringify(secrets),\n\t\t\t\t\t\tContentType: 'application/json',\n\t\t\t\t\t\tServerSideEncryption: 'AES256',\n\t\t\t\t\t\t...(expected === null\n\t\t\t\t\t\t\t? { IfNoneMatch: '*' }\n\t\t\t\t\t\t\t: { IfMatch: expected }),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.remember(stage, ETag);\n\t\t} catch (error) {\n\t\t\tif (lostRace(error)) {\n\t\t\t\tthis.etags.delete(stage);\n\t\t\t\tthrow new StageSecretsChanged(stage, `s3://${Bucket}/${Key}`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * The ETag the stage is now at. Some S3-compatible servers answer without\n\t * one: then nothing is remembered, and the next write asks for it first.\n\t */\n\tprivate remember(stage: string, etag: string | undefined): void {\n\t\tif (etag) this.etags.set(stage, etag);\n\t\telse this.etags.delete(stage);\n\t}\n\n\tprivate async currentEtag(\n\t\ts3: S3Client,\n\t\tstage: string,\n\t\tBucket: string,\n\t\tKey: string,\n\t): Promise<string | null> {\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(new HeadObjectCommand({ Bucket, Key })),\n\t\t\t);\n\t\t\treturn ETag ?? null;\n\t\t} catch (error) {\n\t\t\tif (notFound(error)) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"s3-pqgmCTOq.cjs","names":["GkmError","projectBucketName","s3SecretsKey","awsClientConfig","S3Client","STSClient","withStageCredentials","callerAccountId","ensureProjectBucket","findProjectBucket","GetObjectCommand","PutObjectCommand","HeadObjectCommand"],"sources":["../src/secrets/s3.ts"],"sourcesContent":["/**\n * A stage's secrets in S3: one object per stage,\n * `<prefix>/<project>/<stage>/secrets.json`, in the project bucket beside the\n * deploy state (`providers/projectBucket.ts`) — or in a bucket the config\n * names, which must exist.\n *\n * Encrypted at rest with SSE-S3, asked for on every write although the\n * project bucket defaults to it, so no KMS key is another place to keep. The\n * bucket's versioning keeps every past document. Unlike an SSM parameter\n * there is no size to outgrow.\n *\n * The project bucket is created by the first write, never by a read: a stage\n * whose bucket or object does not exist yet has no secrets. Every write is\n * conditional — `If-Match` on the ETag this store last read for the stage,\n * `If-None-Match: *` when it read none — so two `secrets:set` runs at once\n * cannot each overwrite the other's key: the second is refused with\n * {@link StageSecretsChanged}.\n */\n\nimport {\n\tGetObjectCommand,\n\tHeadObjectCommand,\n\tPutObjectCommand,\n\tS3Client,\n\ttype S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport { STSClient } from '@aws-sdk/client-sts';\nimport type { DeployIdentity } from '../deploy/identity.js';\nimport { GkmError } from '../errors';\nimport {\n\tcallerAccountId,\n\tensureProjectBucket,\n\tfindProjectBucket,\n\tprojectBucketName,\n} from '../providers/projectBucket.js';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\twithStageCredentials,\n} from './awsStore.js';\nimport { s3SecretsKey } from './providers.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface S3SecretsStoreOptions extends AwsStoreOptions {\n\t/** The deploy identity: the project bucket's name and its tag. */\n\tidentity: Pick<DeployIdentity, 'scope' | 'key'>;\n\t/** A bucket that exists; omitted, the project bucket. */\n\tbucket?: string;\n\t/** Key prefix inside the bucket, without a trailing slash. */\n\tprefix: string;\n\t/** For tests: credentials to use instead of the default chain. */\n\tcredentials?: S3ClientConfig['credentials'];\n}\n\n/**\n * Another run wrote the stage's secrets after this one read them. Nothing was\n * written: the change is to be made again, on top of theirs.\n */\nexport class StageSecretsChanged extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** `s3://<bucket>/<key>` */\n\t\treadonly location: string,\n\t) {\n\t\tsuper(\n\t\t\t`The secrets for stage \"${stage}\" at ${location} changed after this command read them — ` +\n\t\t\t\t'another secrets command or deploy wrote them first. Nothing was written; run the command ' +\n\t\t\t\t'again to make the change on top of theirs.',\n\t\t);\n\t\tthis.name = 'StageSecretsChanged';\n\t}\n}\n\ninterface S3Failure {\n\tname?: string;\n\t$metadata?: { httpStatusCode?: number };\n}\n\n/** A conditional write that lost: the object is not what the write assumed. */\nfunction lostRace(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'PreconditionFailed' ||\n\t\tname === 'ConditionalRequestConflict' ||\n\t\t$metadata?.httpStatusCode === 412 ||\n\t\t$metadata?.httpStatusCode === 409\n\t);\n}\n\nfunction notFound(error: unknown): boolean {\n\tconst { name, $metadata } = error as S3Failure;\n\treturn (\n\t\tname === 'NoSuchKey' ||\n\t\tname === 'NotFound' ||\n\t\t$metadata?.httpStatusCode === 404\n\t);\n}\n\nexport class S3SecretsStore implements SecretsStore {\n\treadonly name = 's3';\n\n\tprivate clients?: { s3: S3Client; sts: STSClient };\n\t/** The bucket's name, once known. */\n\tprivate bucketName?: string;\n\t/** Whether the bucket is known to exist. */\n\tprivate exists = false;\n\t/** The ETag each stage was last read at — null: read, and not there. */\n\tprivate readonly etags = new Map<string, string | null>();\n\n\tconstructor(private readonly options: S3SecretsStoreOptions) {\n\t\tif (options.bucket) {\n\t\t\tthis.bucketName = options.bucket;\n\t\t\tthis.exists = true;\n\t\t}\n\t}\n\n\t/** The bucket's name; the project bucket's is known after the first call. */\n\tget bucket(): string {\n\t\treturn (\n\t\t\tthis.bucketName ??\n\t\t\tprojectBucketName(this.options.identity.scope, '<account id>')\n\t\t);\n\t}\n\n\t/** Where a stage's secrets are kept: `s3://<bucket>/<key>`. */\n\tlocation(stage: string): string {\n\t\treturn `s3://${this.bucket}/${this.key(stage)}`;\n\t}\n\n\tprivate key(stage: string): string {\n\t\treturn s3SecretsKey(this.options.prefix, this.options.project, stage);\n\t}\n\n\tprivate async client(): Promise<{ s3: S3Client; sts: STSClient }> {\n\t\tif (this.clients) return this.clients;\n\t\tconst base = await awsClientConfig(this.options);\n\t\tconst endpoint =\n\t\t\tbase.endpoint ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL_S3 ??\n\t\t\tprocess.env.AWS_ENDPOINT_URL;\n\t\tconst credentials = this.options.credentials ?? base.credentials;\n\t\tthis.clients = {\n\t\t\ts3: new S3Client({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(endpoint ? { endpoint, forcePathStyle: true } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t\tsts: new STSClient({\n\t\t\t\tregion: base.region,\n\t\t\t\t...(base.endpoint ? { endpoint: base.endpoint } : {}),\n\t\t\t\t...(credentials ? { credentials } : {}),\n\t\t\t}),\n\t\t};\n\t\treturn this.clients;\n\t}\n\n\t/** One AWS call, a missing or expired credential refused by name. */\n\tprivate call<T>(\n\t\tstage: string,\n\t\taccess: 'read' | 'write',\n\t\trun: () => Promise<T>,\n\t): Promise<T> {\n\t\treturn withStageCredentials(\n\t\t\t{ stage, store: this.name, profile: this.options.profile, access },\n\t\t\trun,\n\t\t);\n\t}\n\n\t/**\n\t * The bucket, or null for a project bucket that does not exist yet and is\n\t * not to be created (a read).\n\t */\n\tprivate async use(\n\t\tstage: string,\n\t\tcreate: boolean,\n\t): Promise<{ s3: S3Client; bucket: string | null }> {\n\t\tconst { s3, sts } = await this.client();\n\t\tif (this.exists) return { s3, bucket: this.bucketName! };\n\t\tconst access = create ? 'write' : 'read';\n\t\tthis.bucketName ??= projectBucketName(\n\t\t\tthis.options.identity.scope,\n\t\t\tawait this.call(stage, access, () => callerAccountId(sts)),\n\t\t);\n\t\tconst bucket = this.bucketName;\n\t\tif (create) {\n\t\t\tawait this.call(stage, access, () =>\n\t\t\t\tensureProjectBucket(s3, {\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion: this.options.region,\n\t\t\t\t\tidentity: this.options.identity,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (\n\t\t\t(await this.call(stage, access, () => findProjectBucket(s3, bucket))) ===\n\t\t\t'none'\n\t\t) {\n\t\t\treturn { s3, bucket: null };\n\t\t}\n\t\tthis.exists = true;\n\t\treturn { s3, bucket };\n\t}\n\n\t/**\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * read it with, or they have expired\n\t */\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst { s3, bucket } = await this.use(stage, false);\n\t\tif (!bucket) {\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tconst response = await this.call(stage, 'read', () =>\n\t\t\t\ts3.send(new GetObjectCommand({ Bucket: bucket, Key: this.key(stage) })),\n\t\t\t);\n\t\t\tconst body = await (\n\t\t\t\tresponse.Body as {\n\t\t\t\t\ttransformToString(encoding: string): Promise<string>;\n\t\t\t\t}\n\t\t\t).transformToString('utf-8');\n\t\t\tthis.remember(stage, response.ETag);\n\t\t\treturn JSON.parse(body) as StageSecrets;\n\t\t} catch (error) {\n\t\t\tif (!notFound(error)) throw error;\n\t\t\tthis.etags.set(stage, null);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Replace the stage's secrets — on the condition that they are still what\n\t * this store last read. A stage never read here is replaced as it is now.\n\t *\n\t * @throws {StageSecretsChanged} when another run wrote them in between\n\t * @throws {StageSecretsUnreadable} when there are no AWS credentials to\n\t * write it with, or they have expired\n\t */\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst { s3, bucket } = await this.use(stage, true);\n\t\tconst Bucket = bucket!;\n\t\tconst Key = this.key(stage);\n\t\tconst expected = this.etags.has(stage)\n\t\t\t? (this.etags.get(stage) ?? null)\n\t\t\t: await this.currentEtag(s3, stage, Bucket, Key);\n\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(\n\t\t\t\t\tnew PutObjectCommand({\n\t\t\t\t\t\tBucket,\n\t\t\t\t\t\tKey,\n\t\t\t\t\t\tBody: JSON.stringify(secrets),\n\t\t\t\t\t\tContentType: 'application/json',\n\t\t\t\t\t\tServerSideEncryption: 'AES256',\n\t\t\t\t\t\t...(expected === null\n\t\t\t\t\t\t\t? { IfNoneMatch: '*' }\n\t\t\t\t\t\t\t: { IfMatch: expected }),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.remember(stage, ETag);\n\t\t} catch (error) {\n\t\t\tif (lostRace(error)) {\n\t\t\t\tthis.etags.delete(stage);\n\t\t\t\tthrow new StageSecretsChanged(stage, `s3://${Bucket}/${Key}`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * The ETag the stage is now at. Some S3-compatible servers answer without\n\t * one: then nothing is remembered, and the next write asks for it first.\n\t */\n\tprivate remember(stage: string, etag: string | undefined): void {\n\t\tif (etag) this.etags.set(stage, etag);\n\t\telse this.etags.delete(stage);\n\t}\n\n\tprivate async currentEtag(\n\t\ts3: S3Client,\n\t\tstage: string,\n\t\tBucket: string,\n\t\tKey: string,\n\t): Promise<string | null> {\n\t\ttry {\n\t\t\tconst { ETag } = await this.call(stage, 'write', () =>\n\t\t\t\ts3.send(new HeadObjectCommand({ Bucket, Key })),\n\t\t\t);\n\t\t\treturn ETag ?? null;\n\t\t} catch (error) {\n\t\t\tif (notFound(error)) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- const require_discover = require("../discover-ojkcbxHw.cjs");
1
+ const require_discover = require("../discover-DL6h-J97.cjs");
2
2
  const require_sandbox = require("../sandbox-CHv3OYXg.cjs");
3
3
  const require_workerRuntime = require("../workerRuntime-BXfhbe13.cjs");
4
- const require_credentialSchemas = require("../credentialSchemas-AhIBuQxQ.cjs");
4
+ const require_credentialSchemas = require("../credentialSchemas-DFxvGEwa.cjs");
5
5
  let node_path = require("node:path");
6
6
  let node_fs_promises = require("node:fs/promises");
7
7
  //#region src/sandbox/credentials-worker.ts
@@ -1,7 +1,7 @@
1
- import { i as discover } from "../discover-BvJOVsYG.mjs";
1
+ import { i as discover } from "../discover-CzGM5P3p.mjs";
2
2
  import { t as SECRETS_DIR_ENV } from "../sandbox-CbVB7uOD.mjs";
3
3
  import { a as registerAdjacentTsconfig, n as answer, r as errorData } from "../workerRuntime-CsOyBRx2.mjs";
4
- import { a as liveCredentials, r as inspectLive } from "../credentialSchemas-DLKbxYBy.mjs";
4
+ import { a as liveCredentials, r as inspectLive } from "../credentialSchemas-DaMpt-Dx.mjs";
5
5
  import { join } from "node:path";
6
6
  import { readFile, readdir } from "node:fs/promises";
7
7
  //#region src/sandbox/credentials-worker.ts
@@ -1,4 +1,4 @@
1
- const require_discover = require("../discover-ojkcbxHw.cjs");
1
+ const require_discover = require("../discover-DL6h-J97.cjs");
2
2
  const require_workerRuntime = require("../workerRuntime-BXfhbe13.cjs");
3
3
  //#region src/sandbox/discover-worker.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { i as discover } from "../discover-BvJOVsYG.mjs";
1
+ import { i as discover } from "../discover-CzGM5P3p.mjs";
2
2
  import { a as registerAdjacentTsconfig, i as liveValuePaths, n as answer, r as errorData } from "../workerRuntime-CsOyBRx2.mjs";
3
3
  //#region src/sandbox/discover-worker.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- const require_discover = require("../discover-ojkcbxHw.cjs");
1
+ const require_discover = require("../discover-DL6h-J97.cjs");
2
2
  const require_sandbox = require("../sandbox-CHv3OYXg.cjs");
3
3
  const require_workerRuntime = require("../workerRuntime-BXfhbe13.cjs");
4
4
  const require_databases = require("../databases-fOaoBInm.cjs");
@@ -1,4 +1,4 @@
1
- import { i as discover } from "../discover-BvJOVsYG.mjs";
1
+ import { i as discover } from "../discover-CzGM5P3p.mjs";
2
2
  import { t as SECRETS_DIR_ENV } from "../sandbox-CbVB7uOD.mjs";
3
3
  import { a as registerAdjacentTsconfig, n as answer, r as errorData } from "../workerRuntime-CsOyBRx2.mjs";
4
4
  import { o as SeedFailed, p as seedDatabases, u as migrateDatabases } from "../databases-BPOgTn1u.mjs";