@geekmidas/cli 10.0.0-alpha.12 → 10.0.0-alpha.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. package/README.md +310 -377
  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-BDa6pPgE.cjs +1090 -0
  7. package/dist/EndpointGenerator-BDa6pPgE.cjs.map +1 -0
  8. package/dist/EndpointGenerator-CP_z_E3e.mjs +1031 -0
  9. package/dist/EndpointGenerator-CP_z_E3e.mjs.map +1 -0
  10. package/dist/GoDaddyProvider-3C8U_tVu.cjs +388 -0
  11. package/dist/GoDaddyProvider-3C8U_tVu.cjs.map +1 -0
  12. package/dist/GoDaddyProvider-D0MQoOM4.mjs +388 -0
  13. package/dist/GoDaddyProvider-D0MQoOM4.mjs.map +1 -0
  14. package/dist/{HostingerProvider-BcyFRbqV.mjs → HostingerProvider-BNpS9aRJ.mjs} +29 -25
  15. package/dist/HostingerProvider-BNpS9aRJ.mjs.map +1 -0
  16. package/dist/{HostingerProvider-BOvsgATO.cjs → HostingerProvider-DR1iws1P.cjs} +29 -25
  17. package/dist/HostingerProvider-DR1iws1P.cjs.map +1 -0
  18. package/dist/LegacyStateStore-CRi7TosX.mjs +124 -0
  19. package/dist/LegacyStateStore-CRi7TosX.mjs.map +1 -0
  20. package/dist/LegacyStateStore-DHsoQGOo.cjs +124 -0
  21. package/dist/LegacyStateStore-DHsoQGOo.cjs.map +1 -0
  22. package/dist/LocalStateStore-BQXTkeoS.cjs +178 -0
  23. package/dist/LocalStateStore-BQXTkeoS.cjs.map +1 -0
  24. package/dist/LocalStateStore-Dkth0jXX.mjs +167 -0
  25. package/dist/LocalStateStore-Dkth0jXX.mjs.map +1 -0
  26. package/dist/OpenApiTsGenerator-CsrukCE-.mjs +536 -0
  27. package/dist/OpenApiTsGenerator-CsrukCE-.mjs.map +1 -0
  28. package/dist/OpenApiTsGenerator-FNhY7Ssz.cjs +541 -0
  29. package/dist/OpenApiTsGenerator-FNhY7Ssz.cjs.map +1 -0
  30. package/dist/{Route53Provider-CH9XH7bz.cjs → Route53Provider-Bllus2NR.cjs} +21 -22
  31. package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
  32. package/dist/{Route53Provider-C0xmer8U.mjs → Route53Provider-QXxjkZO1.mjs} +13 -13
  33. package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
  34. package/dist/S3StateStore-DGKZgyKz.cjs +222 -0
  35. package/dist/S3StateStore-DGKZgyKz.cjs.map +1 -0
  36. package/dist/S3StateStore-pZZnLLBd.mjs +223 -0
  37. package/dist/S3StateStore-pZZnLLBd.mjs.map +1 -0
  38. package/dist/SSMStateStore-CZRMERDA.mjs +205 -0
  39. package/dist/SSMStateStore-CZRMERDA.mjs.map +1 -0
  40. package/dist/SSMStateStore-DzkyjQ5D.cjs +204 -0
  41. package/dist/SSMStateStore-DzkyjQ5D.cjs.map +1 -0
  42. package/dist/SubscriberGenerator-C8CPxrCK.cjs +592 -0
  43. package/dist/SubscriberGenerator-C8CPxrCK.cjs.map +1 -0
  44. package/dist/SubscriberGenerator-y3pncae_.mjs +533 -0
  45. package/dist/SubscriberGenerator-y3pncae_.mjs.map +1 -0
  46. package/dist/add-C0kXOsWS.mjs +717 -0
  47. package/dist/add-C0kXOsWS.mjs.map +1 -0
  48. package/dist/add-Df8cmz0H.cjs +719 -0
  49. package/dist/add-Df8cmz0H.cjs.map +1 -0
  50. package/dist/appPorts-BoXMwolc.mjs +249 -0
  51. package/dist/appPorts-BoXMwolc.mjs.map +1 -0
  52. package/dist/appPorts-IW-OZmRi.cjs +296 -0
  53. package/dist/appPorts-IW-OZmRi.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-DXXg6FIL.mjs → backup-provisioner-C8DnCmxK.mjs} +11 -8
  63. package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
  64. package/dist/{backup-provisioner-cE2PuCTb.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-Bux2iF-v.mjs → bundler-B-I4Du99.mjs} +35 -16
  75. package/dist/bundler-B-I4Du99.mjs.map +1 -0
  76. package/dist/{bundler-BMekgx7a.cjs → bundler-Dx_grUmc.cjs} +37 -19
  77. package/dist/bundler-Dx_grUmc.cjs.map +1 -0
  78. package/dist/cli-Cd9exatJ.cjs +71 -0
  79. package/dist/cli-Cd9exatJ.cjs.map +1 -0
  80. package/dist/cli-DL7GxGAe.mjs +71 -0
  81. package/dist/cli-DL7GxGAe.mjs.map +1 -0
  82. package/dist/compose-C43c03WZ.mjs +3284 -0
  83. package/dist/compose-C43c03WZ.mjs.map +1 -0
  84. package/dist/compose-Mdgea4Yt.cjs +3427 -0
  85. package/dist/compose-Mdgea4Yt.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-B67WJOOm.cjs +272 -0
  97. package/dist/credentialSchemas-B67WJOOm.cjs.map +1 -0
  98. package/dist/credentialSchemas-DDOLRCLF.mjs +237 -0
  99. package/dist/credentialSchemas-DDOLRCLF.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-BPOgTn1u.mjs +522 -0
  105. package/dist/databases-BPOgTn1u.mjs.map +1 -0
  106. package/dist/databases-fOaoBInm.cjs +625 -0
  107. package/dist/databases-fOaoBInm.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 +654 -0
  115. package/dist/deploy/public.d.cts.map +1 -0
  116. package/dist/deploy/public.d.mts +654 -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-BMM2hx-K.cjs +2401 -0
  163. package/dist/deploy-BMM2hx-K.cjs.map +1 -0
  164. package/dist/deploy-D5YhwDng.mjs +2328 -0
  165. package/dist/deploy-D5YhwDng.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-C5roJuc9.mjs +560 -0
  171. package/dist/discover-C5roJuc9.mjs.map +1 -0
  172. package/dist/discover-CSW_BMWa.d.cts +125 -0
  173. package/dist/discover-CSW_BMWa.d.cts.map +1 -0
  174. package/dist/discover-DozUKs8f.cjs +639 -0
  175. package/dist/discover-DozUKs8f.cjs.map +1 -0
  176. package/dist/discover-xtT7fgWg.d.mts +125 -0
  177. package/dist/discover-xtT7fgWg.d.mts.map +1 -0
  178. package/dist/dns-BIYf20p7.cjs +1057 -0
  179. package/dist/dns-BIYf20p7.cjs.map +1 -0
  180. package/dist/dns-agf2VCdV.mjs +926 -0
  181. package/dist/dns-agf2VCdV.mjs.map +1 -0
  182. package/dist/dokploy-2p4PK6ej.mjs +38 -0
  183. package/dist/dokploy-2p4PK6ej.mjs.map +1 -0
  184. package/dist/dokploy-BANMTroy.cjs +38 -0
  185. package/dist/dokploy-BANMTroy.cjs.map +1 -0
  186. package/dist/drivers-BjGDYfnC.mjs +195 -0
  187. package/dist/drivers-BjGDYfnC.mjs.map +1 -0
  188. package/dist/drivers-DbjiYpW6.cjs +224 -0
  189. package/dist/drivers-DbjiYpW6.cjs.map +1 -0
  190. package/dist/eas-CNi16SoO.cjs +337 -0
  191. package/dist/eas-CNi16SoO.cjs.map +1 -0
  192. package/dist/eas-iT2JDHCh.mjs +334 -0
  193. package/dist/eas-iT2JDHCh.mjs.map +1 -0
  194. package/dist/{emit-CIlvnDvV.mjs → emit-C1e8qD08.mjs} +13 -26
  195. package/dist/emit-C1e8qD08.mjs.map +1 -0
  196. package/dist/{emit-CUD1BWls.cjs → emit-Dmc1nvdS.cjs} +31 -57
  197. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  198. package/dist/encryption-DkXVbyZc.mjs +89 -0
  199. package/dist/encryption-DkXVbyZc.mjs.map +1 -0
  200. package/dist/encryption-d2lLtkYx.cjs +90 -0
  201. package/dist/encryption-d2lLtkYx.cjs.map +1 -0
  202. package/dist/engine-CatKW6E-.mjs +3089 -0
  203. package/dist/engine-CatKW6E-.mjs.map +1 -0
  204. package/dist/engine-DlEHexED.cjs +3202 -0
  205. package/dist/engine-DlEHexED.cjs.map +1 -0
  206. package/dist/errors-D8Gwp5kU.mjs +23 -0
  207. package/dist/errors-D8Gwp5kU.mjs.map +1 -0
  208. package/dist/errors-DMC4Umsb.cjs +34 -0
  209. package/dist/errors-DMC4Umsb.cjs.map +1 -0
  210. package/dist/github-BAeaC1Pl.cjs +833 -0
  211. package/dist/github-BAeaC1Pl.cjs.map +1 -0
  212. package/dist/github-DErsqKGN.mjs +832 -0
  213. package/dist/github-DErsqKGN.mjs.map +1 -0
  214. package/dist/googlePlay-BVcfFWRO.cjs +931 -0
  215. package/dist/googlePlay-BVcfFWRO.cjs.map +1 -0
  216. package/dist/googlePlay-BXJ5ZjMK.mjs +931 -0
  217. package/dist/googlePlay-BXJ5ZjMK.mjs.map +1 -0
  218. package/dist/identity-CBXr4wNi.mjs +129 -0
  219. package/dist/identity-CBXr4wNi.mjs.map +1 -0
  220. package/dist/identity-CbLfgQNT.cjs +182 -0
  221. package/dist/identity-CbLfgQNT.cjs.map +1 -0
  222. package/dist/{index-BzJ7QJ9c.d.mts → index-8OfpOtSI.d.cts} +39 -20
  223. package/dist/index-8OfpOtSI.d.cts.map +1 -0
  224. package/dist/{index-CfMjtdVC.d.cts → index-Dpji6Bxq.d.mts} +39 -20
  225. package/dist/index-Dpji6Bxq.d.mts.map +1 -0
  226. package/dist/index.cjs +14291 -11898
  227. package/dist/index.cjs.map +1 -1
  228. package/dist/index.d.cts +1 -1
  229. package/dist/index.d.mts +1 -1
  230. package/dist/index.mjs +13938 -11560
  231. package/dist/index.mjs.map +1 -1
  232. package/dist/local-BwC2v2Y8.mjs +224 -0
  233. package/dist/local-BwC2v2Y8.mjs.map +1 -0
  234. package/dist/local-DNhnkugT.cjs +241 -0
  235. package/dist/local-DNhnkugT.cjs.map +1 -0
  236. package/dist/migrate-Bb1MmGHl.mjs +181 -0
  237. package/dist/migrate-Bb1MmGHl.mjs.map +1 -0
  238. package/dist/migrate-D79GI0XM.cjs +271 -0
  239. package/dist/migrate-D79GI0XM.cjs.map +1 -0
  240. package/dist/migrate-L4a273dY.cjs +181 -0
  241. package/dist/migrate-L4a273dY.cjs.map +1 -0
  242. package/dist/migrate-s4QizIoM.mjs +266 -0
  243. package/dist/migrate-s4QizIoM.mjs.map +1 -0
  244. package/dist/openapi.cjs +214 -10
  245. package/dist/openapi.cjs.map +1 -0
  246. package/dist/openapi.d.cts +38 -17
  247. package/dist/openapi.d.cts.map +1 -1
  248. package/dist/openapi.d.mts +38 -17
  249. package/dist/openapi.d.mts.map +1 -1
  250. package/dist/openapi.mjs +208 -5
  251. package/dist/openapi.mjs.map +1 -0
  252. package/dist/projectBucket-BBbQ1lHF.cjs +263 -0
  253. package/dist/projectBucket-BBbQ1lHF.cjs.map +1 -0
  254. package/dist/projectBucket-C_DN4WzF.mjs +222 -0
  255. package/dist/projectBucket-C_DN4WzF.mjs.map +1 -0
  256. package/dist/provider-BqpjG9QM.cjs +57 -0
  257. package/dist/provider-BqpjG9QM.cjs.map +1 -0
  258. package/dist/provider-CEOKk8NS.mjs +46 -0
  259. package/dist/provider-CEOKk8NS.mjs.map +1 -0
  260. package/dist/publish-CcTlmJT6.mjs +123 -0
  261. package/dist/publish-CcTlmJT6.mjs.map +1 -0
  262. package/dist/publish-ydscCYsW.cjs +124 -0
  263. package/dist/publish-ydscCYsW.cjs.map +1 -0
  264. package/dist/ready-BFFP838V.cjs +404 -0
  265. package/dist/ready-BFFP838V.cjs.map +1 -0
  266. package/dist/ready-BOfogqzr.mjs +375 -0
  267. package/dist/ready-BOfogqzr.mjs.map +1 -0
  268. package/dist/reconcile/public.cjs +3 -5
  269. package/dist/reconcile/public.d.cts +11 -87
  270. package/dist/reconcile/public.d.cts.map +1 -1
  271. package/dist/reconcile/public.d.mts +11 -87
  272. package/dist/reconcile/public.d.mts.map +1 -1
  273. package/dist/reconcile/public.mjs +3 -4
  274. package/dist/{reconcile-BI0tWkwz.mjs → reconcile--I7V4Klj.mjs} +4 -7
  275. package/dist/reconcile--I7V4Klj.mjs.map +1 -0
  276. package/dist/{reconcile-Bhw5fmKu.cjs → reconcile-CuCQBa5-.cjs} +5 -8
  277. package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
  278. package/dist/resolve-BLp2trep.mjs +263 -0
  279. package/dist/resolve-BLp2trep.mjs.map +1 -0
  280. package/dist/resolve-BgL-brF9.cjs +316 -0
  281. package/dist/resolve-BgL-brF9.cjs.map +1 -0
  282. package/dist/rollback-2cyLXEH1.cjs +165 -0
  283. package/dist/rollback-2cyLXEH1.cjs.map +1 -0
  284. package/dist/rollback-DwqZ8zzj.mjs +136 -0
  285. package/dist/rollback-DwqZ8zzj.mjs.map +1 -0
  286. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  287. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  288. package/dist/run-BJLIerMM.mjs +133 -0
  289. package/dist/run-BJLIerMM.mjs.map +1 -0
  290. package/dist/run-fVZ-rLnc.cjs +174 -0
  291. package/dist/run-fVZ-rLnc.cjs.map +1 -0
  292. package/dist/runtime-ACdfK59n.d.cts +82 -0
  293. package/dist/runtime-ACdfK59n.d.cts.map +1 -0
  294. package/dist/runtime-YyQuekxi.d.mts +82 -0
  295. package/dist/runtime-YyQuekxi.d.mts.map +1 -0
  296. package/dist/s3-CrPoA89T.cjs +215 -0
  297. package/dist/s3-CrPoA89T.cjs.map +1 -0
  298. package/dist/s3-DQXZdmCM.mjs +215 -0
  299. package/dist/s3-DQXZdmCM.mjs.map +1 -0
  300. package/dist/sandbox/config-worker.cjs +43 -0
  301. package/dist/sandbox/config-worker.cjs.map +1 -0
  302. package/dist/sandbox/config-worker.d.cts +1 -0
  303. package/dist/sandbox/config-worker.d.mts +1 -0
  304. package/dist/sandbox/config-worker.mjs +44 -0
  305. package/dist/sandbox/config-worker.mjs.map +1 -0
  306. package/dist/sandbox/credentials-worker.cjs +54 -0
  307. package/dist/sandbox/credentials-worker.cjs.map +1 -0
  308. package/dist/sandbox/credentials-worker.d.cts +1 -0
  309. package/dist/sandbox/credentials-worker.d.mts +1 -0
  310. package/dist/sandbox/credentials-worker.mjs +55 -0
  311. package/dist/sandbox/credentials-worker.mjs.map +1 -0
  312. package/dist/sandbox/discover-worker.cjs +50 -0
  313. package/dist/sandbox/discover-worker.cjs.map +1 -0
  314. package/dist/sandbox/discover-worker.d.cts +1 -0
  315. package/dist/sandbox/discover-worker.d.mts +1 -0
  316. package/dist/sandbox/discover-worker.mjs +51 -0
  317. package/dist/sandbox/discover-worker.mjs.map +1 -0
  318. package/dist/sandbox/migrate-worker.cjs +75 -0
  319. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  320. package/dist/sandbox/migrate-worker.d.cts +1 -0
  321. package/dist/sandbox/migrate-worker.d.mts +1 -0
  322. package/dist/sandbox/migrate-worker.mjs +76 -0
  323. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  324. package/dist/sandbox-C4g1eG31.d.mts +104 -0
  325. package/dist/sandbox-C4g1eG31.d.mts.map +1 -0
  326. package/dist/sandbox-CHv3OYXg.cjs +165 -0
  327. package/dist/sandbox-CHv3OYXg.cjs.map +1 -0
  328. package/dist/sandbox-CbVB7uOD.mjs +118 -0
  329. package/dist/sandbox-CbVB7uOD.mjs.map +1 -0
  330. package/dist/sandbox-CdKgQ3XU.d.cts +104 -0
  331. package/dist/sandbox-CdKgQ3XU.d.cts.map +1 -0
  332. package/dist/{workspace-DPV7FtAv.cjs → schemas-BCwKKA42.mjs} +958 -1816
  333. package/dist/schemas-BCwKKA42.mjs.map +1 -0
  334. package/dist/{workspace-CtnZnWsa.mjs → schemas-BQ_v0lEX.cjs} +1048 -1626
  335. package/dist/schemas-BQ_v0lEX.cjs.map +1 -0
  336. package/dist/secretsManager-CQORubp9.mjs +97 -0
  337. package/dist/secretsManager-CQORubp9.mjs.map +1 -0
  338. package/dist/secretsManager-RAGcEDX1.cjs +108 -0
  339. package/dist/secretsManager-RAGcEDX1.cjs.map +1 -0
  340. package/dist/seeds-C2w4UqVP.cjs +9347 -0
  341. package/dist/seeds-C2w4UqVP.cjs.map +1 -0
  342. package/dist/seeds-Cwtv-U9-.mjs +8350 -0
  343. package/dist/seeds-Cwtv-U9-.mjs.map +1 -0
  344. package/dist/serverSetup-BdFOD93s.cjs +631 -0
  345. package/dist/serverSetup-BdFOD93s.cjs.map +1 -0
  346. package/dist/serverSetup-utKsoyGH.mjs +631 -0
  347. package/dist/serverSetup-utKsoyGH.mjs.map +1 -0
  348. package/dist/sniffer-8C4q6Szd.mjs +1825 -0
  349. package/dist/sniffer-8C4q6Szd.mjs.map +1 -0
  350. package/dist/sniffer-CF7wNxMo.cjs +1998 -0
  351. package/dist/sniffer-CF7wNxMo.cjs.map +1 -0
  352. package/dist/sst-B-Uz4cvm.cjs +464 -0
  353. package/dist/sst-B-Uz4cvm.cjs.map +1 -0
  354. package/dist/sst-C1pxbFEd.mjs +441 -0
  355. package/dist/sst-C1pxbFEd.mjs.map +1 -0
  356. package/dist/stage-BvM_u2z4.mjs +302 -0
  357. package/dist/stage-BvM_u2z4.mjs.map +1 -0
  358. package/dist/stage-DEQJGW3r.cjs +313 -0
  359. package/dist/stage-DEQJGW3r.cjs.map +1 -0
  360. package/dist/stages-Cb9rqRbN.mjs +190 -0
  361. package/dist/stages-Cb9rqRbN.mjs.map +1 -0
  362. package/dist/stages-D4SnG5yl.cjs +190 -0
  363. package/dist/stages-D4SnG5yl.cjs.map +1 -0
  364. package/dist/target/public.cjs +15 -0
  365. package/dist/target/public.d.cts +28 -0
  366. package/dist/target/public.d.cts.map +1 -0
  367. package/dist/target/public.d.mts +28 -0
  368. package/dist/target/public.d.mts.map +1 -0
  369. package/dist/target/public.mjs +4 -0
  370. package/dist/terminal-CW_dWeTe.mjs +85 -0
  371. package/dist/terminal-CW_dWeTe.mjs.map +1 -0
  372. package/dist/terminal-DJlqcW_U.cjs +85 -0
  373. package/dist/terminal-DJlqcW_U.cjs.map +1 -0
  374. package/dist/types-B6UXlEkf.d.cts +7650 -0
  375. package/dist/types-B6UXlEkf.d.cts.map +1 -0
  376. package/dist/types-HqVPddRK.d.mts +7649 -0
  377. package/dist/types-HqVPddRK.d.mts.map +1 -0
  378. package/dist/utils-D2Nk1Nv2.cjs +205 -0
  379. package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
  380. package/dist/utils-D_fxUqvU.mjs +156 -0
  381. package/dist/utils-D_fxUqvU.mjs.map +1 -0
  382. package/dist/vitest.cjs +65 -0
  383. package/dist/vitest.cjs.map +1 -0
  384. package/dist/vitest.d.cts +29 -0
  385. package/dist/vitest.d.cts.map +1 -0
  386. package/dist/vitest.d.mts +29 -0
  387. package/dist/vitest.d.mts.map +1 -0
  388. package/dist/vitest.mjs +65 -0
  389. package/dist/vitest.mjs.map +1 -0
  390. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  391. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  392. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  393. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  394. package/dist/workspace/index.cjs +8 -4
  395. package/dist/workspace/index.d.cts +3 -3
  396. package/dist/workspace/index.d.mts +3 -3
  397. package/dist/workspace/index.mjs +2 -3
  398. package/dist/workspace-BwqQnool.cjs +2806 -0
  399. package/dist/workspace-BwqQnool.cjs.map +1 -0
  400. package/dist/workspace-D1QbNd55.mjs +2394 -0
  401. package/dist/workspace-D1QbNd55.mjs.map +1 -0
  402. package/package.json +54 -22
  403. package/dist/CachedStateProvider-BEBl2wQT.cjs +0 -60
  404. package/dist/CachedStateProvider-BEBl2wQT.cjs.map +0 -1
  405. package/dist/CachedStateProvider-C-8wtlto.mjs +0 -3
  406. package/dist/CachedStateProvider-Co4n5Wvs.mjs +0 -54
  407. package/dist/CachedStateProvider-Co4n5Wvs.mjs.map +0 -1
  408. package/dist/CachedStateProvider-DqhGpzsm.cjs +0 -3
  409. package/dist/HostingerProvider-BOvsgATO.cjs.map +0 -1
  410. package/dist/HostingerProvider-BcyFRbqV.mjs.map +0 -1
  411. package/dist/LocalStateProvider-Bq-0C0sg.mjs +0 -42
  412. package/dist/LocalStateProvider-Bq-0C0sg.mjs.map +0 -1
  413. package/dist/LocalStateProvider-yjXZXZDM.cjs +0 -43
  414. package/dist/LocalStateProvider-yjXZXZDM.cjs.map +0 -1
  415. package/dist/Route53Provider-C0xmer8U.mjs.map +0 -1
  416. package/dist/Route53Provider-CH9XH7bz.cjs.map +0 -1
  417. package/dist/SSMStateProvider-CXtNgPfy.cjs +0 -66
  418. package/dist/SSMStateProvider-CXtNgPfy.cjs.map +0 -1
  419. package/dist/SSMStateProvider-DOZifZfE.mjs +0 -66
  420. package/dist/SSMStateProvider-DOZifZfE.mjs.map +0 -1
  421. package/dist/backup-provisioner-DXXg6FIL.mjs.map +0 -1
  422. package/dist/backup-provisioner-cE2PuCTb.cjs.map +0 -1
  423. package/dist/bundler-BMekgx7a.cjs.map +0 -1
  424. package/dist/bundler-Bux2iF-v.mjs.map +0 -1
  425. package/dist/chunk-Duj1WY3L.mjs +0 -7
  426. package/dist/config-DTsVjKZD.mjs +0 -402
  427. package/dist/config-DTsVjKZD.mjs.map +0 -1
  428. package/dist/config-RYR9j6EF.cjs +0 -462
  429. package/dist/config-RYR9j6EF.cjs.map +0 -1
  430. package/dist/config.d.cts.map +0 -1
  431. package/dist/config.d.mts.map +0 -1
  432. package/dist/credentials-B5zRHdAl.mjs +0 -141
  433. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  434. package/dist/credentials-BapzjyV5.cjs +0 -195
  435. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  436. package/dist/credentials-DQRvPz2S.cjs +0 -2769
  437. package/dist/credentials-DQRvPz2S.cjs.map +0 -1
  438. package/dist/credentials-jMJC63qs.mjs +0 -2625
  439. package/dist/credentials-jMJC63qs.mjs.map +0 -1
  440. package/dist/discover-BYHQwQqu.mjs +0 -242
  441. package/dist/discover-BYHQwQqu.mjs.map +0 -1
  442. package/dist/discover-DmW9Bscc.cjs +0 -290
  443. package/dist/discover-DmW9Bscc.cjs.map +0 -1
  444. package/dist/dokploy-api-5cK2InBm.cjs +0 -3
  445. package/dist/dokploy-api-D2Ny4Jrc.mjs +0 -3
  446. package/dist/dokploy-api-pdaBryoY.mjs +0 -706
  447. package/dist/dokploy-api-pdaBryoY.mjs.map +0 -1
  448. package/dist/dokploy-api-zqKe9lHH.cjs +0 -718
  449. package/dist/dokploy-api-zqKe9lHH.cjs.map +0 -1
  450. package/dist/emit-CIlvnDvV.mjs.map +0 -1
  451. package/dist/emit-CUD1BWls.cjs.map +0 -1
  452. package/dist/encryption-D2pL3tHH.cjs +0 -54
  453. package/dist/encryption-D2pL3tHH.cjs.map +0 -1
  454. package/dist/encryption-YDsXXi6w.mjs +0 -3
  455. package/dist/encryption-_4zwjOAR.mjs +0 -42
  456. package/dist/encryption-_4zwjOAR.mjs.map +0 -1
  457. package/dist/encryption-sQ2Oxx0d.cjs +0 -4
  458. package/dist/fullstack-secrets-B6KBHf-g.mjs +0 -87
  459. package/dist/fullstack-secrets-B6KBHf-g.mjs.map +0 -1
  460. package/dist/fullstack-secrets-DL8v0y4D.cjs +0 -99
  461. package/dist/fullstack-secrets-DL8v0y4D.cjs.map +0 -1
  462. package/dist/generator-CNzBw7g5.cjs +0 -289
  463. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  464. package/dist/generator-VE2JrFlY.mjs +0 -253
  465. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  466. package/dist/github-BThvbf2W.cjs +0 -197
  467. package/dist/github-BThvbf2W.cjs.map +0 -1
  468. package/dist/github-DpMZurEK.mjs +0 -196
  469. package/dist/github-DpMZurEK.mjs.map +0 -1
  470. package/dist/index-BzJ7QJ9c.d.mts.map +0 -1
  471. package/dist/index-CfMjtdVC.d.cts.map +0 -1
  472. package/dist/keystore-C9rint2E.cjs +0 -101
  473. package/dist/keystore-C9rint2E.cjs.map +0 -1
  474. package/dist/keystore-TxeYM7an.mjs +0 -83
  475. package/dist/keystore-TxeYM7an.mjs.map +0 -1
  476. package/dist/openapi-Bs3-5q_r.mjs +0 -2021
  477. package/dist/openapi-Bs3-5q_r.mjs.map +0 -1
  478. package/dist/openapi-DWLTsYLL.cjs +0 -2075
  479. package/dist/openapi-DWLTsYLL.cjs.map +0 -1
  480. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  481. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  482. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  483. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  484. package/dist/openapi-react-query.cjs +0 -4
  485. package/dist/openapi-react-query.d.cts +0 -11
  486. package/dist/openapi-react-query.d.cts.map +0 -1
  487. package/dist/openapi-react-query.d.mts +0 -11
  488. package/dist/openapi-react-query.d.mts.map +0 -1
  489. package/dist/openapi-react-query.mjs +0 -4
  490. package/dist/reconcile-BI0tWkwz.mjs.map +0 -1
  491. package/dist/reconcile-Bhw5fmKu.cjs.map +0 -1
  492. package/dist/setup-BmLoNrDX.mjs +0 -12
  493. package/dist/setup-BrR1_xGy.cjs +0 -12
  494. package/dist/setup-BsNR2LBG.cjs +0 -467
  495. package/dist/setup-BsNR2LBG.cjs.map +0 -1
  496. package/dist/setup-D5-JMknk.mjs +0 -437
  497. package/dist/setup-D5-JMknk.mjs.map +0 -1
  498. package/dist/storage-B020InPW.mjs +0 -222
  499. package/dist/storage-B020InPW.mjs.map +0 -1
  500. package/dist/storage-CSNplaJn.cjs +0 -282
  501. package/dist/storage-CSNplaJn.cjs.map +0 -1
  502. package/dist/storage-DGBzMLZa.mjs +0 -4
  503. package/dist/storage-DlVol_oj.cjs +0 -8
  504. package/dist/sync-0ILCb-1S.cjs +0 -93
  505. package/dist/sync-0ILCb-1S.cjs.map +0 -1
  506. package/dist/sync-CzHXiR9c.mjs +0 -76
  507. package/dist/sync-CzHXiR9c.mjs.map +0 -1
  508. package/dist/sync-DYENfOt4.cjs +0 -4
  509. package/dist/sync-HAau6h_R.mjs +0 -3
  510. package/dist/types-DVIx8I1N.d.mts +0 -1950
  511. package/dist/types-DVIx8I1N.d.mts.map +0 -1
  512. package/dist/types-PMP_qXRY.d.cts +0 -1950
  513. package/dist/types-PMP_qXRY.d.cts.map +0 -1
  514. package/dist/workspace-Cji6lE8E.cjs +0 -10
  515. package/dist/workspace-CkJAtRIX.mjs +0 -9
  516. package/dist/workspace-CtnZnWsa.mjs.map +0 -1
  517. package/dist/workspace-DPV7FtAv.cjs.map +0 -1
