@geekmidas/cli 10.0.0-alpha.10 → 10.0.0-alpha.101

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 (489) hide show
  1. package/README.md +315 -414
  2. package/bin/adjacent-tsconfig.mjs +46 -8
  3. package/bin/gkm.mjs +11 -3
  4. package/bin/owning-tsconfig-jsx-register.mjs +18 -0
  5. package/bin/owning-tsconfig-jsx.mjs +108 -0
  6. package/dist/EndpointGenerator-Br97xgs_.mjs +1031 -0
  7. package/dist/EndpointGenerator-Br97xgs_.mjs.map +1 -0
  8. package/dist/EndpointGenerator-By5_tYE9.cjs +1090 -0
  9. package/dist/EndpointGenerator-By5_tYE9.cjs.map +1 -0
  10. package/dist/GoDaddyProvider-BOuLf_Py.cjs +388 -0
  11. package/dist/GoDaddyProvider-BOuLf_Py.cjs.map +1 -0
  12. package/dist/GoDaddyProvider-u9MF-Dqk.mjs +388 -0
  13. package/dist/GoDaddyProvider-u9MF-Dqk.mjs.map +1 -0
  14. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-BNpS9aRJ.mjs} +29 -25
  15. package/dist/HostingerProvider-BNpS9aRJ.mjs.map +1 -0
  16. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-DR1iws1P.cjs} +29 -25
  17. package/dist/HostingerProvider-DR1iws1P.cjs.map +1 -0
  18. package/dist/LegacyStateStore-DWmHGNgH.cjs +124 -0
  19. package/dist/LegacyStateStore-DWmHGNgH.cjs.map +1 -0
  20. package/dist/LegacyStateStore-vhkx7Bbq.mjs +124 -0
  21. package/dist/LegacyStateStore-vhkx7Bbq.mjs.map +1 -0
  22. package/dist/LocalStateStore-BVKDADoG.cjs +178 -0
  23. package/dist/LocalStateStore-BVKDADoG.cjs.map +1 -0
  24. package/dist/LocalStateStore-FVsg0UoM.mjs +167 -0
  25. package/dist/LocalStateStore-FVsg0UoM.mjs.map +1 -0
  26. package/dist/OpenApiTsGenerator-BgSX_Z-e.cjs +541 -0
  27. package/dist/OpenApiTsGenerator-BgSX_Z-e.cjs.map +1 -0
  28. package/dist/OpenApiTsGenerator-C8aTX--y.mjs +536 -0
  29. package/dist/OpenApiTsGenerator-C8aTX--y.mjs.map +1 -0
  30. package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-Bllus2NR.cjs} +21 -22
  31. package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
  32. package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-QXxjkZO1.mjs} +13 -13
  33. package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
  34. package/dist/S3StateStore-B8seZUsw.mjs +223 -0
  35. package/dist/S3StateStore-B8seZUsw.mjs.map +1 -0
  36. package/dist/S3StateStore-B_2gE9Un.cjs +222 -0
  37. package/dist/S3StateStore-B_2gE9Un.cjs.map +1 -0
  38. package/dist/SSMStateStore-CTDEI5Bi.cjs +204 -0
  39. package/dist/SSMStateStore-CTDEI5Bi.cjs.map +1 -0
  40. package/dist/SSMStateStore-DGTbBomw.mjs +205 -0
  41. package/dist/SSMStateStore-DGTbBomw.mjs.map +1 -0
  42. package/dist/SubscriberGenerator-1-IsjIwF.mjs +449 -0
  43. package/dist/SubscriberGenerator-1-IsjIwF.mjs.map +1 -0
  44. package/dist/SubscriberGenerator-BlIOdbi-.cjs +490 -0
  45. package/dist/SubscriberGenerator-BlIOdbi-.cjs.map +1 -0
  46. package/dist/add-BB2tLVc2.cjs +720 -0
  47. package/dist/add-BB2tLVc2.cjs.map +1 -0
  48. package/dist/add-CIbhGE5v.mjs +718 -0
  49. package/dist/add-CIbhGE5v.mjs.map +1 -0
  50. package/dist/appPorts-C9z9Pzn9.mjs +223 -0
  51. package/dist/appPorts-C9z9Pzn9.mjs.map +1 -0
  52. package/dist/appPorts-Cu79hJF6.cjs +264 -0
  53. package/dist/appPorts-Cu79hJF6.cjs.map +1 -0
  54. package/dist/aws-8QQ8n-t6.mjs +89 -0
  55. package/dist/aws-8QQ8n-t6.mjs.map +1 -0
  56. package/dist/aws-DY9NqQIT.cjs +100 -0
  57. package/dist/aws-DY9NqQIT.cjs.map +1 -0
  58. package/dist/awsStore-Bx5nCFnS.mjs +121 -0
  59. package/dist/awsStore-Bx5nCFnS.mjs.map +1 -0
  60. package/dist/awsStore-u3ehhMoY.cjs +138 -0
  61. package/dist/awsStore-u3ehhMoY.cjs.map +1 -0
  62. package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-C8DnCmxK.mjs} +11 -8
  63. package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
  64. package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-oDEsPj02.cjs} +22 -20
  65. package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
  66. package/dist/backups/runner.cjs +519 -0
  67. package/dist/backups/runner.cjs.map +1 -0
  68. package/dist/backups/runner.d.cts +102 -0
  69. package/dist/backups/runner.d.cts.map +1 -0
  70. package/dist/backups/runner.d.mts +102 -0
  71. package/dist/backups/runner.d.mts.map +1 -0
  72. package/dist/backups/runner.mjs +506 -0
  73. package/dist/backups/runner.mjs.map +1 -0
  74. package/dist/{bundler-BY1OmV1e.cjs → bundler-Ba6BER3w.cjs} +38 -35
  75. package/dist/bundler-Ba6BER3w.cjs.map +1 -0
  76. package/dist/{bundler-Be8Zg4Wd.mjs → bundler-CHjRYVKh.mjs} +36 -32
  77. package/dist/bundler-CHjRYVKh.mjs.map +1 -0
  78. package/dist/cli-CtlqYRlN.cjs +71 -0
  79. package/dist/cli-CtlqYRlN.cjs.map +1 -0
  80. package/dist/cli-DOlkhrsh.mjs +71 -0
  81. package/dist/cli-DOlkhrsh.mjs.map +1 -0
  82. package/dist/compose-FDP_TaFt.mjs +3154 -0
  83. package/dist/compose-FDP_TaFt.mjs.map +1 -0
  84. package/dist/compose-uAWLy-nR.cjs +3267 -0
  85. package/dist/compose-uAWLy-nR.cjs.map +1 -0
  86. package/dist/config-D48erO2j.d.mts +269 -0
  87. package/dist/config-D48erO2j.d.mts.map +1 -0
  88. package/dist/config-DHDtsQrB.d.cts +269 -0
  89. package/dist/config-DHDtsQrB.d.cts.map +1 -0
  90. package/dist/config.cjs +421 -11
  91. package/dist/config.cjs.map +1 -0
  92. package/dist/config.d.cts +4 -120
  93. package/dist/config.d.mts +4 -120
  94. package/dist/config.mjs +405 -4
  95. package/dist/config.mjs.map +1 -0
  96. package/dist/credentialSchemas-DDda4Mmm.cjs +272 -0
  97. package/dist/credentialSchemas-DDda4Mmm.cjs.map +1 -0
  98. package/dist/credentialSchemas-DvitraL-.mjs +237 -0
  99. package/dist/credentialSchemas-DvitraL-.mjs.map +1 -0
  100. package/dist/credentials-B5N5yKk6.mjs +267 -0
  101. package/dist/credentials-B5N5yKk6.mjs.map +1 -0
  102. package/dist/credentials-Zqr3QQYB.cjs +350 -0
  103. package/dist/credentials-Zqr3QQYB.cjs.map +1 -0
  104. package/dist/databases-BeGP5eDh.mjs +495 -0
  105. package/dist/databases-BeGP5eDh.mjs.map +1 -0
  106. package/dist/databases-DGALFDG3.cjs +598 -0
  107. package/dist/databases-DGALFDG3.cjs.map +1 -0
  108. package/dist/define-6poNqm5O.mjs +106 -0
  109. package/dist/define-6poNqm5O.mjs.map +1 -0
  110. package/dist/define-crmMcXFS.cjs +153 -0
  111. package/dist/define-crmMcXFS.cjs.map +1 -0
  112. package/dist/deploy/public.cjs +212 -0
  113. package/dist/deploy/public.cjs.map +1 -0
  114. package/dist/deploy/public.d.cts +653 -0
  115. package/dist/deploy/public.d.cts.map +1 -0
  116. package/dist/deploy/public.d.mts +653 -0
  117. package/dist/deploy/public.d.mts.map +1 -0
  118. package/dist/deploy/public.mjs +145 -0
  119. package/dist/deploy/public.mjs.map +1 -0
  120. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  121. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  122. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  123. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  124. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  125. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  126. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  127. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  128. package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
  129. package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
  130. package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
  131. package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
  132. package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
  133. package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
  134. package/dist/deploy/sniffer-hooks.cjs +13 -7
  135. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  136. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  137. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  138. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  139. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  140. package/dist/deploy/sniffer-hooks.mjs +10 -3
  141. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  142. package/dist/deploy/sniffer-loader.cjs +16 -7
  143. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  144. package/dist/deploy/sniffer-loader.d.cts +1 -1
  145. package/dist/deploy/sniffer-loader.d.mts +1 -1
  146. package/dist/deploy/sniffer-loader.mjs +14 -3
  147. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  148. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  149. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  150. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  151. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  152. package/dist/deploy/sniffer-routes-worker.mjs +4 -4
  153. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  154. package/dist/deploy/sniffer-worker.cjs +15 -6
  155. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  156. package/dist/deploy/sniffer-worker.d.cts +1 -3
  157. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  158. package/dist/deploy/sniffer-worker.d.mts +1 -3
  159. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  160. package/dist/deploy/sniffer-worker.mjs +15 -4
  161. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  162. package/dist/deploy-DUUc3jV9.cjs +2390 -0
  163. package/dist/deploy-DUUc3jV9.cjs.map +1 -0
  164. package/dist/deploy-DgZxTnGS.mjs +2317 -0
  165. package/dist/deploy-DgZxTnGS.mjs.map +1 -0
  166. package/dist/derive-B4vDpzgP.mjs +150 -0
  167. package/dist/derive-B4vDpzgP.mjs.map +1 -0
  168. package/dist/derive-DAbo49sm.cjs +161 -0
  169. package/dist/derive-DAbo49sm.cjs.map +1 -0
  170. package/dist/discover-BfhVW_kT.cjs +600 -0
  171. package/dist/discover-BfhVW_kT.cjs.map +1 -0
  172. package/dist/discover-CvTtV5ZD.d.cts +108 -0
  173. package/dist/discover-CvTtV5ZD.d.cts.map +1 -0
  174. package/dist/discover-W2kab9Lc.d.mts +108 -0
  175. package/dist/discover-W2kab9Lc.d.mts.map +1 -0
  176. package/dist/discover-kziEht4W.mjs +527 -0
  177. package/dist/discover-kziEht4W.mjs.map +1 -0
  178. package/dist/dns-DDDCfj75.mjs +926 -0
  179. package/dist/dns-DDDCfj75.mjs.map +1 -0
  180. package/dist/dns-DnE_02tB.cjs +1057 -0
  181. package/dist/dns-DnE_02tB.cjs.map +1 -0
  182. package/dist/dokploy-BrfdeVEu.cjs +38 -0
  183. package/dist/dokploy-BrfdeVEu.cjs.map +1 -0
  184. package/dist/dokploy-DBlGSdnb.mjs +38 -0
  185. package/dist/dokploy-DBlGSdnb.mjs.map +1 -0
  186. package/dist/drivers-BLU1fNs_.cjs +200 -0
  187. package/dist/drivers-BLU1fNs_.cjs.map +1 -0
  188. package/dist/drivers-C08LL4E8.mjs +177 -0
  189. package/dist/drivers-C08LL4E8.mjs.map +1 -0
  190. package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
  191. package/dist/emit-C1e8qD08.mjs.map +1 -0
  192. package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
  193. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  194. package/dist/encryption-CeW3xpE1.cjs +90 -0
  195. package/dist/encryption-CeW3xpE1.cjs.map +1 -0
  196. package/dist/encryption-DC8zsh2s.mjs +89 -0
  197. package/dist/encryption-DC8zsh2s.mjs.map +1 -0
  198. package/dist/engine-BXxvcxVq.cjs +3195 -0
  199. package/dist/engine-BXxvcxVq.cjs.map +1 -0
  200. package/dist/engine-z0UClzE9.mjs +3082 -0
  201. package/dist/engine-z0UClzE9.mjs.map +1 -0
  202. package/dist/errors-D8Gwp5kU.mjs +23 -0
  203. package/dist/errors-D8Gwp5kU.mjs.map +1 -0
  204. package/dist/errors-DMC4Umsb.cjs +34 -0
  205. package/dist/errors-DMC4Umsb.cjs.map +1 -0
  206. package/dist/github-DJgO5z37.mjs +829 -0
  207. package/dist/github-DJgO5z37.mjs.map +1 -0
  208. package/dist/github-DWoFgxtl.cjs +829 -0
  209. package/dist/github-DWoFgxtl.cjs.map +1 -0
  210. package/dist/identity-CBXr4wNi.mjs +129 -0
  211. package/dist/identity-CBXr4wNi.mjs.map +1 -0
  212. package/dist/identity-CbLfgQNT.cjs +182 -0
  213. package/dist/identity-CbLfgQNT.cjs.map +1 -0
  214. package/dist/{index-C6e-ULLx.d.mts → index-8OfpOtSI.d.cts} +39 -24
  215. package/dist/index-8OfpOtSI.d.cts.map +1 -0
  216. package/dist/{index-CR5urhWX.d.cts → index-Dpji6Bxq.d.mts} +39 -24
  217. package/dist/index-Dpji6Bxq.d.mts.map +1 -0
  218. package/dist/index.cjs +10022 -12718
  219. package/dist/index.cjs.map +1 -1
  220. package/dist/index.d.cts +1 -1
  221. package/dist/index.d.mts +1 -1
  222. package/dist/index.mjs +10648 -13356
  223. package/dist/index.mjs.map +1 -1
  224. package/dist/local-BwC2v2Y8.mjs +224 -0
  225. package/dist/local-BwC2v2Y8.mjs.map +1 -0
  226. package/dist/local-DNhnkugT.cjs +241 -0
  227. package/dist/local-DNhnkugT.cjs.map +1 -0
  228. package/dist/migrate-B1OjPwUY.cjs +181 -0
  229. package/dist/migrate-B1OjPwUY.cjs.map +1 -0
  230. package/dist/migrate-CWSCkzu3.cjs +271 -0
  231. package/dist/migrate-CWSCkzu3.cjs.map +1 -0
  232. package/dist/migrate-DIVxoju6.mjs +266 -0
  233. package/dist/migrate-DIVxoju6.mjs.map +1 -0
  234. package/dist/migrate-DoI2hWNH.mjs +181 -0
  235. package/dist/migrate-DoI2hWNH.mjs.map +1 -0
  236. package/dist/openapi.cjs +214 -10
  237. package/dist/openapi.cjs.map +1 -0
  238. package/dist/openapi.d.cts +38 -17
  239. package/dist/openapi.d.cts.map +1 -1
  240. package/dist/openapi.d.mts +38 -17
  241. package/dist/openapi.d.mts.map +1 -1
  242. package/dist/openapi.mjs +208 -5
  243. package/dist/openapi.mjs.map +1 -0
  244. package/dist/projectBucket-BBbQ1lHF.cjs +263 -0
  245. package/dist/projectBucket-BBbQ1lHF.cjs.map +1 -0
  246. package/dist/projectBucket-C_DN4WzF.mjs +222 -0
  247. package/dist/projectBucket-C_DN4WzF.mjs.map +1 -0
  248. package/dist/provider-BqpjG9QM.cjs +57 -0
  249. package/dist/provider-BqpjG9QM.cjs.map +1 -0
  250. package/dist/provider-CEOKk8NS.mjs +46 -0
  251. package/dist/provider-CEOKk8NS.mjs.map +1 -0
  252. package/dist/ready-BtxiI7Qb.cjs +403 -0
  253. package/dist/ready-BtxiI7Qb.cjs.map +1 -0
  254. package/dist/ready-CzHNHhI6.mjs +374 -0
  255. package/dist/ready-CzHNHhI6.mjs.map +1 -0
  256. package/dist/reconcile/public.cjs +3 -5
  257. package/dist/reconcile/public.d.cts +11 -87
  258. package/dist/reconcile/public.d.cts.map +1 -1
  259. package/dist/reconcile/public.d.mts +11 -87
  260. package/dist/reconcile/public.d.mts.map +1 -1
  261. package/dist/reconcile/public.mjs +3 -4
  262. package/dist/{reconcile-CFs8C_1a.mjs → reconcile--I7V4Klj.mjs} +4 -7
  263. package/dist/reconcile--I7V4Klj.mjs.map +1 -0
  264. package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
  265. package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
  266. package/dist/resolve-WAwYMN6q.cjs +316 -0
  267. package/dist/resolve-WAwYMN6q.cjs.map +1 -0
  268. package/dist/resolve-pmXIdi9j.mjs +263 -0
  269. package/dist/resolve-pmXIdi9j.mjs.map +1 -0
  270. package/dist/rollback-CLtwbByg.mjs +136 -0
  271. package/dist/rollback-CLtwbByg.mjs.map +1 -0
  272. package/dist/rollback-Cz8F9xSB.cjs +165 -0
  273. package/dist/rollback-Cz8F9xSB.cjs.map +1 -0
  274. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  275. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  276. package/dist/run-BJLIerMM.mjs +133 -0
  277. package/dist/run-BJLIerMM.mjs.map +1 -0
  278. package/dist/run-fVZ-rLnc.cjs +174 -0
  279. package/dist/run-fVZ-rLnc.cjs.map +1 -0
  280. package/dist/runtime-ACdfK59n.d.cts +82 -0
  281. package/dist/runtime-ACdfK59n.d.cts.map +1 -0
  282. package/dist/runtime-YyQuekxi.d.mts +82 -0
  283. package/dist/runtime-YyQuekxi.d.mts.map +1 -0
  284. package/dist/s3-CrPoA89T.cjs +215 -0
  285. package/dist/s3-CrPoA89T.cjs.map +1 -0
  286. package/dist/s3-DQXZdmCM.mjs +215 -0
  287. package/dist/s3-DQXZdmCM.mjs.map +1 -0
  288. package/dist/sandbox/config-worker.cjs +43 -0
  289. package/dist/sandbox/config-worker.cjs.map +1 -0
  290. package/dist/sandbox/config-worker.d.cts +1 -0
  291. package/dist/sandbox/config-worker.d.mts +1 -0
  292. package/dist/sandbox/config-worker.mjs +44 -0
  293. package/dist/sandbox/config-worker.mjs.map +1 -0
  294. package/dist/sandbox/credentials-worker.cjs +54 -0
  295. package/dist/sandbox/credentials-worker.cjs.map +1 -0
  296. package/dist/sandbox/credentials-worker.d.cts +1 -0
  297. package/dist/sandbox/credentials-worker.d.mts +1 -0
  298. package/dist/sandbox/credentials-worker.mjs +55 -0
  299. package/dist/sandbox/credentials-worker.mjs.map +1 -0
  300. package/dist/sandbox/discover-worker.cjs +47 -0
  301. package/dist/sandbox/discover-worker.cjs.map +1 -0
  302. package/dist/sandbox/discover-worker.d.cts +1 -0
  303. package/dist/sandbox/discover-worker.d.mts +1 -0
  304. package/dist/sandbox/discover-worker.mjs +48 -0
  305. package/dist/sandbox/discover-worker.mjs.map +1 -0
  306. package/dist/sandbox/migrate-worker.cjs +75 -0
  307. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  308. package/dist/sandbox/migrate-worker.d.cts +1 -0
  309. package/dist/sandbox/migrate-worker.d.mts +1 -0
  310. package/dist/sandbox/migrate-worker.mjs +76 -0
  311. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  312. package/dist/sandbox-C4g1eG31.d.mts +104 -0
  313. package/dist/sandbox-C4g1eG31.d.mts.map +1 -0
  314. package/dist/sandbox-CHv3OYXg.cjs +165 -0
  315. package/dist/sandbox-CHv3OYXg.cjs.map +1 -0
  316. package/dist/sandbox-CbVB7uOD.mjs +118 -0
  317. package/dist/sandbox-CbVB7uOD.mjs.map +1 -0
  318. package/dist/sandbox-CdKgQ3XU.d.cts +104 -0
  319. package/dist/sandbox-CdKgQ3XU.d.cts.map +1 -0
  320. package/dist/{workspace-C6VJQVtG.cjs → schemas-BCwKKA42.mjs} +958 -1842
  321. package/dist/schemas-BCwKKA42.mjs.map +1 -0
  322. package/dist/{workspace-zoqRbihZ.mjs → schemas-BQ_v0lEX.cjs} +1048 -1658
  323. package/dist/schemas-BQ_v0lEX.cjs.map +1 -0
  324. package/dist/secretsManager-CQORubp9.mjs +97 -0
  325. package/dist/secretsManager-CQORubp9.mjs.map +1 -0
  326. package/dist/secretsManager-RAGcEDX1.cjs +108 -0
  327. package/dist/secretsManager-RAGcEDX1.cjs.map +1 -0
  328. package/dist/seeds-BHKUAExH.mjs +8148 -0
  329. package/dist/seeds-BHKUAExH.mjs.map +1 -0
  330. package/dist/seeds-Dk4WHhjU.cjs +9115 -0
  331. package/dist/seeds-Dk4WHhjU.cjs.map +1 -0
  332. package/dist/sniffer-BjBZ01PE.cjs +1998 -0
  333. package/dist/sniffer-BjBZ01PE.cjs.map +1 -0
  334. package/dist/sniffer-CaXl51vO.mjs +1825 -0
  335. package/dist/sniffer-CaXl51vO.mjs.map +1 -0
  336. package/dist/sst-B-Uz4cvm.cjs +464 -0
  337. package/dist/sst-B-Uz4cvm.cjs.map +1 -0
  338. package/dist/sst-C1pxbFEd.mjs +441 -0
  339. package/dist/sst-C1pxbFEd.mjs.map +1 -0
  340. package/dist/stages-DJrOYLZ-.mjs +176 -0
  341. package/dist/stages-DJrOYLZ-.mjs.map +1 -0
  342. package/dist/stages-_3RVNG83.cjs +176 -0
  343. package/dist/stages-_3RVNG83.cjs.map +1 -0
  344. package/dist/target/public.cjs +15 -0
  345. package/dist/target/public.d.cts +28 -0
  346. package/dist/target/public.d.cts.map +1 -0
  347. package/dist/target/public.d.mts +28 -0
  348. package/dist/target/public.d.mts.map +1 -0
  349. package/dist/target/public.mjs +4 -0
  350. package/dist/terminal-Bs_lNQhL.mjs +85 -0
  351. package/dist/terminal-Bs_lNQhL.mjs.map +1 -0
  352. package/dist/terminal-CsQz4oT0.cjs +85 -0
  353. package/dist/terminal-CsQz4oT0.cjs.map +1 -0
  354. package/dist/types-B6UXlEkf.d.cts +7650 -0
  355. package/dist/types-B6UXlEkf.d.cts.map +1 -0
  356. package/dist/types-HqVPddRK.d.mts +7649 -0
  357. package/dist/types-HqVPddRK.d.mts.map +1 -0
  358. package/dist/utils-D2Nk1Nv2.cjs +205 -0
  359. package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
  360. package/dist/utils-D_fxUqvU.mjs +156 -0
  361. package/dist/utils-D_fxUqvU.mjs.map +1 -0
  362. package/dist/vitest.cjs +65 -0
  363. package/dist/vitest.cjs.map +1 -0
  364. package/dist/vitest.d.cts +29 -0
  365. package/dist/vitest.d.cts.map +1 -0
  366. package/dist/vitest.d.mts +29 -0
  367. package/dist/vitest.d.mts.map +1 -0
  368. package/dist/vitest.mjs +65 -0
  369. package/dist/vitest.mjs.map +1 -0
  370. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  371. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  372. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  373. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  374. package/dist/workspace/index.cjs +8 -4
  375. package/dist/workspace/index.d.cts +3 -3
  376. package/dist/workspace/index.d.mts +3 -3
  377. package/dist/workspace/index.mjs +2 -3
  378. package/dist/workspace-BwqQnool.cjs +2806 -0
  379. package/dist/workspace-BwqQnool.cjs.map +1 -0
  380. package/dist/workspace-D1QbNd55.mjs +2394 -0
  381. package/dist/workspace-D1QbNd55.mjs.map +1 -0
  382. package/package.json +54 -22
  383. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  384. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  385. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  386. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  387. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  388. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  389. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  390. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  391. package/dist/LocalStateProvider-Bn6tS-oL.mjs +0 -42
  392. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  393. package/dist/LocalStateProvider-Db9SEjyH.cjs +0 -43
  394. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  395. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  396. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  397. package/dist/SSMStateProvider-BRt2py-A.mjs +0 -66
  398. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  399. package/dist/SSMStateProvider-DyX8s9HI.cjs +0 -66
  400. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  401. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  402. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  403. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  404. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  405. package/dist/chunk-Duj1WY3L.mjs +0 -7
  406. package/dist/config-BZ1F0WuA.cjs +0 -462
  407. package/dist/config-BZ1F0WuA.cjs.map +0 -1
  408. package/dist/config-DVVph9yz.mjs +0 -402
  409. package/dist/config-DVVph9yz.mjs.map +0 -1
  410. package/dist/config.d.cts.map +0 -1
  411. package/dist/config.d.mts.map +0 -1
  412. package/dist/credentials-B5zRHdAl.mjs +0 -141
  413. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  414. package/dist/credentials-BapzjyV5.cjs +0 -195
  415. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  416. package/dist/credentials-Xamqe_NJ.cjs +0 -2681
  417. package/dist/credentials-Xamqe_NJ.cjs.map +0 -1
  418. package/dist/credentials-dP8vRVRv.mjs +0 -2549
  419. package/dist/credentials-dP8vRVRv.mjs.map +0 -1
  420. package/dist/discover-CAlFgYec.mjs +0 -229
  421. package/dist/discover-CAlFgYec.mjs.map +0 -1
  422. package/dist/discover-DTmFeloL.cjs +0 -271
  423. package/dist/discover-DTmFeloL.cjs.map +0 -1
  424. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  425. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  426. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  427. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  428. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  429. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  430. package/dist/emit-CbcRolsa.cjs.map +0 -1
  431. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  432. package/dist/encryption-C6jaU0hE.cjs +0 -54
  433. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  434. package/dist/encryption-CHzzeR8a.cjs +0 -4
  435. package/dist/encryption-CQUncu7v.mjs +0 -3
  436. package/dist/encryption-D-abyhZx.mjs +0 -42
  437. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  438. package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
  439. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  440. package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
  441. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  442. package/dist/generator-CNzBw7g5.cjs +0 -289
  443. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  444. package/dist/generator-VE2JrFlY.mjs +0 -253
  445. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  446. package/dist/index-C6e-ULLx.d.mts.map +0 -1
  447. package/dist/index-CR5urhWX.d.cts.map +0 -1
  448. package/dist/openapi-SjsgARie.cjs +0 -2075
  449. package/dist/openapi-SjsgARie.cjs.map +0 -1
  450. package/dist/openapi-Xx0A7Wg0.mjs +0 -2021
  451. package/dist/openapi-Xx0A7Wg0.mjs.map +0 -1
  452. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  453. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  454. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  455. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  456. package/dist/openapi-react-query.cjs +0 -4
  457. package/dist/openapi-react-query.d.cts +0 -11
  458. package/dist/openapi-react-query.d.cts.map +0 -1
  459. package/dist/openapi-react-query.d.mts +0 -11
  460. package/dist/openapi-react-query.d.mts.map +0 -1
  461. package/dist/openapi-react-query.mjs +0 -4
  462. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  463. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  464. package/dist/setup-BA8ciTPU.mjs +0 -11
  465. package/dist/setup-BsZvZP6f.cjs +0 -11
  466. package/dist/setup-C8KOx8_8.mjs +0 -443
  467. package/dist/setup-C8KOx8_8.mjs.map +0 -1
  468. package/dist/setup-hC6hI86f.cjs +0 -473
  469. package/dist/setup-hC6hI86f.cjs.map +0 -1
  470. package/dist/storage-BJmzYxt8.cjs +0 -363
  471. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  472. package/dist/storage-BM9hGpgv.cjs +0 -7
  473. package/dist/storage-Bi24WfoW.mjs +0 -297
  474. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  475. package/dist/storage-CYlGwWTj.mjs +0 -3
  476. package/dist/sync-CmEuNZsB.mjs +0 -76
  477. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  478. package/dist/sync-D306yOWu.cjs +0 -4
  479. package/dist/sync-SizaChmC.cjs +0 -93
  480. package/dist/sync-SizaChmC.cjs.map +0 -1
  481. package/dist/sync-hOqAWHR6.mjs +0 -3
  482. package/dist/types-6pkp2RRj.d.mts +0 -2220
  483. package/dist/types-6pkp2RRj.d.mts.map +0 -1
  484. package/dist/types-Y3fKQSAK.d.cts +0 -2220
  485. package/dist/types-Y3fKQSAK.d.cts.map +0 -1
  486. package/dist/workspace-BzrG_2SI.mjs +0 -8
  487. package/dist/workspace-C6VJQVtG.cjs.map +0 -1
  488. package/dist/workspace-XXtNhqJl.cjs +0 -9
  489. package/dist/workspace-zoqRbihZ.mjs.map +0 -1
