@geekmidas/cli 10.0.0-alpha.97 → 10.0.0-alpha.99

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 (209) hide show
  1. package/dist/{GoDaddyProvider-AqNu60WQ.mjs → GoDaddyProvider-206NguW1.mjs} +2 -2
  2. package/dist/{GoDaddyProvider-AqNu60WQ.mjs.map → GoDaddyProvider-206NguW1.mjs.map} +1 -1
  3. package/dist/{GoDaddyProvider-B4R_QFl8.cjs → GoDaddyProvider-D1aQy2i1.cjs} +2 -2
  4. package/dist/{GoDaddyProvider-B4R_QFl8.cjs.map → GoDaddyProvider-D1aQy2i1.cjs.map} +1 -1
  5. package/dist/{LegacyStateStore-B-aRqRdD.cjs → LegacyStateStore-CgJEr1G7.cjs} +3 -3
  6. package/dist/{LegacyStateStore-B-aRqRdD.cjs.map → LegacyStateStore-CgJEr1G7.cjs.map} +1 -1
  7. package/dist/{LegacyStateStore-8F05-BOo.mjs → LegacyStateStore-wmFfdzuh.mjs} +3 -3
  8. package/dist/{LegacyStateStore-8F05-BOo.mjs.map → LegacyStateStore-wmFfdzuh.mjs.map} +1 -1
  9. package/dist/{LocalStateStore-B_bRI8M7.cjs → LocalStateStore-BD14kra9.cjs} +2 -2
  10. package/dist/{LocalStateStore-B_bRI8M7.cjs.map → LocalStateStore-BD14kra9.cjs.map} +1 -1
  11. package/dist/{LocalStateStore-B_mfgcO8.mjs → LocalStateStore-C5mNp91D.mjs} +2 -2
  12. package/dist/{LocalStateStore-B_mfgcO8.mjs.map → LocalStateStore-C5mNp91D.mjs.map} +1 -1
  13. package/dist/{S3StateStore-CMN0Uzdp.mjs → S3StateStore-CEGbsDHi.mjs} +10 -9
  14. package/dist/S3StateStore-CEGbsDHi.mjs.map +1 -0
  15. package/dist/{S3StateStore-zK9zcd9f.cjs → S3StateStore-Csu_kJCy.cjs} +11 -10
  16. package/dist/S3StateStore-Csu_kJCy.cjs.map +1 -0
  17. package/dist/{SSMStateStore-Cv7VcMak.mjs → SSMStateStore-Bd62qwp4.mjs} +2 -2
  18. package/dist/{SSMStateStore-Cv7VcMak.mjs.map → SSMStateStore-Bd62qwp4.mjs.map} +1 -1
  19. package/dist/{SSMStateStore-C489DnR6.cjs → SSMStateStore-Rp21jtP5.cjs} +2 -2
  20. package/dist/{SSMStateStore-C489DnR6.cjs.map → SSMStateStore-Rp21jtP5.cjs.map} +1 -1
  21. package/dist/{add-BA5d4pA0.mjs → add-DyIEYI97.mjs} +4 -4
  22. package/dist/{add-BA5d4pA0.mjs.map → add-DyIEYI97.mjs.map} +1 -1
  23. package/dist/{add-HXzTCy_I.cjs → add-Iuo3ao5E.cjs} +5 -5
  24. package/dist/{add-HXzTCy_I.cjs.map → add-Iuo3ao5E.cjs.map} +1 -1
  25. package/dist/{aws-Dz2bYxK1.mjs → aws-8QQ8n-t6.mjs} +2 -2
  26. package/dist/{aws-Dz2bYxK1.mjs.map → aws-8QQ8n-t6.mjs.map} +1 -1
  27. package/dist/{aws-BTReGjpY.cjs → aws-DY9NqQIT.cjs} +2 -2
  28. package/dist/{aws-BTReGjpY.cjs.map → aws-DY9NqQIT.cjs.map} +1 -1
  29. package/dist/{awsStore-BWa1KNY-.mjs → awsStore-Bx5nCFnS.mjs} +8 -6
  30. package/dist/awsStore-Bx5nCFnS.mjs.map +1 -0
  31. package/dist/{awsStore-B5We7bMg.cjs → awsStore-u3ehhMoY.cjs} +8 -6
  32. package/dist/awsStore-u3ehhMoY.cjs.map +1 -0
  33. package/dist/{bundler-SX3Uy8qT.cjs → bundler-Bgoq8IyR.cjs} +5 -5
  34. package/dist/{bundler-SX3Uy8qT.cjs.map → bundler-Bgoq8IyR.cjs.map} +1 -1
  35. package/dist/{bundler-CBomFsnd.mjs → bundler-Q6Kp8b0r.mjs} +5 -5
  36. package/dist/{bundler-CBomFsnd.mjs.map → bundler-Q6Kp8b0r.mjs.map} +1 -1
  37. package/dist/{cli-D7z1lQtO.mjs → cli-B9BudUV0.mjs} +2 -4
  38. package/dist/cli-B9BudUV0.mjs.map +1 -0
  39. package/dist/{cli-1l0L9LCA.cjs → cli-W2DMRIbP.cjs} +2 -4
  40. package/dist/cli-W2DMRIbP.cjs.map +1 -0
  41. package/dist/compose-CIrFNWHb.cjs +3147 -0
  42. package/dist/compose-CIrFNWHb.cjs.map +1 -0
  43. package/dist/compose-CLsRcHkA.mjs +3052 -0
  44. package/dist/compose-CLsRcHkA.mjs.map +1 -0
  45. package/dist/{config-xIWIaDhW.d.cts → config-BVdHfj8b.d.cts} +4 -4
  46. package/dist/{config-D-k0gaAr.d.mts.map → config-BVdHfj8b.d.cts.map} +1 -1
  47. package/dist/{config-D-k0gaAr.d.mts → config-D2OqCmAM.d.mts} +4 -4
  48. package/dist/{config-xIWIaDhW.d.cts.map → config-D2OqCmAM.d.mts.map} +1 -1
  49. package/dist/config.cjs +1 -1
  50. package/dist/config.d.cts +3 -3
  51. package/dist/config.d.mts +3 -3
  52. package/dist/config.mjs +1 -1
  53. package/dist/deploy/public.cjs +9 -8
  54. package/dist/deploy/public.cjs.map +1 -1
  55. package/dist/deploy/public.d.cts +5 -16
  56. package/dist/deploy/public.d.cts.map +1 -1
  57. package/dist/deploy/public.d.mts +5 -16
  58. package/dist/deploy/public.d.mts.map +1 -1
  59. package/dist/deploy/public.mjs +8 -7
  60. package/dist/deploy/public.mjs.map +1 -1
  61. package/dist/{deploy-Cu_HyWoJ.cjs → deploy-CbJMJsgX.cjs} +26 -62
  62. package/dist/deploy-CbJMJsgX.cjs.map +1 -0
  63. package/dist/{deploy-LY-20Yeb.mjs → deploy-n_IB8r6H.mjs} +17 -59
  64. package/dist/deploy-n_IB8r6H.mjs.map +1 -0
  65. package/dist/{discover-CbJCQq4J.d.mts → discover-Caf6Hnv1.d.cts} +2 -2
  66. package/dist/{discover-CbJCQq4J.d.mts.map → discover-Caf6Hnv1.d.cts.map} +1 -1
  67. package/dist/{discover-RCW5mBXb.d.cts → discover-Cd5M2jPv.d.mts} +2 -2
  68. package/dist/{discover-RCW5mBXb.d.cts.map → discover-Cd5M2jPv.d.mts.map} +1 -1
  69. package/dist/{dns-BbTOzmVp.mjs → dns-C_LPS3qV.mjs} +3 -3
  70. package/dist/{dns-BbTOzmVp.mjs.map → dns-C_LPS3qV.mjs.map} +1 -1
  71. package/dist/{dns-BFnoawgh.cjs → dns-kp8To8Qj.cjs} +3 -3
  72. package/dist/{dns-BFnoawgh.cjs.map → dns-kp8To8Qj.cjs.map} +1 -1
  73. package/dist/{dokploy-LR94sBVI.mjs → dokploy-Dl_kNVeE.mjs} +2 -2
  74. package/dist/{dokploy-LR94sBVI.mjs.map → dokploy-Dl_kNVeE.mjs.map} +1 -1
  75. package/dist/{dokploy-CKgSww82.cjs → dokploy-gRIae9Ht.cjs} +2 -2
  76. package/dist/{dokploy-CKgSww82.cjs.map → dokploy-gRIae9Ht.cjs.map} +1 -1
  77. package/dist/{encryption-C0plOf4a.mjs → encryption-C3DcVZQs.mjs} +3 -3
  78. package/dist/{encryption-C0plOf4a.mjs.map → encryption-C3DcVZQs.mjs.map} +1 -1
  79. package/dist/{encryption-CUyw-8sc.cjs → encryption-CmQvQOSe.cjs} +3 -3
  80. package/dist/{encryption-CUyw-8sc.cjs.map → encryption-CmQvQOSe.cjs.map} +1 -1
  81. package/dist/{engine-DqbqQhck.mjs → engine-DBXuhHyf.mjs} +5 -4
  82. package/dist/{engine-DqbqQhck.mjs.map → engine-DBXuhHyf.mjs.map} +1 -1
  83. package/dist/{engine-D8TeraDK.cjs → engine-Dk19Mxc4.cjs} +27 -26
  84. package/dist/{engine-D8TeraDK.cjs.map → engine-Dk19Mxc4.cjs.map} +1 -1
  85. package/dist/{github-DC4SIqV1.cjs → github-Ds2RYnSU.cjs} +43 -20
  86. package/dist/github-Ds2RYnSU.cjs.map +1 -0
  87. package/dist/{github-zgaBOQvh.mjs → github-RawRLERq.mjs} +42 -19
  88. package/dist/github-RawRLERq.mjs.map +1 -0
  89. package/dist/identity-CBXr4wNi.mjs +129 -0
  90. package/dist/identity-CBXr4wNi.mjs.map +1 -0
  91. package/dist/identity-CbLfgQNT.cjs +182 -0
  92. package/dist/identity-CbLfgQNT.cjs.map +1 -0
  93. package/dist/{index-ClqOsbBl.d.mts → index-BU4G20G6.d.cts} +2 -2
  94. package/dist/{index-ClqOsbBl.d.mts.map → index-BU4G20G6.d.cts.map} +1 -1
  95. package/dist/{index-DgOBAEl5.d.cts → index-yDbd1WcM.d.mts} +2 -2
  96. package/dist/{index-DgOBAEl5.d.cts.map → index-yDbd1WcM.d.mts.map} +1 -1
  97. package/dist/index.cjs +156 -151
  98. package/dist/index.cjs.map +1 -1
  99. package/dist/index.mjs +153 -148
  100. package/dist/index.mjs.map +1 -1
  101. package/dist/{migrate-BJ8aLOWk.mjs → migrate-CZIGT3kB.mjs} +3 -3
  102. package/dist/{migrate-BJ8aLOWk.mjs.map → migrate-CZIGT3kB.mjs.map} +1 -1
  103. package/dist/migrate-CxZYzF_u.cjs +181 -0
  104. package/dist/migrate-CxZYzF_u.cjs.map +1 -0
  105. package/dist/migrate-DR1x96I4.mjs +181 -0
  106. package/dist/migrate-DR1x96I4.mjs.map +1 -0
  107. package/dist/{migrate-CWq8-s21.cjs → migrate-DjrTwWJA.cjs} +3 -3
  108. package/dist/{migrate-CWq8-s21.cjs.map → migrate-DjrTwWJA.cjs.map} +1 -1
  109. package/dist/openapi.cjs +1 -1
  110. package/dist/openapi.d.cts +1 -1
  111. package/dist/openapi.d.mts +1 -1
  112. package/dist/openapi.mjs +1 -1
  113. package/dist/{projectBucket-BFp-SFee.mjs → projectBucket-BYOxRnHY.mjs} +2 -2
  114. package/dist/{projectBucket-BFp-SFee.mjs.map → projectBucket-BYOxRnHY.mjs.map} +1 -1
  115. package/dist/{projectBucket-Cho9DpSh.cjs → projectBucket-CDu5rXjp.cjs} +2 -2
  116. package/dist/{projectBucket-Cho9DpSh.cjs.map → projectBucket-CDu5rXjp.cjs.map} +1 -1
  117. package/dist/reconcile/public.d.cts +2 -2
  118. package/dist/reconcile/public.d.mts +2 -2
  119. package/dist/{resolve-6EYNqYdr.mjs → resolve-CNYbGH8g.mjs} +3 -3
  120. package/dist/{resolve-6EYNqYdr.mjs.map → resolve-CNYbGH8g.mjs.map} +1 -1
  121. package/dist/{resolve-C8VkR4oW.cjs → resolve-DC98Rl1t.cjs} +3 -3
  122. package/dist/{resolve-C8VkR4oW.cjs.map → resolve-DC98Rl1t.cjs.map} +1 -1
  123. package/dist/{rollback-BsThTeSN.mjs → rollback-BkIkE8Qe.mjs} +5 -5
  124. package/dist/{rollback-BsThTeSN.mjs.map → rollback-BkIkE8Qe.mjs.map} +1 -1
  125. package/dist/{rollback-CvGfm4DX.cjs → rollback-DBfLvC8k.cjs} +5 -5
  126. package/dist/{rollback-CvGfm4DX.cjs.map → rollback-DBfLvC8k.cjs.map} +1 -1
  127. package/dist/{runtime-CaW4QqF2.d.cts → runtime-CLz3bf07.d.mts} +2 -2
  128. package/dist/{runtime-CaW4QqF2.d.cts.map → runtime-CLz3bf07.d.mts.map} +1 -1
  129. package/dist/{runtime-K5uxp6HE.d.mts → runtime-CUWf0IUk.d.cts} +2 -2
  130. package/dist/{runtime-K5uxp6HE.d.mts.map → runtime-CUWf0IUk.d.cts.map} +1 -1
  131. package/dist/s3-BwhQk3QM.mjs +215 -0
  132. package/dist/s3-BwhQk3QM.mjs.map +1 -0
  133. package/dist/s3-DLp0V-Ox.cjs +215 -0
  134. package/dist/s3-DLp0V-Ox.cjs.map +1 -0
  135. package/dist/{sandbox-D8cfZUAA.d.cts → sandbox-CfpLWTPP.d.mts} +2 -2
  136. package/dist/{sandbox-B_BkfmTP.d.mts.map → sandbox-CfpLWTPP.d.mts.map} +1 -1
  137. package/dist/{sandbox-B_BkfmTP.d.mts → sandbox-D1XeNEJ9.d.cts} +2 -2
  138. package/dist/{sandbox-D8cfZUAA.d.cts.map → sandbox-D1XeNEJ9.d.cts.map} +1 -1
  139. package/dist/{secretsManager-C6wm-9uZ.mjs → secretsManager-CQORubp9.mjs} +2 -2
  140. package/dist/{secretsManager-C6wm-9uZ.mjs.map → secretsManager-CQORubp9.mjs.map} +1 -1
  141. package/dist/{secretsManager-Cwwgs81g.cjs → secretsManager-RAGcEDX1.cjs} +2 -2
  142. package/dist/{secretsManager-Cwwgs81g.cjs.map → secretsManager-RAGcEDX1.cjs.map} +1 -1
  143. package/dist/{seeds-BQlj9Fsg.cjs → seeds-BNHSpjNP.cjs} +22 -166
  144. package/dist/seeds-BNHSpjNP.cjs.map +1 -0
  145. package/dist/{seeds-BsJRUL1K.mjs → seeds-C4bZ8L-T.mjs} +23 -119
  146. package/dist/seeds-C4bZ8L-T.mjs.map +1 -0
  147. package/dist/{sniffer-DVsvP8s-.mjs → sniffer-BIBm9dAb.mjs} +7 -7
  148. package/dist/{sniffer-DVsvP8s-.mjs.map → sniffer-BIBm9dAb.mjs.map} +1 -1
  149. package/dist/{sniffer-CeUKUoHn.cjs → sniffer-Cylp9W2D.cjs} +7 -7
  150. package/dist/{sniffer-CeUKUoHn.cjs.map → sniffer-Cylp9W2D.cjs.map} +1 -1
  151. package/dist/{stages-DEmn7qI8.mjs → stages-CcS9vnNu.mjs} +5 -18
  152. package/dist/stages-CcS9vnNu.mjs.map +1 -0
  153. package/dist/{stages-BpDXFPGg.cjs → stages-DdBV7msu.cjs} +5 -18
  154. package/dist/stages-DdBV7msu.cjs.map +1 -0
  155. package/dist/target/public.cjs +1 -1
  156. package/dist/target/public.d.cts +2 -2
  157. package/dist/target/public.d.mts +2 -2
  158. package/dist/target/public.mjs +1 -1
  159. package/dist/{types-4vPS_YFX.d.cts → types-BhThob0H.d.mts} +90 -21
  160. package/dist/types-BhThob0H.d.mts.map +1 -0
  161. package/dist/{types-CFsEyFb1.d.mts → types-DwoLHelT.d.cts} +91 -20
  162. package/dist/types-DwoLHelT.d.cts.map +1 -0
  163. package/dist/workspace/index.cjs +1 -1
  164. package/dist/workspace/index.d.cts +2 -2
  165. package/dist/workspace/index.d.mts +2 -2
  166. package/dist/workspace/index.mjs +1 -1
  167. package/dist/{workspace-Bv4xROeu.mjs → workspace-D5CpOp1y.mjs} +77 -5
  168. package/dist/workspace-D5CpOp1y.mjs.map +1 -0
  169. package/dist/{workspace-C1M-S4al.cjs → workspace-DRjdu1OY.cjs} +88 -4
  170. package/dist/workspace-DRjdu1OY.cjs.map +1 -0
  171. package/package.json +15 -15
  172. package/dist/S3StateStore-CMN0Uzdp.mjs.map +0 -1
  173. package/dist/S3StateStore-zK9zcd9f.cjs.map +0 -1
  174. package/dist/awsStore-B5We7bMg.cjs.map +0 -1
  175. package/dist/awsStore-BWa1KNY-.mjs.map +0 -1
  176. package/dist/cli-1l0L9LCA.cjs.map +0 -1
  177. package/dist/cli-D7z1lQtO.mjs.map +0 -1
  178. package/dist/compose-C39XupJu.cjs +0 -1558
  179. package/dist/compose-C39XupJu.cjs.map +0 -1
  180. package/dist/compose-DgWrNd2k.mjs +0 -1511
  181. package/dist/compose-DgWrNd2k.mjs.map +0 -1
  182. package/dist/deploy-Cu_HyWoJ.cjs.map +0 -1
  183. package/dist/deploy-LY-20Yeb.mjs.map +0 -1
  184. package/dist/dns-Bmbhmz41.mjs +0 -44
  185. package/dist/dns-Bmbhmz41.mjs.map +0 -1
  186. package/dist/dns-Dro_vbk9.cjs +0 -55
  187. package/dist/dns-Dro_vbk9.cjs.map +0 -1
  188. package/dist/github-DC4SIqV1.cjs.map +0 -1
  189. package/dist/github-zgaBOQvh.mjs.map +0 -1
  190. package/dist/migrate-C230QeXU.mjs +0 -94
  191. package/dist/migrate-C230QeXU.mjs.map +0 -1
  192. package/dist/migrate-CsMrI7Dk.cjs +0 -94
  193. package/dist/migrate-CsMrI7Dk.cjs.map +0 -1
  194. package/dist/secrets-BTY6JhTp.cjs +0 -47
  195. package/dist/secrets-BTY6JhTp.cjs.map +0 -1
  196. package/dist/secrets-HzKNTWg9.mjs +0 -36
  197. package/dist/secrets-HzKNTWg9.mjs.map +0 -1
  198. package/dist/seeds-BQlj9Fsg.cjs.map +0 -1
  199. package/dist/seeds-BsJRUL1K.mjs.map +0 -1
  200. package/dist/stack-BQOyqaVG.mjs +0 -1201
  201. package/dist/stack-BQOyqaVG.mjs.map +0 -1
  202. package/dist/stack-Clzi40EE.cjs +0 -1308
  203. package/dist/stack-Clzi40EE.cjs.map +0 -1
  204. package/dist/stages-BpDXFPGg.cjs.map +0 -1
  205. package/dist/stages-DEmn7qI8.mjs.map +0 -1
  206. package/dist/types-4vPS_YFX.d.cts.map +0 -1
  207. package/dist/types-CFsEyFb1.d.mts.map +0 -1
  208. package/dist/workspace-Bv4xROeu.mjs.map +0 -1
  209. package/dist/workspace-C1M-S4al.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-CbJMJsgX.cjs","names":["isReservedStageKey","secretsStoreFor","storedCredentials","GkmError","kebabCase","randomInt","provideKey","appEnvKeys","appKey","dependentsOf","resolveHost","isMainFrontendApp","NoDomainForStage","S3RegionRequired","BucketRegionUnknown","appKey","provideKey","BucketProbeFailed","BucketOwnedByAnotherProject","RecordedBucketUnreachable","BucketNameUnavailable","IamUserNotOwned","s3Url","BucketKeySetElsewhere","RotationInProgress","AccessKeyLimit","ProvisionedBucketUnreachable","BucketRegionMismatch","checkS3Config","S3_PROVISIONING","PROVIDER_KINDS","stageProvider","GkmError","deployIdentity","DeployJournal","createComposeState","createEmptyState","initStageSecrets","GkmError","providedKeyFor","externalServices","stageServiceDeclarations","stageProviderNotes","ExternalServicesNotConfigured","devServicesUsed","assertStageCredentials","constructGlobs","GkmError","builtinTarget","eventError","dnsCredentials","stageDnsDomains","assertStateRoom","initStageSecrets","resolveTarget","parseTargetOptions","DevServicesNeedServerTarget","discover","constructGlobs","usesTelemetry","derivedApps","deployIdentity","getAppBuildOrder","createStateStore","applicationName","storedCredentials","gkmHome","withOutput","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","eventError","loadWorkspaceConfig"],"sources":["../src/target/secrets.ts","../src/providers/dns.ts","../src/providers/aws.ts","../src/providers/s3/naming.ts","../src/providers/s3/origins.ts","../src/providers/s3/policy.ts","../src/providers/s3/index.ts","../src/providers/registry.ts","../src/providers/index.ts","../src/secrets/stale.ts","../src/deploy/readiness.ts","../src/deploy/orchestrate.ts","../src/deploy/deploy.ts"],"sourcesContent":["/**\n * A stage's secrets as a target sees them: read and written through the\n * stage's own store, and masked in everything the run prints once read.\n */\n\nimport { isReservedStageKey } from '../compose/dnsConfig.js';\nimport { secretsStoreFor } from '../secrets/store';\nimport type { StageSecrets } from '../secrets/types';\nimport type { NormalizedWorkspace } from '../workspace/types';\nimport type { DeploySecrets } from './types';\n\n/**\n * Shorter values are left alone: what a progress line legitimately prints —\n * a port, a stage, an app name — would otherwise come out as `***` wherever\n * a secret happened to share it.\n */\nconst SHORTEST_MASKED = 6;\n\n/** The values a run must never print, and the rewrite that keeps it so. */\nexport class Redactor {\n\tprivate readonly values = new Set<string>();\n\n\tadd(value: string | undefined): void {\n\t\tif (value && value.length >= SHORTEST_MASKED) this.values.add(value);\n\t}\n\n\t/** `text` with every masked value replaced by `***`, longest first. */\n\tredact(text: string): string {\n\t\tif (this.values.size === 0) return text;\n\t\tlet out = text;\n\t\tconst longestFirst = [...this.values].sort((a, b) => b.length - a.length);\n\t\tfor (const value of longestFirst) out = out.replaceAll(value, '***');\n\t\treturn out;\n\t}\n}\n\n/** Every value in `secrets` that is a secret rather than a label. */\nfunction secretValues(secrets: StageSecrets): string[] {\n\treturn [\n\t\tsecrets.seed,\n\t\t// The server's address is not one: it is in public DNS, and the deploy\n\t\t// prints it as the place it is deploying to.\n\t\t...Object.entries(secrets.custom ?? {})\n\t\t\t.filter(([key]) => !isReservedStageKey(key))\n\t\t\t.map(([, value]) => value),\n\t\t...Object.values(secrets.urls ?? {}),\n\t\t...Object.values(secrets.services ?? {}).map(\n\t\t\t(service) => service?.password,\n\t\t),\n\t].filter((value): value is string => typeof value === 'string');\n}\n\n/**\n * The stage's secrets through the store `secrets.store` names for it. Opening\n * one builds a client and makes no request, so a target that never reads them\n * costs nothing.\n */\nexport async function deploySecrets(\n\tworkspace: NormalizedWorkspace,\n\tstage: string,\n\tredactor: Redactor,\n\toptions: { home?: string } = {},\n): Promise<DeploySecrets> {\n\tconst store = await secretsStoreFor(workspace, stage, options);\n\tconst mask = (secrets: StageSecrets) => {\n\t\tfor (const value of secretValues(secrets)) redactor.add(value);\n\t};\n\n\treturn {\n\t\tstore: store.name,\n\t\tasync read() {\n\t\t\tconst secrets = await store.read(stage);\n\t\t\tif (secrets) mask(secrets);\n\t\t\treturn secrets;\n\t\t},\n\t\tasync write(secrets) {\n\t\t\tmask(secrets);\n\t\t\tawait store.write(stage, secrets);\n\t\t},\n\t\tmask: (value) => redactor.add(value),\n\t};\n}\n","/**\n * What the deploy's DNS step needs to know about a workspace before its\n * stack is run: whether it deploys with compose.\n *\n * The step itself is `stageDns` in `compose/dns.ts`, run by every deploy\n * (`gkm deploy`, and `gkm compose`, the same run) where the deploy runs — a\n * CI runner or a developer's machine, which hold the DNS provider's token.\n * The server never does.\n */\n\nimport type { NormalizedWorkspace } from '../workspace/types.js';\n\n/** Whether the workspace deploys through the compose target. */\nexport function deploysWithCompose(workspace: NormalizedWorkspace): boolean {\n\treturn (\n\t\tworkspace.deploy?.default === 'compose' ||\n\t\tObject.values(workspace.apps).some(\n\t\t\t(app) => app.resolvedDeployTarget === 'compose',\n\t\t)\n\t);\n}\n","/**\n * The AWS account a provider provisions in — the stage's, found the way the\n * SSM and Secrets Manager stores find it.\n *\n * 1. `--profile`, resolved on its own: exported keys left over from another\n * account never win over a profile someone named.\n * 2. `AWS_PROFILE`, else `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` — the\n * deploy's own `aws` credential kind (`storedCredentials`).\n * 3. The SDK's default chain: `~/.aws` default profile, SSO, a role. In CI,\n * whatever `aws-actions/configure-aws-credentials` exported.\n *\n * None of them: the provider has no provisioning credentials, and the stage\n * is treated as `external`.\n */\n\nimport {\n\ttype AwsCredential,\n\tstoredCredentials,\n} from '../deploy/credentials.js';\nimport type { CredentialLookup } from './types.js';\n\n/** An AWS credential, or the default chain the SDK resolves itself. */\nexport type AwsProvisioning =\n\t| AwsCredential\n\t| {\n\t\t\tchain: true;\n\t\t\tregion?: string;\n\t };\n\nexport async function awsProvisioningCredentials(\n\tlookup: CredentialLookup,\n): Promise<AwsProvisioning | undefined> {\n\tconst region = lookup.env.AWS_REGION ?? lookup.env.AWS_DEFAULT_REGION;\n\tconst where = region ? { region } : {};\n\tif (lookup.profile) return { profile: lookup.profile, ...where };\n\n\tconst stored = await storedCredentials({\n\t\tenv: lookup.env,\n\t\t...(lookup.home ? { home: lookup.home } : {}),\n\t}).get({ kind: 'aws', stage: lookup.stage });\n\tif (stored) return stored;\n\n\ttry {\n\t\tconst { fromNodeProviderChain } = await import(\n\t\t\t'@aws-sdk/credential-providers'\n\t\t);\n\t\tawait fromNodeProviderChain({ timeout: 1000, maxRetries: 0 })();\n\t\treturn { chain: true, ...where };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * An S3-compatible endpoint the environment points the SDK at — the AWS\n * emulator in tests. The SDK reads it itself; it is read here too, because\n * an emulator takes path-style requests, and a key written for one has to\n * say where it is.\n */\nexport function awsEndpoint(\n\tenv: NodeJS.ProcessEnv,\n\tservice: 'S3' | 'IAM',\n): string | undefined {\n\treturn env[`AWS_ENDPOINT_URL_${service}`] ?? env.AWS_ENDPOINT_URL;\n}\n\n/** An SDK client's config for a provisioning credential. */\nexport async function awsClientConfig(\n\tcredential: AwsProvisioning,\n\tregion: string,\n): Promise<{\n\tregion: string;\n\tcredentials?:\n\t\t| ReturnType<typeof import('@aws-sdk/credential-providers').fromIni>\n\t\t| { accessKeyId: string; secretAccessKey: string; sessionToken?: string };\n}> {\n\tif ('profile' in credential) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\treturn { region, credentials: fromIni({ profile: credential.profile }) };\n\t}\n\tif ('accessKeyId' in credential) {\n\t\treturn {\n\t\t\tregion,\n\t\t\tcredentials: {\n\t\t\t\taccessKeyId: credential.accessKeyId,\n\t\t\t\tsecretAccessKey: credential.secretAccessKey,\n\t\t\t\t...(credential.sessionToken\n\t\t\t\t\t? { sessionToken: credential.sessionToken }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t};\n\t}\n\treturn { region };\n}\n","/**\n * What the `s3` provider names a bucket and its IAM user.\n *\n * A bucket name is global across every AWS account, so the good name — the\n * one a person reading the console would guess — is tried first and a random\n * suffix is the fallback for a clash. Whatever name is created is recorded in\n * the stage's state and read back on every later run: a name is never\n * regenerated, because a new name is a new, empty bucket.\n */\n\nimport { randomInt } from 'node:crypto';\nimport { kebabCase } from '@geekmidas/manifest';\nimport { GkmError } from '../../errors';\n\n/** S3's limit on a bucket name. */\nexport const BUCKET_NAME_MAX = 63;\n/** IAM's limit on a user name. */\nexport const IAM_USER_NAME_MAX = 64;\n/** `-` and six characters: what a clash appends. */\nexport const SUFFIX_LENGTH = 7;\n/** How many suffixed names are tried after the good one. */\nexport const SUFFIX_ATTEMPTS = 5;\n\nconst SUFFIX_ALPHABET = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n/** A name that S3 would refuse — what the name builder never returns. */\nexport class InvalidBucketName extends GkmError {\n\tconstructor(\n\t\treadonly bucket: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${bucket}' is not a valid S3 bucket name: ${reason}. Rename the ` +\n\t\t\t\t'construct or set deploy.namespace in gkm.config.ts to something ' +\n\t\t\t\t'that leaves room for it.',\n\t\t);\n\t\tthis.name = 'InvalidBucketName';\n\t}\n}\n\n/** Lowercase `[a-z0-9-]`, runs of anything else one `-`, no edge dashes. */\nfunction part(value: string): string {\n\treturn kebabCase(value)\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '');\n}\n\n/**\n * `parts` joined by `-`, shortened to `max` characters by trimming the longest\n * part one character at a time — so a long construct id gives way before a\n * short stage name does, and every part keeps its start.\n */\nexport function fitParts(parts: readonly string[], max: number): string {\n\tconst kept = parts.map(part).filter(Boolean);\n\tconst length = () =>\n\t\tkept.reduce((sum, p) => sum + p.length, 0) + kept.length - 1;\n\twhile (length() > max) {\n\t\tlet longest = 0;\n\t\tfor (let i = 1; i < kept.length; i++) {\n\t\t\tif (kept[i]!.length > kept[longest]!.length) longest = i;\n\t\t}\n\t\tif (kept[longest]!.length <= 1) break;\n\t\tkept[longest] = kept[longest]!.slice(0, -1).replace(/-+$/, '');\n\t}\n\treturn kept.join('-');\n}\n\n/** Why `name` is not a valid bucket name, or undefined when it is. */\nexport function bucketNameProblem(name: string): string | undefined {\n\tif (name.length < 3 || name.length > BUCKET_NAME_MAX) {\n\t\treturn `it is ${name.length} characters, and S3 takes 3 to ${BUCKET_NAME_MAX}`;\n\t}\n\tif (!/^[a-z0-9-]+$/.test(name)) {\n\t\treturn 'it may hold only lowercase letters, digits and -';\n\t}\n\tif (!/^[a-z0-9].*[a-z0-9]$/.test(name)) {\n\t\treturn 'it must start and end with a letter or a digit';\n\t}\n\tif (name.startsWith('xn--') || name.startsWith('sthree-')) {\n\t\treturn \"it starts with a prefix S3 reserves ('xn--', 'sthree-')\";\n\t}\n\tif (name.endsWith('-s3alias') || name.endsWith('--ol-s3')) {\n\t\treturn \"it ends with a suffix S3 reserves ('-s3alias', '--ol-s3')\";\n\t}\n\treturn undefined;\n}\n\n/** What a bucket is named from. */\nexport interface BucketNameInput {\n\t/** The deploy identity's scope: `<namespace>-<project>`, or the project. */\n\tscope: string;\n\tstage: string;\n\t/** The `ObjectStorage` construct's id. */\n\tid: string;\n}\n\n/**\n * The good name: `<namespace>-<project>-<stage>-<bucket id>`, lowercased, no\n * dots, shortened to leave room for a clash's suffix.\n *\n * @throws {InvalidBucketName} when nothing usable is left\n */\nexport function bucketName(input: BucketNameInput): string {\n\tconst name = fitParts(\n\t\t[input.scope, input.stage, input.id],\n\t\tBUCKET_NAME_MAX - SUFFIX_LENGTH,\n\t);\n\tconst problem = bucketNameProblem(name);\n\tif (problem) throw new InvalidBucketName(name, problem);\n\treturn name;\n}\n\n/** Six random `[a-z0-9]` characters. */\nexport function randomSuffix(random: (max: number) => number = randomInt) {\n\tlet suffix = '';\n\tfor (let i = 0; i < 6; i++) {\n\t\tsuffix += SUFFIX_ALPHABET[random(SUFFIX_ALPHABET.length)];\n\t}\n\treturn suffix;\n}\n\n/** The good name with a clash's suffix. */\nexport function suffixedBucketName(good: string, suffix: string): string {\n\treturn `${good}-${suffix}`;\n}\n\n/**\n * The IAM user a bucket is reached with on a stage:\n * `gkm-<project>-<stage>-<bucket id>`, at most 64 characters.\n */\nexport function iamUserName(input: BucketNameInput): string {\n\treturn fitParts(\n\t\t['gkm', input.scope, input.stage, input.id],\n\t\tIAM_USER_NAME_MAX,\n\t);\n}\n\n/** The path every user gkm creates is under, so it finds its own. */\nexport const IAM_USER_PATH = '/gkm/';\n\n/** The inline policy each user is given. */\nexport const IAM_POLICY_NAME = 'gkm-bucket';\n","/**\n * Which browser origins may call a bucket: the stage's sites that depend on\n * an API using it.\n *\n * The same reading of the graph an API's own CORS origins are — its callers —\n * taken one step further: a site that calls an API which hands it a presigned\n * upload URL is a site whose browser PUTs to the bucket. A site that reads the\n * bucket (or a file server over it) itself is one too. Nothing is written\n * down: add a site that calls the API and the next provision run allows it.\n */\n\nimport {\n\ttype ConstructManifest,\n\tdependentsOf,\n\tprovideKey,\n} from '@geekmidas/manifest';\nimport { appEnvKeys } from '../../reconcile/apps.js';\nimport {\n\tisMainFrontendApp,\n\tNoDomainForStage,\n\tresolveHost,\n} from '../../target/dokploy/domain.js';\nimport { appKey } from '../../workspace/derive.js';\nimport type { NormalizedWorkspace } from '../../workspace/types.js';\n\nexport interface BucketOriginsInput {\n\tworkspace: Pick<NormalizedWorkspace, 'apps' | 'deploy' | 'domains'>;\n\tmanifest: ConstructManifest;\n\t/** Each owner's runnables' edges, from discovery. */\n\trunnables?: Readonly<Record<string, readonly string[]>>;\n\tstage: string;\n\t/** The `objects` construct's id. */\n\tbucket: string;\n}\n\nexport interface BucketOrigins {\n\t/** `https://<host>` for each site, sorted. */\n\torigins: string[];\n\t/** Sites with no address on the stage — no domain for it. */\n\tunresolved: string[];\n}\n\n/** The keys a reader of this bucket holds: its URL, and each server's over it. */\nexport function bucketKeys(manifest: ConstructManifest, bucket: string) {\n\treturn [\n\t\tprovideKey(bucket, 'url'),\n\t\t...Object.entries(manifest)\n\t\t\t.filter(([, d]) => d.kind === 'file-server' && d.of === bucket)\n\t\t\t.map(([id]) => provideKey(id, 'url')),\n\t];\n}\n\nexport function bucketOrigins(input: BucketOriginsInput): BucketOrigins {\n\tconst { manifest, workspace, stage } = input;\n\tconst keys = bucketKeys(manifest, input.bucket);\n\n\tconst readers = Object.entries(manifest)\n\t\t.filter(([, d]) => d.kind === 'rest-api' || d.kind === 'site')\n\t\t.filter(([id]) => {\n\t\t\tconst env = appEnvKeys(manifest, appKey(id), input.runnables);\n\t\t\treturn env !== undefined && keys.some((key) => env.has(key));\n\t\t});\n\n\tconst sites = new Set<string>();\n\tfor (const [id, declaration] of readers) {\n\t\tif (declaration.kind === 'site') {\n\t\t\tsites.add(id);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const caller of dependentsOf(manifest, id)) {\n\t\t\tif (manifest[caller]?.kind === 'site') sites.add(caller);\n\t\t}\n\t}\n\n\tconst origins = new Set<string>();\n\tconst unresolved: string[] = [];\n\tfor (const id of [...sites].sort()) {\n\t\tconst name = appKey(id);\n\t\tconst app = workspace.apps[name];\n\t\tif (!app) {\n\t\t\tunresolved.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst host = resolveHost(\n\t\t\t\tname,\n\t\t\t\tapp,\n\t\t\t\tstage,\n\t\t\t\tworkspace.domains,\n\t\t\t\tisMainFrontendApp(name, app, workspace.apps),\n\t\t\t);\n\t\t\torigins.add(`https://${host}`);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof NoDomainForStage)) throw error;\n\t\t\tunresolved.push(name);\n\t\t}\n\t}\n\n\treturn { origins: [...origins].sort(), unresolved };\n}\n","/**\n * The documents the `s3` provider writes: the user's inline policy, the\n * bucket's policy, its CORS rule and its public access block.\n *\n * Pure, so each is tested as JSON and compared with what AWS holds on every\n * run — a document that differs is drift, and is put back.\n */\n\n/** One IAM or bucket policy statement. */\nexport interface PolicyStatement {\n\tSid: string;\n\tEffect: 'Allow' | 'Deny';\n\tPrincipal?: '*' | { AWS: string | string[] };\n\tAction: string | string[];\n\tResource: string | string[];\n\tCondition?: Record<string, Record<string, string>>;\n}\n\nexport interface PolicyDocument {\n\tVersion: '2012-10-17';\n\tStatement: PolicyStatement[];\n}\n\nconst bucketArn = (bucket: string) => `arn:aws:s3:::${bucket}`;\n\n/**\n * What the app's key may do: objects in this bucket, and listing it — and\n * nothing else in the account.\n *\n * Multipart uploads are in it because a presigned upload of a large file is\n * one, and an abandoned one is cleaned up by the app. Reading old versions is\n * added only when the bucket keeps them.\n */\nexport function userPolicy(\n\tbucket: string,\n\toptions: { versioning?: boolean } = {},\n): PolicyDocument {\n\treturn {\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tSid: 'GkmObjects',\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:AbortMultipartUpload',\n\t\t\t\t\t's3:ListMultipartUploadParts',\n\t\t\t\t\t...(options.versioning ? ['s3:GetObjectVersion'] : []),\n\t\t\t\t],\n\t\t\t\tResource: `${bucketArn(bucket)}/*`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tSid: 'GkmBucket',\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tAction: [\n\t\t\t\t\t's3:ListBucket',\n\t\t\t\t\t's3:GetBucketLocation',\n\t\t\t\t\t's3:ListBucketMultipartUploads',\n\t\t\t\t],\n\t\t\t\tResource: bucketArn(bucket),\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * One open pattern as the resource it is public on. A `**` is S3's `*`; a\n * single `*` is too, which crosses `/` where the construct's own check does\n * not — the construct is the stricter of the two (see `bucketPolicy` in\n * reconcile, which the local MinIO is given the same way).\n */\nexport function openResource(bucket: string, pattern: string): string {\n\tconst path = pattern.replace(/^\\/+/, '').replace(/\\*\\*/g, '*');\n\treturn `${bucketArn(bucket)}/${path}`;\n}\n\n/**\n * The bucket's own policy: every request refused unless it came over TLS,\n * and — only when a file server opens paths on it — anonymous `s3:GetObject`\n * on exactly those prefixes.\n */\nexport function bucketPolicy(\n\tbucket: string,\n\topen: readonly string[] = [],\n): PolicyDocument {\n\tconst statements: PolicyStatement[] = [\n\t\t{\n\t\t\tSid: 'GkmDenyInsecureTransport',\n\t\t\tEffect: 'Deny',\n\t\t\tPrincipal: '*',\n\t\t\tAction: 's3:*',\n\t\t\tResource: [bucketArn(bucket), `${bucketArn(bucket)}/*`],\n\t\t\tCondition: { Bool: { 'aws:SecureTransport': 'false' } },\n\t\t},\n\t];\n\tif (open.length > 0) {\n\t\tstatements.push({\n\t\t\tSid: 'GkmOpenPaths',\n\t\t\tEffect: 'Allow',\n\t\t\tPrincipal: '*',\n\t\t\tAction: 's3:GetObject',\n\t\t\tResource: [...new Set(open.map((p) => openResource(bucket, p)))].sort(),\n\t\t});\n\t}\n\treturn { Version: '2012-10-17', Statement: statements };\n}\n\n/**\n * Block Public Access. All four flags on, unless the bucket has open paths:\n * then a *policy* may make it public (`BlockPublicPolicy`,\n * `RestrictPublicBuckets` off), and ACLs still may not.\n */\nexport function publicAccessBlock(open: boolean): {\n\tBlockPublicAcls: boolean;\n\tIgnorePublicAcls: boolean;\n\tBlockPublicPolicy: boolean;\n\tRestrictPublicBuckets: boolean;\n} {\n\treturn {\n\t\tBlockPublicAcls: true,\n\t\tIgnorePublicAcls: true,\n\t\tBlockPublicPolicy: !open,\n\t\tRestrictPublicBuckets: !open,\n\t};\n}\n\n/** The one CORS rule: browsers on the stage's sites upload and read. */\nexport interface CorsRule {\n\tAllowedMethods: string[];\n\tAllowedOrigins: string[];\n\tAllowedHeaders: string[];\n\tExposeHeaders: string[];\n\tMaxAgeSeconds: number;\n}\n\nexport function corsRule(origins: readonly string[]): CorsRule {\n\treturn {\n\t\tAllowedMethods: ['GET', 'HEAD', 'POST', 'PUT'],\n\t\tAllowedOrigins: [...new Set(origins)].sort(),\n\t\tAllowedHeaders: ['*'],\n\t\tExposeHeaders: ['ETag'],\n\t\tMaxAgeSeconds: 3000,\n\t};\n}\n\n/**\n * A policy document in one canonical form — keys sorted, a lone string a\n * one-element list, lists sorted — so one AWS reformatted reads as the same\n * document rather than as drift.\n */\nexport function canonicalPolicy(value: unknown): string {\n\treturn JSON.stringify(canonical(value));\n}\n\nfunction canonical(value: unknown, key?: string): unknown {\n\tif (Array.isArray(value)) {\n\t\tconst items = value.map((v) => canonical(v));\n\t\treturn key === 'Statement'\n\t\t\t? items\n\t\t\t: items.map((v) => JSON.stringify(v)).sort();\n\t}\n\tif (value && typeof value === 'object') {\n\t\treturn Object.fromEntries(\n\t\t\tObject.keys(value)\n\t\t\t\t.sort()\n\t\t\t\t.map((k) => {\n\t\t\t\t\tconst v = (value as Record<string, unknown>)[k];\n\t\t\t\t\tconst listy =\n\t\t\t\t\t\tk === 'Action' || k === 'Resource' || k === 'AWS'\n\t\t\t\t\t\t\t? Array.isArray(v)\n\t\t\t\t\t\t\t\t? v\n\t\t\t\t\t\t\t\t: [v]\n\t\t\t\t\t\t\t: v;\n\t\t\t\t\treturn [k, canonical(listy, k)];\n\t\t\t\t}),\n\t\t);\n\t}\n\treturn value;\n}\n","/**\n * `objects: { provider: 's3' }` — each bucket construct, created in the\n * stage's AWS account with a user and key of its own.\n *\n * Per `ObjectStorage` (and each `FileServer` over it), on the stage:\n *\n * - **the bucket**, named `<namespace>-<project>-<stage>-<id>` — or with a\n * random suffix when another account holds that name — recorded in the\n * stage's state and reused forever; Block Public Access, SSE-S3, a policy\n * refusing anything but TLS, versioning when asked, and CORS for the\n * stage's sites that call an API using it;\n * - **an IAM user**, `gkm-<project>-<stage>-<id>` under `/gkm/`, tagged with\n * the deploy identity, with an inline policy for that bucket only;\n * - **its access key**, written into the stage's secrets as the bucket's URL\n * (`s3://KEY:SECRET@bucket?region=…`) — the secret is never printed;\n * - **a file server's** open paths public on exactly those prefixes, and its\n * URL the bucket's regional endpoint.\n *\n * Every run reads what is there and puts back what drifted. Nothing is ever\n * deleted, with one exception asked for by name: the old key a\n * `--rotate-keys` replaced, once the stage has deployed with the new one.\n */\n\nimport type {\n\tConstructManifest,\n\tFileServerDeclaration,\n\tObjectsDeclaration,\n} from '@geekmidas/manifest';\nimport { provideKey } from '@geekmidas/manifest';\nimport * as s3Url from '@geekmidas/storage/s3-url';\nimport { appKey } from '../../workspace/derive.js';\nimport type { S3ObjectsConfig } from '../../workspace/types.js';\nimport {\n\ttype AwsProvisioning,\n\tawsClientConfig,\n\tawsEndpoint,\n\tawsProvisioningCredentials,\n} from '../aws.js';\nimport type {\n\tEnsureContext,\n\tResourceProvider,\n\tStateEntry,\n\tVerifyContext,\n} from '../types.js';\nimport { checkS3Config, S3_PROVISIONING } from './config.js';\nimport {\n\tAccessKeyLimit,\n\tBucketKeySetElsewhere,\n\tBucketNameUnavailable,\n\tBucketOwnedByAnotherProject,\n\tBucketProbeFailed,\n\tBucketRegionMismatch,\n\tBucketRegionUnknown,\n\tIamUserNotOwned,\n\tProvisionedBucketUnreachable,\n\tRecordedBucketUnreachable,\n\tRotationInProgress,\n\tS3RegionRequired,\n} from './errors.js';\nimport {\n\tbucketName,\n\tIAM_POLICY_NAME,\n\tIAM_USER_PATH,\n\tiamUserName,\n\trandomSuffix,\n\tSUFFIX_ATTEMPTS,\n\tsuffixedBucketName,\n} from './naming.js';\nimport { bucketOrigins } from './origins.js';\nimport {\n\tbucketPolicy,\n\ttype CorsRule,\n\tcanonicalPolicy,\n\tcorsRule,\n\tpublicAccessBlock,\n\tuserPolicy,\n} from './policy.js';\n\ntype S3Module = typeof import('@aws-sdk/client-s3');\ntype IamModule = typeof import('@aws-sdk/client-iam');\n\ntype Ctx = EnsureContext<S3ObjectsConfig, AwsProvisioning>;\n\n/** The tags gkm finds its own buckets and users by. */\nexport const TAG_PROJECT = 'gkm:project';\nexport const TAG_STAGE = 'gkm:stage';\nexport const TAG_CONSTRUCT = 'gkm:construct';\n\n/** Each bucket construct, with the file servers over it. */\nexport interface BucketConstruct {\n\tid: string;\n\tversioned: boolean;\n\tservers: { id: string; open: readonly string[] }[];\n}\n\nexport function bucketConstructs(\n\tmanifest: ConstructManifest,\n): BucketConstruct[] {\n\treturn Object.entries(manifest)\n\t\t.filter(([, d]) => d.kind === 'objects')\n\t\t.map(([id, d]) => ({\n\t\t\tid,\n\t\t\tversioned: (d as ObjectsDeclaration).versioned === true,\n\t\t\tservers: Object.entries(manifest)\n\t\t\t\t.filter(\n\t\t\t\t\t([, s]) =>\n\t\t\t\t\t\ts.kind === 'file-server' && (s as FileServerDeclaration).of === id,\n\t\t\t\t)\n\t\t\t\t.map(([sid, s]) => ({\n\t\t\t\t\tid: sid,\n\t\t\t\t\topen: (s as FileServerDeclaration).open ?? [],\n\t\t\t\t}))\n\t\t\t\t.sort((a, b) => a.id.localeCompare(b.id)),\n\t\t}))\n\t\t.sort((a, b) => a.id.localeCompare(b.id));\n}\n\n/**\n * The region the stage's buckets are created in: the entry's, the secrets\n * store's when it is in AWS, the credential's, `AWS_REGION`.\n */\nexport function s3Region(\n\tctx: Pick<Ctx, 'config' | 'workspace' | 'stage'> & {\n\t\tcredential?: AwsProvisioning;\n\t},\n\tenv: NodeJS.ProcessEnv = process.env,\n): string {\n\tconst store = ctx.workspace.secrets?.store;\n\tconst storeRegion =\n\t\tstore && typeof store === 'object' && 'region' in store\n\t\t\t? (store as { region?: string }).region\n\t\t\t: undefined;\n\tconst region =\n\t\tctx.config.region ??\n\t\tstoreRegion ??\n\t\tctx.credential?.region ??\n\t\tenv.AWS_REGION ??\n\t\tenv.AWS_DEFAULT_REGION;\n\tif (!region) throw new S3RegionRequired(ctx.stage);\n\treturn region;\n}\n\n/**\n * The address a file server over `bucket` serves on: the bucket's regional\n * virtual-host endpoint, which is what `FileServer.url(key)` appends a key to\n * — `https://<bucket>.s3.<region>.amazonaws.com/<key>`. Against an emulator,\n * its path-style address.\n */\nexport function bucketPublicUrl(\n\tbucket: string,\n\tregion: string,\n\tendpoint?: string,\n): string {\n\tif (endpoint) return `${endpoint.replace(/\\/+$/, '')}/${bucket}`;\n\treturn `https://${bucket}.s3.${region}.amazonaws.com`;\n}\n\n/** What an AWS SDK error is called, whichever field carries it. */\nfunction errorName(error: unknown): string {\n\tconst e = error as { name?: string; Code?: string };\n\treturn e?.Code ?? e?.name ?? '';\n}\n\n/**\n * What S3 answered a call, read off the response rather than the error's\n * name: a `HEAD` has no body, so SDK v3 names a 301, 400 or 403 `Unknown`\n * (only a 404 becomes `NotFound`). The status, the bucket's region and the\n * request ids are in the response either way.\n */\nexport interface S3Answer {\n\t/** The HTTP status; absent when no response came back. */\n\tstatus?: number;\n\tname: string;\n\tmessage: string;\n\t/** `x-amz-bucket-region`: where the bucket is. */\n\tregion?: string;\n\trequestId?: string;\n\tid2?: string;\n}\n\n/** The answer an SDK call failed with. */\nexport function s3Answer(error: unknown): S3Answer {\n\tconst e = error as {\n\t\tname?: string;\n\t\tCode?: string;\n\t\tmessage?: string;\n\t\t$metadata?: {\n\t\t\thttpStatusCode?: number;\n\t\t\trequestId?: string;\n\t\t\textendedRequestId?: string;\n\t\t};\n\t\t$response?: {\n\t\t\tstatusCode?: number;\n\t\t\theaders?: Record<string, string | undefined>;\n\t\t};\n\t};\n\tconst headers = Object.fromEntries(\n\t\tObject.entries(e?.$response?.headers ?? {}).map(([k, v]) => [\n\t\t\tk.toLowerCase(),\n\t\t\tv,\n\t\t]),\n\t);\n\tconst status = e?.$metadata?.httpStatusCode ?? e?.$response?.statusCode;\n\tconst region = headers['x-amz-bucket-region'];\n\tconst requestId = e?.$metadata?.requestId ?? headers['x-amz-request-id'];\n\tconst id2 = e?.$metadata?.extendedRequestId ?? headers['x-amz-id-2'];\n\treturn {\n\t\t...(status !== undefined ? { status } : {}),\n\t\tname: errorName(error) || 'Error',\n\t\tmessage: e?.message ?? String(error),\n\t\t...(region ? { region } : {}),\n\t\t...(requestId ? { requestId } : {}),\n\t\t...(id2 ? { id2 } : {}),\n\t};\n}\n\n/**\n * `HTTP 403 Unknown: UnknownError [x-amz-bucket-region: eu-west-1,\n * x-amz-request-id: …, x-amz-id-2: …]` — everything S3 said, for a message.\n */\nexport function describeAnswer(answer: S3Answer): string {\n\tconst said =\n\t\tanswer.message && answer.message !== answer.name\n\t\t\t? `${answer.name}: ${answer.message}`\n\t\t\t: answer.name;\n\tconst headers = [\n\t\tanswer.region && `x-amz-bucket-region: ${answer.region}`,\n\t\tanswer.requestId && `x-amz-request-id: ${answer.requestId}`,\n\t\tanswer.id2 && `x-amz-id-2: ${answer.id2}`,\n\t].filter(Boolean);\n\treturn (\n\t\t`${answer.status === undefined ? 'no response' : `HTTP ${answer.status}`} ${said}` +\n\t\t(headers.length > 0 ? ` [${headers.join(', ')}]` : '')\n\t);\n}\n\n/** `HeadBucket`: the bucket's region when it answers, else what S3 said. */\nasync function headBucket(\n\tS3: S3Module,\n\tclient: InstanceType<S3Module['S3Client']>,\n\tbucket: string,\n): Promise<{ ok: true; region?: string } | ({ ok: false } & S3Answer)> {\n\ttry {\n\t\tconst out = await client.send(new S3.HeadBucketCommand({ Bucket: bucket }));\n\t\treturn {\n\t\t\tok: true,\n\t\t\t...(out.BucketRegion ? { region: out.BucketRegion } : {}),\n\t\t};\n\t} catch (error) {\n\t\treturn { ok: false, ...s3Answer(error) };\n\t}\n}\n\n/** `GetBucketLocation`'s answer as a region: none is us-east-1, `EU` eu-west-1. */\nasync function bucketLocation(\n\tS3: S3Module,\n\tclient: InstanceType<S3Module['S3Client']>,\n\tbucket: string,\n): Promise<{ region: string } | { failed: S3Answer }> {\n\ttry {\n\t\tconst out = await client.send(\n\t\t\tnew S3.GetBucketLocationCommand({ Bucket: bucket }),\n\t\t);\n\t\tconst location = out.LocationConstraint as string | undefined;\n\t\treturn {\n\t\t\tregion: !location\n\t\t\t\t? 'us-east-1'\n\t\t\t\t: location === 'EU'\n\t\t\t\t\t? 'eu-west-1'\n\t\t\t\t\t: location,\n\t\t};\n\t} catch (error) {\n\t\treturn { failed: s3Answer(error) };\n\t}\n}\n\n/**\n * Where `bucket` is: `HeadBucket`'s `x-amz-bucket-region` — on a 200, a 301\n * or a 400 alike — else `GetBucketLocation`.\n *\n * @throws {BucketRegionUnknown}\n */\nasync function bucketRegion(clients: Clients, bucket: string): Promise<string> {\n\tconst { S3, s3 } = clients;\n\tconst head = await headBucket(S3, s3, bucket);\n\tif (head.region) return head.region;\n\tconst location = await bucketLocation(S3, s3, bucket);\n\tif ('region' in location) return location.region;\n\tthrow new BucketRegionUnknown(\n\t\tbucket,\n\t\thead.ok ? 'HTTP 200 without x-amz-bucket-region' : describeAnswer(head),\n\t\tdescribeAnswer(location.failed),\n\t);\n}\n\n/** A read whose \"there is none\" answer is one of `missing`. */\nasync function readOr<T>(\n\tread: () => Promise<T>,\n\tmissing: readonly string[],\n): Promise<T | undefined> {\n\ttry {\n\t\treturn await read();\n\t} catch (error) {\n\t\tif (missing.includes(errorName(error))) return undefined;\n\t\tthrow error;\n\t}\n}\n\ninterface Clients {\n\tS3: S3Module;\n\tIAM: IamModule;\n\ts3: InstanceType<S3Module['S3Client']>;\n\tiam: InstanceType<IamModule['IAMClient']>;\n\tregion: string;\n\t/** An emulator's endpoint, when the environment names one. */\n\tendpoint?: string;\n}\n\n/** Clients for a provisioning run, for tests to replace. */\nexport type S3ClientFactory = (\n\tcredential: AwsProvisioning,\n\tregion: string,\n) => Promise<Clients>;\n\nexport const defaultClients: S3ClientFactory = async (credential, region) => {\n\tconst S3 = await import('@aws-sdk/client-s3');\n\tconst IAM = await import('@aws-sdk/client-iam');\n\tconst config = await awsClientConfig(credential, region);\n\tconst endpoint = awsEndpoint(process.env, 'S3');\n\treturn {\n\t\tS3,\n\t\tIAM,\n\t\ts3: new S3.S3Client({\n\t\t\t...config,\n\t\t\t...(endpoint ? { endpoint, forcePathStyle: true } : {}),\n\t\t}),\n\t\tiam: new IAM.IAMClient(config),\n\t\tregion,\n\t\t...(endpoint ? { endpoint } : {}),\n\t};\n};\n\n/** For tests: what makes the clients. */\nlet makeClients: S3ClientFactory = defaultClients;\n\n/** Replace the client factory — a test intercepting a call. Returns the old one. */\nexport function useS3Clients(factory: S3ClientFactory): S3ClientFactory {\n\tconst previous = makeClients;\n\tmakeClients = factory;\n\treturn previous;\n}\n\nasync function ensureS3(ctx: Ctx): Promise<void> {\n\tconst region = s3Region(ctx);\n\tconst clients = await makeClients(ctx.credential, region);\n\tfor (const construct of bucketConstructs(ctx.manifest)) {\n\t\tawait ensureBucket(ctx, clients, construct);\n\t}\n}\n\n/** The keys gkm tags a bucket and a user with. */\nfunction identityTags(ctx: Ctx, id: string) {\n\treturn [\n\t\t{ Key: TAG_PROJECT, Value: ctx.identity.key },\n\t\t{ Key: TAG_STAGE, Value: ctx.stage },\n\t\t{ Key: TAG_CONSTRUCT, Value: id },\n\t];\n}\n\nasync function ensureBucket(\n\tctx: Ctx,\n\tstageClients: Clients,\n\tconstruct: BucketConstruct,\n): Promise<void> {\n\tconst { id } = construct;\n\tconst nameInput = {\n\t\tscope: ctx.identity.scope,\n\t\tstage: ctx.stage,\n\t\tid: appKey(id),\n\t};\n\tconst versioning = ctx.config.versioning ?? construct.versioned;\n\tconst open = [...new Set(construct.servers.flatMap((s) => s.open))].sort();\n\n\tconst located = await ensureBucketName(\n\t\tctx,\n\t\tstageClients,\n\t\tid,\n\t\tbucketName(nameInput),\n\t);\n\tconst { bucket, exists } = located;\n\t// The bucket is reached, and its URL written, in the region it is in —\n\t// one value for both, read off the bucket: an adopted bucket, or one made\n\t// before the stage's region changed, may be elsewhere.\n\tlet clients = stageClients;\n\tif (located.region !== stageClients.region) {\n\t\tclients = await makeClients(ctx.credential, located.region);\n\t\tctx.log(\n\t\t\t` '${bucket}' is in ${located.region}, not ${stageClients.region}: '${id}' is reached and addressed there`,\n\t\t);\n\t}\n\tawait ensureBucketSettings(ctx, clients, {\n\t\tid,\n\t\tbucket,\n\t\texists,\n\t\tversioning,\n\t\topen,\n\t});\n\n\tconst user = await ensureUser(\n\t\tctx,\n\t\tclients,\n\t\tid,\n\t\tiamUserName(nameInput),\n\t\tuserPolicy(bucket, { versioning }),\n\t);\n\tawait ensureAccessKey(ctx, clients, { id, bucket, ...user });\n\n\t// Each file server over it serves on the bucket's own endpoint — unless the\n\t// stage set an address of its own for it (a CDN), which is kept.\n\tconst publicUrl = bucketPublicUrl(bucket, clients.region, clients.endpoint);\n\tfor (const server of construct.servers) {\n\t\tconst key = provideKey(server.id, 'url');\n\t\tconst entry: StateEntry = { key: `file-server:${server.id}`, type: 'url' };\n\t\tconst recorded = ctx.state.record(entry.key)?.id;\n\t\tconst current = ctx.secrets[key];\n\t\tif (current === publicUrl) {\n\t\t\tawait ctx.state.ready(entry, publicUrl);\n\t\t\tcontinue;\n\t\t}\n\t\tif (current !== undefined && current !== recorded) {\n\t\t\tctx.log(\n\t\t\t\t` ${key} is set to ${current} by you, and kept — the bucket's own address is ${publicUrl}`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tawait ctx.change(\n\t\t\t{ construct: server.id, resource: key, change: `set to ${publicUrl}` },\n\t\t\tasync () => {\n\t\t\t\tawait ctx.writeSecrets({ [key]: publicUrl });\n\t\t\t\tawait ctx.state.ready(entry, publicUrl);\n\t\t\t},\n\t\t);\n\t}\n}\n\n/**\n * The bucket's name: the recorded one, else the good name, else the good\n * name with a random suffix — up to {@link SUFFIX_ATTEMPTS} times.\n */\nasync function ensureBucketName(\n\tctx: Ctx,\n\tclients: Clients,\n\tid: string,\n\tgood: string,\n): Promise<{ bucket: string; exists: boolean; region: string }> {\n\tconst { S3, s3, region } = clients;\n\tconst key = `s3-bucket:${id}`;\n\tconst record = ctx.state.record(key);\n\tconst entry = (name: string, where: string): StateEntry => ({\n\t\tkey,\n\t\ttype: 's3-bucket',\n\t\tdata: { name, region: where },\n\t});\n\n\t/**\n\t * Whether this account holds `name`: yes, no, or someone else does. Read\n\t * by status — a `HEAD` has no body, so its error is named `Unknown` — and,\n\t * when S3 says the bucket is in another region, asked again there.\n\t */\n\tconst probe = async (name: string): Promise<'ours' | 'none' | 'taken'> => {\n\t\tlet head = await headBucket(S3, s3, name);\n\t\tif (\n\t\t\t!head.ok &&\n\t\t\thead.region &&\n\t\t\thead.region !== region &&\n\t\t\t(head.status === 301 || head.status === 400)\n\t\t) {\n\t\t\tconst there = await makeClients(ctx.credential, head.region);\n\t\t\thead = await headBucket(there.S3, there.s3, name);\n\t\t}\n\t\tif (head.ok) return 'ours';\n\t\tif (head.status === 404) return 'none';\n\t\tif (head.status === 403) return 'taken';\n\t\tthrow new BucketProbeFailed(name, describeAnswer(head));\n\t};\n\n\t/** Where the bucket is now — read, not assumed: it may be adopted. */\n\tconst located = async (name: string, made: string): Promise<string> =>\n\t\tctx.dryRun && made === 'created' ? region : bucketRegion(clients, name);\n\n\tconst create = async (\n\t\tname: string,\n\t): Promise<'created' | 'ours' | 'taken'> => {\n\t\tif (ctx.dryRun) {\n\t\t\tconst found = await probe(name);\n\t\t\tif (found === 'none') {\n\t\t\t\tawait ctx.change(\n\t\t\t\t\t{\n\t\t\t\t\t\tconstruct: id,\n\t\t\t\t\t\tresource: `bucket ${name}`,\n\t\t\t\t\t\tchange: `create in ${region}`,\n\t\t\t\t\t},\n\t\t\t\t\tasync () => {},\n\t\t\t\t);\n\t\t\t\treturn 'created';\n\t\t\t}\n\t\t\treturn found;\n\t\t}\n\t\tawait ctx.state.pending(entry(name, region));\n\t\ttry {\n\t\t\tawait s3.send(\n\t\t\t\tnew S3.CreateBucketCommand({\n\t\t\t\t\tBucket: name,\n\t\t\t\t\t// us-east-1 is the one region named by leaving it out.\n\t\t\t\t\t...(region === 'us-east-1'\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tCreateBucketConfiguration: {\n\t\t\t\t\t\t\t\t\tLocationConstraint:\n\t\t\t\t\t\t\t\t\t\tregion as import('@aws-sdk/client-s3').BucketLocationConstraint,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst code = errorName(error);\n\t\t\tif (code === 'BucketAlreadyOwnedByYou') return 'ours';\n\t\t\tif (code === 'BucketAlreadyExists') return 'taken';\n\t\t\tthrow error;\n\t\t}\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `bucket ${name}`,\n\t\t\t\tchange: `create in ${region}`,\n\t\t\t},\n\t\t\tasync () => {},\n\t\t);\n\t\treturn 'created';\n\t};\n\n\tconst adopt = async (name: string, where: string): Promise<void> => {\n\t\tconst there =\n\t\t\twhere === region ? clients : await makeClients(ctx.credential, where);\n\t\tconst tags = await readOr(\n\t\t\t() =>\n\t\t\t\tthere.s3.send(new there.S3.GetBucketTaggingCommand({ Bucket: name })),\n\t\t\t['NoSuchTagSet', 'NoSuchTagSetError'],\n\t\t);\n\t\tconst owner = tags?.TagSet?.find((t) => t.Key === TAG_PROJECT)?.Value;\n\t\tif (owner && owner !== ctx.identity.key) {\n\t\t\tthrow new BucketOwnedByAnotherProject(name, owner, ctx.identity.key);\n\t\t}\n\t};\n\n\t// Recorded: the name is the stage's forever. Gone, it is made again under\n\t// the same name — never a new one.\n\tif (record?.status === 'ready' && record.id) {\n\t\tconst found = await probe(record.id);\n\t\tif (found === 'taken') throw new RecordedBucketUnreachable(id, record.id);\n\t\tconst made = found === 'ours' ? 'ours' : await create(record.id);\n\t\tif (made === 'taken') throw new RecordedBucketUnreachable(id, record.id);\n\t\tconst where = await located(record.id, made);\n\t\tif (!ctx.dryRun) await ctx.state.ready(entry(record.id, where), record.id);\n\t\treturn { bucket: record.id, exists: made === 'ours', region: where };\n\t}\n\n\t// A run that died between creating a suffixed bucket and recording it.\n\tconst pending = record?.data?.name;\n\tconst names = [\n\t\t...(typeof pending === 'string' && pending !== good ? [pending] : []),\n\t\tgood,\n\t\t...Array.from({ length: SUFFIX_ATTEMPTS }, () =>\n\t\t\tsuffixedBucketName(good, randomSuffix()),\n\t\t),\n\t];\n\tconst tried: string[] = [];\n\tfor (const name of names) {\n\t\ttried.push(name);\n\t\tconst made = await create(name);\n\t\tif (made === 'taken') continue;\n\t\tconst where = await located(name, made);\n\t\tif (made === 'ours') await adopt(name, where);\n\t\tif (!ctx.dryRun) await ctx.state.ready(entry(name, where), name);\n\t\tif (name !== good) {\n\t\t\tctx.log(\n\t\t\t\t` '${good}' is taken by another account; '${id}' is '${name}', recorded in the stage's state`,\n\t\t\t);\n\t\t}\n\t\treturn { bucket: name, exists: made === 'ours', region: where };\n\t}\n\tthrow new BucketNameUnavailable(\n\t\tid,\n\t\ttried.filter((n) => n !== pending),\n\t);\n}\n\n/** Tags, Block Public Access, encryption, policy, versioning and CORS. */\nasync function ensureBucketSettings(\n\tctx: Ctx,\n\tclients: Clients,\n\tinput: {\n\t\tid: string;\n\t\tbucket: string;\n\t\t/** False when a dry run would create it: nothing to read yet. */\n\t\texists: boolean;\n\t\tversioning: boolean;\n\t\topen: readonly string[];\n\t},\n): Promise<void> {\n\tconst { S3, s3 } = clients;\n\tconst { id, bucket } = input;\n\tconst Bucket = bucket;\n\t// A bucket a dry run would create has nothing to read: every setting\n\t// would be set.\n\tconst fresh = ctx.dryRun && !input.exists;\n\tconst read = async <T>(\n\t\tfn: () => Promise<T>,\n\t\tmissing: readonly string[],\n\t): Promise<T | undefined> => (fresh ? undefined : readOr(fn, missing));\n\tconst set = (change: string, apply: () => Promise<unknown>) =>\n\t\tctx.change({ construct: id, resource: `bucket ${bucket}`, change }, () =>\n\t\t\tapply().then(() => undefined),\n\t\t);\n\n\t// Tags — gkm's three, beside whatever else is there.\n\tconst tagged = await read(\n\t\t() => s3.send(new S3.GetBucketTaggingCommand({ Bucket })),\n\t\t['NoSuchTagSet', 'NoSuchTagSetError'],\n\t);\n\tconst ours = identityTags(ctx, id);\n\tconst others = (tagged?.TagSet ?? []).filter(\n\t\t(t) => !ours.some((o) => o.Key === t.Key),\n\t);\n\tconst missingTag = ours.some(\n\t\t(o) => !tagged?.TagSet?.some((t) => t.Key === o.Key && t.Value === o.Value),\n\t);\n\tif (missingTag) {\n\t\tawait set('tag', () =>\n\t\t\ts3.send(\n\t\t\t\tnew S3.PutBucketTaggingCommand({\n\t\t\t\t\tBucket,\n\t\t\t\t\tTagging: {\n\t\t\t\t\t\tTagSet: [...others, ...ours].map((t) => ({\n\t\t\t\t\t\t\tKey: t.Key!,\n\t\t\t\t\t\t\tValue: t.Value!,\n\t\t\t\t\t\t})),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\tconst isOpen = input.open.length > 0;\n\tconst block = publicAccessBlock(isOpen);\n\tconst ensureBlock = async () => {\n\t\tconst current = await read(\n\t\t\t() => s3.send(new S3.GetPublicAccessBlockCommand({ Bucket })),\n\t\t\t['NoSuchPublicAccessBlockConfiguration'],\n\t\t);\n\t\tconst now = current?.PublicAccessBlockConfiguration;\n\t\tconst same =\n\t\t\tnow &&\n\t\t\t(Object.keys(block) as (keyof typeof block)[]).every(\n\t\t\t\t(k) => (now[k] ?? false) === block[k],\n\t\t\t);\n\t\tif (!same) {\n\t\t\tawait set(\n\t\t\t\tisOpen\n\t\t\t\t\t? 'block public access (ACLs; the policy opens the open paths)'\n\t\t\t\t\t: 'block all public access',\n\t\t\t\t() =>\n\t\t\t\t\ts3.send(\n\t\t\t\t\t\tnew S3.PutPublicAccessBlockCommand({\n\t\t\t\t\t\t\tBucket,\n\t\t\t\t\t\t\tPublicAccessBlockConfiguration: block,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t};\n\n\tconst policy = bucketPolicy(bucket, input.open);\n\tconst ensurePolicy = async () => {\n\t\tconst current = await read(\n\t\t\t() => s3.send(new S3.GetBucketPolicyCommand({ Bucket })),\n\t\t\t['NoSuchBucketPolicy'],\n\t\t);\n\t\tconst same =\n\t\t\tcurrent?.Policy !== undefined &&\n\t\t\tcanonicalPolicy(JSON.parse(current.Policy)) === canonicalPolicy(policy);\n\t\tif (!same) {\n\t\t\tawait set(\n\t\t\t\tisOpen\n\t\t\t\t\t? `policy: TLS only, public read on ${input.open.join(', ')}`\n\t\t\t\t\t: 'policy: TLS only',\n\t\t\t\t() =>\n\t\t\t\t\ts3.send(\n\t\t\t\t\t\tnew S3.PutBucketPolicyCommand({\n\t\t\t\t\t\t\tBucket,\n\t\t\t\t\t\t\tPolicy: JSON.stringify(policy),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t);\n\t\t}\n\t};\n\n\t// A public policy is refused while BlockPublicPolicy is on, and a block\n\t// put back while one is in place would refuse the next put: relax the\n\t// block before opening, and close the policy before blocking.\n\tif (isOpen) {\n\t\tawait ensureBlock();\n\t\tawait ensurePolicy();\n\t} else {\n\t\tawait ensurePolicy();\n\t\tawait ensureBlock();\n\t}\n\n\t// Default encryption: SSE-S3.\n\tconst encryption = await read(\n\t\t() => s3.send(new S3.GetBucketEncryptionCommand({ Bucket })),\n\t\t['ServerSideEncryptionConfigurationNotFoundError'],\n\t);\n\tconst algorithm =\n\t\tencryption?.ServerSideEncryptionConfiguration?.Rules?.[0]\n\t\t\t?.ApplyServerSideEncryptionByDefault?.SSEAlgorithm;\n\t// A new bucket is SSE-S3 already — S3 has encrypted every new bucket by\n\t// default since 2023 — so a dry run does not promise to set it.\n\tif (algorithm !== 'AES256' && !fresh) {\n\t\tawait set('encrypt by default (SSE-S3)', () =>\n\t\t\ts3.send(\n\t\t\t\tnew S3.PutBucketEncryptionCommand({\n\t\t\t\t\tBucket,\n\t\t\t\t\tServerSideEncryptionConfiguration: {\n\t\t\t\t\t\tRules: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tApplyServerSideEncryptionByDefault: { SSEAlgorithm: 'AES256' },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\t// Versioning: on when asked; a bucket that had it is suspended, never\n\t// stripped of the versions it kept.\n\tconst versioning = await read(\n\t\t() => s3.send(new S3.GetBucketVersioningCommand({ Bucket })),\n\t\t[],\n\t);\n\tconst status = versioning?.Status;\n\tif (input.versioning && status !== 'Enabled') {\n\t\tawait set('enable versioning', () =>\n\t\t\ts3.send(\n\t\t\t\tnew S3.PutBucketVersioningCommand({\n\t\t\t\t\tBucket,\n\t\t\t\t\tVersioningConfiguration: { Status: 'Enabled' },\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t} else if (!input.versioning && status === 'Enabled') {\n\t\tawait set('suspend versioning', () =>\n\t\t\ts3.send(\n\t\t\t\tnew S3.PutBucketVersioningCommand({\n\t\t\t\t\tBucket,\n\t\t\t\t\tVersioningConfiguration: { Status: 'Suspended' },\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\t// CORS for the stage's sites.\n\tconst { origins, unresolved } = bucketOrigins({\n\t\tworkspace: ctx.workspace,\n\t\tmanifest: ctx.manifest,\n\t\trunnables: ctx.runnables,\n\t\tstage: ctx.stage,\n\t\tbucket: id,\n\t});\n\tif (unresolved.length > 0) {\n\t\tctx.log(\n\t\t\t` ${unresolved.join(', ')} ${unresolved.length === 1 ? 'has' : 'have'} no address on '${ctx.stage}' (domains.${ctx.stage}), so ${unresolved.length === 1 ? 'is' : 'are'} not in '${bucket}''s CORS`,\n\t\t);\n\t}\n\tif (origins.length === 0) return;\n\tconst rule = corsRule(origins);\n\tconst cors = await read(\n\t\t() => s3.send(new S3.GetBucketCorsCommand({ Bucket })),\n\t\t['NoSuchCORSConfiguration'],\n\t);\n\tconst sameCors =\n\t\tcors?.CORSRules?.length === 1 &&\n\t\tcanonicalCors(cors.CORSRules[0]!) === canonicalCors(rule);\n\tif (!sameCors) {\n\t\tawait set(`CORS for ${origins.join(', ')}`, () =>\n\t\t\ts3.send(\n\t\t\t\tnew S3.PutBucketCorsCommand({\n\t\t\t\t\tBucket,\n\t\t\t\t\tCORSConfiguration: { CORSRules: [rule] },\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n}\n\nfunction canonicalCors(rule: Partial<CorsRule>): string {\n\tconst sorted = (list?: string[]) => [...(list ?? [])].sort();\n\treturn JSON.stringify({\n\t\tAllowedMethods: sorted(rule.AllowedMethods),\n\t\tAllowedOrigins: sorted(rule.AllowedOrigins),\n\t\tAllowedHeaders: sorted(rule.AllowedHeaders),\n\t\tExposeHeaders: sorted(rule.ExposeHeaders),\n\t\tMaxAgeSeconds: rule.MaxAgeSeconds ?? null,\n\t});\n}\n\n/** The bucket's IAM user and its inline policy. */\nasync function ensureUser(\n\tctx: Ctx,\n\tclients: Clients,\n\tid: string,\n\tuser: string,\n\tpolicy: ReturnType<typeof userPolicy>,\n): Promise<{ user: string; exists: boolean }> {\n\tconst { IAM, iam } = clients;\n\tconst entry: StateEntry = { key: `iam-user:${id}`, type: 'iam-user' };\n\tconst found = await readOr(\n\t\t() => iam.send(new IAM.GetUserCommand({ UserName: user })),\n\t\t['NoSuchEntity', 'NoSuchEntityException'],\n\t);\n\n\tif (found?.User) {\n\t\tconst tags = await iam.send(\n\t\t\tnew IAM.ListUserTagsCommand({ UserName: user }),\n\t\t);\n\t\tconst tag = (key: string) => tags.Tags?.find((t) => t.Key === key)?.Value;\n\t\tif (\n\t\t\tfound.User.Path !== IAM_USER_PATH ||\n\t\t\ttag(TAG_PROJECT) !== ctx.identity.key ||\n\t\t\ttag(TAG_STAGE) !== ctx.stage\n\t\t) {\n\t\t\tthrow new IamUserNotOwned(user, ctx.identity.key, ctx.stage);\n\t\t}\n\t\tawait ctx.state.ready(entry, user);\n\t} else {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `IAM user ${user}`,\n\t\t\t\tchange: `create under ${IAM_USER_PATH}`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait ctx.state.pending(entry);\n\t\t\t\tawait iam.send(\n\t\t\t\t\tnew IAM.CreateUserCommand({\n\t\t\t\t\t\tUserName: user,\n\t\t\t\t\t\tPath: IAM_USER_PATH,\n\t\t\t\t\t\tTags: identityTags(ctx, id),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tawait ctx.state.ready(entry, user);\n\t\t\t},\n\t\t);\n\t}\n\n\tconst exists = Boolean(found?.User) || !ctx.dryRun;\n\tconst current = exists\n\t\t? await readOr(\n\t\t\t\t() =>\n\t\t\t\t\tiam.send(\n\t\t\t\t\t\tnew IAM.GetUserPolicyCommand({\n\t\t\t\t\t\t\tUserName: user,\n\t\t\t\t\t\t\tPolicyName: IAM_POLICY_NAME,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t['NoSuchEntity', 'NoSuchEntityException'],\n\t\t\t)\n\t\t: undefined;\n\tconst document = current?.PolicyDocument\n\t\t? JSON.parse(decodePolicy(current.PolicyDocument))\n\t\t: undefined;\n\tif (!document || canonicalPolicy(document) !== canonicalPolicy(policy)) {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `IAM user ${user}`,\n\t\t\t\tchange: `policy ${IAM_POLICY_NAME}: this bucket only`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait iam.send(\n\t\t\t\t\tnew IAM.PutUserPolicyCommand({\n\t\t\t\t\t\tUserName: user,\n\t\t\t\t\t\tPolicyName: IAM_POLICY_NAME,\n\t\t\t\t\t\tPolicyDocument: JSON.stringify(policy),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t}\n\treturn { user, exists };\n}\n\n/** IAM returns a policy document URL-encoded; an emulator may not. */\nfunction decodePolicy(document: string): string {\n\ttry {\n\t\treturn decodeURIComponent(document);\n\t} catch {\n\t\treturn document;\n\t}\n}\n\n/**\n * The user's access key, in the stage's secrets as the bucket's URL.\n *\n * - First run: one key, written into the stage's secrets.\n * - `--rotate-keys`: a second key, written in place of the first; the first\n * stays active until the stage has deployed with the second, and the next\n * run after that deploy — or `--retire-old-keys` — deletes it.\n * - A key the secrets no longer hold (a store emptied by hand): replaced the\n * same way, since its secret cannot be read back.\n */\nasync function ensureAccessKey(\n\tctx: Ctx,\n\tclients: Clients,\n\tinput: { id: string; bucket: string; user: string; exists: boolean },\n): Promise<void> {\n\tconst { IAM, iam } = clients;\n\tconst { id, bucket, user } = input;\n\tconst urlKey = provideKey(id, 'url');\n\tconst entryKey = `iam-access-key:${id}`;\n\tconst record = ctx.state.record(entryKey);\n\n\tconst given = ctx.secrets[urlKey];\n\tlet inUrl: string | undefined;\n\tlet parsed: s3Url.S3Address | undefined;\n\tif (given !== undefined) {\n\t\ttry {\n\t\t\tparsed = s3Url.parse(given);\n\t\t} catch {\n\t\t\tparsed = undefined;\n\t\t}\n\t\tif (parsed?.bucket !== bucket) {\n\t\t\tthrow new BucketKeySetElsewhere(\n\t\t\t\turlKey,\n\t\t\t\tbucket,\n\t\t\t\tparsed?.bucket ?? given.replace(/\\/\\/[^@]*@/, '//'),\n\t\t\t\tctx.stage,\n\t\t\t);\n\t\t}\n\t\tinUrl = parsed.accessKeyId;\n\t}\n\n\tconst listed = input.exists\n\t\t? ((\n\t\t\t\tawait iam.send(new IAM.ListAccessKeysCommand({ UserName: user }))\n\t\t\t).AccessKeyMetadata?.map((k) => k.AccessKeyId!) ?? [])\n\t\t: [];\n\n\tlet current = record?.status === 'ready' ? record.id : undefined;\n\tlet previous =\n\t\ttypeof record?.data?.previous === 'string'\n\t\t\t? record.data.previous\n\t\t\t: undefined;\n\tconst rotatedAt =\n\t\ttypeof record?.data?.rotatedAt === 'string'\n\t\t\t? record.data.rotatedAt\n\t\t\t: undefined;\n\tconst entry = (data: Record<string, unknown> = {}): StateEntry => ({\n\t\tkey: entryKey,\n\t\ttype: 'iam-access-key',\n\t\tdata: { user, ...data },\n\t});\n\n\t// The old key of a rotation: deleted once the stage deployed after it.\n\tif (previous && current) {\n\t\tconst deployed =\n\t\t\trotatedAt !== undefined &&\n\t\t\tctx.state.lastDeployedAt !== undefined &&\n\t\t\tctx.state.lastDeployedAt > rotatedAt;\n\t\tif (ctx.retireOldKeys || deployed) {\n\t\t\tconst old = previous;\n\t\t\tconst keep = current;\n\t\t\tawait ctx.change(\n\t\t\t\t{\n\t\t\t\t\tconstruct: id,\n\t\t\t\t\tresource: `IAM user ${user}`,\n\t\t\t\t\tchange: `delete the rotated-out access key ${old}`,\n\t\t\t\t},\n\t\t\t\tasync () => {\n\t\t\t\t\tif (listed.includes(old)) {\n\t\t\t\t\t\tawait iam.send(\n\t\t\t\t\t\t\tnew IAM.DeleteAccessKeyCommand({\n\t\t\t\t\t\t\t\tUserName: user,\n\t\t\t\t\t\t\t\tAccessKeyId: old,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait ctx.state.ready(entry(), keep);\n\t\t\t\t},\n\t\t\t);\n\t\t\tprevious = undefined;\n\t\t} else {\n\t\t\tctx.log(\n\t\t\t\t` ${id}: the old access key ${previous} stays active until '${ctx.stage}' is deployed with the new one; the next deploy after that deletes it (or pass --retire-old-keys)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// No record, and the secrets hold a key of this user's: adopt it.\n\tif (!current && inUrl && listed.includes(inUrl)) {\n\t\tawait ctx.state.ready(entry(), inUrl);\n\t\tcurrent = inUrl;\n\t}\n\n\tconst valid =\n\t\tcurrent !== undefined && listed.includes(current) && inUrl === current;\n\tif (valid && !ctx.rotateKeys) {\n\t\t// The key is good; the address must name where the bucket is.\n\t\tif (parsed && parsed.region !== clients.region) {\n\t\t\tconst address = parsed;\n\t\t\tawait ctx.change(\n\t\t\t\t{\n\t\t\t\t\tconstruct: id,\n\t\t\t\t\tresource: urlKey,\n\t\t\t\t\tchange: `name ${clients.region}, the bucket's region (it said ${address.region ?? 'none'})`,\n\t\t\t\t},\n\t\t\t\t() =>\n\t\t\t\t\tctx.writeSecrets({\n\t\t\t\t\t\t[urlKey]: s3Url.build({ ...address, region: clients.region }),\n\t\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tif (ctx.rotateKeys && previous) {\n\t\tthrow new RotationInProgress(id, previous, ctx.stage);\n\t}\n\n\tconst outgoing = current && listed.includes(current) ? current : undefined;\n\tif (listed.length >= 2) throw new AccessKeyLimit(user, listed);\n\n\tconst why = !current\n\t\t? 'create an access key'\n\t\t: ctx.rotateKeys\n\t\t\t? 'rotate: issue a new access key'\n\t\t\t: 'issue a new access key (the secrets no longer hold the recorded one)';\n\tawait ctx.change(\n\t\t{ construct: id, resource: `IAM user ${user}`, change: why },\n\t\tasync () => {\n\t\t\tawait ctx.state.pending(entry(outgoing ? { previous: outgoing } : {}));\n\t\t\tconst created = await iam.send(\n\t\t\t\tnew IAM.CreateAccessKeyCommand({ UserName: user }),\n\t\t\t);\n\t\t\tconst key = created.AccessKey!;\n\t\t\t// Into the stage's secrets before anything else: IAM shows a secret\n\t\t\t// once, and a key whose secret is lost is a key to replace.\n\t\t\tawait ctx.writeSecrets({\n\t\t\t\t[urlKey]: s3Url.build({\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion: clients.region,\n\t\t\t\t\t...(clients.endpoint\n\t\t\t\t\t\t? { endpoint: clients.endpoint, forcePathStyle: true }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\taccessKeyId: key.AccessKeyId!,\n\t\t\t\t\tsecretAccessKey: key.SecretAccessKey!,\n\t\t\t\t}),\n\t\t\t});\n\t\t\t// When it was issued: IAM takes seconds to make a new key usable,\n\t\t\t// and the deploy's check waits for one this young.\n\t\t\tconst issuedAt = new Date().toISOString();\n\t\t\tawait ctx.state.ready(\n\t\t\t\tentry(\n\t\t\t\t\toutgoing\n\t\t\t\t\t\t? { previous: outgoing, rotatedAt: issuedAt, issuedAt }\n\t\t\t\t\t\t: { issuedAt },\n\t\t\t\t),\n\t\t\t\tkey.AccessKeyId!,\n\t\t\t);\n\t\t},\n\t);\n\tif (outgoing) {\n\t\tctx.log(\n\t\t\t` ${urlKey} holds the new key. This deploy moves '${ctx.stage}' onto it; the next deploy after it deletes the old key ${outgoing}`,\n\t\t);\n\t}\n}\n\n/** How long a key issued this recently counts as new to IAM. */\nconst NEW_KEY_WINDOW_MS = 10 * 60 * 1000;\n\n/** The waits between asks while a new key becomes usable: about a minute. */\nlet newKeyWaits: readonly number[] = [2000, 4000, 8000, 15000, 15000, 15000];\n\n/** For tests: the waits for a new key. Returns the old ones. */\nexport function useNewKeyWaits(waits: readonly number[]): readonly number[] {\n\tconst previous = newKeyWaits;\n\tnewKeyWaits = waits;\n\treturn previous;\n}\n\n/** When the key in the URL was issued, if the stage's state says it was just now. */\nfunction issuedJustNow(\n\tctx: VerifyContext<S3ObjectsConfig>,\n\tid: string,\n\taccessKeyId: string,\n): string | undefined {\n\tconst record = ctx.resources?.[`iam-access-key:${id}`];\n\tconst issuedAt = record?.data?.issuedAt;\n\tif (record?.id !== accessKeyId || typeof issuedAt !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst age = Date.now() - Date.parse(issuedAt);\n\treturn age >= 0 && age < NEW_KEY_WINDOW_MS ? issuedAt : undefined;\n}\n\n/**\n * Each provisioned bucket answers `HeadBucket` to the key in the stage's\n * secrets — the one the apps will use. A bucket whose URL carries no key is\n * not one this provider wrote, and the deploy's own check covers a URL that\n * is missing.\n *\n * A failure is read by its status, never its name — a `HEAD` has no body,\n * so SDK v3 calls a 301, 400 or 403 `Unknown` — and the message carries\n * everything S3 said: status, error, region, request ids.\n *\n * @throws {BucketRegionMismatch} the bucket is in another region than its URL says\n * @throws {ProvisionedBucketUnreachable}\n */\nasync function verifyS3(ctx: VerifyContext<S3ObjectsConfig>): Promise<void> {\n\tconst S3 = await import('@aws-sdk/client-s3');\n\tfor (const { id } of bucketConstructs(ctx.manifest)) {\n\t\tconst urlKey = provideKey(id, 'url');\n\t\tconst url = ctx.secrets[urlKey];\n\t\tif (url === undefined) continue;\n\t\tconst address = s3Url.parse(url);\n\t\tif (!address.accessKeyId || !address.secretAccessKey) continue;\n\t\tconst asked = address.region ?? ctx.config.region ?? 'us-east-1';\n\t\tconst client = new S3.S3Client({\n\t\t\tregion: asked,\n\t\t\tcredentials: {\n\t\t\t\taccessKeyId: address.accessKeyId,\n\t\t\t\tsecretAccessKey: address.secretAccessKey,\n\t\t\t},\n\t\t\t...(address.endpoint ? { endpoint: address.endpoint } : {}),\n\t\t\t...(address.forcePathStyle ? { forcePathStyle: true } : {}),\n\t\t});\n\t\ttry {\n\t\t\tlet head = await headBucket(S3, client, address.bucket);\n\t\t\t// A key IAM issued moments ago is refused until it propagates.\n\t\t\tconst issuedAt = issuedJustNow(ctx, id, address.accessKeyId);\n\t\t\tlet waited = 0;\n\t\t\tif (!head.ok && head.status === 403 && issuedAt) {\n\t\t\t\tctx.log?.(\n\t\t\t\t\t` ${id}: waiting for the new key ${address.accessKeyId} to become active…`,\n\t\t\t\t);\n\t\t\t\tfor (const wait of newKeyWaits) {\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, wait));\n\t\t\t\t\twaited += wait;\n\t\t\t\t\thead = await headBucket(S3, client, address.bucket);\n\t\t\t\t\tif (head.ok || head.status !== 403) break;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (head.ok) continue;\n\n\t\t\tconst fail = (reason: string) =>\n\t\t\t\tnew ProvisionedBucketUnreachable(id, address.bucket, ctx.stage, reason);\n\t\t\tconst said = describeAnswer(head);\n\n\t\t\t// In another region: S3 redirects, or refuses the signature, and\n\t\t\t// says where.\n\t\t\tif (\n\t\t\t\thead.status === 301 ||\n\t\t\t\t(head.status === 400 && head.region && head.region !== asked)\n\t\t\t) {\n\t\t\t\tlet where = head.region;\n\t\t\t\tlet located = '';\n\t\t\t\tif (!where) {\n\t\t\t\t\tconst location = await bucketLocation(S3, client, address.bucket);\n\t\t\t\t\tif ('region' in location) where = location.region;\n\t\t\t\t\telse\n\t\t\t\t\t\tlocated = `; GetBucketLocation answered ${describeAnswer(location.failed)}`;\n\t\t\t\t}\n\t\t\t\tif (where && where !== asked) {\n\t\t\t\t\tthrow new BucketRegionMismatch(\n\t\t\t\t\t\tid,\n\t\t\t\t\t\taddress.bucket,\n\t\t\t\t\t\tctx.stage,\n\t\t\t\t\t\turlKey,\n\t\t\t\t\t\twhere,\n\t\t\t\t\t\taddress.region,\n\t\t\t\t\t\tasked,\n\t\t\t\t\t\tsaid,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow fail(`S3 redirected the request (${said}${located})`);\n\t\t\t}\n\t\t\tif (head.status === 404) throw fail(`it does not exist (${said})`);\n\t\t\tif (head.status === 403) {\n\t\t\t\tthrow fail(\n\t\t\t\t\t'the key is refused — AccessDenied, or an invalid or ' +\n\t\t\t\t\t\t`not-yet-active key (${said})` +\n\t\t\t\t\t\t(issuedAt\n\t\t\t\t\t\t\t? `. The key was issued at ${issuedAt} by this deploy, and IAM ` +\n\t\t\t\t\t\t\t\t'keys take seconds to become usable: it was still refused ' +\n\t\t\t\t\t\t\t\t`after waiting ${Math.round(waited / 1000)}s`\n\t\t\t\t\t\t\t: ''),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow fail(said);\n\t\t} finally {\n\t\t\tclient.destroy();\n\t\t}\n\t}\n}\n\nexport const s3Provider: ResourceProvider<S3ObjectsConfig, AwsProvisioning> = {\n\tkind: 'objects',\n\tname: 's3',\n\tcheck: checkS3Config,\n\tprovisioning: S3_PROVISIONING,\n\tcredentials: awsProvisioningCredentials,\n\truntimeKeys(manifest) {\n\t\treturn bucketConstructs(manifest).flatMap((b) => [\n\t\t\tprovideKey(b.id, 'url'),\n\t\t\t...b.servers.map((s) => provideKey(s.id, 'url')),\n\t\t]);\n\t},\n\tensure: ensureS3,\n\tverify: verifyS3,\n};\n","/**\n * The providers gkm ships, by kind and name — registered the way a deploy\n * target's built-ins are (`target/builtins.ts`). A provider from a package is\n * one more entry here once there is a loading story for it.\n */\n\nimport { s3Provider } from './s3/index.js';\nimport type { ProviderKind, ResourceProvider } from './types.js';\n\nexport const BUILTIN_PROVIDERS: {\n\treadonly [K in ProviderKind]: Readonly<\n\t\tRecord<string, ResourceProvider<any, any>>\n\t>;\n} = {\n\tobjects: { s3: s3Provider },\n};\n\n/** The provider `kind` names `name`, if gkm has one. */\nexport function builtinProvider(\n\tkind: ProviderKind,\n\tname: string,\n): ResourceProvider<any, any> | undefined {\n\treturn Object.hasOwn(BUILTIN_PROVIDERS[kind], name)\n\t\t? BUILTIN_PROVIDERS[kind][name]\n\t\t: undefined;\n}\n\n/** The names `deploy.<kind>.<stage>` accepts, for messages. */\nexport function providerNames(kind: ProviderKind): string[] {\n\treturn Object.keys(BUILTIN_PROVIDERS[kind]).sort();\n}\n","/**\n * Running providers on a stage: `ensure()` at the start of every deploy —\n * before its checks, so a key the deploy creates is never reported missing —\n * `verify()` from every deploy's checks, and the hint a stage missing a key\n * is given.\n *\n * See `types.ts` for what a provider is.\n */\n\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport { deployIdentity } from '../deploy/identity.js';\nimport { DeployJournal } from '../deploy/journal.js';\nimport type { ResourceRecord, StateStore } from '../deploy/StateStore.js';\nimport { createComposeState, createEmptyState } from '../deploy/state.js';\nimport { GkmError } from '../errors';\nimport { initStageSecrets } from '../secrets/storage.js';\nimport type { StageSecrets } from '../secrets/types.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport { stageProvider } from './config.js';\nimport { deploysWithCompose } from './dns.js';\nimport { builtinProvider } from './registry.js';\nimport {\n\tPROVIDER_KINDS,\n\ttype ProviderKind,\n\ttype ProvisionAction,\n\ttype ProvisionState,\n\ttype ResourceProvider,\n} from './types.js';\n\nexport {\n\tcheckStageProvider,\n\tstageProvider,\n\tUnknownStageProvider,\n} from './config.js';\nexport {\n\tassertStageProvidersEnabled,\n\tprovisionCommand,\n\tprovisionHint,\n\tStageProviderDisabled,\n\tstageProviderNotes,\n} from './notes.js';\nexport { BUILTIN_PROVIDERS, builtinProvider } from './registry.js';\nexport type * from './types.js';\n\n/** The constructs of a kind: `objects` is every bucket. */\nfunction constructsOf(manifest: ConstructManifest, kind: ProviderKind) {\n\treturn Object.entries(manifest)\n\t\t.filter(([, d]) => d.kind === kind)\n\t\t.map(([id]) => id)\n\t\t.sort();\n}\n\nexport interface VerifyStageInput {\n\tworkspace: NormalizedWorkspace;\n\tmanifest: ConstructManifest;\n\tstage: string;\n\t/** The stage's secrets, by key. */\n\tsecrets: Readonly<Record<string, string>>;\n\t/** What the stage's state records, by key. */\n\tresources?: Readonly<Record<string, ResourceRecord>>;\n\t/** Progress worth printing. */\n\tlog?: (line: string) => void;\n}\n\n/**\n * What every deploy runs: each provider's `verify()` — the cheap check that\n * what it created is still there and the stage's key reaches it. Nothing on\n * the local stage, and nothing for a kind on `external` or `false` — a kind\n * the stage has none of is the deploy's readiness check's to refuse.\n */\nexport async function verifyStageProviders(\n\tinput: VerifyStageInput,\n): Promise<string[]> {\n\tconst verified: string[] = [];\n\tfor (const kind of PROVIDER_KINDS) {\n\t\tif (constructsOf(input.manifest, kind).length === 0) continue;\n\t\tconst choice = stageProvider(input.workspace, kind, input.stage);\n\t\tif (choice.mode !== 'provider') continue;\n\t\tconst provider = builtinProvider(kind, choice.name)!;\n\t\tawait provider.verify({\n\t\t\tworkspace: input.workspace,\n\t\t\tmanifest: input.manifest,\n\t\t\tstage: input.stage,\n\t\t\tconfig: choice.config,\n\t\t\tsecrets: input.secrets,\n\t\t\t...(input.resources ? { resources: input.resources } : {}),\n\t\t\t...(input.log ? { log: input.log } : {}),\n\t\t});\n\t\tverified.push(`${kind}: ${provider.name}`);\n\t}\n\treturn verified;\n}\n\n/** The stage's secrets, as the deploy reads and writes them. */\nexport interface ProvisionSecrets {\n\tread(): Promise<StageSecrets | null>;\n\twrite(secrets: StageSecrets): Promise<void>;\n}\n\nexport interface ProvisionOptions {\n\tworkspace: NormalizedWorkspace;\n\tstage: string;\n\tmanifest: ConstructManifest;\n\trunnables?: Record<string, string[]>;\n\t/** The stage's secrets — where each runtime key is written. */\n\tsecrets: ProvisionSecrets;\n\t/** The stage's deploy state. The caller holds the stage's lock. */\n\tstate: StateStore;\n\t/** Print the plan; write nothing to the account, the state or the secrets. */\n\tdryRun?: boolean;\n\t/** Issue each runtime key a successor. */\n\trotateKeys?: boolean;\n\t/** Delete a rotated-out key now rather than after the next deploy. */\n\tretireOldKeys?: boolean;\n\t/** The AWS profile for the stage's account. */\n\tprofile?: string;\n\t/** The CLI's home. */\n\thome?: string;\n\tenv?: NodeJS.ProcessEnv;\n\tlog?: (line: string) => void;\n}\n\n/** What one kind came to on a provisioning run. */\nexport interface KindReport {\n\tkind: ProviderKind;\n\tmode: 'external' | 'none' | 'provider';\n\tprovider?: string;\n\tactions: ProvisionAction[];\n\t/**\n\t * The runtime keys the stage's secrets do not hold yet, which the run\n\t * writes — or, on a dry run, would.\n\t */\n\tplanned: string[];\n}\n\n/**\n * A stage whose provider creates its resources, and no credentials to create\n * them with. Raised before anything is created, built or started.\n */\nexport class ProviderCredentialsMissing extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly kind: ProviderKind,\n\t\treadonly provider: string,\n\t\t/** The constructs it would have created resources for. */\n\t\treadonly ids: readonly string[],\n\t\t/** The environment variables it reads. */\n\t\treadonly env: readonly string[],\n\t\t/** How to supply them, in one line. */\n\t\treadonly describe: string,\n\t\t/** A `gkm login --provider` name, where it has one. */\n\t\treadonly login?: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.${kind}.${stage} is ${provider}, so the deploy creates what ` +\n\t\t\t\t`${ids.join(', ')} ${ids.length === 1 ? 'is' : 'are'} backed by on ` +\n\t\t\t\t`'${stage}' and writes ${ids.length === 1 ? 'its key' : 'their keys'} ` +\n\t\t\t\t`into the stage's secrets — and it found no ${provider} credentials ` +\n\t\t\t\t`to do it with. On this machine, supply ${describe}` +\n\t\t\t\t(login ? `, or run gkm login --provider ${login}` : '') +\n\t\t\t\t'. In CI, the step that runs the deploy needs them: the ' +\n\t\t\t\t`'${stage}' environment's role ` +\n\t\t\t\t'(AWS_ROLE_ARN, from gkm deploy:github), assumed before that step. ' +\n\t\t\t\t`With the keys set by hand instead, set deploy.${kind}.${stage} to 'external'.`,\n\t\t);\n\t\tthis.name = 'ProviderCredentialsMissing';\n\t}\n}\n\n/**\n * `ensure()` for every provider the stage configures — find or create, fix\n * drift, record in the stage's state, write the runtime keys into its\n * secrets. Run by the deploy, which holds the stage's lock. A provider with\n * no provisioning credentials stops the run with\n * {@link ProviderCredentialsMissing} before anything is created.\n */\nexport async function provisionStage(\n\toptions: ProvisionOptions,\n): Promise<KindReport[]> {\n\tconst { workspace, stage, manifest } = options;\n\tconst dryRun = options.dryRun === true;\n\tconst env = options.env ?? process.env;\n\tconst log = options.log ?? ((line: string) => console.log(line));\n\tconst runnables = options.runnables ?? {};\n\n\tconst reports: KindReport[] = [];\n\tconst configured: {\n\t\tkind: ProviderKind;\n\t\tprovider: ResourceProvider<any, any>;\n\t\tconfig: unknown;\n\t\tcredential: unknown;\n\t\treport: KindReport;\n\t}[] = [];\n\n\tfor (const kind of PROVIDER_KINDS) {\n\t\tconst choice = stageProvider(workspace, kind, stage);\n\t\tif (choice.mode !== 'provider') {\n\t\t\treports.push({ kind, mode: choice.mode, actions: [], planned: [] });\n\t\t\tcontinue;\n\t\t}\n\t\tconst provider = builtinProvider(kind, choice.name)!;\n\t\tconst report: KindReport = {\n\t\t\tkind,\n\t\t\tmode: 'provider',\n\t\t\tprovider: provider.name,\n\t\t\tactions: [],\n\t\t\tplanned: [],\n\t\t};\n\t\treports.push(report);\n\t\tconst ids = constructsOf(manifest, kind);\n\t\tif (ids.length === 0) continue;\n\n\t\tconst credential = await provider.credentials({\n\t\t\tstage,\n\t\t\tenv,\n\t\t\t...(options.profile ? { profile: options.profile } : {}),\n\t\t\t...(options.home ? { home: options.home } : {}),\n\t\t});\n\t\tif (credential === undefined) {\n\t\t\tthrow new ProviderCredentialsMissing(\n\t\t\t\tstage,\n\t\t\t\tkind,\n\t\t\t\tprovider.name,\n\t\t\t\tids,\n\t\t\t\tprovider.provisioning.env,\n\t\t\t\tprovider.provisioning.describe,\n\t\t\t\tprovider.provisioning.login,\n\t\t\t);\n\t\t}\n\t\tconfigured.push({\n\t\t\tkind,\n\t\t\tprovider,\n\t\t\tconfig: choice.config,\n\t\t\tcredential,\n\t\t\treport,\n\t\t});\n\t}\n\n\tif (configured.length === 0) return reports;\n\n\tconst identity = deployIdentity(workspace, stage);\n\tlet secrets = (await options.secrets.read())?.custom ?? {};\n\tfor (const entry of configured) {\n\t\tentry.report.planned = entry.provider\n\t\t\t.runtimeKeys(manifest)\n\t\t\t.filter((key) => secrets[key] === undefined);\n\t}\n\n\tconst state: ProvisionState = dryRun\n\t\t? await readOnlyState(options.state, stage)\n\t\t: journalState(\n\t\t\t\tawait DeployJournal.open(options.state, stage, () =>\n\t\t\t\t\tdeploysWithCompose(workspace)\n\t\t\t\t\t\t? createComposeState(stage)\n\t\t\t\t\t\t: createEmptyState(stage, '', ''),\n\t\t\t\t),\n\t\t\t);\n\n\tconst writeSecrets = async (values: Record<string, string>) => {\n\t\tif (dryRun) return;\n\t\tconst stored = (await options.secrets.read()) ?? initStageSecrets(stage);\n\t\tconst next = {\n\t\t\t...stored,\n\t\t\tcustom: { ...stored.custom, ...values },\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t};\n\t\tawait options.secrets.write(next);\n\t\tsecrets = next.custom;\n\t};\n\n\tfor (const entry of configured) {\n\t\tlog(\n\t\t\t`☁️ ${entry.kind}: ${entry.provider.name}${dryRun ? ' (dry run)' : ''}`,\n\t\t);\n\t\tawait entry.provider.ensure({\n\t\t\tworkspace,\n\t\t\tmanifest,\n\t\t\trunnables,\n\t\t\tstage,\n\t\t\tidentity,\n\t\t\tconfig: entry.config,\n\t\t\tcredential: entry.credential,\n\t\t\tget secrets() {\n\t\t\t\treturn secrets;\n\t\t\t},\n\t\t\tstate,\n\t\t\tdryRun,\n\t\t\trotateKeys: options.rotateKeys === true,\n\t\t\tretireOldKeys: options.retireOldKeys === true,\n\t\t\tasync change(action, apply) {\n\t\t\t\tif (!dryRun) await apply();\n\t\t\t\tentry.report.actions.push(action);\n\t\t\t\tlog(\n\t\t\t\t\t` ${dryRun ? 'would ' : ''}${action.change} — ${action.resource}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\twriteSecrets,\n\t\t\tlog,\n\t\t});\n\t\tif (entry.report.actions.length === 0) {\n\t\t\tlog(' up to date');\n\t\t}\n\t}\n\n\treturn reports;\n}\n\n/** The journal as `ensure()` sees it. */\nfunction journalState(journal: DeployJournal): ProvisionState {\n\treturn {\n\t\trecord: (key) => journal.record(key),\n\t\tpending: (entry) => journal.pending(entry),\n\t\tready: (entry, id) => journal.ready(entry, id),\n\t\tlastDeployedAt: journal.existed ? journal.state.lastDeployedAt : undefined,\n\t};\n}\n\n/** What a dry run reads, and the writes it does not make. */\nasync function readOnlyState(\n\tstore: StateStore,\n\tstage: string,\n): Promise<ProvisionState> {\n\tconst stored = await store.read(stage);\n\treturn {\n\t\trecord: (key) => stored?.resources[key],\n\t\tpending: async () => {},\n\t\tready: async () => {},\n\t\t...(stored ? { lastDeployedAt: stored.state.lastDeployedAt } : {}),\n\t};\n}\n","/**\n * Stored secrets an older gkm generated that now shadow a derived value.\n *\n * Before constructs, initialising a stage wrote an address for each app into\n * its custom secrets: `<APP>_DATABASE_URL` as a `postgresql://…@localhost`\n * URL with a password of its own, and `http://localhost:<port>` for a site or\n * an auth server. Those keys are now a construct's — `database.schema('AuthDatabase')`\n * provides `AUTH_DATABASE_URL`, `new BetterAuth('Auth')` provides `AUTH_URL`\n * — and a deploy derives them. A value the stage holds is a value set by hand,\n * and set by hand wins: the container is handed `localhost`, where nothing\n * answers, with a password no role has.\n *\n * So a deploy refuses such a stage rather than run it, naming each key and\n * the command that removes it. Nothing is deleted for the user: the value is\n * theirs, and only they can say it is stale. A URL that names a real host — a\n * managed database — is a deliberate choice and still wins.\n */\n\nimport {\n\ttype ConstructManifest,\n\ttype DeclarationKind,\n\tprovidedKeyFor,\n} from '@geekmidas/manifest';\nimport { GkmError } from '../errors';\n\n/** The kinds whose URL an older gkm wrote into a stage's secrets. */\nconst ADDRESSED: ReadonlySet<DeclarationKind> = new Set<DeclarationKind>([\n\t'database',\n\t'database-reader',\n\t'database-schema',\n\t'rest-api',\n\t'site',\n]);\n\n/** Hosts that are this machine — never anything, inside a container. */\nconst LOOPBACK = new Set(['localhost', '127.0.0.1', '[::1]', '::1']);\n\n/** One stored key that shadows a construct's derived value. */\nexport interface StaleSecret {\n\tkey: string;\n\t/** The construct that provides the key. */\n\tconstruct: string;\n\t/** The host the stored value names — never the value itself. */\n\thost: string;\n}\n\n/**\n * A stage holds a construct's address as a custom secret, pointing at\n * `localhost` — what an older `gkm secrets:init`, `gkm setup` or `gkm init`\n * generated. Set by hand wins over derived, so the app would be handed it.\n */\nexport class StaleStageSecrets extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly stale: readonly StaleSecret[],\n\t) {\n\t\tconst one = stale.length === 1;\n\t\tsuper(\n\t\t\t`The stage '${stage}' holds ${one ? 'a value' : 'values'} an older gkm generated ` +\n\t\t\t\t`for ${one ? 'an address a construct' : 'addresses constructs'} now ${one ? 'provides' : 'provide'}:\\n` +\n\t\t\t\tstale\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(s) => ` ${s.key}: ${s.construct}'s, stored pointing at ${s.host}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join('\\n') +\n\t\t\t\t`\\nA stored value wins over the derived one, so the app would be handed ` +\n\t\t\t\t`an address where nothing answers inside its container. Remove ` +\n\t\t\t\t`${one ? 'it' : 'each'}, and the construct's own value is used:\\n` +\n\t\t\t\tstale\n\t\t\t\t\t.map((s) => ` gkm secrets:unset ${s.key} --stage ${stage}`)\n\t\t\t\t\t.join('\\n') +\n\t\t\t\t'\\nA managed service set with its real host is not affected.',\n\t\t);\n\t\tthis.name = 'StaleStageSecrets';\n\t}\n}\n\n/** The host a stored value names, if it is a URL. */\nfunction hostOf(value: string): string | undefined {\n\ttry {\n\t\treturn new URL(value).hostname;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Each stored key that a construct provides an address for, holding an\n * address on this machine.\n */\nexport function staleStageSecrets(\n\tmanifest: ConstructManifest,\n\tsupplied: Readonly<Record<string, string>>,\n): StaleSecret[] {\n\tconst stale: StaleSecret[] = [];\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tif (!ADDRESSED.has(declaration.kind)) continue;\n\t\tconst key = providedKeyFor(id, declaration.kind, 'url');\n\t\tconst value = supplied[key];\n\t\tif (value === undefined) continue;\n\t\tconst host = hostOf(value);\n\t\tif (host === undefined || !LOOPBACK.has(host)) continue;\n\t\tstale.push({ key, construct: id, host });\n\t}\n\treturn stale.sort((a, b) => a.key.localeCompare(b.key));\n}\n\n/**\n * Refuse a stage whose stored secrets would shadow a construct's address with\n * `localhost`.\n *\n * @throws {StaleStageSecrets} naming each key and the command removing it\n */\nexport function assertNoStaleSecrets(options: {\n\tmanifest: ConstructManifest;\n\tstage: string;\n\tsupplied: Readonly<Record<string, string>>;\n}): void {\n\tconst stale = staleStageSecrets(options.manifest, options.supplied);\n\tif (stale.length > 0) throw new StaleStageSecrets(options.stage, stale);\n}\n","/**\n * Whether a stage is ready to be deployed: the one check, run once by every\n * deploy through a server target — after the stage's providers have created\n * what they create and written its keys, and before the target touches\n * anything.\n *\n * A build is not a deploy. Images carry no stage's keys, so a build-only run\n * (`gkm compose --build --push`) never calls this: a key the deploy itself\n * writes — a provider's bucket URL — is not there yet when CI builds, and\n * must not stop the build.\n */\n\nimport {\n\tassertStageProvidersEnabled,\n\tstageProviderNotes,\n\tverifyStageProviders,\n} from '../providers/index.js';\nimport { constructGlobs } from '../reconcile/workspace.js';\nimport { assertStageCredentials } from '../secrets/credentialSchemas.js';\nimport { assertNoStaleSecrets } from '../secrets/stale.js';\nimport type { DeployPhaseContext } from '../target/types';\nimport {\n\tdevServicesUsed,\n\tExternalServicesNotConfigured,\n\texternalServices,\n\treportDevServices,\n\tstageServiceDeclarations,\n} from './devServices';\n\n/**\n * The stage has every key it needs, read from its secrets as the providers\n * left them:\n *\n * 1. no kind it declares is one the stage set to `false`;\n * 2. its mail and storage are its own — or a dev service, where allowed,\n * reported once, loudly;\n * 3. what its providers created is still there, and its key reaches it;\n * 4. no key holds an address an older gkm stored for what a construct now\n * provides;\n * 5. each third party's credentials match their construct's schema.\n *\n * The local stage derives its mail and storage, so only 4 and 5 apply to it.\n *\n * @throws {StageProviderDisabled}\n * @throws {ExternalServicesNotConfigured} naming every missing key at once\n * @throws {StaleStageSecrets}\n * @throws {CredentialsInvalid}\n */\nexport async function assertStageReady(\n\tctx: DeployPhaseContext<unknown>,\n): Promise<void> {\n\tconst { workspace, manifest, stage } = ctx;\n\t// Read now, not before the providers ran: they just wrote keys.\n\tconst supplied = (await ctx.secrets.read())?.custom ?? {};\n\n\tif (stage !== workspace.stages.local) {\n\t\tassertStageProvidersEnabled(workspace, manifest, stage);\n\n\t\tconst domain = workspace.domains?.[stage];\n\t\tconst services = externalServices({\n\t\t\tstage,\n\t\t\tdeclarations: stageServiceDeclarations({\n\t\t\t\tmanifest,\n\t\t\t\t...(ctx.runnables ? { runnables: ctx.runnables } : {}),\n\t\t\t}),\n\t\t\tsupplied,\n\t\t\tallow: ctx.allowDevServices,\n\t\t\t...(domain ? { domain } : {}),\n\t\t\tproviders: stageProviderNotes(workspace, stage),\n\t\t});\n\t\tif (services.missing.length > 0) {\n\t\t\tthrow new ExternalServicesNotConfigured(stage, services.missing);\n\t\t}\n\t\t// Loud, every deploy — a dry run included: a deployed stage on Mailpit\n\t\t// delivers no mail, and one on MinIO keeps its files on one disk.\n\t\treportDevServices(ctx, devServicesUsed(services));\n\n\t\tconst verified = await verifyStageProviders({\n\t\t\tworkspace,\n\t\t\tmanifest,\n\t\t\tstage,\n\t\t\tsecrets: supplied,\n\t\t\t// What the providers just recorded: a key issued by this deploy.\n\t\t\tresources: (await ctx.state.read(stage))?.resources ?? {},\n\t\t\tlog: (line) => ctx.logger.info(line),\n\t\t});\n\t\tfor (const line of verified) ctx.logger.info(`✓ ${line} verified`);\n\t}\n\n\t// Set by hand wins, so every app would be handed `localhost`.\n\tassertNoStaleSecrets({ manifest, stage, supplied });\n\t// Before anything is built with one every app reading it would refuse.\n\tawait assertStageCredentials({\n\t\troot: workspace.root,\n\t\tpatterns: constructGlobs(workspace),\n\t\tmanifest,\n\t\tstage,\n\t\tsupplied,\n\t});\n}\n","/**\n * The run around a target: what every deploy does whatever it deploys\n * through.\n *\n * It loads the workspace, resolves the target, works out the apps and the\n * identity, takes the stage's lock, and calls the target's phases in order,\n * reporting each as it starts, finishes or fails. Everything that is about\n * *where* the stage goes is the target's.\n */\n\nimport { dnsCredentials, stageDnsDomains } from '../compose/dns.js';\nimport { GkmError } from '../errors';\nimport { provisionStage } from '../providers/index.js';\nimport { discover } from '../reconcile/discover.js';\nimport { constructGlobs } from '../reconcile/workspace.js';\nimport { initStageSecrets } from '../secrets/storage.js';\nimport { builtinTarget } from '../target/builtins';\nimport {\n\tparseTargetOptions,\n\ttype ResolvedTarget,\n\tresolveTarget,\n} from '../target/resolve';\nimport { deploySecrets, Redactor } from '../target/secrets';\nimport type {\n\tAnyDeployTarget,\n\tDeployPhaseContext,\n\tDeployTargetLogger,\n} from '../target/types';\nimport { resolveStageTelemetry } from '../telemetry/config';\nimport { usesTelemetry } from '../telemetry/edges';\nimport { derivedApps } from '../workspace/derive.js';\nimport { getAppBuildOrder } from '../workspace/index.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport type { CredentialProvider } from './credentials';\nimport { DevServicesNeedServerTarget } from './devServices';\nimport { type DeployEvent, type DeployPhase, eventError } from './events';\nimport { applicationName, deployIdentity } from './identity.js';\nimport { assertStageReady } from './readiness';\nimport {\n\tassertStateOutlivesRun,\n\tassertStateRoom,\n\tcreateStateStore,\n} from './StateStore.js';\nimport type { DeployResult } from './types';\n\n/** What a run deploys, once the workspace is loaded. */\nexport interface DeployRequest {\n\t/** Deployment stage (e.g., 'production', 'staging') */\n\tstage: string;\n\t/** Image tag (default: stage-timestamp) */\n\ttag?: string;\n\t/** Specific apps to deploy (default: all) */\n\tapps?: string[];\n\t/** The target to deploy through. Defaults to `deploy.default`. */\n\ttarget?: string;\n\t/** On a failed release, roll back every app rather than the failed ones. */\n\tatomic?: boolean;\n\t/**\n\t * `--allow-dev-services`: a deployed stage runs the dev service for every\n\t * bucket and mail it does not account for. Server targets only.\n\t */\n\tallowDevServices?: boolean;\n\t/** `--skip-dns`: a server target writes and checks no host's DNS. */\n\tskipDns?: boolean;\n\t/** `--rotate-keys`: each provider issues its runtime keys a successor. */\n\trotateKeys?: boolean;\n\t/** `--retire-old-keys`: delete a rotated-out key now. */\n\tretireOldKeys?: boolean;\n}\n\n/**\n * What a run is handed by whoever started it: where its events go, where it\n * gets credentials, and whether it may change anything. Nothing in a run\n * reads a terminal or exits the process — that is its caller's business.\n */\nexport interface DeployContext {\n\temit: (event: DeployEvent) => void;\n\tcredentials: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Look everything up, create, build and push nothing. */\n\tdryRun: boolean;\n\t/**\n\t * Validate and build — the target's images built, and pushed where it\n\t * pushes them — and nothing else: no lock, nothing provisioned, released,\n\t * verified or recorded. What a CI job runs before a server pulls.\n\t */\n\tbuildOnly?: boolean;\n\t/** The CLI's home, for the stage's keys. Defaults to `GKM_HOME`. */\n\thome?: string;\n\t/** Where spawned processes' output goes. Defaults to the terminal. */\n\tchildOutput?: 'inherit' | 'stderr' | 'ignore';\n\t/** The host's own targets, which win over every other by the same name. */\n\ttargets?: Record<string, AnyDeployTarget>;\n\t/**\n\t * What the run masks in what it prints. `deploy()` passes the one its\n\t * progress lines go through; a run without one masks only its events.\n\t */\n\tredactor?: Redactor;\n}\n\n/** Apps were asked for by name that the workspace does not have. */\nexport class UnknownDeployApps extends GkmError {\n\tconstructor(\n\t\treadonly apps: readonly string[],\n\t\treadonly available: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Unknown apps: ${apps.join(', ')}\\n` +\n\t\t\t\t`Available apps: ${available.join(', ')}`,\n\t\t);\n\t\tthis.name = 'UnknownDeployApps';\n\t}\n}\n\n/** Every app asked for deploys through some other target. */\nexport class NoDeployableApps extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly target: string,\n\t) {\n\t\tsuper(\n\t\t\t`No apps to deploy through \"${target}\": every selected app deploys somewhere else. Pick the target with --target, or set each app's deploy in gkm.config.ts.`,\n\t\t);\n\t\tthis.name = 'NoDeployableApps';\n\t}\n}\n\n/** A build-only run through a target with no build phase. */\nexport class TargetBuildsNothing extends GkmError {\n\tconstructor(readonly target: string) {\n\t\tsuper(\n\t\t\t`\"${target}\" has no build phase, so a build-only run would do nothing. Deploy it in full, or build through a target that builds images (compose).`,\n\t\t);\n\t\tthis.name = 'TargetBuildsNothing';\n\t}\n}\n\n/** A failed rollback, after the failure that called for it. */\nexport class RollbackFailed extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\t/** What failed first, and was being rolled back. */\n\t\treadonly failure: unknown,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Deploying through \"${target}\" failed, and so did rolling it back: ${cause instanceof Error ? cause.message : String(cause)}. The stage may be part-released; deploy again, or roll it back by hand. The first failure: ${failure instanceof Error ? failure.message : String(failure)}`,\n\t\t\t{ cause },\n\t\t);\n\t\tthis.name = 'RollbackFailed';\n\t}\n}\n\n/**\n * Generate image tag from stage and timestamp\n */\nexport function generateTag(stage: string): string {\n\tconst timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n\treturn `${stage}-${timestamp}`;\n}\n\n/** Why an app that deploys through another target is left out. */\nfunction elsewhere(target: string, stage: string): string {\n\tconst instead = builtinTarget(target)?.instead?.(stage);\n\tif (instead) return `it deploys through \"${target}\" — ${instead}`;\n\treturn `it deploys through \"${target}\" — run \\`gkm deploy --target ${target} --stage ${stage}\\``;\n}\n\n/**\n * Deploy a workspace's stage through its target.\n *\n * The engine under `deploy()` and `gkm deploy`. It never prompts and never\n * exits: credentials come from `ctx.credentials`, progress goes to\n * `ctx.emit` and to `output`, and every failure is thrown.\n *\n * @internal\n */\nexport async function runDeploy(\n\tsource: NormalizedWorkspace | (() => Promise<NormalizedWorkspace>),\n\trequest: DeployRequest,\n\tctx: DeployContext,\n): Promise<DeployResult> {\n\tconst { stage } = request;\n\tconst redactor = ctx.redactor ?? new Redactor();\n\tconst emit = (event: DeployEvent) =>\n\t\tctx.emit(\n\t\t\tevent.type === 'log'\n\t\t\t\t? { ...event, message: redactor.redact(event.message) }\n\t\t\t\t: event,\n\t\t);\n\n\t/** Run one phase between its events. */\n\tconst phase = async <T>(name: DeployPhase, body: () => Promise<T>) => {\n\t\tctx.signal?.throwIfAborted();\n\t\temit({ type: 'phase.started', phase: name });\n\t\ttry {\n\t\t\tconst value = await body();\n\t\t\temit({ type: 'phase.finished', phase: name });\n\t\t\treturn value;\n\t\t} catch (error) {\n\t\t\temit({ type: 'phase.failed', phase: name, error: eventError(error) });\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tctx.signal?.throwIfAborted();\n\temit({ type: 'phase.started', phase: 'validate' });\n\n\tlet prepared: Prepared;\n\ttry {\n\t\tprepared = await prepare(source, request, ctx, emit, redactor);\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n\tconst { resolved, phaseCtx, store } = prepared;\n\tconst { target } = resolved;\n\n\t// The stage's resources — what its providers create, and the keys they\n\t// write into its secrets — before any check reads those secrets, so a key\n\t// the deploy creates is never reported missing. A build-only run creates\n\t// nothing, and neither does the local stage.\n\tconst resources =\n\t\t!ctx.buildOnly && phaseCtx.stage !== phaseCtx.workspace.stages.local;\n\tconst provision = async () => {\n\t\t// The token the stage's DNS records are written with, asked for first:\n\t\t// a deploy without it fails before anything is created or started.\n\t\tif (!request.skipDns && resolved.target.runtime === 'server') {\n\t\t\ttry {\n\t\t\t\tawait dnsCredentials(\n\t\t\t\t\tphaseCtx.stage,\n\t\t\t\t\tstageDnsDomains(\n\t\t\t\t\t\tphaseCtx.stage,\n\t\t\t\t\t\tphaseCtx.workspace.domains,\n\t\t\t\t\t\tphaseCtx.workspace.dns,\n\t\t\t\t\t),\n\t\t\t\t\tctx.credentials,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\temit({\n\t\t\t\t\ttype: 'phase.failed',\n\t\t\t\t\tphase: 'validate',\n\t\t\t\t\terror: eventError(error),\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait provisionResources(phaseCtx, request, ctx, store, emit);\n\t};\n\n\t// A dry run takes no lock: it writes nothing a lock would protect, and it\n\t// should not stop a real deploy that starts while it is looking.\n\tif (ctx.dryRun) {\n\t\tif (resources) await provision();\n\t\tconst run = await validate(phaseCtx, emit, () =>\n\t\t\treadyToDeploy(target, phaseCtx),\n\t\t);\n\t\tawait phase('plan', () => target.plan(phaseCtx, run));\n\t\treturn target.result(phaseCtx, run);\n\t}\n\n\t// Building changes no stage — nothing is provisioned, released or\n\t// recorded — so it takes no lock: a CI job building the next release must\n\t// not fail because a server is deploying the last one. Nor is the stage\n\t// asked whether it is ready to be deployed: an image carries none of its\n\t// keys, and a key the deploy writes is not there until the deploy runs.\n\tif (ctx.buildOnly) {\n\t\tif (!target.build) throw new TargetBuildsNothing(resolved.name);\n\t\tconst run = await validate(phaseCtx, emit, () => target.validate(phaseCtx));\n\t\tawait phase('build', () => target.build!(phaseCtx, run));\n\t\treturn target.result(phaseCtx, run);\n\t}\n\n\t// One deploy of a stage at a time. Taken before the target generates,\n\t// provisions or records anything, and held until the run ends however it\n\t// ends. A second run of the stage — another CI job, a laptop — gets\n\t// `StateLocked` naming this one instead of racing it; a run killed with\n\t// the lock held is released with `gkm state:unlock`.\n\tlet lock: Awaited<ReturnType<typeof store.lock>>;\n\ttry {\n\t\t// A CI runner's disk is gone when the job ends; state kept on it is\n\t\t// lost with it, and the next run recreates every resource.\n\t\tassertStateOutlivesRun(phaseCtx.workspace, stage, 'deploy');\n\t\tlock = await store.lock(stage, { operation: 'deploy' });\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n\n\ttry {\n\t\t// The state this run will write fits where it is kept — checked before\n\t\t// anything is created or started, not found out at the last write,\n\t\t// with the stack already running and nowhere to record it.\n\t\ttry {\n\t\t\tawait assertStateRoom(store, stage);\n\t\t} catch (error) {\n\t\t\temit({\n\t\t\t\ttype: 'phase.failed',\n\t\t\t\tphase: 'validate',\n\t\t\t\terror: eventError(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t\tif (resources) await provision();\n\t\tconst run = await validate(phaseCtx, emit, () =>\n\t\t\treadyToDeploy(target, phaseCtx),\n\t\t);\n\t\tif (target.provision) {\n\t\t\tawait phase('provision', () => target.provision!(phaseCtx, run));\n\t\t}\n\t\tif (target.build) {\n\t\t\tawait phase('build', () => target.build!(phaseCtx, run));\n\t\t}\n\n\t\tlet releasing: 'release' | 'verify' = 'release';\n\t\ttry {\n\t\t\tawait phase('release', () => target.release(phaseCtx, run));\n\t\t\treleasing = 'verify';\n\t\t\tif (target.verify) {\n\t\t\t\tawait phase('verify', () => target.verify!(phaseCtx, run));\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// The caller stopping the run is not a release to undo.\n\t\t\tif (ctx.signal?.aborted || !target.capabilities.rollback) throw error;\n\t\t\tif (!target.rollback) throw error;\n\t\t\ttry {\n\t\t\t\tawait phase('rollback', () =>\n\t\t\t\t\ttarget.rollback!(phaseCtx, run, { phase: releasing, error }),\n\t\t\t\t);\n\t\t\t} catch (rollbackError) {\n\t\t\t\tthrow new RollbackFailed(resolved.name, error, rollbackError);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn await target.result(phaseCtx, run);\n\t} finally {\n\t\tawait lock.release();\n\t}\n}\n\n/**\n * The stage's providers, run inside the validate phase. A dry run plans them\n * and, so the checks after it see the stage as the run would leave it, reads\n * the keys they would write as placeholders.\n */\nasync function provisionResources(\n\tphaseCtx: DeployPhaseContext<unknown>,\n\trequest: DeployRequest,\n\tctx: DeployContext,\n\tstore: Awaited<ReturnType<typeof createStateStore>>,\n\temit: (event: DeployEvent) => void,\n): Promise<void> {\n\ttry {\n\t\tconst reports = await provisionStage({\n\t\t\tworkspace: phaseCtx.workspace,\n\t\t\tstage: phaseCtx.stage,\n\t\t\tmanifest: phaseCtx.manifest,\n\t\t\trunnables: (phaseCtx.runnables ?? {}) as Record<string, string[]>,\n\t\t\tsecrets: phaseCtx.secrets,\n\t\t\tstate: store,\n\t\t\tdryRun: ctx.dryRun,\n\t\t\t...(request.rotateKeys ? { rotateKeys: true } : {}),\n\t\t\t...(request.retireOldKeys ? { retireOldKeys: true } : {}),\n\t\t\t...(ctx.home ? { home: ctx.home } : {}),\n\t\t\tlog: (line) => phaseCtx.logger.info(line),\n\t\t});\n\t\tif (!ctx.dryRun) return;\n\t\tconst planned = reports.flatMap((r) => r.planned);\n\t\tif (planned.length === 0) return;\n\t\tconst secrets = phaseCtx.secrets;\n\t\t(phaseCtx as { secrets: typeof secrets }).secrets = {\n\t\t\t...secrets,\n\t\t\tasync read() {\n\t\t\t\tconst stored =\n\t\t\t\t\t(await secrets.read()) ?? initStageSecrets(phaseCtx.stage);\n\t\t\t\tconst custom = { ...stored.custom };\n\t\t\t\tfor (const key of planned) custom[key] ??= PLANNED_BY_THE_DEPLOY;\n\t\t\t\treturn { ...stored, custom };\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n}\n\n/** What a dry run reads for a key its providers would write. */\nexport const PLANNED_BY_THE_DEPLOY = 's3://planned-by-this-deploy';\n\n/**\n * What a deploy validates: the stage ready to be deployed — every key it\n * needs, read as its providers left them — then what the target would run,\n * then whatever only the target checks. A build-only run validates the\n * target's run alone: it calls neither readiness check.\n */\nasync function readyToDeploy(\n\ttarget: AnyDeployTarget,\n\tphaseCtx: DeployPhaseContext<unknown>,\n): Promise<unknown> {\n\t// The rules are a stack's, built from the stage's secrets: a target that\n\t// runs none — AWS — has its stage's keys from its own tool.\n\tif (target.runtime === 'server') await assertStageReady(phaseCtx);\n\tconst run = await target.validate(phaseCtx);\n\tawait target.ready?.(phaseCtx, run);\n\treturn run;\n}\n\n/** `body`, then the run's `deploy.started`, inside the validate phase. */\nasync function validate(\n\tphaseCtx: DeployPhaseContext<unknown>,\n\temit: (event: DeployEvent) => void,\n\tbody: () => Promise<unknown>,\n): Promise<unknown> {\n\ttry {\n\t\tconst run = await body();\n\t\tconst skipped = new Set(phaseCtx.skipped.map((s) => s.app));\n\t\temit({\n\t\t\ttype: 'deploy.started',\n\t\t\tstage: phaseCtx.stage,\n\t\t\ttarget: phaseCtx.target,\n\t\t\tidentity: phaseCtx.identity.key,\n\t\t\ttag: phaseCtx.tag,\n\t\t\tapps: phaseCtx.apps.filter((app) => !skipped.has(app)),\n\t\t\tdryRun: phaseCtx.dryRun,\n\t\t});\n\t\temit({ type: 'phase.finished', phase: 'validate' });\n\t\treturn run;\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n}\n\ninterface Prepared {\n\tresolved: ResolvedTarget;\n\tphaseCtx: DeployPhaseContext<unknown>;\n\tstore: Awaited<ReturnType<typeof createStateStore>>;\n}\n\n/** Everything the phases are handed, worked out before the first of them. */\nasync function prepare(\n\tsource: NormalizedWorkspace | (() => Promise<NormalizedWorkspace>),\n\trequest: DeployRequest,\n\tctx: DeployContext,\n\temit: (event: DeployEvent) => void,\n\tredactor: Redactor,\n): Promise<Prepared> {\n\tconst { stage } = request;\n\tconst configured = typeof source === 'function' ? await source() : source;\n\n\t// Before anything is provisioned: a typo'd stage would otherwise create a\n\t// whole second environment under the wrong name. The local stage is left\n\t// to the target, which says whether it can run it.\n\tconst local = stage === configured.stages.local;\n\tif (!local) assertDeployedStage(configured.stages, stage);\n\n\t// Before anything is discovered or derived: a target that cannot be found\n\t// — or a package that would not load — fails a deploy that has done\n\t// nothing yet.\n\tconst targetName = request.target ?? configured.deploy?.default ?? 'dokploy';\n\tconst resolved = await resolveTarget(targetName, {\n\t\tworkspace: configured,\n\t\tstage,\n\t\t...(ctx.targets ? { host: ctx.targets } : {}),\n\t});\n\tif (local && !resolved.target.capabilities.localStage) {\n\t\tassertDeployedStage(configured.stages, stage);\n\t}\n\tconst options = await parseTargetOptions(resolved);\n\n\t// Before anything is discovered: dev services asked of a target that runs\n\t// no containers fail a deploy that has done nothing.\n\tconst allowDevServices = request.allowDevServices === true;\n\tif (allowDevServices && resolved.target.runtime === 'aws') {\n\t\tthrow new DevServicesNeedServerTarget(targetName);\n\t}\n\n\t// What to deploy comes from the manifest.\n\t//\n\t// Discovered here rather than by the target, because the list of things\n\t// to deploy is the *declarations* — one `rest-api` is one server, one\n\t// `site` is one site — and the config only says how to run each. A project\n\t// that declares no surfaces keeps its configured apps, so adopting\n\t// constructs stays something you do a piece at a time.\n\tconst runnables: Record<string, string[]> = {};\n\tconst background: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(configured),\n\t\tcwd: configured.root,\n\t\trunnables,\n\t\tbackground,\n\t});\n\t// Where the stage's telemetry goes, settled before anything is built: a\n\t// stage that uses a `Telemetry` node on a target that cannot choose for it\n\t// — AWS has no self-hosted provider — fails here, naming the config.\n\tresolveStageTelemetry({\n\t\t...(configured.deploy?.telemetry\n\t\t\t? { telemetry: configured.deploy.telemetry }\n\t\t\t: {}),\n\t\tstage,\n\t\tlocal,\n\t\ttarget: targetName,\n\t\truntime: resolved.target.runtime,\n\t\tselfHosted: resolved.target.capabilities.selfHostedTelemetry === true,\n\t\tused: usesTelemetry(manifest),\n\t});\n\n\tconst units = derivedApps(manifest, configured);\n\tconst workspace: NormalizedWorkspace =\n\t\tObject.keys(units).length > 0 ? { ...configured, apps: units } : configured;\n\n\t// What every resource this deploy touches is named and claimed by —\n\t// resolved first, so a namespace that cannot be a name fails before\n\t// anything is built.\n\tconst identity = deployIdentity(workspace, stage);\n\tconst tag =\n\t\trequest.tag ??\n\t\t(resolved.target.tag\n\t\t\t? await resolved.target.tag({ cwd: workspace.root, stage })\n\t\t\t: generateTag(stage));\n\n\t// The apps asked for, in dependency order.\n\tconst buildOrder = getAppBuildOrder(workspace);\n\tlet selected = buildOrder;\n\tif (request.apps && request.apps.length > 0) {\n\t\tconst unknown = request.apps.filter((name) => !workspace.apps[name]);\n\t\tif (unknown.length > 0) {\n\t\t\tthrow new UnknownDeployApps(unknown, Object.keys(workspace.apps));\n\t\t}\n\t\tselected = buildOrder.filter((name) => request.apps!.includes(name));\n\t}\n\n\tconst skipped: { app: string; reason: string }[] = [];\n\tconst skip = (app: string, reason: string) => {\n\t\tskipped.push({ app, reason });\n\t\temit({ type: 'app.skipped', app, reason });\n\t};\n\n\t// An app that names another target deploys there, in a run of its own.\n\t// One on the default follows the run, so `--target` moves the stage\n\t// without every app having to be told.\n\tconst byDefault = configured.deploy?.default ?? 'dokploy';\n\tconst apps = selected.filter((name) => {\n\t\tconst own = workspace.apps[name]!.resolvedDeployTarget;\n\t\tconst deploysThrough = own === byDefault ? targetName : own;\n\t\tif (deploysThrough === targetName) return true;\n\t\tskip(name, elsewhere(deploysThrough, stage));\n\t\treturn false;\n\t});\n\tif (apps.length === 0) throw new NoDeployableApps(stage, targetName);\n\n\tconst store = await createStateStore({\n\t\tconfig: workspace.state,\n\t\tworkspaceRoot: workspace.root,\n\t\tworkspaceName: workspace.name,\n\t\tnamespace: workspace.deploy?.namespace,\n\t});\n\tconst secrets = await deploySecrets(workspace, stage, redactor, {\n\t\t...(ctx.home ? { home: ctx.home } : {}),\n\t});\n\n\tconst line =\n\t\t(level: 'info' | 'warn' | 'error') =>\n\t\t(message: string): void =>\n\t\t\temit({ type: 'log', level, message });\n\tconst logger: DeployTargetLogger = {\n\t\tinfo: line('info'),\n\t\twarn: line('warn'),\n\t\terror: line('error'),\n\t};\n\n\tconst phaseCtx: DeployPhaseContext<unknown> = {\n\t\ttarget: targetName,\n\t\tcwd: workspace.root,\n\t\tstage,\n\t\ttag,\n\t\ttagGiven: request.tag !== undefined,\n\t\tapps,\n\t\tskipped,\n\t\tidentity,\n\t\tworkspace,\n\t\tmanifest,\n\t\trunnables,\n\t\tbackground,\n\t\toptions,\n\t\tdryRun: ctx.dryRun,\n\t\tatomic: request.atomic ?? false,\n\t\tallowDevServices,\n\t\t...(request.skipDns ? { skipDns: true } : {}),\n\t\tcredentials: ctx.credentials,\n\t\tstate: store,\n\t\tsecrets,\n\t\tlogger,\n\t\tsignal: ctx.signal ?? new AbortController().signal,\n\t\tchildOutput: ctx.childOutput ?? 'inherit',\n\t\temit,\n\t\tskip,\n\t\tname: (resource) => applicationName(identity, resource),\n\t};\n\n\treturn { resolved, phaseCtx, store };\n}\n","/**\n * `deploy()`: a deploy as a library call.\n *\n * `gkm deploy` could only be driven from an interactive terminal: it prompted\n * for what it lacked and exited the process on failure, worked out of\n * `process.cwd()`, and reported progress by printing. Here the caller says\n * where the project is, hands over the credentials and a signal, and gets back\n * a run — events to iterate while it goes, and a structured result at the end.\n * Nothing below this asks a person anything or ends the process; `gkm deploy`\n * is a thin wrapper that does both.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../config';\nimport { gkmHome } from '../home';\nimport { type OutputLevel, withOutput } from '../output';\nimport { LocalSandbox } from '../sandbox/local';\nimport { type Sandbox, withSandbox } from '../sandbox/sandbox';\nimport { Redactor } from '../target/secrets';\nimport type { AnyDeployTarget } from '../target/types';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport { type CredentialProvider, storedCredentials } from './credentials';\nimport { type DeployEvent, eventError } from './events';\nimport { type DeployContext, runDeploy } from './orchestrate';\nimport type { DeployResult } from './types';\n\n/**\n * Where a run's progress lines go, besides its events. `@geekmidas/logger`'s\n * `Logger` is one.\n */\nexport interface DeployLogger {\n\tinfo(message: string): void;\n\twarn(message: string): void;\n\terror?(message: string): void;\n}\n\nexport interface DeployInput {\n\t/**\n\t * The project to deploy: the directory holding `gkm.config.ts`, or any\n\t * directory inside it. Never assumed to be `process.cwd()`.\n\t */\n\tcwd: string;\n\t/**\n\t * The stage to deploy — one of the config's deployed stages, or its local\n\t * stage through a target that runs one (`compose`).\n\t */\n\tstage: string;\n\t/**\n\t * The target to deploy through, by name. Defaults to `deploy.default`,\n\t * else `dokploy`.\n\t */\n\ttarget?: string;\n\t/**\n\t * The host's own targets, by name. Consulted before the built-ins and the\n\t * config's `deploy.targets`, so a host can deploy through an\n\t * implementation of its own — `{ dokploy: myDokploy }` included.\n\t */\n\ttargets?: Record<string, AnyDeployTarget>;\n\t/** The image tag. Defaults to `<stage>-<timestamp>`. */\n\ttag?: string;\n\t/** Deploy only these apps (in dependency order). Defaults to all. */\n\tapps?: string[];\n\t/**\n\t * Look everything up and report what would happen — as `resource.planned`\n\t * events — without taking the lock, writing state, generating secrets,\n\t * changing Dokploy or building and pushing images.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * Validate and build only: the target's images built — and pushed, where\n\t * it pushes them — with no lock taken and nothing provisioned, released,\n\t * verified or recorded. `gkm compose --build --push` runs this way.\n\t */\n\tbuildOnly?: boolean;\n\t/**\n\t * When a release or its verification fails, roll back every app the run\n\t * released rather than only the ones that failed — on a target that can\n\t * roll back. For apps that must move together.\n\t */\n\tatomic?: boolean;\n\t/**\n\t * Where credentials come from. Defaults to the environment, then the\n\t * logins `gkm login` stored. A credential no provider has stops the run\n\t * with `MissingCredential`; nothing prompts.\n\t */\n\tcredentials?: CredentialProvider;\n\t/**\n\t * On a server target, run a dev service for every construct a deployed\n\t * stage does not account for — no key in its secrets, and no provider\n\t * (`deploy.objects`) backing its kind: MinIO for a bucket, Mailpit for\n\t * mail. Neither is production-grade — Mailpit delivers no mail — and every\n\t * run that uses one emits `dev-service.used`. Without it, a deployed stage\n\t * missing a mail or storage key fails with `ExternalServicesNotConfigured`;\n\t * on an AWS target it fails with `DevServicesNeedServerTarget`.\n\t */\n\tallowDevServices?: boolean;\n\t/**\n\t * On a server target, neither write the public hosts' DNS records nor\n\t * check that they point at the stage's server (`GKM_SERVER_IPV4`) — for a\n\t * CDN or proxy in front of the server, or records written by another step.\n\t */\n\tskipDns?: boolean;\n\t/** Each provider issues its runtime keys a successor. */\n\trotateKeys?: boolean;\n\t/** Delete a rotated-out key now, not after the next deploy. */\n\tretireOldKeys?: boolean;\n\t/** Receives each progress line as it is written. Defaults to none. */\n\tlogger?: DeployLogger;\n\t/**\n\t * Stops the run: in-flight Dokploy requests and docker children are\n\t * cancelled, the stage's lock is released, and `result` rejects with the\n\t * signal's reason.\n\t */\n\tsignal?: AbortSignal;\n\t/**\n\t * The CLI's home: stage keys and stored logins. Defaults to `GKM_HOME`,\n\t * else `~/.gkm`.\n\t */\n\thome?: string;\n\t/**\n\t * Where docker's own output goes: the host's terminal (`inherit`, the\n\t * default), its stderr, or nowhere.\n\t */\n\tchildOutput?: 'inherit' | 'stderr' | 'ignore';\n\t/**\n\t * Where the project's own code runs: loading `gkm.config.ts`, discovering\n\t * its constructs, sniffing each app's environment. Defaults to a\n\t * `LocalSandbox` on the project — a child process here with an\n\t * allowlisted environment, for a project the host trusts.\n\t *\n\t * A host deploying repositories it does not trust passes one that\n\t * isolates — a container per build — and the config then reaches the\n\t * deploy only as data. Credentials never enter a sandbox: they go from\n\t * `credentials` to the steps that provision, push and release.\n\t */\n\tsandbox?: Sandbox;\n}\n\n/** A deploy in progress. */\nexport interface DeployRun extends AsyncIterable<DeployEvent> {\n\t/**\n\t * What the deploy did, once it is done. Rejects with the error that\n\t * stopped it — `MissingCredential`, `StateLocked`, `ProjectNotOwned`, … —\n\t * after a `deploy.failed` event carrying the same.\n\t */\n\treadonly result: Promise<DeployResult>;\n}\n\n/**\n * Every event a run emits, kept so that each iteration — however late it\n * starts — sees the run from its first event to its last.\n */\nclass EventLog {\n\tprivate readonly events: DeployEvent[] = [];\n\tprivate closed = false;\n\tprivate waiting: (() => void)[] = [];\n\n\tpush(event: DeployEvent): void {\n\t\tthis.events.push(event);\n\t\tthis.wake();\n\t}\n\n\tclose(): void {\n\t\tthis.closed = true;\n\t\tthis.wake();\n\t}\n\n\tprivate wake(): void {\n\t\tconst waiting = this.waiting;\n\t\tthis.waiting = [];\n\t\tfor (const resume of waiting) resume();\n\t}\n\n\tasync *iterate(): AsyncGenerator<DeployEvent> {\n\t\tlet next = 0;\n\t\twhile (true) {\n\t\t\tif (next < this.events.length) {\n\t\t\t\tyield this.events[next++]!;\n\t\t\t} else if (this.closed) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tawait new Promise<void>((resume) => this.waiting.push(resume));\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction forward(\n\tlogger: DeployLogger | undefined,\n\tlevel: OutputLevel,\n\tmessage: string,\n): void {\n\tif (!logger) return;\n\tif (level === 'info') logger.info(message);\n\telse if (level === 'error' && logger.error) logger.error(message);\n\telse logger.warn(message);\n}\n\n/**\n * Deploy a project's stage.\n *\n * ```ts\n * import { deploy } from '@geekmidas/cli/deploy';\n *\n * const run = deploy({ cwd: '/srv/checkouts/shop', stage: 'production' });\n * for await (const event of run) {\n * if (event.type === 'app.deployed') console.log(event.app, event.url);\n * }\n * const result = await run.result;\n * ```\n *\n * The run starts at once; iterating it is optional, and an iteration started\n * late still sees every event from the first.\n */\nexport function deploy(input: DeployInput): DeployRun {\n\tconst log = new EventLog();\n\t// Every secret the run reads is masked in every line it reports — in the\n\t// events and in what the logger is handed.\n\tconst redactor = new Redactor();\n\tconst emit = (event: DeployEvent) => {\n\t\tconst masked =\n\t\t\tevent.type === 'log'\n\t\t\t\t? { ...event, message: redactor.redact(event.message) }\n\t\t\t\t: event;\n\t\tlog.push(masked);\n\t\tif (masked.type === 'log') {\n\t\t\tforward(input.logger, masked.level, masked.message);\n\t\t}\n\t};\n\n\tconst ctx: DeployContext = {\n\t\temit,\n\t\tcredentials:\n\t\t\tinput.credentials ?? storedCredentials({ home: input.home ?? gkmHome() }),\n\t\tdryRun: input.dryRun ?? false,\n\t\t...(input.buildOnly ? { buildOnly: true } : {}),\n\t\thome: input.home ?? gkmHome(),\n\t\tredactor,\n\t\t...(input.signal ? { signal: input.signal } : {}),\n\t\t...(input.childOutput ? { childOutput: input.childOutput } : {}),\n\t\t...(input.targets ? { targets: input.targets } : {}),\n\t};\n\n\t// Every line anything in the run writes through `output` — the deploy's\n\t// own, the Dockerfile generator's, discovery's warnings — becomes an event\n\t// of this run, and of no other.\n\tconst result = withOutput(\n\t\t(level, message) => emit({ type: 'log', level, message }),\n\t\tasync () => {\n\t\t\ttry {\n\t\t\t\tinput.signal?.throwIfAborted();\n\t\t\t\tconst sandbox =\n\t\t\t\t\tinput.sandbox ??\n\t\t\t\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\t\t\t\t// Every step of the run that executes the project's code — the\n\t\t\t\t// engine's own discoveries and sniffs included — runs in it.\n\t\t\t\tconst deployed = await withSandbox(sandbox, () =>\n\t\t\t\t\trunDeploy(\n\t\t\t\t\t\t() => load(input, sandbox),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstage: input.stage,\n\t\t\t\t\t\t\t...(input.target ? { target: input.target } : {}),\n\t\t\t\t\t\t\t...(input.tag ? { tag: input.tag } : {}),\n\t\t\t\t\t\t\t...(input.apps ? { apps: input.apps } : {}),\n\t\t\t\t\t\t\t...(input.atomic ? { atomic: true } : {}),\n\t\t\t\t\t\t\t...(input.allowDevServices\n\t\t\t\t\t\t\t\t? { allowDevServices: input.allowDevServices }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(input.skipDns ? { skipDns: true } : {}),\n\t\t\t\t\t\t\t...(input.rotateKeys ? { rotateKeys: true } : {}),\n\t\t\t\t\t\t\t...(input.retireOldKeys ? { retireOldKeys: true } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tctx,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\temit({ type: 'deploy.finished', result: deployed });\n\t\t\t\treturn deployed;\n\t\t\t} catch (error) {\n\t\t\t\temit({ type: 'deploy.failed', error: eventError(error) });\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tlog.close();\n\t\t\t}\n\t\t},\n\t);\n\n\t// A caller that only iterates still learns of the failure from the\n\t// `deploy.failed` event; the rejection must not also crash its process as\n\t// unhandled. Awaiting `result` still rejects.\n\tresult.catch(() => {});\n\n\treturn {\n\t\tresult,\n\t\t[Symbol.asyncIterator]: () => log.iterate(),\n\t};\n}\n\n/**\n * The workspace at `input.cwd`. The stage is checked by the run, once it\n * knows the target: one that runs on this machine may take the local stage.\n */\nasync function load(\n\tinput: DeployInput,\n\tsandbox: Sandbox,\n): Promise<NormalizedWorkspace> {\n\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\tsandbox,\n\t});\n\treturn workspace;\n}\n"],"mappings":"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"}
@@ -4,15 +4,15 @@ import { r as storedCredentials } from "./credentials-B5N5yKk6.mjs";
4
4
  import { f as withOutput, r as discover } from "./discover-qjFapetL.mjs";
5
5
  import { c as withSandbox } from "./sandbox-CbVB7uOD.mjs";
6
6
  import { n as derivedApps, t as appKey } from "./derive-B4vDpzgP.mjs";
7
- import { $ as IamUserNotOwned, G as checkS3Config, J as BucketNameUnavailable, K as AccessKeyLimit, L as resolveStageTelemetry, N as assertDeployedStage, Q as BucketRegionUnknown, U as stageProvider, W as S3_PROVISIONING, X as BucketProbeFailed, Y as BucketOwnedByAnotherProject, Z as BucketRegionMismatch, et as ProvisionedBucketUnreachable, nt as RotationInProgress, q as BucketKeySetElsewhere, rt as S3RegionRequired, tt as RecordedBucketUnreachable, u as getAppBuildOrder } from "./workspace-Bv4xROeu.mjs";
7
+ import { $ as IamUserNotOwned, G as checkS3Config, J as BucketNameUnavailable, K as AccessKeyLimit, L as resolveStageTelemetry, N as assertDeployedStage, Q as BucketRegionUnknown, U as stageProvider, W as S3_PROVISIONING, X as BucketProbeFailed, Y as BucketOwnedByAnotherProject, Z as BucketRegionMismatch, et as ProvisionedBucketUnreachable, nt as RotationInProgress, q as BucketKeySetElsewhere, rt as S3RegionRequired, tt as RecordedBucketUnreachable, u as getAppBuildOrder, ut as isReservedStageKey } from "./workspace-D5CpOp1y.mjs";
8
8
  import { o as builtinTarget } from "./define-6poNqm5O.mjs";
9
9
  import { findWorkspaceRoot, loadWorkspaceConfig } from "./config.mjs";
10
- import { E as reportDevServices, F as DeployJournal, H as createComposeState, In as applicationName, It as appEnvKeys, Ln as deployIdentity, N as stageProviderNotes, O as stageServiceDeclarations, On as secretsStoreFor, P as PROVIDER_KINDS, T as externalServices, U as createEmptyState, Wn as initStageSecrets, b as DevServicesNeedServerTarget, ct as constructGlobs, fn as usesTelemetry, j as assertStageProvidersEnabled, nr as isMainFrontendApp, rr as resolveHost, tr as NoDomainForStage, w as devServicesUsed, x as ExternalServicesNotConfigured } from "./seeds-BsJRUL1K.mjs";
11
- import { a as parseTargetOptions, o as resolveTarget } from "./resolve-6EYNqYdr.mjs";
10
+ import { E as reportDevServices, F as DeployJournal, H as createComposeState, In as initStageSecrets, It as appEnvKeys, Jn as isMainFrontendApp, N as stageProviderNotes, O as stageServiceDeclarations, On as secretsStoreFor, P as PROVIDER_KINDS, T as externalServices, U as createEmptyState, Yn as resolveHost, b as DevServicesNeedServerTarget, ct as constructGlobs, fn as usesTelemetry, j as assertStageProvidersEnabled, qn as NoDomainForStage, w as devServicesUsed, x as ExternalServicesNotConfigured } from "./seeds-C4bZ8L-T.mjs";
11
+ import { n as deployIdentity, t as applicationName } from "./identity-CBXr4wNi.mjs";
12
+ import { a as parseTargetOptions, o as resolveTarget } from "./resolve-CNYbGH8g.mjs";
12
13
  import { t as LocalSandbox } from "./local-BwC2v2Y8.mjs";
13
- import { E as eventError, S as createStateStore, v as assertStateOutlivesRun, y as assertStateRoom } from "./sniffer-DVsvP8s-.mjs";
14
- import { c as stageDnsDomains, n as dnsCredentials } from "./dns-BbTOzmVp.mjs";
15
- import { t as deploysWithCompose } from "./dns-Bmbhmz41.mjs";
14
+ import { E as eventError, S as createStateStore, v as assertStateOutlivesRun, y as assertStateRoom } from "./sniffer-BIBm9dAb.mjs";
15
+ import { c as stageDnsDomains, n as dnsCredentials } from "./dns-C_LPS3qV.mjs";
16
16
  import { n as assertStageCredentials } from "./credentialSchemas-BJFvfkaz.mjs";
17
17
  import { resolve } from "node:path";
18
18
  import { dependentsOf, kebabCase, provideKey, providedKeyFor } from "@geekmidas/manifest";
@@ -48,7 +48,7 @@ var Redactor = class {
48
48
  function secretValues(secrets) {
49
49
  return [
50
50
  secrets.seed,
51
- ...Object.values(secrets.custom ?? {}),
51
+ ...Object.entries(secrets.custom ?? {}).filter(([key]) => !isReservedStageKey(key)).map(([, value]) => value),
52
52
  ...Object.values(secrets.urls ?? {}),
53
53
  ...Object.values(secrets.services ?? {}).map((service) => service?.password)
54
54
  ].filter((value) => typeof value === "string");
@@ -78,6 +78,12 @@ async function deploySecrets(workspace, stage, redactor, options = {}) {
78
78
  };
79
79
  }
80
80
  //#endregion
81
+ //#region src/providers/dns.ts
82
+ /** Whether the workspace deploys through the compose target. */
83
+ function deploysWithCompose(workspace) {
84
+ return workspace.deploy?.default === "compose" || Object.values(workspace.apps).some((app) => app.resolvedDeployTarget === "compose");
85
+ }
86
+ //#endregion
81
87
  //#region src/providers/aws.ts
82
88
  /**
83
89
  * The AWS account a provider provisions in — the stage's, found the way the
@@ -1132,7 +1138,7 @@ var ProviderCredentialsMissing = class extends GkmError {
1132
1138
  describe;
1133
1139
  login;
1134
1140
  constructor(stage, kind, provider, ids, env, describe, login) {
1135
- super(`deploy.${kind}.${stage} is ${provider}, so the deploy creates what ${ids.join(", ")} ${ids.length === 1 ? "is" : "are"} backed by on '${stage}' and writes ${ids.length === 1 ? "its key" : "their keys"} into the stage's secrets — and it found no ${provider} credentials to do it with. On this machine, supply ${describe}` + (login ? `, or run gkm login --provider ${login}` : "") + `. In CI, the step that runs the deploy (or gkm deploy --resources-only) needs them: the '${stage}' environment's role (AWS_ROLE_ARN, from gkm deploy:github), assumed before that step. With the keys set by hand instead, set deploy.${kind}.${stage} to 'external'.`);
1141
+ super(`deploy.${kind}.${stage} is ${provider}, so the deploy creates what ${ids.join(", ")} ${ids.length === 1 ? "is" : "are"} backed by on '${stage}' and writes ${ids.length === 1 ? "its key" : "their keys"} into the stage's secrets — and it found no ${provider} credentials to do it with. On this machine, supply ${describe}` + (login ? `, or run gkm login --provider ${login}` : "") + `. In CI, the step that runs the deploy needs them: the '${stage}' environment's role (AWS_ROLE_ARN, from gkm deploy:github), assumed before that step. With the keys set by hand instead, set deploy.${kind}.${stage} to 'external'.`);
1136
1142
  this.stage = stage;
1137
1143
  this.kind = kind;
1138
1144
  this.provider = provider;
@@ -1437,13 +1443,6 @@ async function assertStageReady(ctx) {
1437
1443
  * reporting each as it starts, finishes or fails. Everything that is about
1438
1444
  * *where* the stage goes is the target's.
1439
1445
  */
1440
- /** `--resources-only` with `--skip-resources`: the one asks for what the other skips. */
1441
- var ResourcesOnlyAndSkipped = class extends GkmError {
1442
- constructor() {
1443
- super("--resources-only creates the stage's resources and nothing else, and --skip-resources deploys without creating them. Run the first where the cloud credentials are (a CI runner), then the second where the stack runs.");
1444
- this.name = "ResourcesOnlyAndSkipped";
1445
- }
1446
- };
1447
1446
  /** Apps were asked for by name that the workspace does not have. */
1448
1447
  var UnknownDeployApps = class extends GkmError {
1449
1448
  apps;
@@ -1555,7 +1554,7 @@ async function runDeploy(source, request, ctx) {
1555
1554
  }
1556
1555
  const { resolved, phaseCtx, store } = prepared;
1557
1556
  const { target } = resolved;
1558
- const resources = !ctx.buildOnly && !request.skipResources && phaseCtx.stage !== phaseCtx.workspace.stages.local;
1557
+ const resources = !ctx.buildOnly && phaseCtx.stage !== phaseCtx.workspace.stages.local;
1559
1558
  const provision = async () => {
1560
1559
  if (!request.skipDns && resolved.target.runtime === "server") try {
1561
1560
  await dnsCredentials(phaseCtx.stage, stageDnsDomains(phaseCtx.stage, phaseCtx.workspace.domains, phaseCtx.workspace.dns), ctx.credentials);
@@ -1571,7 +1570,6 @@ async function runDeploy(source, request, ctx) {
1571
1570
  };
1572
1571
  if (ctx.dryRun) {
1573
1572
  if (resources) await provision();
1574
- if (request.resourcesOnly) return resourcesOnly(target, phaseCtx, emit);
1575
1573
  const run = await validate(phaseCtx, emit, () => readyToDeploy(target, phaseCtx));
1576
1574
  await phase("plan", () => target.plan(phaseCtx, run));
1577
1575
  return target.result(phaseCtx, run);
@@ -1606,7 +1604,6 @@ async function runDeploy(source, request, ctx) {
1606
1604
  throw error;
1607
1605
  }
1608
1606
  if (resources) await provision();
1609
- if (request.resourcesOnly) return resourcesOnly(target, phaseCtx, emit);
1610
1607
  const run = await validate(phaseCtx, emit, () => readyToDeploy(target, phaseCtx));
1611
1608
  if (target.provision) await phase("provision", () => target.provision(phaseCtx, run));
1612
1609
  if (target.build) await phase("build", () => target.build(phaseCtx, run));
@@ -1680,41 +1677,6 @@ async function provisionResources(phaseCtx, request, ctx, store, emit) {
1680
1677
  }
1681
1678
  /** What a dry run reads for a key its providers would write. */
1682
1679
  const PLANNED_BY_THE_DEPLOY = "s3://planned-by-this-deploy";
1683
- /** `--resources-only`: the target's own resources, and nothing else. */
1684
- async function resourcesOnly(target, phaseCtx, emit) {
1685
- try {
1686
- if (target.resources) await target.resources(phaseCtx);
1687
- } catch (error) {
1688
- emit({
1689
- type: "phase.failed",
1690
- phase: "validate",
1691
- error: eventError(error)
1692
- });
1693
- throw error;
1694
- }
1695
- emit({
1696
- type: "phase.finished",
1697
- phase: "validate"
1698
- });
1699
- return resourcesResult(phaseCtx);
1700
- }
1701
- /** A `--resources-only` run: no app was deployed. */
1702
- function resourcesResult(phaseCtx) {
1703
- return {
1704
- apps: [],
1705
- projectId: "",
1706
- successCount: 0,
1707
- failedCount: 0,
1708
- stage: phaseCtx.stage,
1709
- identity: phaseCtx.identity.key,
1710
- tag: phaseCtx.tag,
1711
- dryRun: phaseCtx.dryRun,
1712
- environmentId: "",
1713
- skipped: [...phaseCtx.skipped],
1714
- urls: {},
1715
- changes: []
1716
- };
1717
- }
1718
1680
  /**
1719
1681
  * What a deploy validates: the stage ready to be deployed — every key it
1720
1682
  * needs, read as its providers left them — then what the target would run,
@@ -1758,7 +1720,6 @@ async function validate(phaseCtx, emit, body) {
1758
1720
  /** Everything the phases are handed, worked out before the first of them. */
1759
1721
  async function prepare(source, request, ctx, emit, redactor) {
1760
1722
  const { stage } = request;
1761
- if (request.resourcesOnly && request.skipResources) throw new ResourcesOnlyAndSkipped();
1762
1723
  const configured = typeof source === "function" ? await source() : source;
1763
1724
  const local = stage === configured.stages.local;
1764
1725
  if (!local) assertDeployedStage(configured.stages, stage);
@@ -1864,7 +1825,6 @@ async function prepare(source, request, ctx, emit, redactor) {
1864
1825
  atomic: request.atomic ?? false,
1865
1826
  allowDevServices,
1866
1827
  ...request.skipDns ? { skipDns: true } : {},
1867
- ...request.skipResources ? { skipResources: true } : {},
1868
1828
  credentials: ctx.credentials,
1869
1829
  state: store,
1870
1830
  secrets,
@@ -1979,8 +1939,6 @@ function deploy(input) {
1979
1939
  ...input.atomic ? { atomic: true } : {},
1980
1940
  ...input.allowDevServices ? { allowDevServices: input.allowDevServices } : {},
1981
1941
  ...input.skipDns ? { skipDns: true } : {},
1982
- ...input.resourcesOnly ? { resourcesOnly: true } : {},
1983
- ...input.skipResources ? { skipResources: true } : {},
1984
1942
  ...input.rotateKeys ? { rotateKeys: true } : {},
1985
1943
  ...input.retireOldKeys ? { retireOldKeys: true } : {}
1986
1944
  }, ctx));
@@ -2014,6 +1972,6 @@ async function load(input, sandbox) {
2014
1972
  return workspace;
2015
1973
  }
2016
1974
  //#endregion
2017
- export { UnknownDeployApps as a, iamUserName as c, TargetBuildsNothing as i, NoDeployableApps as n, IAM_USER_PATH as o, RollbackFailed as r, bucketName as s, deploy as t };
1975
+ export { UnknownDeployApps as a, iamUserName as c, TargetBuildsNothing as i, deploysWithCompose as l, NoDeployableApps as n, IAM_USER_PATH as o, RollbackFailed as r, bucketName as s, deploy as t };
2018
1976
 
2019
- //# sourceMappingURL=deploy-LY-20Yeb.mjs.map
1977
+ //# sourceMappingURL=deploy-n_IB8r6H.mjs.map