@@ -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-DXXg6FIL.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":"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"}
@@ -1,8 +1,12 @@
1
- const require_chunk = require('./chunk-CUT6urMc.cjs');
2
- const __aws_sdk_client_s3 = require_chunk.__toESM(require("@aws-sdk/client-s3"));
3
- const __aws_sdk_client_iam = require_chunk.__toESM(require("@aws-sdk/client-iam"));
4
-
5
- //#region src/deploy/backup-provisioner.ts
1
+ let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
2
+ let _aws_sdk_client_iam = require("@aws-sdk/client-iam");
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
+ */
6
10
  /**
7
11
  * Generate a random suffix for unique resource names
8
12
  */
@@ -33,8 +37,8 @@ async function createAwsClients(region, profile, endpoint) {
33
37
  };
34
38
  }
35
39
  return {
36
- s3: new __aws_sdk_client_s3.S3Client(config),
37
- iam: new __aws_sdk_client_iam.IAMClient(config)
40
+ s3: new _aws_sdk_client_s3.S3Client(config),
41
+ iam: new _aws_sdk_client_iam.IAMClient(config)
38
42
  };
39
43
  }
40
44
  /**
@@ -42,7 +46,7 @@ async function createAwsClients(region, profile, endpoint) {
42
46
  */
43
47
  async function bucketExists(s3, bucketName) {
44
48
  try {
45
- await s3.send(new __aws_sdk_client_s3.HeadBucketCommand({ Bucket: bucketName }));
49
+ await s3.send(new _aws_sdk_client_s3.HeadBucketCommand({ Bucket: bucketName }));
46
50
  return true;
47
51
  } catch (error) {
48
52
  if (error.name === "NotFound") return false;
@@ -55,7 +59,7 @@ async function bucketExists(s3, bucketName) {
55
59
  */
56
60
  async function userExists(iam, userName) {
57
61
  try {
58
- await iam.send(new __aws_sdk_client_iam.GetUserCommand({ UserName: userName }));
62
+ await iam.send(new _aws_sdk_client_iam.GetUserCommand({ UserName: userName }));
59
63
  return true;
60
64
  } catch (error) {
61
65
  const errorName = error.name;
@@ -81,22 +85,20 @@ async function provisionBackupDestination(options) {
81
85
  const aws = await createAwsClients(config.region, config.profile, awsEndpoint);
82
86
  const sanitizedProject = sanitizeName(projectName);
83
87
  const bucketName = existingState?.bucketName ?? `${sanitizedProject}-${stage}-backups-${randomSuffix()}`;
84
- const bucketAlreadyExists = await bucketExists(aws.s3, bucketName);
85
- if (!bucketAlreadyExists) {
88
+ if (!await bucketExists(aws.s3, bucketName)) {
86
89
  logger.log(` Creating S3 bucket: ${bucketName}`);
87
90
  const createBucketParams = { Bucket: bucketName };
88
91
  if (config.region !== "us-east-1") createBucketParams.CreateBucketConfiguration = { LocationConstraint: config.region };
89
- await aws.s3.send(new __aws_sdk_client_s3.CreateBucketCommand(createBucketParams));
90
- await aws.s3.send(new __aws_sdk_client_s3.PutBucketVersioningCommand({
92
+ await aws.s3.send(new _aws_sdk_client_s3.CreateBucketCommand(createBucketParams));
93
+ await aws.s3.send(new _aws_sdk_client_s3.PutBucketVersioningCommand({
91
94
  Bucket: bucketName,
92
95
  VersioningConfiguration: { Status: "Enabled" }
93
96
  }));
94
97
  } else logger.log(` Using existing S3 bucket: ${bucketName}`);
95
98
  const iamUserName = existingState?.iamUserName ?? `dokploy-backup-${sanitizedProject}-${stage}`;
96
- const iamUserAlreadyExists = await userExists(aws.iam, iamUserName);
97
- if (!iamUserAlreadyExists) {
99
+ if (!await userExists(aws.iam, iamUserName)) {
98
100
  logger.log(` Creating IAM user: ${iamUserName}`);
99
- await aws.iam.send(new __aws_sdk_client_iam.CreateUserCommand({ UserName: iamUserName }));
101
+ await aws.iam.send(new _aws_sdk_client_iam.CreateUserCommand({ UserName: iamUserName }));
100
102
  } else logger.log(` Using existing IAM user: ${iamUserName}`);
101
103
  const policyDocument = {
102
104
  Version: "2012-10-17",
@@ -113,7 +115,7 @@ async function provisionBackupDestination(options) {
113
115
  }]
114
116
  };
115
117
  logger.log(" Updating IAM policy");
116
- await aws.iam.send(new __aws_sdk_client_iam.PutUserPolicyCommand({
118
+ await aws.iam.send(new _aws_sdk_client_iam.PutUserPolicyCommand({
117
119
  UserName: iamUserName,
118
120
  PolicyName: "DokployBackupAccess",
119
121
  PolicyDocument: JSON.stringify(policyDocument)
@@ -126,7 +128,7 @@ async function provisionBackupDestination(options) {
126
128
  secretAccessKey = existingState.iamSecretAccessKey;
127
129
  } else {
128
130
  logger.log(" Creating IAM access key");
129
- const accessKeyResult = await aws.iam.send(new __aws_sdk_client_iam.CreateAccessKeyCommand({ UserName: iamUserName }));
131
+ const accessKeyResult = await aws.iam.send(new _aws_sdk_client_iam.CreateAccessKeyCommand({ UserName: iamUserName }));
130
132
  if (!accessKeyResult.AccessKey) throw new Error("Failed to create IAM access key");
131
133
  accessKeyId = accessKeyResult.AccessKey.AccessKeyId;
132
134
  secretAccessKey = accessKeyResult.AccessKey.SecretAccessKey;
@@ -158,7 +160,7 @@ async function provisionBackupDestination(options) {
158
160
  createdAt: existingState?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
159
161
  };
160
162
  }
161
-
162
163
  //#endregion
163
164
  exports.provisionBackupDestination = provisionBackupDestination;
164
- //# sourceMappingURL=backup-provisioner-cE2PuCTb.cjs.map
165
+
166
+ //# sourceMappingURL=backup-provisioner-oDEsPj02.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-provisioner-oDEsPj02.cjs","names":["S3Client","IAMClient","HeadBucketCommand","GetUserCommand","CreateBucketCommand","PutBucketVersioningCommand","CreateUserCommand","PutUserPolicyCommand","CreateAccessKeyCommand"],"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":"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"}