@@ -0,0 +1,89 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
+ import { n as serializeWithin, r as withStageCredentials, t as awsClientConfig } from "./awsStore-Bx5nCFnS.mjs";
3
+ import { GetParameterCommand, ParameterNotFound, PutParameterCommand, SSMClient } from "@aws-sdk/client-ssm";
4
+ //#region src/secrets/aws.ts
5
+ /**
6
+ * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.
7
+ *
8
+ * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —
9
+ * encrypted at rest by KMS, so nothing about it needs a key file anywhere.
10
+ * Which account it is in is whichever credentials are active: the stage's
11
+ * OIDC role in a deploy job, or `--profile` on a developer's machine. With
12
+ * staging and production in different accounts, each stage's secrets sit
13
+ * beside its infrastructure, and a staging role cannot read production's.
14
+ *
15
+ * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free
16
+ * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB
17
+ * the write is refused with {@link StageSecretsTooLarge} before AWS is
18
+ * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.
19
+ */
20
+ var aws_exports = /* @__PURE__ */ __exportAll({
21
+ AwsSecretsStore: () => AwsSecretsStore,
22
+ SSM_PARAMETER_LIMIT: () => SSM_PARAMETER_LIMIT,
23
+ secretsParameterName: () => secretsParameterName
24
+ });
25
+ /** The most an SSM parameter holds: 8 KB, in the advanced tier. */
26
+ const SSM_PARAMETER_LIMIT = 8192;
27
+ /** The parameter a stage's secrets are kept in. */
28
+ function secretsParameterName(project, stage) {
29
+ return `/gkm/${project}/${stage}/secrets`;
30
+ }
31
+ var AwsSecretsStore = class {
32
+ options;
33
+ name = "ssm";
34
+ client;
35
+ constructor(options) {
36
+ this.options = options;
37
+ }
38
+ async ssm() {
39
+ if (this.client) return this.client;
40
+ this.client = new SSMClient(await awsClientConfig(this.options));
41
+ return this.client;
42
+ }
43
+ /** Where a call for `stage` is, for an error saying it has no credentials. */
44
+ context(stage, access) {
45
+ return {
46
+ stage,
47
+ store: this.name,
48
+ profile: this.options.profile,
49
+ access
50
+ };
51
+ }
52
+ /**
53
+ * @throws {StageSecretsUnreadable} when there are no AWS credentials to
54
+ * read it with, or they have expired
55
+ */
56
+ async read(stage) {
57
+ const ssm = await this.ssm();
58
+ try {
59
+ const { Parameter } = await withStageCredentials(this.context(stage, "read"), () => ssm.send(new GetParameterCommand({
60
+ Name: secretsParameterName(this.options.project, stage),
61
+ WithDecryption: true
62
+ })));
63
+ return Parameter?.Value ? JSON.parse(Parameter.Value) : null;
64
+ } catch (error) {
65
+ if (error instanceof ParameterNotFound) return null;
66
+ throw error;
67
+ }
68
+ }
69
+ /**
70
+ * @throws {StageSecretsUnreadable} when there are no AWS credentials to
71
+ * write it with, or they have expired
72
+ */
73
+ async write(stage, secrets) {
74
+ const value = serializeWithin(stage, this.name, secrets, SSM_PARAMETER_LIMIT);
75
+ const ssm = await this.ssm();
76
+ await withStageCredentials(this.context(stage, "write"), () => ssm.send(new PutParameterCommand({
77
+ Name: secretsParameterName(this.options.project, stage),
78
+ Value: value,
79
+ Type: "SecureString",
80
+ Tier: "Intelligent-Tiering",
81
+ Overwrite: true,
82
+ Description: `gkm secrets for ${this.options.project}/${stage}`
83
+ })));
84
+ }
85
+ };
86
+ //#endregion
87
+ export { secretsParameterName as n, aws_exports as t };
88
+
89
+ //# sourceMappingURL=aws-8QQ8n-t6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-8QQ8n-t6.mjs","names":[],"sources":["../src/secrets/aws.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n *\n * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free\n * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB\n * the write is refused with {@link StageSecretsTooLarge} before AWS is\n * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n} from '@aws-sdk/client-ssm';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\tserializeWithin,\n\twithStageCredentials,\n} from './awsStore.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport type AwsSecretsStoreOptions = AwsStoreOptions;\n\n/** The most an SSM parameter holds: 8 KB, in the advanced tier. */\nexport const SSM_PARAMETER_LIMIT = 8 * 1024;\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class AwsSecretsStore implements SecretsStore {\n\treadonly name = 'ssm';\n\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: AwsSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tthis.client = new SSMClient(await awsClientConfig(this.options));\n\t\treturn this.client;\n\t}\n\n\t/** Where a call for `stage` is, for an error saying it has no credentials. */\n\tprivate context(stage: string, access: 'read' | 'write') {\n\t\treturn { stage, store: this.name, profile: this.options.profile, access };\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 ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await withStageCredentials(\n\t\t\t\tthis.context(stage, 'read'),\n\t\t\t\t() =>\n\t\t\t\t\tssm.send(\n\t\t\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\t\t\tWithDecryption: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\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 value = serializeWithin(\n\t\t\tstage,\n\t\t\tthis.name,\n\t\t\tsecrets,\n\t\t\tSSM_PARAMETER_LIMIT,\n\t\t);\n\t\tconst ssm = await this.ssm();\n\n\t\tawait withStageCredentials(this.context(stage, 'write'), () =>\n\t\t\tssm.send(\n\t\t\t\tnew PutParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tValue: value,\n\t\t\t\t\tType: 'SecureString',\n\t\t\t\t\t// Standard (free) under 4 KB, advanced past it; never the other way.\n\t\t\t\t\tTier: 'Intelligent-Tiering',\n\t\t\t\t\tOverwrite: true,\n\t\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAa,sBAAsB;;AAGnC,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAKvB;CAJ7B,OAAgB;CAEhB;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,KAAK,SAAS,IAAI,UAAU,MAAM,gBAAgB,KAAK,OAAO,CAAC;EAC/D,OAAO,KAAK;CACb;;CAGA,QAAgB,OAAe,QAA0B;EACxD,OAAO;GAAE;GAAO,OAAO,KAAK;GAAM,SAAS,KAAK,QAAQ;GAAS;EAAO;CACzE;;;;;CAMA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAM,qBAC3B,KAAK,QAAQ,OAAO,MAAM,SAEzB,IAAI,KACH,IAAI,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiB,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;;;;;CAMA,MAAM,MAAM,OAAe,SAAsC;EAChE,MAAM,QAAQ,gBACb,OACA,KAAK,MACL,SACA,mBACD;EACA,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,MAAM,qBAAqB,KAAK,QAAQ,OAAO,OAAO,SACrD,IAAI,KACH,IAAI,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO;GACP,MAAM;GAEN,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF,CACD;CACD;AACD"}
@@ -0,0 +1,100 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
+ const require_awsStore = require("./awsStore-u3ehhMoY.cjs");
3
+ let _aws_sdk_client_ssm = require("@aws-sdk/client-ssm");
4
+ //#region src/secrets/aws.ts
5
+ /**
6
+ * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.
7
+ *
8
+ * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —
9
+ * encrypted at rest by KMS, so nothing about it needs a key file anywhere.
10
+ * Which account it is in is whichever credentials are active: the stage's
11
+ * OIDC role in a deploy job, or `--profile` on a developer's machine. With
12
+ * staging and production in different accounts, each stage's secrets sit
13
+ * beside its infrastructure, and a staging role cannot read production's.
14
+ *
15
+ * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free
16
+ * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB
17
+ * the write is refused with {@link StageSecretsTooLarge} before AWS is
18
+ * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.
19
+ */
20
+ var aws_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
21
+ AwsSecretsStore: () => AwsSecretsStore,
22
+ SSM_PARAMETER_LIMIT: () => SSM_PARAMETER_LIMIT,
23
+ secretsParameterName: () => secretsParameterName
24
+ });
25
+ /** The most an SSM parameter holds: 8 KB, in the advanced tier. */
26
+ const SSM_PARAMETER_LIMIT = 8192;
27
+ /** The parameter a stage's secrets are kept in. */
28
+ function secretsParameterName(project, stage) {
29
+ return `/gkm/${project}/${stage}/secrets`;
30
+ }
31
+ var AwsSecretsStore = class {
32
+ options;
33
+ name = "ssm";
34
+ client;
35
+ constructor(options) {
36
+ this.options = options;
37
+ }
38
+ async ssm() {
39
+ if (this.client) return this.client;
40
+ this.client = new _aws_sdk_client_ssm.SSMClient(await require_awsStore.awsClientConfig(this.options));
41
+ return this.client;
42
+ }
43
+ /** Where a call for `stage` is, for an error saying it has no credentials. */
44
+ context(stage, access) {
45
+ return {
46
+ stage,
47
+ store: this.name,
48
+ profile: this.options.profile,
49
+ access
50
+ };
51
+ }
52
+ /**
53
+ * @throws {StageSecretsUnreadable} when there are no AWS credentials to
54
+ * read it with, or they have expired
55
+ */
56
+ async read(stage) {
57
+ const ssm = await this.ssm();
58
+ try {
59
+ const { Parameter } = await require_awsStore.withStageCredentials(this.context(stage, "read"), () => ssm.send(new _aws_sdk_client_ssm.GetParameterCommand({
60
+ Name: secretsParameterName(this.options.project, stage),
61
+ WithDecryption: true
62
+ })));
63
+ return Parameter?.Value ? JSON.parse(Parameter.Value) : null;
64
+ } catch (error) {
65
+ if (error instanceof _aws_sdk_client_ssm.ParameterNotFound) return null;
66
+ throw error;
67
+ }
68
+ }
69
+ /**
70
+ * @throws {StageSecretsUnreadable} when there are no AWS credentials to
71
+ * write it with, or they have expired
72
+ */
73
+ async write(stage, secrets) {
74
+ const value = require_awsStore.serializeWithin(stage, this.name, secrets, SSM_PARAMETER_LIMIT);
75
+ const ssm = await this.ssm();
76
+ await require_awsStore.withStageCredentials(this.context(stage, "write"), () => ssm.send(new _aws_sdk_client_ssm.PutParameterCommand({
77
+ Name: secretsParameterName(this.options.project, stage),
78
+ Value: value,
79
+ Type: "SecureString",
80
+ Tier: "Intelligent-Tiering",
81
+ Overwrite: true,
82
+ Description: `gkm secrets for ${this.options.project}/${stage}`
83
+ })));
84
+ }
85
+ };
86
+ //#endregion
87
+ Object.defineProperty(exports, "aws_exports", {
88
+ enumerable: true,
89
+ get: function() {
90
+ return aws_exports;
91
+ }
92
+ });
93
+ Object.defineProperty(exports, "secretsParameterName", {
94
+ enumerable: true,
95
+ get: function() {
96
+ return secretsParameterName;
97
+ }
98
+ });
99
+
100
+ //# sourceMappingURL=aws-DY9NqQIT.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-DY9NqQIT.cjs","names":["SSMClient","awsClientConfig","withStageCredentials","GetParameterCommand","ParameterNotFound","serializeWithin","PutParameterCommand"],"sources":["../src/secrets/aws.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n *\n * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free\n * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB\n * the write is refused with {@link StageSecretsTooLarge} before AWS is\n * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n} from '@aws-sdk/client-ssm';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\tserializeWithin,\n\twithStageCredentials,\n} from './awsStore.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport type AwsSecretsStoreOptions = AwsStoreOptions;\n\n/** The most an SSM parameter holds: 8 KB, in the advanced tier. */\nexport const SSM_PARAMETER_LIMIT = 8 * 1024;\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class AwsSecretsStore implements SecretsStore {\n\treadonly name = 'ssm';\n\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: AwsSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tthis.client = new SSMClient(await awsClientConfig(this.options));\n\t\treturn this.client;\n\t}\n\n\t/** Where a call for `stage` is, for an error saying it has no credentials. */\n\tprivate context(stage: string, access: 'read' | 'write') {\n\t\treturn { stage, store: this.name, profile: this.options.profile, access };\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 ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await withStageCredentials(\n\t\t\t\tthis.context(stage, 'read'),\n\t\t\t\t() =>\n\t\t\t\t\tssm.send(\n\t\t\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\t\t\tWithDecryption: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\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 value = serializeWithin(\n\t\t\tstage,\n\t\t\tthis.name,\n\t\t\tsecrets,\n\t\t\tSSM_PARAMETER_LIMIT,\n\t\t);\n\t\tconst ssm = await this.ssm();\n\n\t\tawait withStageCredentials(this.context(stage, 'write'), () =>\n\t\t\tssm.send(\n\t\t\t\tnew PutParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tValue: value,\n\t\t\t\t\tType: 'SecureString',\n\t\t\t\t\t// Standard (free) under 4 KB, advanced past it; never the other way.\n\t\t\t\t\tTier: 'Intelligent-Tiering',\n\t\t\t\t\tOverwrite: true,\n\t\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAa,sBAAsB;;AAGnC,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAKvB;CAJ7B,OAAgB;CAEhB;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,KAAK,SAAS,IAAIA,oBAAAA,UAAU,MAAMC,iBAAAA,gBAAgB,KAAK,OAAO,CAAC;EAC/D,OAAO,KAAK;CACb;;CAGA,QAAgB,OAAe,QAA0B;EACxD,OAAO;GAAE;GAAO,OAAO,KAAK;GAAM,SAAS,KAAK,QAAQ;GAAS;EAAO;CACzE;;;;;CAMA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAMC,iBAAAA,qBAC3B,KAAK,QAAQ,OAAO,MAAM,SAEzB,IAAI,KACH,IAAIC,oBAAAA,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiBC,oBAAAA,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;;;;;CAMA,MAAM,MAAM,OAAe,SAAsC;EAChE,MAAM,QAAQC,iBAAAA,gBACb,OACA,KAAK,MACL,SACA,mBACD;EACA,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,MAAMH,iBAAAA,qBAAqB,KAAK,QAAQ,OAAO,OAAO,SACrD,IAAI,KACH,IAAII,oBAAAA,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO;GACP,MAAM;GAEN,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF,CACD;CACD;AACD"}
@@ -0,0 +1,121 @@
1
+ import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
2
+ //#region src/secrets/awsStore.ts
3
+ /**
4
+ * What the AWS secrets stores share: how a client finds its credentials, what
5
+ * it says when it has none, and — for SSM and Secrets Manager, which hold a
6
+ * stage in one value of a fixed size — how big a stage may be before AWS
7
+ * would refuse it. S3 has no such limit.
8
+ */
9
+ /** The client config both stores build their SDK client from. */
10
+ async function awsClientConfig(options) {
11
+ const config = { region: options.region };
12
+ if (options.profile) {
13
+ const { fromIni } = await import("@aws-sdk/credential-providers");
14
+ config.credentials = fromIni({ profile: options.profile });
15
+ }
16
+ if (options.endpoint) config.endpoint = options.endpoint;
17
+ return config;
18
+ }
19
+ /**
20
+ * A stage's secrets, serialized, are larger than the store can hold: 8 KB for
21
+ * an SSM parameter (advanced tier), 64 KB for a Secrets Manager secret.
22
+ *
23
+ * Refused before AWS is called, so nothing half-written is left behind and
24
+ * the answer is not a bare `ValidationException`.
25
+ */
26
+ var StageSecretsTooLarge = class extends GkmError {
27
+ stage;
28
+ store;
29
+ bytes;
30
+ limit;
31
+ constructor(stage, store, bytes, limit) {
32
+ super(`The secrets for stage "${stage}" are ${bytes} bytes, more than the ${limit} bytes ${store} holds in one ${store === "ssm" ? "parameter" : "secret"}. ` + (store === "ssm" ? `Keep them in S3 instead, which has no such limit: copy the stage with gkm secrets:migrate --stage ${stage} --to s3, then set secrets.store to { provider: 's3' } in gkm.config.ts.` : "Remove credentials the stage no longer uses, or keep the largest ones somewhere they are fetched from at runtime."));
33
+ this.stage = stage;
34
+ this.store = store;
35
+ this.bytes = bytes;
36
+ this.limit = limit;
37
+ this.name = "StageSecretsTooLarge";
38
+ }
39
+ };
40
+ /** The stage serialized, refused if it is larger than `limit` bytes. */
41
+ function serializeWithin(stage, store, value, limit) {
42
+ const serialized = JSON.stringify(value);
43
+ const bytes = Buffer.byteLength(serialized, "utf8");
44
+ if (bytes > limit) throw new StageSecretsTooLarge(stage, store, bytes, limit);
45
+ return serialized;
46
+ }
47
+ /** Where each AWS store keeps a stage's secrets, as a person reads it. */
48
+ const AWS_STORES = {
49
+ ssm: "SSM Parameter Store",
50
+ "secrets-manager": "Secrets Manager",
51
+ s3: "S3"
52
+ };
53
+ /**
54
+ * A deployed stage's secrets are kept in its AWS account, and no AWS
55
+ * credentials were found to reach them with — or the ones found have expired.
56
+ *
57
+ * Raised by the AWS stores themselves, on a read or a write, so every command
58
+ * that touches a stage's secrets says it the same way.
59
+ */
60
+ var StageSecretsUnreadable = class extends GkmError {
61
+ stage;
62
+ store;
63
+ profile;
64
+ access;
65
+ reason;
66
+ constructor(input, cause) {
67
+ const { stage, store, profile } = input;
68
+ const access = input.access ?? "read";
69
+ const reason = input.reason ?? "no-credentials";
70
+ const where = AWS_STORES[store] ?? `the '${store}' store`;
71
+ const named = "--profile <profile> where the command takes it, or AWS_PROFILE=<profile>";
72
+ const lacking = reason === "expired" ? profile ? `the AWS profile '${profile}' signed in, but its session has expired. ` : "the AWS credentials found have expired. " : profile ? `the AWS profile '${profile}' has no credentials to ${access} them with. ` : `no AWS credentials were found to ${access} them with. `;
73
+ const fix = profile ? `Sign in to it (aws sso login --profile ${profile}) or name another: ${named}.` : reason === "expired" ? `Export fresh ones, or name the account's profile: ${named}.` : `Name the account's profile: ${named}.`;
74
+ super(`The '${stage}' stage's secrets are kept in ${where}, in the stage's AWS account, and ` + lacking + fix, cause === void 0 ? void 0 : { cause });
75
+ this.name = "StageSecretsUnreadable";
76
+ this.stage = stage;
77
+ this.store = store;
78
+ this.profile = profile;
79
+ this.access = access;
80
+ this.reason = reason;
81
+ }
82
+ };
83
+ /**
84
+ * Why an AWS call failed for want of credentials, by the SDK's error name —
85
+ * its message being free to change — or undefined when it failed for any
86
+ * other reason.
87
+ *
88
+ * - `CredentialsProviderError`: the credential chain found nothing, or a
89
+ * profile's SSO session is missing or expired (the SSO provider wraps its
90
+ * token errors in this one).
91
+ * - `TokenProviderError`: an SSO token, should one reach here unwrapped.
92
+ * - `ExpiredTokenException`/`ExpiredToken`: credentials were found, and AWS
93
+ * refused them as expired.
94
+ */
95
+ function credentialsFailure(error) {
96
+ const name = error?.name;
97
+ if (name === "CredentialsProviderError" || name === "TokenProviderError") return "no-credentials";
98
+ if (name === "ExpiredTokenException" || name === "ExpiredToken") return "expired";
99
+ }
100
+ /**
101
+ * Run one AWS call of a store, refusing a failure for want of credentials
102
+ * with {@link StageSecretsUnreadable}. Any other failure is the store's own,
103
+ * and passes through.
104
+ */
105
+ async function withStageCredentials(context, call) {
106
+ try {
107
+ return await call();
108
+ } catch (error) {
109
+ const reason = credentialsFailure(error);
110
+ if (reason === void 0) throw error;
111
+ throw new StageSecretsUnreadable({
112
+ ...context,
113
+ profile: context.profile ?? (process.env.AWS_PROFILE || void 0),
114
+ reason
115
+ }, error);
116
+ }
117
+ }
118
+ //#endregion
119
+ export { serializeWithin as n, withStageCredentials as r, awsClientConfig as t };
120
+
121
+ //# sourceMappingURL=awsStore-Bx5nCFnS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"awsStore-Bx5nCFnS.mjs","names":[],"sources":["../src/secrets/awsStore.ts"],"sourcesContent":["/**\n * What the AWS secrets stores share: how a client finds its credentials, what\n * it says when it has none, and — for SSM and Secrets Manager, which hold a\n * stage in one value of a fixed size — how big a stage may be before AWS\n * would refuse it. S3 has no such limit.\n */\n\nimport { GkmError } from '../errors';\n\nexport interface AwsStoreOptions {\n\t/** The workspace name, which scopes where the stage is kept. */\n\tproject: string;\n\tregion: string;\n\t/**\n\t * A named AWS profile, resolved with `fromIni` only. The default chain\n\t * reads AWS_* from the environment first, so exported staging keys would\n\t * win over `--profile prod` and put production's secrets in staging.\n\t */\n\tprofile?: string;\n\t/** For tests: an endpoint such as the AWS emulator. */\n\tendpoint?: string;\n}\n\n/** The client config both stores build their SDK client from. */\nexport async function awsClientConfig(options: AwsStoreOptions): Promise<{\n\tregion: string;\n\tendpoint?: string;\n\tcredentials?: ReturnType<\n\t\ttypeof import('@aws-sdk/credential-providers').fromIni\n\t>;\n}> {\n\tconst config: Awaited<ReturnType<typeof awsClientConfig>> = {\n\t\tregion: options.region,\n\t};\n\tif (options.profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile: options.profile });\n\t}\n\tif (options.endpoint) {\n\t\tconfig.endpoint = options.endpoint;\n\t}\n\treturn config;\n}\n\n/**\n * A stage's secrets, serialized, are larger than the store can hold: 8 KB for\n * an SSM parameter (advanced tier), 64 KB for a Secrets Manager secret.\n *\n * Refused before AWS is called, so nothing half-written is left behind and\n * the answer is not a bare `ValidationException`.\n */\nexport class StageSecretsTooLarge extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly store: string,\n\t\treadonly bytes: number,\n\t\treadonly limit: number,\n\t) {\n\t\tsuper(\n\t\t\t`The secrets for stage \"${stage}\" are ${bytes} bytes, more than the ${limit} bytes ${store} holds in one ${store === 'ssm' ? 'parameter' : 'secret'}. ` +\n\t\t\t\t(store === 'ssm'\n\t\t\t\t\t? `Keep them in S3 instead, which has no such limit: copy the stage with gkm secrets:migrate --stage ${stage} --to s3, then set secrets.store to { provider: 's3' } in gkm.config.ts.`\n\t\t\t\t\t: 'Remove credentials the stage no longer uses, or keep the largest ones somewhere they are fetched from at runtime.'),\n\t\t);\n\t\tthis.name = 'StageSecretsTooLarge';\n\t}\n}\n\n/** The stage serialized, refused if it is larger than `limit` bytes. */\nexport function serializeWithin(\n\tstage: string,\n\tstore: string,\n\tvalue: unknown,\n\tlimit: number,\n): string {\n\tconst serialized = JSON.stringify(value);\n\tconst bytes = Buffer.byteLength(serialized, 'utf8');\n\tif (bytes > limit) {\n\t\tthrow new StageSecretsTooLarge(stage, store, bytes, limit);\n\t}\n\treturn serialized;\n}\n\n/** Where each AWS store keeps a stage's secrets, as a person reads it. */\nconst AWS_STORES: Record<string, string> = {\n\tssm: 'SSM Parameter Store',\n\t'secrets-manager': 'Secrets Manager',\n\ts3: 'S3',\n};\n\n/** Why the stage's account could not be reached. */\nexport type StageSecretsUnreadableReason = 'no-credentials' | 'expired';\n\nexport interface StageSecretsUnreadableInput {\n\tstage: string;\n\t/** The store's name: `ssm`, `secrets-manager`, `s3`. */\n\tstore: string;\n\t/** The AWS profile the credentials were looked up with, where one was. */\n\tprofile?: string;\n\t/** Whether the stage was being read or written. */\n\taccess?: 'read' | 'write';\n\treason?: StageSecretsUnreadableReason;\n}\n\n/**\n * A deployed stage's secrets are kept in its AWS account, and no AWS\n * credentials were found to reach them with — or the ones found have expired.\n *\n * Raised by the AWS stores themselves, on a read or a write, so every command\n * that touches a stage's secrets says it the same way.\n */\nexport class StageSecretsUnreadable extends GkmError {\n\treadonly stage: string;\n\treadonly store: string;\n\treadonly profile: string | undefined;\n\treadonly access: 'read' | 'write';\n\treadonly reason: StageSecretsUnreadableReason;\n\n\tconstructor(input: StageSecretsUnreadableInput, cause?: unknown) {\n\t\tconst { stage, store, profile } = input;\n\t\tconst access = input.access ?? 'read';\n\t\tconst reason = input.reason ?? 'no-credentials';\n\t\tconst where = AWS_STORES[store] ?? `the '${store}' store`;\n\t\t// How to name the account: the command's --profile, where it takes\n\t\t// one, or the SDK's own variable.\n\t\tconst named =\n\t\t\t'--profile <profile> where the command takes it, or AWS_PROFILE=<profile>';\n\t\tconst lacking =\n\t\t\treason === 'expired'\n\t\t\t\t? profile\n\t\t\t\t\t? `the AWS profile '${profile}' signed in, but its session has expired. `\n\t\t\t\t\t: 'the AWS credentials found have expired. '\n\t\t\t\t: profile\n\t\t\t\t\t? `the AWS profile '${profile}' has no credentials to ${access} them with. `\n\t\t\t\t\t: `no AWS credentials were found to ${access} them with. `;\n\t\tconst fix = profile\n\t\t\t? `Sign in to it (aws sso login --profile ${profile}) or name another: ${named}.`\n\t\t\t: reason === 'expired'\n\t\t\t\t? `Export fresh ones, or name the account's profile: ${named}.`\n\t\t\t\t: `Name the account's profile: ${named}.`;\n\t\tsuper(\n\t\t\t`The '${stage}' stage's secrets are kept in ${where}, in the stage's AWS account, and ` +\n\t\t\t\tlacking +\n\t\t\t\tfix,\n\t\t\tcause === undefined ? undefined : { cause },\n\t\t);\n\t\tthis.name = 'StageSecretsUnreadable';\n\t\tthis.stage = stage;\n\t\tthis.store = store;\n\t\tthis.profile = profile;\n\t\tthis.access = access;\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * Why an AWS call failed for want of credentials, by the SDK's error name —\n * its message being free to change — or undefined when it failed for any\n * other reason.\n *\n * - `CredentialsProviderError`: the credential chain found nothing, or a\n * profile's SSO session is missing or expired (the SSO provider wraps its\n * token errors in this one).\n * - `TokenProviderError`: an SSO token, should one reach here unwrapped.\n * - `ExpiredTokenException`/`ExpiredToken`: credentials were found, and AWS\n * refused them as expired.\n */\nexport function credentialsFailure(\n\terror: unknown,\n): StageSecretsUnreadableReason | undefined {\n\tconst name = (error as Error | undefined)?.name;\n\tif (name === 'CredentialsProviderError' || name === 'TokenProviderError') {\n\t\treturn 'no-credentials';\n\t}\n\tif (name === 'ExpiredTokenException' || name === 'ExpiredToken') {\n\t\treturn 'expired';\n\t}\n\treturn undefined;\n}\n\n/**\n * Run one AWS call of a store, refusing a failure for want of credentials\n * with {@link StageSecretsUnreadable}. Any other failure is the store's own,\n * and passes through.\n */\nexport async function withStageCredentials<T>(\n\tcontext: {\n\t\tstage: string;\n\t\tstore: string;\n\t\tprofile: string | undefined;\n\t\taccess: 'read' | 'write';\n\t},\n\tcall: () => Promise<T>,\n): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (error) {\n\t\tconst reason = credentialsFailure(error);\n\t\tif (reason === undefined) throw error;\n\t\tthrow new StageSecretsUnreadable(\n\t\t\t{\n\t\t\t\t...context,\n\t\t\t\t// The profile the SDK's default chain read, when none was named.\n\t\t\t\tprofile: context.profile ?? (process.env.AWS_PROFILE || undefined),\n\t\t\t\treason,\n\t\t\t},\n\t\t\terror,\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;AAwBA,eAAsB,gBAAgB,SAMnC;CACF,MAAM,SAAsD,EAC3D,QAAQ,QAAQ,OACjB;CACA,IAAI,QAAQ,SAAS;EACpB,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,OAAO,cAAc,QAAQ,EAAE,SAAS,QAAQ,QAAQ,CAAC;CAC1D;CACA,IAAI,QAAQ,UACX,OAAO,WAAW,QAAQ;CAE3B,OAAO;AACR;;;;;;;;AASA,IAAa,uBAAb,cAA0C,SAAS;CAExC;CACA;CACA;CACA;CAJV,YACC,OACA,OACA,OACA,OACC;EACD,MACC,0BAA0B,MAAM,QAAQ,MAAM,wBAAwB,MAAM,SAAS,MAAM,gBAAgB,UAAU,QAAQ,cAAc,SAAS,OAClJ,UAAU,QACR,qGAAqG,MAAM,4EAC3G,oHACL;EAVS,KAAA,QAAA;EACA,KAAA,QAAA;EACA,KAAA,QAAA;EACA,KAAA,QAAA;EAQT,KAAK,OAAO;CACb;AACD;;AAGA,SAAgB,gBACf,OACA,OACA,OACA,OACS;CACT,MAAM,aAAa,KAAK,UAAU,KAAK;CACvC,MAAM,QAAQ,OAAO,WAAW,YAAY,MAAM;CAClD,IAAI,QAAQ,OACX,MAAM,IAAI,qBAAqB,OAAO,OAAO,OAAO,KAAK;CAE1D,OAAO;AACR;;AAGA,MAAM,aAAqC;CAC1C,KAAK;CACL,mBAAmB;CACnB,IAAI;AACL;;;;;;;;AAuBA,IAAa,yBAAb,cAA4C,SAAS;CACpD;CACA;CACA;CACA;CACA;CAEA,YAAY,OAAoC,OAAiB;EAChE,MAAM,EAAE,OAAO,OAAO,YAAY;EAClC,MAAM,SAAS,MAAM,UAAU;EAC/B,MAAM,SAAS,MAAM,UAAU;EAC/B,MAAM,QAAQ,WAAW,UAAU,QAAQ,MAAM;EAGjD,MAAM,QACL;EACD,MAAM,UACL,WAAW,YACR,UACC,oBAAoB,QAAQ,8CAC5B,6CACD,UACC,oBAAoB,QAAQ,0BAA0B,OAAO,gBAC7D,oCAAoC,OAAO;EAChD,MAAM,MAAM,UACT,0CAA0C,QAAQ,qBAAqB,MAAM,KAC7E,WAAW,YACV,qDAAqD,MAAM,KAC3D,+BAA+B,MAAM;EACzC,MACC,QAAQ,MAAM,gCAAgC,MAAM,sCACnD,UACA,KACD,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,MAAM,CAC3C;EACA,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,UAAU;EACf,KAAK,SAAS;EACd,KAAK,SAAS;CACf;AACD;;;;;;;;;;;;;AAcA,SAAgB,mBACf,OAC2C;CAC3C,MAAM,OAAQ,OAA6B;CAC3C,IAAI,SAAS,8BAA8B,SAAS,sBACnD,OAAO;CAER,IAAI,SAAS,2BAA2B,SAAS,gBAChD,OAAO;AAGT;;;;;;AAOA,eAAsB,qBACrB,SAMA,MACa;CACb,IAAI;EACH,OAAO,MAAM,KAAK;CACnB,SAAS,OAAO;EACf,MAAM,SAAS,mBAAmB,KAAK;EACvC,IAAI,WAAW,KAAA,GAAW,MAAM;EAChC,MAAM,IAAI,uBACT;GACC,GAAG;GAEH,SAAS,QAAQ,YAAY,QAAQ,IAAI,eAAe,KAAA;GACxD;EACD,GACA,KACD;CACD;AACD"}
@@ -0,0 +1,138 @@
1
+ const require_errors = require("./errors-DMC4Umsb.cjs");
2
+ //#region src/secrets/awsStore.ts
3
+ /**
4
+ * What the AWS secrets stores share: how a client finds its credentials, what
5
+ * it says when it has none, and — for SSM and Secrets Manager, which hold a
6
+ * stage in one value of a fixed size — how big a stage may be before AWS
7
+ * would refuse it. S3 has no such limit.
8
+ */
9
+ /** The client config both stores build their SDK client from. */
10
+ async function awsClientConfig(options) {
11
+ const config = { region: options.region };
12
+ if (options.profile) {
13
+ const { fromIni } = await import("@aws-sdk/credential-providers");
14
+ config.credentials = fromIni({ profile: options.profile });
15
+ }
16
+ if (options.endpoint) config.endpoint = options.endpoint;
17
+ return config;
18
+ }
19
+ /**
20
+ * A stage's secrets, serialized, are larger than the store can hold: 8 KB for
21
+ * an SSM parameter (advanced tier), 64 KB for a Secrets Manager secret.
22
+ *
23
+ * Refused before AWS is called, so nothing half-written is left behind and
24
+ * the answer is not a bare `ValidationException`.
25
+ */
26
+ var StageSecretsTooLarge = class extends require_errors.GkmError {
27
+ stage;
28
+ store;
29
+ bytes;
30
+ limit;
31
+ constructor(stage, store, bytes, limit) {
32
+ super(`The secrets for stage "${stage}" are ${bytes} bytes, more than the ${limit} bytes ${store} holds in one ${store === "ssm" ? "parameter" : "secret"}. ` + (store === "ssm" ? `Keep them in S3 instead, which has no such limit: copy the stage with gkm secrets:migrate --stage ${stage} --to s3, then set secrets.store to { provider: 's3' } in gkm.config.ts.` : "Remove credentials the stage no longer uses, or keep the largest ones somewhere they are fetched from at runtime."));
33
+ this.stage = stage;
34
+ this.store = store;
35
+ this.bytes = bytes;
36
+ this.limit = limit;
37
+ this.name = "StageSecretsTooLarge";
38
+ }
39
+ };
40
+ /** The stage serialized, refused if it is larger than `limit` bytes. */
41
+ function serializeWithin(stage, store, value, limit) {
42
+ const serialized = JSON.stringify(value);
43
+ const bytes = Buffer.byteLength(serialized, "utf8");
44
+ if (bytes > limit) throw new StageSecretsTooLarge(stage, store, bytes, limit);
45
+ return serialized;
46
+ }
47
+ /** Where each AWS store keeps a stage's secrets, as a person reads it. */
48
+ const AWS_STORES = {
49
+ ssm: "SSM Parameter Store",
50
+ "secrets-manager": "Secrets Manager",
51
+ s3: "S3"
52
+ };
53
+ /**
54
+ * A deployed stage's secrets are kept in its AWS account, and no AWS
55
+ * credentials were found to reach them with — or the ones found have expired.
56
+ *
57
+ * Raised by the AWS stores themselves, on a read or a write, so every command
58
+ * that touches a stage's secrets says it the same way.
59
+ */
60
+ var StageSecretsUnreadable = class extends require_errors.GkmError {
61
+ stage;
62
+ store;
63
+ profile;
64
+ access;
65
+ reason;
66
+ constructor(input, cause) {
67
+ const { stage, store, profile } = input;
68
+ const access = input.access ?? "read";
69
+ const reason = input.reason ?? "no-credentials";
70
+ const where = AWS_STORES[store] ?? `the '${store}' store`;
71
+ const named = "--profile <profile> where the command takes it, or AWS_PROFILE=<profile>";
72
+ const lacking = reason === "expired" ? profile ? `the AWS profile '${profile}' signed in, but its session has expired. ` : "the AWS credentials found have expired. " : profile ? `the AWS profile '${profile}' has no credentials to ${access} them with. ` : `no AWS credentials were found to ${access} them with. `;
73
+ const fix = profile ? `Sign in to it (aws sso login --profile ${profile}) or name another: ${named}.` : reason === "expired" ? `Export fresh ones, or name the account's profile: ${named}.` : `Name the account's profile: ${named}.`;
74
+ super(`The '${stage}' stage's secrets are kept in ${where}, in the stage's AWS account, and ` + lacking + fix, cause === void 0 ? void 0 : { cause });
75
+ this.name = "StageSecretsUnreadable";
76
+ this.stage = stage;
77
+ this.store = store;
78
+ this.profile = profile;
79
+ this.access = access;
80
+ this.reason = reason;
81
+ }
82
+ };
83
+ /**
84
+ * Why an AWS call failed for want of credentials, by the SDK's error name —
85
+ * its message being free to change — or undefined when it failed for any
86
+ * other reason.
87
+ *
88
+ * - `CredentialsProviderError`: the credential chain found nothing, or a
89
+ * profile's SSO session is missing or expired (the SSO provider wraps its
90
+ * token errors in this one).
91
+ * - `TokenProviderError`: an SSO token, should one reach here unwrapped.
92
+ * - `ExpiredTokenException`/`ExpiredToken`: credentials were found, and AWS
93
+ * refused them as expired.
94
+ */
95
+ function credentialsFailure(error) {
96
+ const name = error?.name;
97
+ if (name === "CredentialsProviderError" || name === "TokenProviderError") return "no-credentials";
98
+ if (name === "ExpiredTokenException" || name === "ExpiredToken") return "expired";
99
+ }
100
+ /**
101
+ * Run one AWS call of a store, refusing a failure for want of credentials
102
+ * with {@link StageSecretsUnreadable}. Any other failure is the store's own,
103
+ * and passes through.
104
+ */
105
+ async function withStageCredentials(context, call) {
106
+ try {
107
+ return await call();
108
+ } catch (error) {
109
+ const reason = credentialsFailure(error);
110
+ if (reason === void 0) throw error;
111
+ throw new StageSecretsUnreadable({
112
+ ...context,
113
+ profile: context.profile ?? (process.env.AWS_PROFILE || void 0),
114
+ reason
115
+ }, error);
116
+ }
117
+ }
118
+ //#endregion
119
+ Object.defineProperty(exports, "awsClientConfig", {
120
+ enumerable: true,
121
+ get: function() {
122
+ return awsClientConfig;
123
+ }
124
+ });
125
+ Object.defineProperty(exports, "serializeWithin", {
126
+ enumerable: true,
127
+ get: function() {
128
+ return serializeWithin;
129
+ }
130
+ });
131
+ Object.defineProperty(exports, "withStageCredentials", {
132
+ enumerable: true,
133
+ get: function() {
134
+ return withStageCredentials;
135
+ }
136
+ });
137
+
138
+ //# sourceMappingURL=awsStore-u3ehhMoY.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"awsStore-u3ehhMoY.cjs","names":["GkmError"],"sources":["../src/secrets/awsStore.ts"],"sourcesContent":["/**\n * What the AWS secrets stores share: how a client finds its credentials, what\n * it says when it has none, and — for SSM and Secrets Manager, which hold a\n * stage in one value of a fixed size — how big a stage may be before AWS\n * would refuse it. S3 has no such limit.\n */\n\nimport { GkmError } from '../errors';\n\nexport interface AwsStoreOptions {\n\t/** The workspace name, which scopes where the stage is kept. */\n\tproject: string;\n\tregion: string;\n\t/**\n\t * A named AWS profile, resolved with `fromIni` only. The default chain\n\t * reads AWS_* from the environment first, so exported staging keys would\n\t * win over `--profile prod` and put production's secrets in staging.\n\t */\n\tprofile?: string;\n\t/** For tests: an endpoint such as the AWS emulator. */\n\tendpoint?: string;\n}\n\n/** The client config both stores build their SDK client from. */\nexport async function awsClientConfig(options: AwsStoreOptions): Promise<{\n\tregion: string;\n\tendpoint?: string;\n\tcredentials?: ReturnType<\n\t\ttypeof import('@aws-sdk/credential-providers').fromIni\n\t>;\n}> {\n\tconst config: Awaited<ReturnType<typeof awsClientConfig>> = {\n\t\tregion: options.region,\n\t};\n\tif (options.profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile: options.profile });\n\t}\n\tif (options.endpoint) {\n\t\tconfig.endpoint = options.endpoint;\n\t}\n\treturn config;\n}\n\n/**\n * A stage's secrets, serialized, are larger than the store can hold: 8 KB for\n * an SSM parameter (advanced tier), 64 KB for a Secrets Manager secret.\n *\n * Refused before AWS is called, so nothing half-written is left behind and\n * the answer is not a bare `ValidationException`.\n */\nexport class StageSecretsTooLarge extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly store: string,\n\t\treadonly bytes: number,\n\t\treadonly limit: number,\n\t) {\n\t\tsuper(\n\t\t\t`The secrets for stage \"${stage}\" are ${bytes} bytes, more than the ${limit} bytes ${store} holds in one ${store === 'ssm' ? 'parameter' : 'secret'}. ` +\n\t\t\t\t(store === 'ssm'\n\t\t\t\t\t? `Keep them in S3 instead, which has no such limit: copy the stage with gkm secrets:migrate --stage ${stage} --to s3, then set secrets.store to { provider: 's3' } in gkm.config.ts.`\n\t\t\t\t\t: 'Remove credentials the stage no longer uses, or keep the largest ones somewhere they are fetched from at runtime.'),\n\t\t);\n\t\tthis.name = 'StageSecretsTooLarge';\n\t}\n}\n\n/** The stage serialized, refused if it is larger than `limit` bytes. */\nexport function serializeWithin(\n\tstage: string,\n\tstore: string,\n\tvalue: unknown,\n\tlimit: number,\n): string {\n\tconst serialized = JSON.stringify(value);\n\tconst bytes = Buffer.byteLength(serialized, 'utf8');\n\tif (bytes > limit) {\n\t\tthrow new StageSecretsTooLarge(stage, store, bytes, limit);\n\t}\n\treturn serialized;\n}\n\n/** Where each AWS store keeps a stage's secrets, as a person reads it. */\nconst AWS_STORES: Record<string, string> = {\n\tssm: 'SSM Parameter Store',\n\t'secrets-manager': 'Secrets Manager',\n\ts3: 'S3',\n};\n\n/** Why the stage's account could not be reached. */\nexport type StageSecretsUnreadableReason = 'no-credentials' | 'expired';\n\nexport interface StageSecretsUnreadableInput {\n\tstage: string;\n\t/** The store's name: `ssm`, `secrets-manager`, `s3`. */\n\tstore: string;\n\t/** The AWS profile the credentials were looked up with, where one was. */\n\tprofile?: string;\n\t/** Whether the stage was being read or written. */\n\taccess?: 'read' | 'write';\n\treason?: StageSecretsUnreadableReason;\n}\n\n/**\n * A deployed stage's secrets are kept in its AWS account, and no AWS\n * credentials were found to reach them with — or the ones found have expired.\n *\n * Raised by the AWS stores themselves, on a read or a write, so every command\n * that touches a stage's secrets says it the same way.\n */\nexport class StageSecretsUnreadable extends GkmError {\n\treadonly stage: string;\n\treadonly store: string;\n\treadonly profile: string | undefined;\n\treadonly access: 'read' | 'write';\n\treadonly reason: StageSecretsUnreadableReason;\n\n\tconstructor(input: StageSecretsUnreadableInput, cause?: unknown) {\n\t\tconst { stage, store, profile } = input;\n\t\tconst access = input.access ?? 'read';\n\t\tconst reason = input.reason ?? 'no-credentials';\n\t\tconst where = AWS_STORES[store] ?? `the '${store}' store`;\n\t\t// How to name the account: the command's --profile, where it takes\n\t\t// one, or the SDK's own variable.\n\t\tconst named =\n\t\t\t'--profile <profile> where the command takes it, or AWS_PROFILE=<profile>';\n\t\tconst lacking =\n\t\t\treason === 'expired'\n\t\t\t\t? profile\n\t\t\t\t\t? `the AWS profile '${profile}' signed in, but its session has expired. `\n\t\t\t\t\t: 'the AWS credentials found have expired. '\n\t\t\t\t: profile\n\t\t\t\t\t? `the AWS profile '${profile}' has no credentials to ${access} them with. `\n\t\t\t\t\t: `no AWS credentials were found to ${access} them with. `;\n\t\tconst fix = profile\n\t\t\t? `Sign in to it (aws sso login --profile ${profile}) or name another: ${named}.`\n\t\t\t: reason === 'expired'\n\t\t\t\t? `Export fresh ones, or name the account's profile: ${named}.`\n\t\t\t\t: `Name the account's profile: ${named}.`;\n\t\tsuper(\n\t\t\t`The '${stage}' stage's secrets are kept in ${where}, in the stage's AWS account, and ` +\n\t\t\t\tlacking +\n\t\t\t\tfix,\n\t\t\tcause === undefined ? undefined : { cause },\n\t\t);\n\t\tthis.name = 'StageSecretsUnreadable';\n\t\tthis.stage = stage;\n\t\tthis.store = store;\n\t\tthis.profile = profile;\n\t\tthis.access = access;\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * Why an AWS call failed for want of credentials, by the SDK's error name —\n * its message being free to change — or undefined when it failed for any\n * other reason.\n *\n * - `CredentialsProviderError`: the credential chain found nothing, or a\n * profile's SSO session is missing or expired (the SSO provider wraps its\n * token errors in this one).\n * - `TokenProviderError`: an SSO token, should one reach here unwrapped.\n * - `ExpiredTokenException`/`ExpiredToken`: credentials were found, and AWS\n * refused them as expired.\n */\nexport function credentialsFailure(\n\terror: unknown,\n): StageSecretsUnreadableReason | undefined {\n\tconst name = (error as Error | undefined)?.name;\n\tif (name === 'CredentialsProviderError' || name === 'TokenProviderError') {\n\t\treturn 'no-credentials';\n\t}\n\tif (name === 'ExpiredTokenException' || name === 'ExpiredToken') {\n\t\treturn 'expired';\n\t}\n\treturn undefined;\n}\n\n/**\n * Run one AWS call of a store, refusing a failure for want of credentials\n * with {@link StageSecretsUnreadable}. Any other failure is the store's own,\n * and passes through.\n */\nexport async function withStageCredentials<T>(\n\tcontext: {\n\t\tstage: string;\n\t\tstore: string;\n\t\tprofile: string | undefined;\n\t\taccess: 'read' | 'write';\n\t},\n\tcall: () => Promise<T>,\n): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (error) {\n\t\tconst reason = credentialsFailure(error);\n\t\tif (reason === undefined) throw error;\n\t\tthrow new StageSecretsUnreadable(\n\t\t\t{\n\t\t\t\t...context,\n\t\t\t\t// The profile the SDK's default chain read, when none was named.\n\t\t\t\tprofile: context.profile ?? (process.env.AWS_PROFILE || undefined),\n\t\t\t\treason,\n\t\t\t},\n\t\t\terror,\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;AAwBA,eAAsB,gBAAgB,SAMnC;CACF,MAAM,SAAsD,EAC3D,QAAQ,QAAQ,OACjB;CACA,IAAI,QAAQ,SAAS;EACpB,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,OAAO,cAAc,QAAQ,EAAE,SAAS,QAAQ,QAAQ,CAAC;CAC1D;CACA,IAAI,QAAQ,UACX,OAAO,WAAW,QAAQ;CAE3B,OAAO;AACR;;;;;;;;AASA,IAAa,uBAAb,cAA0CA,eAAAA,SAAS;CAExC;CACA;CACA;CACA;CAJV,YACC,OACA,OACA,OACA,OACC;EACD,MACC,0BAA0B,MAAM,QAAQ,MAAM,wBAAwB,MAAM,SAAS,MAAM,gBAAgB,UAAU,QAAQ,cAAc,SAAS,OAClJ,UAAU,QACR,qGAAqG,MAAM,4EAC3G,oHACL;EAVS,KAAA,QAAA;EACA,KAAA,QAAA;EACA,KAAA,QAAA;EACA,KAAA,QAAA;EAQT,KAAK,OAAO;CACb;AACD;;AAGA,SAAgB,gBACf,OACA,OACA,OACA,OACS;CACT,MAAM,aAAa,KAAK,UAAU,KAAK;CACvC,MAAM,QAAQ,OAAO,WAAW,YAAY,MAAM;CAClD,IAAI,QAAQ,OACX,MAAM,IAAI,qBAAqB,OAAO,OAAO,OAAO,KAAK;CAE1D,OAAO;AACR;;AAGA,MAAM,aAAqC;CAC1C,KAAK;CACL,mBAAmB;CACnB,IAAI;AACL;;;;;;;;AAuBA,IAAa,yBAAb,cAA4CA,eAAAA,SAAS;CACpD;CACA;CACA;CACA;CACA;CAEA,YAAY,OAAoC,OAAiB;EAChE,MAAM,EAAE,OAAO,OAAO,YAAY;EAClC,MAAM,SAAS,MAAM,UAAU;EAC/B,MAAM,SAAS,MAAM,UAAU;EAC/B,MAAM,QAAQ,WAAW,UAAU,QAAQ,MAAM;EAGjD,MAAM,QACL;EACD,MAAM,UACL,WAAW,YACR,UACC,oBAAoB,QAAQ,8CAC5B,6CACD,UACC,oBAAoB,QAAQ,0BAA0B,OAAO,gBAC7D,oCAAoC,OAAO;EAChD,MAAM,MAAM,UACT,0CAA0C,QAAQ,qBAAqB,MAAM,KAC7E,WAAW,YACV,qDAAqD,MAAM,KAC3D,+BAA+B,MAAM;EACzC,MACC,QAAQ,MAAM,gCAAgC,MAAM,sCACnD,UACA,KACD,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,MAAM,CAC3C;EACA,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,UAAU;EACf,KAAK,SAAS;EACd,KAAK,SAAS;CACf;AACD;;;;;;;;;;;;;AAcA,SAAgB,mBACf,OAC2C;CAC3C,MAAM,OAAQ,OAA6B;CAC3C,IAAI,SAAS,8BAA8B,SAAS,sBACnD,OAAO;CAER,IAAI,SAAS,2BAA2B,SAAS,gBAChD,OAAO;AAGT;;;;;;AAOA,eAAsB,qBACrB,SAMA,MACa;CACb,IAAI;EACH,OAAO,MAAM,KAAK;CACnB,SAAS,OAAO;EACf,MAAM,SAAS,mBAAmB,KAAK;EACvC,IAAI,WAAW,KAAA,GAAW,MAAM;EAChC,MAAM,IAAI,uBACT;GACC,GAAG;GAEH,SAAS,QAAQ,YAAY,QAAQ,IAAI,eAAe,KAAA;GACxD;EACD,GACA,KACD;CACD;AACD"}
@@ -1,7 +1,12 @@
1
1
  import { CreateBucketCommand, HeadBucketCommand, PutBucketVersioningCommand, S3Client } from "@aws-sdk/client-s3";
2
2
  import { CreateAccessKeyCommand, CreateUserCommand, GetUserCommand, IAMClient, PutUserPolicyCommand } from "@aws-sdk/client-iam";
3
-
4
- //#region src/deploy/backup-provisioner.ts
3
+ //#region src/target/dokploy/backup-provisioner.ts
4
+ /**
5
+ * Backup Destination Provisioner
6
+ *
7
+ * Creates AWS resources (S3 bucket, IAM user, access keys) and configures
8
+ * Dokploy backup destinations for database backups.
9
+ */
5
10
  /**
6
11
  * Generate a random suffix for unique resource names
7
12
  */
@@ -80,8 +85,7 @@ async function provisionBackupDestination(options) {
80
85
  const aws = await createAwsClients(config.region, config.profile, awsEndpoint);
81
86
  const sanitizedProject = sanitizeName(projectName);
82
87
  const bucketName = existingState?.bucketName ?? `${sanitizedProject}-${stage}-backups-${randomSuffix()}`;
83
- const bucketAlreadyExists = await bucketExists(aws.s3, bucketName);
84
- if (!bucketAlreadyExists) {
88
+ if (!await bucketExists(aws.s3, bucketName)) {
85
89
  logger.log(` Creating S3 bucket: ${bucketName}`);
86
90
  const createBucketParams = { Bucket: bucketName };
87
91
  if (config.region !== "us-east-1") createBucketParams.CreateBucketConfiguration = { LocationConstraint: config.region };
@@ -92,8 +96,7 @@ async function provisionBackupDestination(options) {
92
96
  }));
93
97
  } else logger.log(` Using existing S3 bucket: ${bucketName}`);
94
98
  const iamUserName = existingState?.iamUserName ?? `dokploy-backup-${sanitizedProject}-${stage}`;
95
- const iamUserAlreadyExists = await userExists(aws.iam, iamUserName);
96
- if (!iamUserAlreadyExists) {
99
+ if (!await userExists(aws.iam, iamUserName)) {
97
100
  logger.log(` Creating IAM user: ${iamUserName}`);
98
101
  await aws.iam.send(new CreateUserCommand({ UserName: iamUserName }));
99
102
  } else logger.log(` Using existing IAM user: ${iamUserName}`);
@@ -157,7 +160,7 @@ async function provisionBackupDestination(options) {
157
160
  createdAt: existingState?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
158
161
  };
159
162
  }
160
-
161
163
  //#endregion
162
164
  export { provisionBackupDestination };
163
- //# sourceMappingURL=backup-provisioner-Bgj5Vi_L.mjs.map
165
+
166
+ //# sourceMappingURL=backup-provisioner-C8DnCmxK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-provisioner-C8DnCmxK.mjs","names":[],"sources":["../src/target/dokploy/backup-provisioner.ts"],"sourcesContent":["/**\n * Backup Destination Provisioner\n *\n * Creates AWS resources (S3 bucket, IAM user, access keys) and configures\n * Dokploy backup destinations for database backups.\n */\n\nimport {\n\tCreateAccessKeyCommand,\n\tCreateUserCommand,\n\tGetUserCommand,\n\tIAMClient,\n\ttype IAMClientConfig,\n\tPutUserPolicyCommand,\n} from '@aws-sdk/client-iam';\nimport {\n\ttype BucketLocationConstraint,\n\tCreateBucketCommand,\n\tHeadBucketCommand,\n\tPutBucketVersioningCommand,\n\tS3Client,\n\ttype S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport type { BackupState } from '../../deploy/state.js';\nimport type { DokployBackupsConfig } from '../../workspace/types.js';\nimport type { DokployApi } from './dokploy-api.js';\n\nexport interface ProvisionBackupOptions {\n\t/** Dokploy API client */\n\tapi: DokployApi;\n\t/** Dokploy project ID */\n\tprojectId: string;\n\t/** Workspace name (used for resource naming) */\n\tprojectName: string;\n\t/** Deploy stage (e.g., 'production', 'staging') */\n\tstage: string;\n\t/** Backup configuration */\n\tconfig: DokployBackupsConfig;\n\t/** Existing backup state (if any) */\n\texistingState?: BackupState;\n\t/** Logger for progress output */\n\tlogger: { log: (msg: string) => void };\n\t/** AWS endpoint override (for testing with LocalStack) */\n\tawsEndpoint?: string;\n}\n\n/**\n * Generate a random suffix for unique resource names\n */\nfunction randomSuffix(): string {\n\treturn Math.random().toString(36).substring(2, 8);\n}\n\n/**\n * Sanitize a name for AWS resources (lowercase alphanumeric and hyphens)\n */\nfunction sanitizeName(name: string): string {\n\treturn name.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n}\n\n/**\n * Create AWS clients with optional profile credentials\n */\nasync function createAwsClients(\n\tregion: string,\n\tprofile?: string,\n\tendpoint?: string,\n): Promise<{ s3: S3Client; iam: IAMClient }> {\n\tconst config: S3ClientConfig & IAMClientConfig = { region };\n\n\tif (profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile });\n\t}\n\n\t// Support custom endpoint for testing (e.g., LocalStack)\n\tif (endpoint) {\n\t\tconfig.endpoint = endpoint;\n\t\t(config as S3ClientConfig).forcePathStyle = true;\n\t\t// Use test credentials when endpoint is specified\n\t\tconfig.credentials = {\n\t\t\taccessKeyId: 'test',\n\t\t\tsecretAccessKey: 'test',\n\t\t};\n\t}\n\n\treturn {\n\t\ts3: new S3Client(config),\n\t\tiam: new IAMClient(config),\n\t};\n}\n\n/**\n * Check if an S3 bucket exists\n */\nasync function bucketExists(\n\ts3: S3Client,\n\tbucketName: string,\n): Promise<boolean> {\n\ttry {\n\t\tawait s3.send(new HeadBucketCommand({ Bucket: bucketName }));\n\t\treturn true;\n\t} catch (error) {\n\t\tif ((error as { name?: string }).name === 'NotFound') {\n\t\t\treturn false;\n\t\t}\n\t\t// 403 means bucket exists but we don't have access\n\t\tif (\n\t\t\t(error as { $metadata?: { httpStatusCode?: number } }).$metadata\n\t\t\t\t?.httpStatusCode === 403\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Check if an IAM user exists\n */\nasync function userExists(iam: IAMClient, userName: string): Promise<boolean> {\n\ttry {\n\t\tawait iam.send(new GetUserCommand({ UserName: userName }));\n\t\treturn true;\n\t} catch (error) {\n\t\tconst errorName = (error as { name?: string }).name;\n\t\t// AWS returns 'NoSuchEntity', LocalStack returns 'NoSuchEntityException'\n\t\tif (errorName === 'NoSuchEntity' || errorName === 'NoSuchEntityException') {\n\t\t\treturn false;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Provision backup destination for a deployment.\n *\n * Creates AWS resources (S3 bucket, IAM user) and Dokploy destination if needed.\n * Reuses existing resources from state when possible.\n */\nexport async function provisionBackupDestination(\n\toptions: ProvisionBackupOptions,\n): Promise<BackupState> {\n\tconst {\n\t\tapi,\n\t\tprojectName,\n\t\tstage,\n\t\tconfig,\n\t\texistingState,\n\t\tlogger,\n\t\tawsEndpoint,\n\t} = options;\n\n\t// If we have existing state, verify the Dokploy destination still exists\n\tif (existingState?.destinationId) {\n\t\ttry {\n\t\t\tawait api.getDestination(existingState.destinationId);\n\t\t\tlogger.log(' Using existing backup destination');\n\t\t\treturn existingState;\n\t\t} catch {\n\t\t\tlogger.log(' Existing destination not found, recreating...');\n\t\t}\n\t}\n\n\t// Create AWS clients\n\tconst aws = await createAwsClients(\n\t\tconfig.region,\n\t\tconfig.profile,\n\t\tawsEndpoint,\n\t);\n\tconst sanitizedProject = sanitizeName(projectName);\n\n\t// 1. Create or verify S3 bucket\n\tconst bucketName =\n\t\texistingState?.bucketName ??\n\t\t`${sanitizedProject}-${stage}-backups-${randomSuffix()}`;\n\n\tconst bucketAlreadyExists = await bucketExists(aws.s3, bucketName);\n\tif (!bucketAlreadyExists) {\n\t\tlogger.log(` Creating S3 bucket: ${bucketName}`);\n\n\t\t// CreateBucket needs LocationConstraint for non-us-east-1 regions\n\t\tconst createBucketParams: {\n\t\t\tBucket: string;\n\t\t\tCreateBucketConfiguration?: {\n\t\t\t\tLocationConstraint: BucketLocationConstraint;\n\t\t\t};\n\t\t} = {\n\t\t\tBucket: bucketName,\n\t\t};\n\t\tif (config.region !== 'us-east-1') {\n\t\t\tcreateBucketParams.CreateBucketConfiguration = {\n\t\t\t\tLocationConstraint: config.region as BucketLocationConstraint,\n\t\t\t};\n\t\t}\n\n\t\tawait aws.s3.send(new CreateBucketCommand(createBucketParams));\n\n\t\t// Enable versioning for backup integrity\n\t\tawait aws.s3.send(\n\t\t\tnew PutBucketVersioningCommand({\n\t\t\t\tBucket: bucketName,\n\t\t\t\tVersioningConfiguration: { Status: 'Enabled' },\n\t\t\t}),\n\t\t);\n\t} else {\n\t\tlogger.log(` Using existing S3 bucket: ${bucketName}`);\n\t}\n\n\t// 2. Create or verify IAM user\n\tconst iamUserName =\n\t\texistingState?.iamUserName ?? `dokploy-backup-${sanitizedProject}-${stage}`;\n\n\tconst iamUserAlreadyExists = await userExists(aws.iam, iamUserName);\n\tif (!iamUserAlreadyExists) {\n\t\tlogger.log(` Creating IAM user: ${iamUserName}`);\n\t\tawait aws.iam.send(new CreateUserCommand({ UserName: iamUserName }));\n\t} else {\n\t\tlogger.log(` Using existing IAM user: ${iamUserName}`);\n\t}\n\n\t// 3. Attach bucket policy to IAM user\n\tconst policyDocument = {\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tAction: [\n\t\t\t\t\t's3:GetObject',\n\t\t\t\t\t's3:PutObject',\n\t\t\t\t\t's3:DeleteObject',\n\t\t\t\t\t's3:ListBucket',\n\t\t\t\t\t's3:GetBucketLocation',\n\t\t\t\t],\n\t\t\t\tResource: [\n\t\t\t\t\t`arn:aws:s3:::${bucketName}`,\n\t\t\t\t\t`arn:aws:s3:::${bucketName}/*`,\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tlogger.log(' Updating IAM policy');\n\tawait aws.iam.send(\n\t\tnew PutUserPolicyCommand({\n\t\t\tUserName: iamUserName,\n\t\t\tPolicyName: 'DokployBackupAccess',\n\t\t\tPolicyDocument: JSON.stringify(policyDocument),\n\t\t}),\n\t);\n\n\t// 4. Create access key (or reuse existing if state has it and destination needs recreation)\n\tlet accessKeyId: string;\n\tlet secretAccessKey: string;\n\n\tif (existingState?.iamAccessKeyId && existingState?.iamSecretAccessKey) {\n\t\t// Reuse existing credentials\n\t\tlogger.log(' Using existing IAM access key');\n\t\taccessKeyId = existingState.iamAccessKeyId;\n\t\tsecretAccessKey = existingState.iamSecretAccessKey;\n\t} else {\n\t\t// Create new access key\n\t\tlogger.log(' Creating IAM access key');\n\t\tconst accessKeyResult = await aws.iam.send(\n\t\t\tnew CreateAccessKeyCommand({ UserName: iamUserName }),\n\t\t);\n\n\t\tif (!accessKeyResult.AccessKey) {\n\t\t\tthrow new Error('Failed to create IAM access key');\n\t\t}\n\n\t\taccessKeyId = accessKeyResult.AccessKey.AccessKeyId!;\n\t\tsecretAccessKey = accessKeyResult.AccessKey.SecretAccessKey!;\n\t}\n\n\t// 5. Create Dokploy destination\n\tconst destinationName = `${sanitizedProject}-${stage}-s3`;\n\tlogger.log(` Creating Dokploy destination: ${destinationName}`);\n\n\tconst { destination, created } = await api.findOrCreateDestination(\n\t\tdestinationName,\n\t\t{\n\t\t\taccessKey: accessKeyId,\n\t\t\tsecretAccessKey: secretAccessKey,\n\t\t\tbucket: bucketName,\n\t\t\tregion: config.region,\n\t\t},\n\t);\n\n\tif (created) {\n\t\tlogger.log(' ✓ Dokploy destination created');\n\t} else {\n\t\tlogger.log(' ✓ Using existing Dokploy destination');\n\t}\n\n\t// 6. Test connection\n\ttry {\n\t\tawait api.testDestinationConnection(destination.destinationId);\n\t\tlogger.log(' ✓ Destination connection verified');\n\t} catch (error) {\n\t\tlogger.log(\n\t\t\t` ⚠ Warning: Could not verify destination connection: ${error}`,\n\t\t);\n\t}\n\n\treturn {\n\t\tbucketName,\n\t\tbucketArn: `arn:aws:s3:::${bucketName}`,\n\t\tiamUserName,\n\t\tiamAccessKeyId: accessKeyId,\n\t\tiamSecretAccessKey: secretAccessKey,\n\t\tdestinationId: destination.destinationId,\n\t\tregion: config.region,\n\t\tcreatedAt: existingState?.createdAt ?? new Date().toISOString(),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;AAiDA,SAAS,eAAuB;CAC/B,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC;AACjD;;;;AAKA,SAAS,aAAa,MAAsB;CAC3C,OAAO,KAAK,YAAY,CAAC,CAAC,QAAQ,eAAe,GAAG;AACrD;;;;AAKA,eAAe,iBACd,QACA,SACA,UAC4C;CAC5C,MAAM,SAA2C,EAAE,OAAO;CAE1D,IAAI,SAAS;EACZ,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,OAAO,cAAc,QAAQ,EAAE,QAAQ,CAAC;CACzC;CAGA,IAAI,UAAU;EACb,OAAO,WAAW;EAClB,OAA2B,iBAAiB;EAE5C,OAAO,cAAc;GACpB,aAAa;GACb,iBAAiB;EAClB;CACD;CAEA,OAAO;EACN,IAAI,IAAI,SAAS,MAAM;EACvB,KAAK,IAAI,UAAU,MAAM;CAC1B;AACD;;;;AAKA,eAAe,aACd,IACA,YACmB;CACnB,IAAI;EACH,MAAM,GAAG,KAAK,IAAI,kBAAkB,EAAE,QAAQ,WAAW,CAAC,CAAC;EAC3D,OAAO;CACR,SAAS,OAAO;EACf,IAAK,MAA4B,SAAS,YACzC,OAAO;EAGR,IACE,MAAsD,WACpD,mBAAmB,KAEtB,OAAO;EAER,MAAM;CACP;AACD;;;;AAKA,eAAe,WAAW,KAAgB,UAAoC;CAC7E,IAAI;EACH,MAAM,IAAI,KAAK,IAAI,eAAe,EAAE,UAAU,SAAS,CAAC,CAAC;EACzD,OAAO;CACR,SAAS,OAAO;EACf,MAAM,YAAa,MAA4B;EAE/C,IAAI,cAAc,kBAAkB,cAAc,yBACjD,OAAO;EAER,MAAM;CACP;AACD;;;;;;;AAQA,eAAsB,2BACrB,SACuB;CACvB,MAAM,EACL,KACA,aACA,OACA,QACA,eACA,QACA,gBACG;CAGJ,IAAI,eAAe,eAClB,IAAI;EACH,MAAM,IAAI,eAAe,cAAc,aAAa;EACpD,OAAO,IAAI,sCAAsC;EACjD,OAAO;CACR,QAAQ;EACP,OAAO,IAAI,kDAAkD;CAC9D;CAID,MAAM,MAAM,MAAM,iBACjB,OAAO,QACP,OAAO,SACP,WACD;CACA,MAAM,mBAAmB,aAAa,WAAW;CAGjD,MAAM,aACL,eAAe,cACf,GAAG,iBAAiB,GAAG,MAAM,WAAW,aAAa;CAGtD,IAAI,CAAC,MAD6B,aAAa,IAAI,IAAI,UAAU,GACvC;EACzB,OAAO,IAAI,0BAA0B,YAAY;EAGjD,MAAM,qBAKF,EACH,QAAQ,WACT;EACA,IAAI,OAAO,WAAW,aACrB,mBAAmB,4BAA4B,EAC9C,oBAAoB,OAAO,OAC5B;EAGD,MAAM,IAAI,GAAG,KAAK,IAAI,oBAAoB,kBAAkB,CAAC;EAG7D,MAAM,IAAI,GAAG,KACZ,IAAI,2BAA2B;GAC9B,QAAQ;GACR,yBAAyB,EAAE,QAAQ,UAAU;EAC9C,CAAC,CACF;CACD,OACC,OAAO,IAAI,gCAAgC,YAAY;CAIxD,MAAM,cACL,eAAe,eAAe,kBAAkB,iBAAiB,GAAG;CAGrE,IAAI,CAAC,MAD8B,WAAW,IAAI,KAAK,WAAW,GACvC;EAC1B,OAAO,IAAI,yBAAyB,aAAa;EACjD,MAAM,IAAI,IAAI,KAAK,IAAI,kBAAkB,EAAE,UAAU,YAAY,CAAC,CAAC;CACpE,OACC,OAAO,IAAI,+BAA+B,aAAa;CAIxD,MAAM,iBAAiB;EACtB,SAAS;EACT,WAAW,CACV;GACC,QAAQ;GACR,QAAQ;IACP;IACA;IACA;IACA;IACA;GACD;GACA,UAAU,CACT,gBAAgB,cAChB,gBAAgB,WAAW,GAC5B;EACD,CACD;CACD;CAEA,OAAO,IAAI,wBAAwB;CACnC,MAAM,IAAI,IAAI,KACb,IAAI,qBAAqB;EACxB,UAAU;EACV,YAAY;EACZ,gBAAgB,KAAK,UAAU,cAAc;CAC9C,CAAC,CACF;CAGA,IAAI;CACJ,IAAI;CAEJ,IAAI,eAAe,kBAAkB,eAAe,oBAAoB;EAEvE,OAAO,IAAI,kCAAkC;EAC7C,cAAc,cAAc;EAC5B,kBAAkB,cAAc;CACjC,OAAO;EAEN,OAAO,IAAI,4BAA4B;EACvC,MAAM,kBAAkB,MAAM,IAAI,IAAI,KACrC,IAAI,uBAAuB,EAAE,UAAU,YAAY,CAAC,CACrD;EAEA,IAAI,CAAC,gBAAgB,WACpB,MAAM,IAAI,MAAM,iCAAiC;EAGlD,cAAc,gBAAgB,UAAU;EACxC,kBAAkB,gBAAgB,UAAU;CAC7C;CAGA,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,MAAM;CACrD,OAAO,IAAI,oCAAoC,iBAAiB;CAEhE,MAAM,EAAE,aAAa,YAAY,MAAM,IAAI,wBAC1C,iBACA;EACC,WAAW;EACM;EACjB,QAAQ;EACR,QAAQ,OAAO;CAChB,CACD;CAEA,IAAI,SACH,OAAO,IAAI,kCAAkC;MAE7C,OAAO,IAAI,yCAAyC;CAIrD,IAAI;EACH,MAAM,IAAI,0BAA0B,YAAY,aAAa;EAC7D,OAAO,IAAI,sCAAsC;CAClD,SAAS,OAAO;EACf,OAAO,IACN,0DAA0D,OAC3D;CACD;CAEA,OAAO;EACN;EACA,WAAW,gBAAgB;EAC3B;EACA,gBAAgB;EAChB,oBAAoB;EACpB,eAAe,YAAY;EAC3B,QAAQ,OAAO;EACf,WAAW,eAAe,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;CAC/D;AACD"}