@geekmidas/cli 10.0.0-alpha.126 → 10.0.0-alpha.127

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 (207) hide show
  1. package/dist/{EndpointGenerator-errMeldx.mjs → EndpointGenerator-B99OGzbO.mjs} +2 -2
  2. package/dist/{EndpointGenerator-errMeldx.mjs.map → EndpointGenerator-B99OGzbO.mjs.map} +1 -1
  3. package/dist/{EndpointGenerator-BGxf9jWE.cjs → EndpointGenerator-De0lknKD.cjs} +2 -2
  4. package/dist/{EndpointGenerator-BGxf9jWE.cjs.map → EndpointGenerator-De0lknKD.cjs.map} +1 -1
  5. package/dist/{GoDaddyProvider-CvRVmN4W.mjs → GoDaddyProvider-BG-UdElN.mjs} +2 -2
  6. package/dist/{GoDaddyProvider-CvRVmN4W.mjs.map → GoDaddyProvider-BG-UdElN.mjs.map} +1 -1
  7. package/dist/{GoDaddyProvider-DFfpzCOP.cjs → GoDaddyProvider-DnmLq7eo.cjs} +2 -2
  8. package/dist/{GoDaddyProvider-DFfpzCOP.cjs.map → GoDaddyProvider-DnmLq7eo.cjs.map} +1 -1
  9. package/dist/{LegacyStateStore-BFrCHrFQ.cjs → LegacyStateStore-CeBkK9K2.cjs} +3 -3
  10. package/dist/{LegacyStateStore-BFrCHrFQ.cjs.map → LegacyStateStore-CeBkK9K2.cjs.map} +1 -1
  11. package/dist/{LegacyStateStore-CgfENrXF.mjs → LegacyStateStore-DHG_4jcn.mjs} +3 -3
  12. package/dist/{LegacyStateStore-CgfENrXF.mjs.map → LegacyStateStore-DHG_4jcn.mjs.map} +1 -1
  13. package/dist/{LocalStateStore-DxoNpiBg.mjs → LocalStateStore-EenTHwr4.mjs} +2 -2
  14. package/dist/{LocalStateStore-DxoNpiBg.mjs.map → LocalStateStore-EenTHwr4.mjs.map} +1 -1
  15. package/dist/{LocalStateStore-BU5z_IOE.cjs → LocalStateStore-HRnBQFe3.cjs} +2 -2
  16. package/dist/{LocalStateStore-BU5z_IOE.cjs.map → LocalStateStore-HRnBQFe3.cjs.map} +1 -1
  17. package/dist/{OpenApiTsGenerator-cQgtxWQo.cjs → OpenApiTsGenerator-DMLzN-LU.cjs} +2 -2
  18. package/dist/{OpenApiTsGenerator-cQgtxWQo.cjs.map → OpenApiTsGenerator-DMLzN-LU.cjs.map} +1 -1
  19. package/dist/{OpenApiTsGenerator-W_HRXH1X.mjs → OpenApiTsGenerator-DNUCgkkx.mjs} +2 -2
  20. package/dist/{OpenApiTsGenerator-W_HRXH1X.mjs.map → OpenApiTsGenerator-DNUCgkkx.mjs.map} +1 -1
  21. package/dist/{S3StateStore-DiekMLpn.cjs → S3StateStore-DyLljVN1.cjs} +2 -2
  22. package/dist/{S3StateStore-DiekMLpn.cjs.map → S3StateStore-DyLljVN1.cjs.map} +1 -1
  23. package/dist/{S3StateStore-CGMSDilh.mjs → S3StateStore-vbkyBnRB.mjs} +2 -2
  24. package/dist/{S3StateStore-CGMSDilh.mjs.map → S3StateStore-vbkyBnRB.mjs.map} +1 -1
  25. package/dist/{SSMStateStore-BDCOFdKq.cjs → SSMStateStore-BBKlmfaU.cjs} +2 -2
  26. package/dist/{SSMStateStore-BDCOFdKq.cjs.map → SSMStateStore-BBKlmfaU.cjs.map} +1 -1
  27. package/dist/{SSMStateStore-Cq2H9MlF.mjs → SSMStateStore-uk2QLUgz.mjs} +2 -2
  28. package/dist/{SSMStateStore-Cq2H9MlF.mjs.map → SSMStateStore-uk2QLUgz.mjs.map} +1 -1
  29. package/dist/{SubscriberGenerator-BALddfuW.mjs → SubscriberGenerator-0ruEmYXj.mjs} +3 -3
  30. package/dist/{SubscriberGenerator-BALddfuW.mjs.map → SubscriberGenerator-0ruEmYXj.mjs.map} +1 -1
  31. package/dist/{SubscriberGenerator-LgyTxZ8r.cjs → SubscriberGenerator-CPjbWEOI.cjs} +3 -3
  32. package/dist/{SubscriberGenerator-LgyTxZ8r.cjs.map → SubscriberGenerator-CPjbWEOI.cjs.map} +1 -1
  33. package/dist/{add-BsiBYkAW.cjs → add-CH7-9AHI.cjs} +7 -7
  34. package/dist/add-CH7-9AHI.cjs.map +1 -0
  35. package/dist/{add-CamA9Uqv.mjs → add-CgyyN6aF.mjs} +7 -7
  36. package/dist/add-CgyyN6aF.mjs.map +1 -0
  37. package/dist/{bundler-CijtdIZ2.cjs → bundler-BtAkF9wb.cjs} +5 -5
  38. package/dist/{bundler-CijtdIZ2.cjs.map → bundler-BtAkF9wb.cjs.map} +1 -1
  39. package/dist/{bundler-2V2PR_E-.mjs → bundler-DqHozK8W.mjs} +5 -5
  40. package/dist/{bundler-2V2PR_E-.mjs.map → bundler-DqHozK8W.mjs.map} +1 -1
  41. package/dist/{cli-7gc1QG8X.cjs → cli-D08bMg7m.cjs} +3 -3
  42. package/dist/{cli-7gc1QG8X.cjs.map → cli-D08bMg7m.cjs.map} +1 -1
  43. package/dist/{cli-PiyYqHGx.mjs → cli-D_BQkb4B.mjs} +3 -3
  44. package/dist/{cli-PiyYqHGx.mjs.map → cli-D_BQkb4B.mjs.map} +1 -1
  45. package/dist/{compose-8e2xJ61E.cjs → compose-BK9s_2Qe.cjs} +68 -40
  46. package/dist/compose-BK9s_2Qe.cjs.map +1 -0
  47. package/dist/{compose-CvHIjMDd.mjs → compose-CIzCcsoz.mjs} +68 -40
  48. package/dist/compose-CIzCcsoz.mjs.map +1 -0
  49. package/dist/{config-_y1FGBWR.d.mts → config-B8fXmuK0.d.cts} +3 -3
  50. package/dist/{config-CdytFgSR.d.cts.map → config-B8fXmuK0.d.cts.map} +1 -1
  51. package/dist/{config-CdytFgSR.d.cts → config-CRRxZMk7.d.mts} +3 -3
  52. package/dist/{config-_y1FGBWR.d.mts.map → config-CRRxZMk7.d.mts.map} +1 -1
  53. package/dist/config.cjs +2 -2
  54. package/dist/config.d.cts +3 -3
  55. package/dist/config.d.mts +3 -3
  56. package/dist/config.mjs +2 -2
  57. package/dist/{credentialSchemas-DFxvGEwa.cjs → credentialSchemas-CM0rxWmS.cjs} +2 -2
  58. package/dist/{credentialSchemas-DFxvGEwa.cjs.map → credentialSchemas-CM0rxWmS.cjs.map} +1 -1
  59. package/dist/{credentialSchemas-DaMpt-Dx.mjs → credentialSchemas-DPOGqOrU.mjs} +2 -2
  60. package/dist/{credentialSchemas-DaMpt-Dx.mjs.map → credentialSchemas-DPOGqOrU.mjs.map} +1 -1
  61. package/dist/deploy/public.cjs +8 -8
  62. package/dist/deploy/public.d.cts +3 -3
  63. package/dist/deploy/public.d.mts +3 -3
  64. package/dist/deploy/public.mjs +8 -8
  65. package/dist/{deploy-wSlIRPn5.cjs → deploy-A_fzSa59.cjs} +10 -10
  66. package/dist/deploy-A_fzSa59.cjs.map +1 -0
  67. package/dist/{deploy-CIPwTJ47.mjs → deploy-BVf6c_h8.mjs} +10 -10
  68. package/dist/deploy-BVf6c_h8.mjs.map +1 -0
  69. package/dist/{derive-DAbo49sm.cjs → derive-BtGidITm.cjs} +7 -7
  70. package/dist/derive-BtGidITm.cjs.map +1 -0
  71. package/dist/{derive-B4vDpzgP.mjs → derive-Dew0QoGe.mjs} +7 -7
  72. package/dist/derive-Dew0QoGe.mjs.map +1 -0
  73. package/dist/{discover-DL6h-J97.cjs → discover-DEOspD9M.cjs} +12 -1
  74. package/dist/discover-DEOspD9M.cjs.map +1 -0
  75. package/dist/{discover-CzGM5P3p.mjs → discover-DOhYSKY_.mjs} +12 -1
  76. package/dist/discover-DOhYSKY_.mjs.map +1 -0
  77. package/dist/{dokploy-BKbUrz05.cjs → dokploy-CshlFRwr.cjs} +2 -2
  78. package/dist/{dokploy-BKbUrz05.cjs.map → dokploy-CshlFRwr.cjs.map} +1 -1
  79. package/dist/{dokploy-BZf1AHd0.mjs → dokploy-DOndleTd.mjs} +2 -2
  80. package/dist/{dokploy-BZf1AHd0.mjs.map → dokploy-DOndleTd.mjs.map} +1 -1
  81. package/dist/{eas-DzDMGzfc.cjs → eas-ApfPYR4-.cjs} +3 -3
  82. package/dist/{eas-DzDMGzfc.cjs.map → eas-ApfPYR4-.cjs.map} +1 -1
  83. package/dist/{eas-CxX2RCE_.mjs → eas-Dlr1Lw56.mjs} +3 -3
  84. package/dist/{eas-CxX2RCE_.mjs.map → eas-Dlr1Lw56.mjs.map} +1 -1
  85. package/dist/{encryption-BFSrt89F.mjs → encryption-D0tWRvy_.mjs} +2 -2
  86. package/dist/{encryption-BFSrt89F.mjs.map → encryption-D0tWRvy_.mjs.map} +1 -1
  87. package/dist/{encryption-RNcBnG4Z.cjs → encryption-SGWvnBxV.cjs} +2 -2
  88. package/dist/{encryption-RNcBnG4Z.cjs.map → encryption-SGWvnBxV.cjs.map} +1 -1
  89. package/dist/{engine-Dqe9KQCm.cjs → engine-CYu4wavP.cjs} +5 -5
  90. package/dist/{engine-Dqe9KQCm.cjs.map → engine-CYu4wavP.cjs.map} +1 -1
  91. package/dist/{engine-_0pjyCd_.mjs → engine-DKz1NYDX.mjs} +5 -5
  92. package/dist/{engine-_0pjyCd_.mjs.map → engine-DKz1NYDX.mjs.map} +1 -1
  93. package/dist/{github-Csev5EFf.cjs → github-CxWaWQtW.cjs} +5 -5
  94. package/dist/{github-Csev5EFf.cjs.map → github-CxWaWQtW.cjs.map} +1 -1
  95. package/dist/{github-Dck0nLW9.mjs → github-VQaj8gLE.mjs} +5 -5
  96. package/dist/{github-Dck0nLW9.mjs.map → github-VQaj8gLE.mjs.map} +1 -1
  97. package/dist/{googlePlay-DBtDAGBk.cjs → googlePlay-4KVtZ89D.cjs} +3 -3
  98. package/dist/{googlePlay-DBtDAGBk.cjs.map → googlePlay-4KVtZ89D.cjs.map} +1 -1
  99. package/dist/{googlePlay-DTuvDHi5.mjs → googlePlay-Nqc4EAiC.mjs} +3 -3
  100. package/dist/{googlePlay-DTuvDHi5.mjs.map → googlePlay-Nqc4EAiC.mjs.map} +1 -1
  101. package/dist/{index-DrkV7N5w.d.mts → index-Cu8eIwUW.d.mts} +2 -2
  102. package/dist/{index-DrkV7N5w.d.mts.map → index-Cu8eIwUW.d.mts.map} +1 -1
  103. package/dist/{index-yaXZ9m-J.d.cts → index-Dx93n3Ur.d.cts} +2 -2
  104. package/dist/{index-yaXZ9m-J.d.cts.map → index-Dx93n3Ur.d.cts.map} +1 -1
  105. package/dist/index.cjs +101 -73
  106. package/dist/index.cjs.map +1 -1
  107. package/dist/index.mjs +101 -73
  108. package/dist/index.mjs.map +1 -1
  109. package/dist/{migrate-3ZEoqx5q.cjs → migrate-BQPRclv2.cjs} +2 -2
  110. package/dist/{migrate-3ZEoqx5q.cjs.map → migrate-BQPRclv2.cjs.map} +1 -1
  111. package/dist/{migrate-BABIuzQj.mjs → migrate-C7exqXTD.mjs} +2 -2
  112. package/dist/{migrate-BABIuzQj.mjs.map → migrate-C7exqXTD.mjs.map} +1 -1
  113. package/dist/{migrate-DZeNpuX2.mjs → migrate-DQPEUiFC.mjs} +3 -3
  114. package/dist/{migrate-DZeNpuX2.mjs.map → migrate-DQPEUiFC.mjs.map} +1 -1
  115. package/dist/{migrate-pGiUqvBi.cjs → migrate-DTv6LHux.cjs} +3 -3
  116. package/dist/{migrate-pGiUqvBi.cjs.map → migrate-DTv6LHux.cjs.map} +1 -1
  117. package/dist/openapi.cjs +3 -3
  118. package/dist/openapi.d.cts +1 -1
  119. package/dist/openapi.d.mts +1 -1
  120. package/dist/openapi.mjs +3 -3
  121. package/dist/{publish-CS6xDvGT.cjs → publish-CgwqwKDs.cjs} +2 -2
  122. package/dist/{publish-CS6xDvGT.cjs.map → publish-CgwqwKDs.cjs.map} +1 -1
  123. package/dist/{publish-BsnDeOVL.mjs → publish-VYt4xOOc.mjs} +2 -2
  124. package/dist/{publish-BsnDeOVL.mjs.map → publish-VYt4xOOc.mjs.map} +1 -1
  125. package/dist/{ready-DrvaAwKv.mjs → ready-BwtLriAF.mjs} +5 -5
  126. package/dist/{ready-DrvaAwKv.mjs.map → ready-BwtLriAF.mjs.map} +1 -1
  127. package/dist/{ready-CxPJm0Hc.cjs → ready-Cj4pI0dw.cjs} +5 -5
  128. package/dist/{ready-CxPJm0Hc.cjs.map → ready-Cj4pI0dw.cjs.map} +1 -1
  129. package/dist/reconcile/public.cjs +1 -1
  130. package/dist/reconcile/public.d.cts +1 -1
  131. package/dist/reconcile/public.d.mts +1 -1
  132. package/dist/reconcile/public.mjs +1 -1
  133. package/dist/{resolve-zqCMFio0.cjs → resolve-C-W3kZM7.cjs} +4 -4
  134. package/dist/{resolve-zqCMFio0.cjs.map → resolve-C-W3kZM7.cjs.map} +1 -1
  135. package/dist/{resolve-fCGJmM-R.mjs → resolve-CCVCc43b.mjs} +4 -4
  136. package/dist/{resolve-fCGJmM-R.mjs.map → resolve-CCVCc43b.mjs.map} +1 -1
  137. package/dist/{rollback-qc79mj6L.cjs → rollback-CdBj1Boy.cjs} +4 -4
  138. package/dist/{rollback-qc79mj6L.cjs.map → rollback-CdBj1Boy.cjs.map} +1 -1
  139. package/dist/{rollback-BkhVrtAf.mjs → rollback-dUShCpZu.mjs} +4 -4
  140. package/dist/{rollback-BkhVrtAf.mjs.map → rollback-dUShCpZu.mjs.map} +1 -1
  141. package/dist/{runtime-DCkfI2E7.d.mts → runtime-C_1PteGG.d.cts} +2 -2
  142. package/dist/{runtime-DCkfI2E7.d.mts.map → runtime-C_1PteGG.d.cts.map} +1 -1
  143. package/dist/{runtime-Ie4znWIB.d.cts → runtime-jjB2e3-M.d.mts} +2 -2
  144. package/dist/{runtime-Ie4znWIB.d.cts.map → runtime-jjB2e3-M.d.mts.map} +1 -1
  145. package/dist/sandbox/credentials-worker.cjs +2 -2
  146. package/dist/sandbox/credentials-worker.mjs +2 -2
  147. package/dist/sandbox/discover-worker.cjs +1 -1
  148. package/dist/sandbox/discover-worker.mjs +1 -1
  149. package/dist/sandbox/migrate-worker.cjs +1 -1
  150. package/dist/sandbox/migrate-worker.mjs +1 -1
  151. package/dist/{seeds-Cfejy8wj.mjs → seeds-BX9pskrU.mjs} +66 -27
  152. package/dist/seeds-BX9pskrU.mjs.map +1 -0
  153. package/dist/{seeds-3awh33Wz.cjs → seeds-sMVADbkg.cjs} +66 -27
  154. package/dist/seeds-sMVADbkg.cjs.map +1 -0
  155. package/dist/{serverSetup-BFQuwUeL.cjs → serverSetup-4avavig6.cjs} +25 -5
  156. package/dist/serverSetup-4avavig6.cjs.map +1 -0
  157. package/dist/{serverSetup-C8ZbHTm_.mjs → serverSetup-BvHpm7QD.mjs} +25 -5
  158. package/dist/serverSetup-BvHpm7QD.mjs.map +1 -0
  159. package/dist/{sniffer-Cq1nhxIB.cjs → sniffer-DWLala8l.cjs} +7 -7
  160. package/dist/{sniffer-Cq1nhxIB.cjs.map → sniffer-DWLala8l.cjs.map} +1 -1
  161. package/dist/{sniffer-CCkdzjiU.mjs → sniffer-XnAnEbuI.mjs} +7 -7
  162. package/dist/{sniffer-CCkdzjiU.mjs.map → sniffer-XnAnEbuI.mjs.map} +1 -1
  163. package/dist/{snsSubscriptions-R_AKBZYK.mjs → snsSubscriptions-BxLJQH4u.mjs} +3 -3
  164. package/dist/{snsSubscriptions-R_AKBZYK.mjs.map → snsSubscriptions-BxLJQH4u.mjs.map} +1 -1
  165. package/dist/{snsSubscriptions-DYyYP0Xf.cjs → snsSubscriptions-f_z4PSFb.cjs} +3 -3
  166. package/dist/{snsSubscriptions-DYyYP0Xf.cjs.map → snsSubscriptions-f_z4PSFb.cjs.map} +1 -1
  167. package/dist/{sst-lEkBwzGc.cjs → sst-DmVJRu5l.cjs} +2 -2
  168. package/dist/{sst-lEkBwzGc.cjs.map → sst-DmVJRu5l.cjs.map} +1 -1
  169. package/dist/{sst-CTqZZl1_.mjs → sst-fop6uZ25.mjs} +2 -2
  170. package/dist/{sst-CTqZZl1_.mjs.map → sst-fop6uZ25.mjs.map} +1 -1
  171. package/dist/{stage-BkgbVJ9Z.cjs → stage-ZWOE0oLB.cjs} +5 -5
  172. package/dist/{stage-BkgbVJ9Z.cjs.map → stage-ZWOE0oLB.cjs.map} +1 -1
  173. package/dist/{stage-DCaxqm-G.mjs → stage-mta618Oy.mjs} +5 -5
  174. package/dist/{stage-DCaxqm-G.mjs.map → stage-mta618Oy.mjs.map} +1 -1
  175. package/dist/target/public.cjs +1 -1
  176. package/dist/target/public.d.cts +2 -2
  177. package/dist/target/public.d.mts +2 -2
  178. package/dist/target/public.mjs +1 -1
  179. package/dist/{terminal-bqY33lpN.mjs → terminal-CebFDhWQ.mjs} +2 -2
  180. package/dist/{terminal-bqY33lpN.mjs.map → terminal-CebFDhWQ.mjs.map} +1 -1
  181. package/dist/{terminal-PKhPAajN.cjs → terminal-DBwedwSS.cjs} +2 -2
  182. package/dist/{terminal-PKhPAajN.cjs.map → terminal-DBwedwSS.cjs.map} +1 -1
  183. package/dist/{types-D0IsQxES.d.cts → types-DLANxOpy.d.mts} +7 -2
  184. package/dist/types-DLANxOpy.d.mts.map +1 -0
  185. package/dist/{types-Bmjs4jZV.d.mts → types-SEHMr6Aw.d.cts} +8 -1
  186. package/dist/types-SEHMr6Aw.d.cts.map +1 -0
  187. package/dist/vitest.cjs +1 -1
  188. package/dist/vitest.mjs +1 -1
  189. package/dist/workspace/index.d.cts +2 -2
  190. package/dist/workspace/index.d.mts +2 -2
  191. package/package.json +15 -15
  192. package/dist/add-BsiBYkAW.cjs.map +0 -1
  193. package/dist/add-CamA9Uqv.mjs.map +0 -1
  194. package/dist/compose-8e2xJ61E.cjs.map +0 -1
  195. package/dist/compose-CvHIjMDd.mjs.map +0 -1
  196. package/dist/deploy-CIPwTJ47.mjs.map +0 -1
  197. package/dist/deploy-wSlIRPn5.cjs.map +0 -1
  198. package/dist/derive-B4vDpzgP.mjs.map +0 -1
  199. package/dist/derive-DAbo49sm.cjs.map +0 -1
  200. package/dist/discover-CzGM5P3p.mjs.map +0 -1
  201. package/dist/discover-DL6h-J97.cjs.map +0 -1
  202. package/dist/seeds-3awh33Wz.cjs.map +0 -1
  203. package/dist/seeds-Cfejy8wj.mjs.map +0 -1
  204. package/dist/serverSetup-BFQuwUeL.cjs.map +0 -1
  205. package/dist/serverSetup-C8ZbHTm_.mjs.map +0 -1
  206. package/dist/types-Bmjs4jZV.d.mts.map +0 -1
  207. package/dist/types-D0IsQxES.d.cts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy-wSlIRPn5.cjs","names":["isReservedStageKey","secretsStoreFor","GkmError","kebabCase","randomInt","readOr","IamUserNotOwned","s3Url","BucketKeySetElsewhere","RotationInProgress","AccessKeyLimit","GkmError","S3_PROVISIONING","BACKUPS_URL_KEY","stageBackups","stageProvider","appKey","awsProvisioningCredentials","projectBucketName","callerAccountId","backupsPrefix","backupExpiries","findProjectBucket","BACKUPS_SERVICE","ensureProjectBucket","reconcileProjectBucketLifecycle","awsClientConfig","awsEndpoint","normalizeDnsConfig","findRootDomain","extractSubdomain","recordTtl","dnsCredentials","settleStackDns","GkmError","appKey","ORIGIN_VERIFY_HEADER","awsClientConfig","awsEndpoint","errorName","readOr","processorOriginHost","originSecretKey","newOriginSecret","provideKey","eventsEdge","GkmError","awsClientConfig","awsEndpoint","errorName","readOr","s3Url","appKey","deploysWithCompose","NoDomainForStage","subscriberRoute","subscriptionKey","subscriptionResource","provideKey","appEnvKeys","appKey","dependentsOf","resolveHost","isMainFrontendApp","NoDomainForStage","bucketExpiry","S3RegionRequired","BucketRegionUnknown","awsClientConfig","awsEndpoint","appKey","provideKey","BucketProbeFailed","BucketOwnedByAnotherProject","RecordedBucketUnreachable","BucketNameUnavailable","mergeLifecycle","s3Url","ProvisionedBucketUnreachable","BucketRegionMismatch","checkS3Config","S3_PROVISIONING","awsProvisioningCredentials","PROVIDER_KINDS","stageProvider","GkmError","stageBackups","deployIdentity","DeployJournal","deploysWithCompose","createComposeState","createEmptyState","initStageSecrets","storedCredentials","BACKUPS_URL_KEY","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/s3/naming.ts","../src/providers/s3/policy.ts","../src/providers/iam.ts","../src/backups/provision.ts","../src/providers/dnsWriter.ts","../src/providers/s3/cdn.ts","../src/providers/s3/events.ts","../src/providers/s3/origins.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 `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 * 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[] } | { Service: string };\n\tAction: string | string[];\n\tResource: string | string[];\n\tCondition?: Record<string, Record<string, 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: {\n\t\tversioning?: boolean;\n\t\t/**\n\t\t * The bucket's events topic, when a subscriber watches it: the worker\n\t\t * confirms the subscriptions the deploy made with this key, and does\n\t\t * nothing else to the topic.\n\t\t */\n\t\teventsTopicArn?: string;\n\t} = {},\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\t...(options.eventsTopicArn\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tSid: 'GkmEvents',\n\t\t\t\t\t\t\tEffect: 'Allow' as const,\n\t\t\t\t\t\t\tAction: 'sns:ConfirmSubscription',\n\t\t\t\t\t\t\tResource: options.eventsTopicArn,\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\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 — `s3:GetObject` on\n * exactly those prefixes: to anyone, or, when a CDN serves them, to\n * CloudFront alone, for exactly the stage's distributions. Behind a CDN the\n * bucket is never public: a key outside the open prefixes is refused to\n * CloudFront too, so the edge answers it 403.\n */\nexport function bucketPolicy(\n\tbucket: string,\n\topen: readonly string[] = [],\n\toptions: { cdn?: { distributionArns: 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\tconst resources = [\n\t\t...new Set(open.map((p) => openResource(bucket, p))),\n\t].sort();\n\tif (open.length > 0 && options.cdn) {\n\t\tstatements.push({\n\t\t\tSid: 'GkmCdnRead',\n\t\t\tEffect: 'Allow',\n\t\t\tPrincipal: { Service: 'cloudfront.amazonaws.com' },\n\t\t\tAction: 's3:GetObject',\n\t\t\tResource: resources,\n\t\t\tCondition: {\n\t\t\t\tStringEquals: {\n\t\t\t\t\t'AWS:SourceArn': [...new Set(options.cdn.distributionArns)].sort(),\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t} else if (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: resources,\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' ||\n\t\t\t\t\t\tk === 'Resource' ||\n\t\t\t\t\t\tk === 'AWS' ||\n\t\t\t\t\t\tk === 'AWS:SourceArn'\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 * An IAM user gkm creates for one thing on a stage, its inline policy, and\n * the access key written into the stage's secrets as an `s3://` URL — what\n * the `s3` provider gives each bucket, and the deploy gives a stage's\n * backups.\n *\n * - **The user** is under `/gkm/`, tagged with the deploy identity, the stage\n * and what it is for. One that exists without those tags is someone\n * else's, and is refused rather than taken over.\n * - **Its policy** is read on every run and put back when it drifted.\n * - **Its key**: one, written into the stage's secrets the moment IAM shows\n * its secret. `--rotate-keys` issues a successor and keeps the old one\n * active until the stage has deployed with the new one; the next run after\n * that — or `--retire-old-keys` — deletes it.\n * - **A new key** takes IAM seconds to become usable: the state records when\n * it was issued, and a check made with it waits that out\n * ({@link whileKeyIsNew}).\n */\n\nimport * as s3Url from '@geekmidas/storage/s3-url';\nimport type { ResourceRecord } from '../deploy/StateStore.js';\nimport {\n\tAccessKeyLimit,\n\tBucketKeySetElsewhere,\n\tIamUserNotOwned,\n\tRotationInProgress,\n} from './s3/errors.js';\nimport { IAM_USER_PATH } from './s3/naming.js';\nimport { canonicalPolicy } from './s3/policy.js';\nimport type { EnsureContext, ProviderConfig, StateEntry } from './types.js';\n\ntype IamModule = typeof import('@aws-sdk/client-iam');\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/** What creating a user and its key is done through. */\nexport interface IamClients {\n\tIAM: IamModule;\n\tiam: InstanceType<IamModule['IAMClient']>;\n\t/** The region the key's URL names. */\n\tregion: string;\n\t/** An emulator's endpoint, written into the URL when there is one. */\n\tendpoint?: string;\n}\n\n/** What creating a user and its key reads from a provisioning run. */\nexport type KeyContext = Pick<\n\tEnsureContext<ProviderConfig, unknown>,\n\t| 'identity'\n\t| 'stage'\n\t| 'state'\n\t| 'change'\n\t| 'dryRun'\n\t| 'secrets'\n\t| 'writeSecrets'\n\t| 'rotateKeys'\n\t| 'retireOldKeys'\n\t| 'log'\n>;\n\n/** The keys gkm tags a bucket and a user with. */\nexport function identityTags(\n\tctx: Pick<KeyContext, 'identity' | 'stage'>,\n\tid: string,\n) {\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\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\tconst e = error as { name?: string; Code?: string };\n\t\tif (missing.includes(e?.Code ?? e?.name ?? '')) return undefined;\n\t\tthrow error;\n\t}\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\nexport interface IamUserInput {\n\t/** What it is for: a bucket construct's id, or `backups`. */\n\tid: string;\n\t/** `gkm-<project>-<stage>-<id>`. */\n\tuser: string;\n\t/** The inline policy's name. */\n\tpolicyName: string;\n\tpolicy: object;\n\t/** The policy's change line: `this bucket only`. */\n\tdescribe: string;\n}\n\n/**\n * The user and its inline policy: found — and refused when it is not this\n * stage's — or created, and the policy put back when it drifted.\n *\n * @throws {IamUserNotOwned}\n */\nexport async function ensureIamUser(\n\tctx: KeyContext,\n\tclients: IamClients,\n\tinput: IamUserInput,\n): Promise<{ user: string; exists: boolean }> {\n\tconst { IAM, iam } = clients;\n\tconst { id, user, policy } = input;\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: input.policyName,\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 ${input.policyName}: ${input.describe}`,\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: input.policyName,\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\nexport interface AccessKeyInput {\n\t/** What it is for, as {@link IamUserInput.id}. */\n\tid: string;\n\tuser: string;\n\t/** Whether the user exists yet — false in a dry run that would create it. */\n\texists: boolean;\n\t/** The bucket the URL addresses. */\n\tbucket: string;\n\t/** The secret the URL is written to: `UPLOADS_URL`, `BACKUPS_URL`. */\n\turlKey: string;\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 *\n * @throws {BucketKeySetElsewhere} when the secret names another bucket\n * @throws {RotationInProgress} on `--rotate-keys` with the last rotation's old key still active\n * @throws {AccessKeyLimit} when the user has two keys gkm did not record\n */\nexport async function ensureAccessKey(\n\tctx: KeyContext,\n\tclients: IamClients,\n\tinput: AccessKeyInput,\n): Promise<void> {\n\tconst { IAM, iam } = clients;\n\tconst { id, bucket, user, urlKey } = input;\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/**\n * When the key in a URL was issued, if the stage's state says it was just\n * now — the record of `id`'s key naming that very key.\n */\nexport function issuedJustNow(\n\tresources: Readonly<Record<string, ResourceRecord>> | undefined,\n\tid: string,\n\taccessKeyId: string,\n): string | undefined {\n\tconst record = 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 * `ask` again, for about a minute, while it is `refused` and the key was\n * issued just now — IAM refuses a key for seconds after making it. Returns\n * the last answer and how long was waited.\n */\nexport async function whileKeyIsNew<T>(\n\tfirst: T,\n\toptions: {\n\t\tissuedAt: string | undefined;\n\t\trefused: (answer: T) => boolean;\n\t\task: () => Promise<T>;\n\t\t/** Said once, before the first wait. */\n\t\tonWait?: () => void;\n\t},\n): Promise<{ answer: T; waited: number }> {\n\tlet answer = first;\n\tlet waited = 0;\n\tif (!options.issuedAt || !options.refused(answer)) return { answer, waited };\n\toptions.onWait?.();\n\tfor (const wait of newKeyWaits) {\n\t\tawait new Promise((resolve) => setTimeout(resolve, wait));\n\t\twaited += wait;\n\t\tanswer = await options.ask();\n\t\tif (!options.refused(answer)) break;\n\t}\n\treturn { answer, waited };\n}\n","/**\n * What a deploy creates for a stage's backups, in its AWS account — before\n * its checks, beside the stage's providers, with the same credentials:\n *\n * - **the project bucket**, if it is not there yet, and its lifecycle — the\n * bucket's own rule and an expiry on every stage's `backups/` prefix,\n * rebuilt from every stage's `deploy.backups` each time, so one stage's\n * deploy never drops another's rule;\n * - **an IAM user**, `gkm-<project>-<stage>-backups` under `/gkm/`, whose\n * inline policy allows `s3:PutObject` under the stage's backups prefix and\n * nothing else — no get, no list, no delete: a server that is broken into\n * can neither read the backups nor wipe them;\n * - **its key**, written into the stage's secrets as `BACKUPS_URL`, rotated\n * by `--rotate-keys` and retired by `--retire-old-keys` like a bucket's.\n *\n * Every deploy's check puts a marker object with the key — the one thing it\n * may do — so a key that does not work stops the deploy, not the 02:00 run.\n */\n\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport type { ResourceRecord } from '../deploy/StateStore.js';\nimport { GkmError } from '../errors';\nimport {\n\ttype AwsProvisioning,\n\tawsClientConfig,\n\tawsEndpoint,\n\tawsProvisioningCredentials,\n} from '../providers/aws.js';\nimport { stageProvider } from '../providers/config.js';\nimport {\n\tensureAccessKey,\n\tensureIamUser,\n\tissuedJustNow,\n\ttype KeyContext,\n\twhileKeyIsNew,\n} from '../providers/iam.js';\nimport {\n\tcallerAccountId,\n\tensureProjectBucket,\n\tfindProjectBucket,\n\tprojectBucketName,\n\treconcileProjectBucketLifecycle,\n} from '../providers/projectBucket.js';\nimport { S3_PROVISIONING } from '../providers/s3/config.js';\nimport { iamUserName } from '../providers/s3/naming.js';\nimport { appKey } from '../workspace/derive.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport {\n\tbackupExpiries,\n\tbackupsPrefix,\n\ttype StageBackupsChoice,\n\tstageBackups,\n} from './config.js';\nimport { BACKUPS_SERVICE, BACKUPS_URL_KEY } from './service.js';\n\n/** What the backups user and its key are recorded and tagged as. */\nexport const BACKUPS_ID = 'backups';\n\n/** The backups user's inline policy's name. */\nexport const BACKUPS_POLICY_NAME = 'gkm-backups';\n\n/** Where a deploy's check puts its marker, under the backups prefix. */\nexport const VERIFY_MARKER = '.gkm-verify';\n\n/** The backups user's name: `gkm-<project>-<stage>-backups`. */\nexport function backupsUserName(scope: string, stage: string): string {\n\treturn iamUserName({ scope, stage, id: BACKUPS_ID });\n}\n\n/**\n * The backups key's policy: put objects under the stage's backups prefix.\n * Uploading in parts is `s3:PutObject` too; aborting one is not, and the\n * bucket's lifecycle does it instead.\n */\nexport function backupsPolicy(bucket: string, prefix: string) {\n\treturn {\n\t\tVersion: '2012-10-17' as const,\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tSid: 'GkmBackupsPut',\n\t\t\t\tEffect: 'Allow' as const,\n\t\t\t\tAction: ['s3:PutObject'],\n\t\t\t\tResource: `arn:aws:s3:::${bucket}/${prefix}/*`,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** A stage that backs up, and no AWS credentials to create its key with. */\nexport class BackupsCredentialsMissing extends GkmError {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`'${stage}' runs Postgres, so the deploy backs it up — and creates the ` +\n\t\t\t\t\"IAM user and key it backs up with in the stage's AWS account — and \" +\n\t\t\t\t`it found no AWS credentials to do it with. On this machine, supply ` +\n\t\t\t\t`${S3_PROVISIONING.describe}. In CI, the step that runs the deploy ` +\n\t\t\t\t\"needs the stage's role (AWS_ROLE_ARN, \" +\n\t\t\t\t`from gkm deploy:github). To take no backups, set deploy.backups.${stage}: false.`,\n\t\t);\n\t\tthis.name = 'BackupsCredentialsMissing';\n\t}\n}\n\n/** No region to create the project bucket in. */\nexport class BackupsRegionRequired extends GkmError {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`'${stage}' is backed up to the project bucket, and there is no region ` +\n\t\t\t\t\"to find it in: set state: { provider: 's3', region } in gkm.config.ts, \" +\n\t\t\t\t'or AWS_REGION.',\n\t\t);\n\t\tthis.name = 'BackupsRegionRequired';\n\t}\n}\n\n/** A bucket construct whose IAM user would be the backups user. */\nexport class BackupsUserNameTaken extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly construct: string,\n\t) {\n\t\tsuper(\n\t\t\t`The bucket '${construct}' is reached on '${stage}' with the IAM user ` +\n\t\t\t\t\"the stage's backups are put with — both are named after 'backups'. \" +\n\t\t\t\t`Rename the construct, or set deploy.backups.${stage}: false.`,\n\t\t);\n\t\tthis.name = 'BackupsUserNameTaken';\n\t}\n}\n\n/** The backups key could not put its marker: backups would fail too. */\nexport class BackupsKeyRefused extends GkmError {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly bucket: string,\n\t\treadonly key: string,\n\t\treadonly said: string,\n\t) {\n\t\tsuper(\n\t\t\t`The ${BACKUPS_URL_KEY} key of '${stage}' could not put s3://${bucket}/${key} ` +\n\t\t\t\t`(${said}), so its backups would fail the same way. Run the deploy ` +\n\t\t\t\t\"with the stage's AWS credentials to put its user and policy back, or \" +\n\t\t\t\t'--rotate-keys to issue it a new key.',\n\t\t);\n\t\tthis.name = 'BackupsKeyRefused';\n\t}\n}\n\n/**\n * The region the project bucket is in: the state's, when it is kept in S3,\n * the secrets store's when that is in AWS, the credential's, `AWS_REGION`.\n */\nexport function backupsRegion(\n\tworkspace: Pick<NormalizedWorkspace, 'state' | 'secrets'>,\n\tstage: string,\n\tcredential?: { region?: string },\n\tenv: NodeJS.ProcessEnv = process.env,\n): string {\n\tconst state = workspace.state;\n\tconst store = workspace.secrets?.store;\n\tconst region =\n\t\t(state && 'region' in state ? (state.region as string) : undefined) ??\n\t\t(store && typeof store === 'object' && 'region' in store\n\t\t\t? (store as { region?: string }).region\n\t\t\t: undefined) ??\n\t\tcredential?.region ??\n\t\tenv.AWS_REGION ??\n\t\tenv.AWS_DEFAULT_REGION;\n\tif (!region) throw new BackupsRegionRequired(stage);\n\treturn region;\n}\n\nexport interface EnsureBackupsInput {\n\tworkspace: NormalizedWorkspace;\n\tmanifest: ConstructManifest;\n\tstage: string;\n\t/** Everything creating the user and key reads — the providers' own. */\n\tctx: KeyContext;\n\tprofile?: string;\n\thome?: string;\n\tenv?: NodeJS.ProcessEnv;\n}\n\n/**\n * The stage's backups bucket, lifecycle, user and key — or, for a stage set\n * to `false`, a notice and nothing else. Returns what the stage's backups\n * came to.\n *\n * @throws {BackupsCredentialsMissing} when there are no AWS credentials\n */\nexport async function ensureStageBackups(\n\tinput: EnsureBackupsInput,\n): Promise<StageBackupsChoice> {\n\tconst { workspace, manifest, stage, ctx } = input;\n\tconst env = input.env ?? process.env;\n\tconst choice = stageBackups(workspace, manifest, stage);\n\tif (choice.mode === 'disabled') {\n\t\tctx.log(\n\t\t\t`💾 backups: off — deploy.backups.${stage} is false. Nothing is backed up, and nothing already backed up is deleted.`,\n\t\t);\n\t\treturn choice;\n\t}\n\tif (choice.mode !== 'on') return choice;\n\n\tconst objects = stageProvider(workspace, 'objects', stage);\n\tif (objects.mode === 'provider') {\n\t\tconst clash = Object.entries(manifest).find(\n\t\t\t([id, d]) => d.kind === 'objects' && appKey(id) === BACKUPS_ID,\n\t\t);\n\t\tif (clash) throw new BackupsUserNameTaken(stage, clash[0]);\n\t}\n\n\tconst credential = await awsProvisioningCredentials({\n\t\tstage,\n\t\tenv,\n\t\t...(input.profile ? { profile: input.profile } : {}),\n\t\t...(input.home ? { home: input.home } : {}),\n\t});\n\tif (!credential) throw new BackupsCredentialsMissing(stage);\n\n\tconst region = backupsRegion(workspace, stage, credential, env);\n\tconst clients = await backupsClients(credential, region, env);\n\tconst bucket = projectBucketName(\n\t\tctx.identity.scope,\n\t\tawait callerAccountId(clients.sts),\n\t);\n\tconst prefix = backupsPrefix(workspace, stage);\n\tconst expiries = backupExpiries(workspace, manifest);\n\n\tctx.log(\n\t\t`💾 backups: ${choice.backups.describe}, to s3://${bucket}/${prefix}/${ctx.dryRun ? ' (dry run)' : ''}`,\n\t);\n\n\t// The bucket, and every stage's expiry on it.\n\tif ((await findProjectBucket(clients.s3, bucket)) === 'none') {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: BACKUPS_SERVICE,\n\t\t\t\tresource: `bucket ${bucket}`,\n\t\t\t\tchange: `create in ${region}, expiring each stage's backups`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait ensureProjectBucket(clients.s3, {\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion,\n\t\t\t\t\tidentity: ctx.identity,\n\t\t\t\t\texpiries,\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else if (\n\t\tawait reconcileProjectBucketLifecycle(clients.s3, bucket, expiries, {\n\t\t\tdryRun: true,\n\t\t})\n\t) {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: BACKUPS_SERVICE,\n\t\t\t\tresource: `bucket ${bucket}`,\n\t\t\t\tchange: `lifecycle: ${expiries.map((e) => `${e.prefix} after ${e.days} days`).join(', ')}`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait reconcileProjectBucketLifecycle(clients.s3, bucket, expiries);\n\t\t\t},\n\t\t);\n\t}\n\n\tconst user = await ensureIamUser(ctx, clients, {\n\t\tid: BACKUPS_ID,\n\t\tuser: backupsUserName(ctx.identity.scope, stage),\n\t\tpolicyName: BACKUPS_POLICY_NAME,\n\t\tpolicy: backupsPolicy(bucket, prefix),\n\t\tdescribe: `put objects under ${prefix}/ only`,\n\t});\n\tawait ensureAccessKey(ctx, clients, {\n\t\tid: BACKUPS_ID,\n\t\tbucket,\n\t\turlKey: BACKUPS_URL_KEY,\n\t\t...user,\n\t});\n\treturn choice;\n}\n\n/** The clients a backups run creates through. */\nasync function backupsClients(\n\tcredential: AwsProvisioning,\n\tregion: string,\n\tenv: NodeJS.ProcessEnv,\n) {\n\tconst S3 = await import('@aws-sdk/client-s3');\n\tconst IAM = await import('@aws-sdk/client-iam');\n\tconst { STSClient } = await import('@aws-sdk/client-sts');\n\tconst config = await awsClientConfig(credential, region);\n\tconst endpoint = awsEndpoint(env, 'S3');\n\treturn {\n\t\tIAM,\n\t\tiam: new IAM.IAMClient(config),\n\t\ts3: new S3.S3Client({\n\t\t\t...config,\n\t\t\t...(endpoint ? { endpoint, forcePathStyle: true } : {}),\n\t\t}),\n\t\tsts: new STSClient(config),\n\t\tregion,\n\t\t...(endpoint ? { endpoint } : {}),\n\t};\n}\n\nexport interface VerifyBackupsInput {\n\tworkspace: NormalizedWorkspace;\n\tmanifest: ConstructManifest;\n\tstage: string;\n\tsecrets: Readonly<Record<string, string>>;\n\tresources?: Readonly<Record<string, ResourceRecord>>;\n\tlog?: (line: string) => void;\n}\n\n/**\n * The stage's backups key puts its marker under the prefix — the one thing\n * it may do. A key issued by this deploy is waited for, as a bucket's is.\n * Returns whether there was a key to check.\n *\n * @throws {BackupsKeyRefused}\n */\nexport async function verifyStageBackups(\n\tinput: VerifyBackupsInput,\n): Promise<boolean> {\n\tconst { stage } = input;\n\tif (stageBackups(input.workspace, input.manifest, stage).mode !== 'on') {\n\t\treturn false;\n\t}\n\tconst url = input.secrets[BACKUPS_URL_KEY];\n\tif (!url) return false;\n\tconst s3Url = await import('@geekmidas/storage/s3-url');\n\tconst address = s3Url.parse(url);\n\tif (!address.accessKeyId || !address.secretAccessKey) return false;\n\n\tconst S3 = await import('@aws-sdk/client-s3');\n\tconst client = new S3.S3Client({\n\t\tregion: address.region ?? 'us-east-1',\n\t\tcredentials: {\n\t\t\taccessKeyId: address.accessKeyId,\n\t\t\tsecretAccessKey: address.secretAccessKey,\n\t\t},\n\t\t...(address.endpoint ? { endpoint: address.endpoint } : {}),\n\t\t...(address.forcePathStyle ? { forcePathStyle: true } : {}),\n\t});\n\tconst Key = `${backupsPrefix(input.workspace, stage)}/${VERIFY_MARKER}`;\n\tconst put = async (): Promise<{\n\t\tok: boolean;\n\t\tstatus?: number;\n\t\tsaid: string;\n\t}> => {\n\t\ttry {\n\t\t\tawait client.send(\n\t\t\t\tnew S3.PutObjectCommand({\n\t\t\t\t\tBucket: address.bucket,\n\t\t\t\t\tKey,\n\t\t\t\t\tBody: new Date().toISOString(),\n\t\t\t\t\tContentType: 'text/plain',\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn { ok: true, said: '' };\n\t\t} catch (error) {\n\t\t\tconst e = error as {\n\t\t\t\tname?: string;\n\t\t\t\tmessage?: string;\n\t\t\t\t$metadata?: { httpStatusCode?: number };\n\t\t\t};\n\t\t\tconst status = e.$metadata?.httpStatusCode;\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\t...(status !== undefined ? { status } : {}),\n\t\t\t\tsaid: `HTTP ${status ?? 'no response'} ${e.name ?? 'Error'}: ${e.message ?? ''}`,\n\t\t\t};\n\t\t}\n\t};\n\ttry {\n\t\tconst { answer } = await whileKeyIsNew(await put(), {\n\t\t\tissuedAt: issuedJustNow(input.resources, BACKUPS_ID, address.accessKeyId),\n\t\t\trefused: (answer) => !answer.ok && answer.status === 403,\n\t\t\task: put,\n\t\t\tonWait: () =>\n\t\t\t\tinput.log?.(\n\t\t\t\t\t` backups: waiting for the new key ${address.accessKeyId} to become active…`,\n\t\t\t\t),\n\t\t});\n\t\tif (!answer.ok) {\n\t\t\tthrow new BackupsKeyRefused(stage, address.bucket, Key, answer.said);\n\t\t}\n\t\treturn true;\n\t} finally {\n\t\tclient.destroy();\n\t}\n}\n","/**\n * The DNS records a provider asks for — a certificate's validation record, a\n * CDN's name — written through the stage's own DNS providers.\n *\n * The same machinery the deploy's DNS step uses for the stack's hosts\n * (`settleStackDns`), handed a plan of CNAMEs instead of the server's\n * addresses: a record holding its value is left alone, one with another value\n * is replaced and printed, and what is written is read back. A host under no\n * domain in `dns`, or under a `manual` one, is printed for the person to\n * create and reported back, so the provider can say what it is waiting on.\n */\n\nimport {\n\ttype DomainDnsPlan,\n\tdnsCredentials,\n\ttype PlannedDnsRecord,\n\trecordTtl,\n\tsettleStackDns,\n} from '../compose/dns.js';\nimport type { CredentialProvider } from '../deploy/credentials.js';\nimport type { DnsProvider } from '../target/dokploy/dns/DnsProvider.js';\nimport {\n\textractSubdomain,\n\tfindRootDomain,\n\tnormalizeDnsConfig,\n} from '../target/dokploy/dns/index.js';\nimport type {\n\tDnsProvider as DnsProviderConfig,\n\tNormalizedWorkspace,\n} from '../workspace/types.js';\nimport type { ProviderDnsRecord, ProviderDnsResult } from './types.js';\n\nexport interface ProviderDnsOptions {\n\tworkspace: Pick<NormalizedWorkspace, 'dns'>;\n\tstage: string;\n\tdryRun: boolean;\n\t/** Where the DNS providers' tokens come from. */\n\tcredentials: CredentialProvider;\n\t/** The provider for a domain — `createDnsProvider` by default. */\n\tproviderFor?: (config: DnsProviderConfig) => Promise<DnsProvider | null>;\n\tlog: (line: string) => void;\n}\n\nexport async function writeProviderDns(\n\trecords: readonly ProviderDnsRecord[],\n\toptions: ProviderDnsOptions,\n): Promise<ProviderDnsResult> {\n\tconst { log } = options;\n\tconst dns = options.workspace.dns\n\t\t? normalizeDnsConfig(options.workspace.dns)\n\t\t: {};\n\tconst manual: string[] = [];\n\tconst domains = new Map<string, DomainDnsPlan>();\n\n\tfor (const record of records) {\n\t\tconst host = record.host.toLowerCase().replace(/\\.$/, '');\n\t\tconst value = record.value.replace(/\\.$/, '');\n\t\tconst domain = findRootDomain(host, dns);\n\t\tif (!domain) {\n\t\t\tlog(` create at its DNS host: ${host} CNAME ${value}`);\n\t\t\tmanual.push(host);\n\t\t\tcontinue;\n\t\t}\n\t\tconst config = dns[domain]!;\n\t\tconst plan = domains.get(domain) ?? {\n\t\t\tdomain,\n\t\t\tprovider:\n\t\t\t\ttypeof config.provider === 'string' ? config.provider : 'custom',\n\t\t\tconfig,\n\t\t\trecords: [],\n\t\t};\n\t\tconst planned: PlannedDnsRecord = {\n\t\t\thost,\n\t\t\tdomain,\n\t\t\tname: extractSubdomain(host, domain),\n\t\t\ttype: record.type,\n\t\t\tvalue,\n\t\t\tttl: recordTtl(config),\n\t\t};\n\t\tplan.records.push(planned);\n\t\tdomains.set(domain, plan);\n\t}\n\tif (domains.size === 0) return { manual };\n\n\tconst plans = [...domains.values()];\n\tconst tokens = await dnsCredentials(\n\t\toptions.stage,\n\t\tplans.map(({ domain, config }) => ({ domain, config })),\n\t\toptions.credentials,\n\t);\n\tconst applied = await settleStackDns(\n\t\t{\n\t\t\tstage: options.stage,\n\t\t\t// No address: these records are CNAMEs, never the server's.\n\t\t\tserver: { ipv4: '' },\n\t\t\tdomains: plans,\n\t\t\tuncovered: [],\n\t\t},\n\t\t{\n\t\t\t...(options.dryRun ? { dryRun: true } : { confirm: true }),\n\t\t\tlog,\n\t\t\tcredentials: {\n\t\t\t\t...(tokens.godaddy ? { credential: tokens.godaddy } : {}),\n\t\t\t\tlog,\n\t\t\t},\n\t\t\t...(tokens.hostinger ? { hostinger: tokens.hostinger } : {}),\n\t\t\t...(options.providerFor ? { providerFor: options.providerFor } : {}),\n\t\t},\n\t);\n\n\t// A `manual` domain's records were printed, not written.\n\tfor (const change of applied.changes) {\n\t\tif (change.action !== 'manual') continue;\n\t\tconst host = plans\n\t\t\t.find((p) => p.domain === change.domain)\n\t\t\t?.records.find((r) => r.name === change.name)?.host;\n\t\tif (host) manual.push(host);\n\t}\n\treturn { manual: [...new Set(manual)].sort() };\n}\n","/**\n * A file server over an `s3` bucket, served through a CDN.\n *\n * Without one a file server answers on the bucket's regional endpoint: every\n * reader, wherever they are, fetches from one region, on an `amazonaws.com`\n * host. With one — the default — each file server gets, on the stage:\n *\n * - **a certificate** for `<fileserver>.<domain>`, from ACM in us-east-1 (the\n * one region CloudFront reads certificates from), validated by a CNAME the\n * deploy writes through the stage's DNS providers and keeps, because ACM\n * renews against the same record;\n * - **an origin access control**, which signs CloudFront's requests to the\n * bucket, and a bucket policy statement granting exactly the stage's\n * distributions `s3:GetObject` on exactly the open prefixes (see\n * `bucketPolicy`) — the bucket itself is never public;\n * - **response headers policies**: CORS for the stage's sites (the same\n * derivation the bucket's own CORS rule uses), and, for the paths the file\n * server calls `immutable`, `Cache-Control: public, max-age=31536000,\n * immutable` over whatever the object was stored with;\n * - **a distribution** on that name: HTTPS only, compressed, GET/HEAD/OPTIONS,\n * cached with AWS's managed `CachingOptimized` policy — keyed on the path\n * alone, so no query string or cookie fragments the cache;\n * - **a CNAME** from the name to the distribution, through the same DNS\n * providers.\n *\n * Open paths only: a key outside them is refused to CloudFront by the bucket\n * policy, so the edge answers it 403, and a signed read goes to the bucket's\n * own host as before (`signedUrl` is an S3 presign).\n *\n * Every resource is recorded in the stage's state and reused, found by its\n * name when a run died before recording it, and put back when it drifted.\n * Nothing is ever deleted.\n */\n\nimport type {\n\tDistributionConfig,\n\tResponseHeadersPolicyConfig,\n} from '@aws-sdk/client-cloudfront';\nimport { GkmError } from '../../errors';\nimport { appKey } from '../../workspace/derive.js';\nimport type { S3ObjectsConfig } from '../../workspace/types.js';\nimport { type AwsProvisioning, awsClientConfig, awsEndpoint } from '../aws.js';\nimport { identityTags } from '../iam.js';\nimport {\n\tnewOriginSecret,\n\tORIGIN_VERIFY_HEADER,\n\toriginSecretKey,\n\tprocessorOriginHost,\n} from '../processorOrigin.js';\nimport type { EnsureContext, StateEntry } from '../types.js';\n\ntype CloudFrontModule = typeof import('@aws-sdk/client-cloudfront');\ntype AcmModule = typeof import('@aws-sdk/client-acm');\n\ntype Ctx = EnsureContext<S3ObjectsConfig, AwsProvisioning>;\n\n/** AWS's managed `CachingOptimized` cache policy: path-keyed, gzip and brotli. */\nexport const CACHING_OPTIMIZED = '658327ea-f89d-4fab-a63d-7e88639e58f6';\n\n/** What an immutable path is served with. */\nexport const IMMUTABLE_CACHE_CONTROL = 'public, max-age=31536000, immutable';\n\n/** The only region CloudFront reads a certificate from. */\nconst CDN_REGION = 'us-east-1';\n\n/** The distribution's bucket origin. */\nconst ORIGIN_ID = 'bucket';\n\n/** Its processors' origin: the stack's processor unit, at a host of its own. */\nconst PROCESSORS_ORIGIN_ID = 'processors';\n\n/**\n * AWS's managed `CachingOptimizedForUncompressedObjects`: keyed on the path\n * alone, and nothing re-compressed — a derivative is an image, already\n * compressed, and its width is in the path, so nothing else may fragment it.\n */\nexport const CACHING_OPTIMIZED_UNCOMPRESSED =\n\t'b2884449-e4de-46a7-ac36-70bc7f1ddd6d';\n\n/** A file server, as the CDN serves it. */\nexport interface CdnServer {\n\tid: string;\n\topen: readonly string[];\n\timmutable: readonly string[];\n\t/** Its processors' prefixes — `/i/` — each sent to the processor unit. */\n\tprocessors?: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/** A CDN is a name on the stage's domain, and the stage has none. */\nexport class FileServerCdnNeedsDomain extends GkmError {\n\tconstructor(\n\t\treadonly server: string,\n\t\treadonly stage: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${server}' is served through a CDN on '${stage}', which answers on ` +\n\t\t\t\t`<fileserver>.<domain> — and '${stage}' has no domain. Set ` +\n\t\t\t\t`domains.${stage} in gkm.config.ts, or set deploy.objects.${stage}.cdn ` +\n\t\t\t\t\"to false to serve it from the bucket's own endpoint.\",\n\t\t);\n\t\tthis.name = 'FileServerCdnNeedsDomain';\n\t}\n}\n\n/**\n * The certificate is waiting on its validation record: one the person has to\n * create, or one that has not propagated yet. Everything up to it is\n * recorded, so the next deploy carries on from here.\n */\nexport class CdnCertificatePending extends GkmError {\n\tconstructor(\n\t\treadonly server: string,\n\t\treadonly host: string,\n\t\treadonly record: { name: string; value: string },\n\t\treadonly reason: 'manual' | 'timeout',\n\t) {\n\t\tsuper(\n\t\t\t(reason === 'manual'\n\t\t\t\t? `The certificate for ${host} ('${server}') is validated by a DNS ` +\n\t\t\t\t\t'record no DNS provider in gkm.config.ts can write. Create it at ' +\n\t\t\t\t\t\"the domain's DNS host:\\n\"\n\t\t\t\t: `The certificate for ${host} ('${server}') is not issued yet: ACM ` +\n\t\t\t\t\t'has not seen its validation record. It is written; DNS can take ' +\n\t\t\t\t\t'a while to answer with it. Check it resolves:\\n') +\n\t\t\t\t` ${record.name} CNAME ${record.value}\\n` +\n\t\t\t\t'then deploy again — the certificate and everything before it are ' +\n\t\t\t\t'recorded, and the deploy carries on from there.',\n\t\t);\n\t\tthis.name = 'CdnCertificatePending';\n\t}\n}\n\n/** ACM gave up on the certificate. */\nexport class CdnCertificateFailed extends GkmError {\n\tconstructor(\n\t\treadonly server: string,\n\t\treadonly host: string,\n\t\treadonly status: string,\n\t\treadonly reason: string | undefined,\n\t) {\n\t\tsuper(\n\t\t\t`ACM did not issue the certificate for ${host} ('${server}'): ${status}` +\n\t\t\t\t(reason ? ` (${reason})` : '') +\n\t\t\t\t'. A CAA record on the domain that does not allow amazon.com, or a ' +\n\t\t\t\t'validation record removed before it was checked, are the usual ' +\n\t\t\t\t'causes. Fix it and deploy again: a new certificate is requested.',\n\t\t);\n\t\tthis.name = 'CdnCertificateFailed';\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Names and documents — pure\n// ---------------------------------------------------------------------------\n\n/** Where a file server answers: `<fileserver>.<domain>`. */\nexport function cdnHost(serverId: string, domain: string): string {\n\treturn `${appKey(serverId)}.${domain}`.toLowerCase();\n}\n\n/**\n * The name the stage's CDN resources go by, within CloudFront's limits:\n * letters, digits, `-` and `_`, and at most 64 characters (an origin access\n * control's). Kept whole where it fits; otherwise shortened with a hash of\n * the whole, so two long names never meet.\n */\nexport function cdnName(\n\tscope: string,\n\tstage: string,\n\tserverId: string,\n): string {\n\tconst whole = `gkm-${scope}-${stage}-${appKey(serverId)}`.replace(\n\t\t/[^A-Za-z0-9_-]/g,\n\t\t'-',\n\t);\n\tif (whole.length <= 56) return whole;\n\treturn `${whole.slice(0, 47)}-${hash(whole)}`;\n}\n\nfunction hash(value: string): string {\n\tlet h = 2166136261;\n\tfor (let i = 0; i < value.length; i++) {\n\t\th ^= value.charCodeAt(i);\n\t\th = Math.imul(h, 16777619);\n\t}\n\treturn (h >>> 0).toString(36).padStart(8, '0').slice(0, 8);\n}\n\n/**\n * An open or immutable glob as a CloudFront path pattern. CloudFront's `*`\n * crosses `/`, so a single star is as wide as a double one — the bucket\n * policy reads it the same way, and the construct's own check is the\n * stricter of the three.\n */\nexport function pathPattern(glob: string): string {\n\treturn glob.replace(/^\\/+/, '').replace(/\\*\\*/g, '*');\n}\n\n/** A CloudFront list: its `Quantity` and, when it has some, its `Items`. */\nfunction list<T>(items: readonly T[]): { Quantity: number; Items?: T[] } {\n\treturn items.length > 0\n\t\t? { Quantity: items.length, Items: [...items] }\n\t\t: { Quantity: 0 };\n}\n\n/** One of the stage's response headers policies. */\nexport function headersPolicyConfig(input: {\n\tname: string;\n\tcomment: string;\n\t/** The stage's sites, for CORS; none, no CORS. */\n\torigins: readonly string[];\n\timmutable: boolean;\n}): ResponseHeadersPolicyConfig {\n\treturn {\n\t\tName: input.name,\n\t\tComment: input.comment,\n\t\t...(input.origins.length > 0\n\t\t\t? {\n\t\t\t\t\tCorsConfig: {\n\t\t\t\t\t\tAccessControlAllowOrigins: list([...input.origins].sort()) as {\n\t\t\t\t\t\t\tQuantity: number;\n\t\t\t\t\t\t\tItems: string[];\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAccessControlAllowHeaders: { Quantity: 1, Items: ['*'] },\n\t\t\t\t\t\tAccessControlAllowMethods: {\n\t\t\t\t\t\t\tQuantity: 3,\n\t\t\t\t\t\t\tItems: ['GET', 'HEAD', 'OPTIONS'],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAccessControlAllowCredentials: false,\n\t\t\t\t\t\tAccessControlMaxAgeSec: 86400,\n\t\t\t\t\t\tOriginOverride: false,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t\t...(input.immutable\n\t\t\t? {\n\t\t\t\t\tCustomHeadersConfig: {\n\t\t\t\t\t\tQuantity: 1,\n\t\t\t\t\t\tItems: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tHeader: 'Cache-Control',\n\t\t\t\t\t\t\t\tValue: IMMUTABLE_CACHE_CONTROL,\n\t\t\t\t\t\t\t\t// Over the origin: objects already in the bucket were\n\t\t\t\t\t\t\t\t// stored with whatever they were stored with, or nothing.\n\t\t\t\t\t\t\t\tOverride: true,\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};\n}\n\n/** The parts of a distribution's config this provider owns. */\nexport function distributionConfig(input: {\n\tcomment: string;\n\tcallerReference: string;\n\thost: string;\n\tcertificateArn: string;\n\t/** The bucket's regional domain. */\n\tbucketDomain: string;\n\toriginAccessControlId: string;\n\t/** For every path: CORS. */\n\tcorsPolicyId?: string;\n\t/** For the immutable paths: CORS and the forever header. */\n\timmutablePolicyId?: string;\n\timmutable: readonly string[];\n\t/**\n\t * The file server's processors: each prefix sent to the processor unit\n\t * at `host`, with the secret header its edge checks.\n\t */\n\tprocessors?: { prefixes: readonly string[]; host: string; secret: string };\n}): DistributionConfig {\n\tconst behaviour = (policy?: string) => ({\n\t\tTargetOriginId: ORIGIN_ID,\n\t\tViewerProtocolPolicy: 'redirect-to-https' as const,\n\t\tAllowedMethods: {\n\t\t\tQuantity: 3,\n\t\t\tItems: ['GET' as const, 'HEAD' as const, 'OPTIONS' as const],\n\t\t\tCachedMethods: { Quantity: 2, Items: ['GET' as const, 'HEAD' as const] },\n\t\t},\n\t\tCompress: true,\n\t\tCachePolicyId: CACHING_OPTIMIZED,\n\t\t...(policy ? { ResponseHeadersPolicyId: policy } : {}),\n\t});\n\tconst patterns = [...new Set(input.immutable.map(pathPattern))].sort();\n\tconst processors = input.processors;\n\tconst processorPatterns = processors\n\t\t? [...new Set(processors.prefixes.map((p) => `${pathPattern(p)}*`))].sort()\n\t\t: [];\n\treturn {\n\t\tCallerReference: input.callerReference,\n\t\tComment: input.comment,\n\t\tEnabled: true,\n\t\tAliases: { Quantity: 1, Items: [input.host] },\n\t\tOrigins: list([\n\t\t\t{\n\t\t\t\tId: ORIGIN_ID,\n\t\t\t\tDomainName: input.bucketDomain,\n\t\t\t\tOriginPath: '',\n\t\t\t\tS3OriginConfig: { OriginAccessIdentity: '' },\n\t\t\t\tOriginAccessControlId: input.originAccessControlId,\n\t\t\t},\n\t\t\t...(processors\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tId: PROCESSORS_ORIGIN_ID,\n\t\t\t\t\t\t\tDomainName: processors.host,\n\t\t\t\t\t\t\tOriginPath: '',\n\t\t\t\t\t\t\tCustomOriginConfig: {\n\t\t\t\t\t\t\t\tHTTPPort: 80,\n\t\t\t\t\t\t\t\tHTTPSPort: 443,\n\t\t\t\t\t\t\t\tOriginProtocolPolicy: 'https-only',\n\t\t\t\t\t\t\t\tOriginSslProtocols: { Quantity: 1, Items: ['TLSv1.2'] },\n\t\t\t\t\t\t\t\tOriginReadTimeout: 30,\n\t\t\t\t\t\t\t\tOriginKeepaliveTimeout: 5,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t// What the processor unit's edge checks: without it, its\n\t\t\t\t\t\t\t// public host refuses the request.\n\t\t\t\t\t\t\tCustomHeaders: {\n\t\t\t\t\t\t\t\tQuantity: 1,\n\t\t\t\t\t\t\t\tItems: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tHeaderName: ORIGIN_VERIFY_HEADER,\n\t\t\t\t\t\t\t\t\t\tHeaderValue: processors.secret,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\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]),\n\t\tDefaultCacheBehavior: behaviour(input.corsPolicyId),\n\t\t// The processors' first: CloudFront takes the first pattern that\n\t\t// matches, and an immutable `*` would otherwise answer from the bucket.\n\t\tCacheBehaviors: list([\n\t\t\t...processorPatterns.map((PathPattern) => ({\n\t\t\t\t...behaviour(input.corsPolicyId),\n\t\t\t\tTargetOriginId: PROCESSORS_ORIGIN_ID,\n\t\t\t\tCompress: false,\n\t\t\t\tCachePolicyId: CACHING_OPTIMIZED_UNCOMPRESSED,\n\t\t\t\tPathPattern,\n\t\t\t})),\n\t\t\t...patterns.map((PathPattern) => ({\n\t\t\t\t...behaviour(input.immutablePolicyId),\n\t\t\t\tPathPattern,\n\t\t\t})),\n\t\t]),\n\t\tViewerCertificate: {\n\t\t\tACMCertificateArn: input.certificateArn,\n\t\t\tSSLSupportMethod: 'sni-only',\n\t\t\tMinimumProtocolVersion: 'TLSv1.2_2021',\n\t\t\tCloudFrontDefaultCertificate: false,\n\t\t},\n\t\tHttpVersion: 'http2and3',\n\t\tIsIPV6Enabled: true,\n\t\tDefaultRootObject: '',\n\t} as DistributionConfig;\n}\n\n/**\n * Whether `current` already holds everything in `wanted`: each key `wanted`\n * names, recursively, with lists compared as sets. What else `current` holds\n * — logging, a WAF, geo restrictions set by hand — is left alone, and a\n * `CallerReference`, fixed at creation, is never compared.\n */\nexport function holds(\n\tcurrent: unknown,\n\twanted: unknown,\n\tkey?: string,\n): boolean {\n\tif (key === 'CallerReference') return true;\n\tif (Array.isArray(wanted)) {\n\t\treturn (\n\t\t\tArray.isArray(current) &&\n\t\t\tcurrent.length === wanted.length &&\n\t\t\twanted.every((w) => current.some((c) => holds(c, w)))\n\t\t);\n\t}\n\tif (wanted && typeof wanted === 'object') {\n\t\tif (!current || typeof current !== 'object') return false;\n\t\treturn Object.entries(wanted).every(([k, v]) =>\n\t\t\tholds((current as Record<string, unknown>)[k], v, k),\n\t\t);\n\t}\n\treturn current === wanted;\n}\n\n/** Header configs a policy may hold that this provider never sets. */\nconst FOREIGN_HEADER_CONFIGS = [\n\t'CorsConfig',\n\t'CustomHeadersConfig',\n\t'SecurityHeadersConfig',\n\t'RemoveHeadersConfig',\n\t'ServerTimingHeadersConfig',\n] as const;\n\n/** Whether a policy is exactly what is wanted: nothing missing, nothing more. */\nexport function sameHeadersPolicy(\n\tcurrent: ResponseHeadersPolicyConfig | undefined,\n\twanted: ResponseHeadersPolicyConfig,\n): boolean {\n\tif (!current || !holds(current, wanted)) return false;\n\treturn FOREIGN_HEADER_CONFIGS.every((k) => {\n\t\tif (k in wanted) return true;\n\t\tconst extra = current[k] as { Quantity?: number } | undefined;\n\t\treturn !extra || extra.Quantity === 0;\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Clients\n// ---------------------------------------------------------------------------\n\nexport interface CdnClients {\n\tCF: CloudFrontModule;\n\tACM: AcmModule;\n\tcloudfront: InstanceType<CloudFrontModule['CloudFrontClient']>;\n\tacm: InstanceType<AcmModule['ACMClient']>;\n\t/** How long a certificate is waited on, and how often it is asked. */\n\twait: { timeoutMs: number; intervalMs: number };\n}\n\nexport type CdnClientFactory = (\n\tcredential: AwsProvisioning,\n) => Promise<CdnClients>;\n\nexport const defaultCdnClients: CdnClientFactory = async (credential) => {\n\tconst CF = await import('@aws-sdk/client-cloudfront');\n\tconst ACM = await import('@aws-sdk/client-acm');\n\tconst config = await awsClientConfig(credential, CDN_REGION);\n\tconst cloudfront = awsEndpoint(process.env, 'CLOUDFRONT');\n\tconst acm = awsEndpoint(process.env, 'ACM');\n\treturn {\n\t\tCF,\n\t\tACM,\n\t\tcloudfront: new CF.CloudFrontClient({\n\t\t\t...config,\n\t\t\t...(cloudfront ? { endpoint: cloudfront } : {}),\n\t\t}),\n\t\tacm: new ACM.ACMClient({ ...config, ...(acm ? { endpoint: acm } : {}) }),\n\t\t// ACM issues within minutes of seeing the record; DNS decides how many.\n\t\twait: { timeoutMs: 15 * 60_000, intervalMs: 10_000 },\n\t};\n};\n\nlet makeCdnClients: CdnClientFactory = defaultCdnClients;\n\n/** Replace the client factory — a test intercepting a call. Returns the old one. */\nexport function useCdnClients(factory: CdnClientFactory): CdnClientFactory {\n\tconst previous = makeCdnClients;\n\tmakeCdnClients = factory;\n\treturn previous;\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\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\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** What stands in for an id a dry run would create. */\nconst PLANNED = '(created by this deploy)';\n\n// ---------------------------------------------------------------------------\n// Ensuring\n// ---------------------------------------------------------------------------\n\nexport interface BucketCdnInput {\n\tbucket: string;\n\tregion: string;\n\tservers: readonly CdnServer[];\n\t/** The stage's sites, for CORS. */\n\torigins: readonly string[];\n}\n\nexport interface BucketCdn {\n\t/** Each distribution's ARN — what the bucket policy grants. */\n\tdistributionArns: string[];\n\t/** Each file server's public address, by its id. */\n\turls: Record<string, string>;\n}\n\n/** Each file server over a bucket, behind its own distribution. */\nexport async function ensureBucketCdn(\n\tctx: Ctx,\n\tinput: BucketCdnInput,\n): Promise<BucketCdn> {\n\tconst domain = ctx.workspace.domains?.[ctx.stage];\n\tif (!domain) {\n\t\tthrow new FileServerCdnNeedsDomain(input.servers[0]!.id, ctx.stage);\n\t}\n\tconst clients = await makeCdnClients(ctx.credential);\n\tconst out: BucketCdn = { distributionArns: [], urls: {} };\n\tfor (const server of input.servers) {\n\t\tconst { arn, url } = await ensureServerCdn(ctx, clients, {\n\t\t\t...input,\n\t\t\tserver,\n\t\t\thost: cdnHost(server.id, domain),\n\t\t\tprocessorHost: processorOriginHost(server.id, domain),\n\t\t});\n\t\tout.distributionArns.push(arn);\n\t\tout.urls[server.id] = url;\n\t}\n\treturn out;\n}\n\nasync function ensureServerCdn(\n\tctx: Ctx,\n\tclients: CdnClients,\n\tinput: BucketCdnInput & {\n\t\tserver: CdnServer;\n\t\thost: string;\n\t\tprocessorHost: string;\n\t},\n): Promise<{ arn: string; url: string }> {\n\tconst { server, host } = input;\n\tconst name = cdnName(ctx.identity.scope, ctx.stage, server.id);\n\tconst comment = `gkm ${ctx.identity.key} ${ctx.stage} ${server.id}`.slice(\n\t\t0,\n\t\t128,\n\t);\n\n\tconst certificateArn = await ensureCertificate(ctx, clients, {\n\t\tid: server.id,\n\t\thost,\n\t\tname,\n\t});\n\tconst originAccessControlId = await ensureOriginAccessControl(ctx, clients, {\n\t\tid: server.id,\n\t\tname,\n\t\tbucket: input.bucket,\n\t});\n\tconst corsPolicyId =\n\t\tinput.origins.length > 0\n\t\t\t? await ensureHeadersPolicy(ctx, clients, {\n\t\t\t\t\tid: server.id,\n\t\t\t\t\tkind: 'cors',\n\t\t\t\t\tconfig: headersPolicyConfig({\n\t\t\t\t\t\tname: `${name}-cors`,\n\t\t\t\t\t\tcomment: `${comment}: CORS`,\n\t\t\t\t\t\torigins: input.origins,\n\t\t\t\t\t\timmutable: false,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t: undefined;\n\tconst immutablePolicyId =\n\t\tserver.immutable.length > 0\n\t\t\t? await ensureHeadersPolicy(ctx, clients, {\n\t\t\t\t\tid: server.id,\n\t\t\t\t\tkind: 'immutable',\n\t\t\t\t\tconfig: headersPolicyConfig({\n\t\t\t\t\t\tname: `${name}-immutable`,\n\t\t\t\t\t\tcomment: `${comment}: CORS and Cache-Control immutable`,\n\t\t\t\t\t\torigins: input.origins,\n\t\t\t\t\t\timmutable: true,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t: undefined;\n\n\tconst processors = server.processors?.length\n\t\t? {\n\t\t\t\tprefixes: server.processors,\n\t\t\t\thost: input.processorHost,\n\t\t\t\tsecret: await ensureOriginSecret(ctx, server.id),\n\t\t\t}\n\t\t: undefined;\n\n\tconst distribution = await ensureDistribution(ctx, clients, {\n\t\tid: server.id,\n\t\tcomment,\n\t\tconfig: distributionConfig({\n\t\t\tcomment,\n\t\t\tcallerReference: name,\n\t\t\thost,\n\t\t\tcertificateArn,\n\t\t\tbucketDomain: `${input.bucket}.s3.${input.region}.amazonaws.com`,\n\t\t\toriginAccessControlId,\n\t\t\t...(corsPolicyId ? { corsPolicyId } : {}),\n\t\t\t...(immutablePolicyId ? { immutablePolicyId } : {}),\n\t\t\timmutable: server.immutable,\n\t\t\t...(processors ? { processors } : {}),\n\t\t}),\n\t});\n\n\tif (distribution.domainName !== PLANNED) {\n\t\tconst written = await ctx.writeDns([\n\t\t\t{ host, type: 'CNAME', value: distribution.domainName },\n\t\t]);\n\t\tif (written.manual.includes(host)) {\n\t\t\tctx.log(\n\t\t\t\t` ${host} answers once that record exists — ${server.id}'s URL is https://${host}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn { arn: distribution.arn, url: `https://${host}` };\n}\n\n/**\n * The secret the CDN sends a file server's processors: the one in the stage's\n * secrets, or a new one written there — read by the stack, whose edge checks\n * it, when it composes.\n */\nasync function ensureOriginSecret(ctx: Ctx, serverId: string): Promise<string> {\n\tconst key = originSecretKey(serverId);\n\tconst kept = ctx.secrets[key];\n\tif (kept) return kept;\n\tconst secret = newOriginSecret();\n\tctx.log(` ${serverId}: a new processor origin secret, kept as ${key}`);\n\tawait ctx.writeSecrets({ [key]: secret });\n\treturn secret;\n}\n\n/** The certificate for `host`: recorded, adopted, or requested — then issued. */\nasync function ensureCertificate(\n\tctx: Ctx,\n\tclients: CdnClients,\n\tinput: { id: string; host: string; name: string },\n): Promise<string> {\n\tconst { ACM, acm } = clients;\n\tconst { id, host } = input;\n\tconst entry: StateEntry = {\n\t\tkey: `acm-certificate:${id}`,\n\t\ttype: 'acm-certificate',\n\t\tdata: { host },\n\t};\n\tconst describe = (arn: string) =>\n\t\treadOr(\n\t\t\t() =>\n\t\t\t\tacm.send(new ACM.DescribeCertificateCommand({ CertificateArn: arn })),\n\t\t\t['ResourceNotFoundException'],\n\t\t).then((out) => out?.Certificate);\n\n\tlet arn: string | undefined;\n\tconst recorded = ctx.state.record(entry.key);\n\tif (recorded?.id && recorded.data?.host === host) {\n\t\tconst found = await describe(recorded.id);\n\t\tconst usable =\n\t\t\tfound &&\n\t\t\tfound.Status !== 'FAILED' &&\n\t\t\tfound.Status !== 'VALIDATION_TIMED_OUT' &&\n\t\t\tfound.Status !== 'REVOKED' &&\n\t\t\tfound.Status !== 'EXPIRED';\n\t\tif (usable) arn = recorded.id;\n\t}\n\tif (!arn) {\n\t\tarn = await findCertificate(clients, host);\n\t\tif (arn) ctx.log(` adopting the certificate for ${host} — ${arn}`);\n\t}\n\tif (!arn) {\n\t\tif (ctx.dryRun) {\n\t\t\tawait ctx.change(\n\t\t\t\t{\n\t\t\t\t\tconstruct: id,\n\t\t\t\t\tresource: `certificate ${host}`,\n\t\t\t\t\tchange: 'request (ACM, us-east-1, DNS-validated)',\n\t\t\t\t},\n\t\t\t\tasync () => {},\n\t\t\t);\n\t\t\treturn PLANNED;\n\t\t}\n\t\tawait ctx.state.pending(entry);\n\t\tconst requested = await acm.send(\n\t\t\tnew ACM.RequestCertificateCommand({\n\t\t\t\tDomainName: host,\n\t\t\t\tValidationMethod: 'DNS',\n\t\t\t\tIdempotencyToken: input.name.replace(/[^A-Za-z0-9]/g, '').slice(0, 32),\n\t\t\t\tTags: identityTags(ctx, id).map((t) => ({\n\t\t\t\t\tKey: t.Key,\n\t\t\t\t\tValue: t.Value,\n\t\t\t\t})),\n\t\t\t}),\n\t\t);\n\t\tarn = requested.CertificateArn!;\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `certificate ${host}`,\n\t\t\t\tchange: 'request (ACM, us-east-1, DNS-validated)',\n\t\t\t},\n\t\t\tasync () => {},\n\t\t);\n\t}\n\tif (!ctx.dryRun) await ctx.state.ready(entry, arn);\n\n\t// ACM publishes the validation record moments after the request.\n\tlet certificate = await describe(arn);\n\tlet record = certificate?.DomainValidationOptions?.[0]?.ResourceRecord;\n\tfor (let i = 0; !record && i < 15; i++) {\n\t\tawait sleep(Math.min(clients.wait.intervalMs, 2000));\n\t\tcertificate = await describe(arn);\n\t\trecord = certificate?.DomainValidationOptions?.[0]?.ResourceRecord;\n\t}\n\t// Written whether or not it is issued: ACM renews against the same record.\n\tconst validation = record\n\t\t? {\n\t\t\t\tname: record.Name!.replace(/\\.$/, ''),\n\t\t\t\tvalue: record.Value!.replace(/\\.$/, ''),\n\t\t\t}\n\t\t: undefined;\n\tconst written = validation\n\t\t? await ctx.writeDns([\n\t\t\t\t{ host: validation.name, type: 'CNAME', value: validation.value },\n\t\t\t])\n\t\t: { manual: [] };\n\n\tif (certificate?.Status === 'ISSUED' || ctx.dryRun) return arn;\n\tif (validation && written.manual.includes(validation.name.toLowerCase())) {\n\t\tthrow new CdnCertificatePending(id, host, validation, 'manual');\n\t}\n\n\tctx.log(` waiting for ACM to issue the certificate for ${host}…`);\n\tconst deadline = Date.now() + clients.wait.timeoutMs;\n\twhile (\n\t\tcertificate?.Status === 'PENDING_VALIDATION' &&\n\t\tDate.now() < deadline\n\t) {\n\t\tawait sleep(clients.wait.intervalMs);\n\t\tcertificate = await describe(arn);\n\t}\n\tif (certificate?.Status === 'ISSUED') return arn;\n\tif (certificate?.Status === 'PENDING_VALIDATION' || !certificate) {\n\t\tthrow new CdnCertificatePending(\n\t\t\tid,\n\t\t\thost,\n\t\t\tvalidation ?? { name: `(not published yet) ${host}`, value: '' },\n\t\t\t'timeout',\n\t\t);\n\t}\n\tthrow new CdnCertificateFailed(\n\t\tid,\n\t\thost,\n\t\tcertificate.Status ?? 'unknown',\n\t\tcertificate.FailureReason,\n\t);\n}\n\n/** An issued or pending certificate for exactly `host`, if the account has one. */\nasync function findCertificate(\n\tclients: CdnClients,\n\thost: string,\n): Promise<string | undefined> {\n\tconst { ACM, acm } = clients;\n\tlet NextToken: string | undefined;\n\tdo {\n\t\tconst page = await acm.send(\n\t\t\tnew ACM.ListCertificatesCommand({\n\t\t\t\tCertificateStatuses: ['ISSUED', 'PENDING_VALIDATION'],\n\t\t\t\t...(NextToken ? { NextToken } : {}),\n\t\t\t}),\n\t\t);\n\t\tconst match = page.CertificateSummaryList?.find(\n\t\t\t(c) => c.DomainName?.toLowerCase() === host,\n\t\t);\n\t\tif (match?.CertificateArn) return match.CertificateArn;\n\t\tNextToken = page.NextToken;\n\t} while (NextToken);\n\treturn undefined;\n}\n\n/** The origin access control CloudFront signs its bucket requests with. */\nasync function ensureOriginAccessControl(\n\tctx: Ctx,\n\tclients: CdnClients,\n\tinput: { id: string; name: string; bucket: string },\n): Promise<string> {\n\tconst { CF, cloudfront } = clients;\n\tconst entry: StateEntry = {\n\t\tkey: `cloudfront-oac:${input.id}`,\n\t\ttype: 'cloudfront-oac',\n\t\tdata: { name: input.name },\n\t};\n\tconst recorded = ctx.state.record(entry.key)?.id;\n\tif (recorded) {\n\t\tconst found = await readOr(\n\t\t\t() =>\n\t\t\t\tcloudfront.send(new CF.GetOriginAccessControlCommand({ Id: recorded })),\n\t\t\t['NoSuchOriginAccessControl'],\n\t\t);\n\t\tif (found) return recorded;\n\t}\n\n\tlet Marker: string | undefined;\n\tdo {\n\t\tconst page = await cloudfront.send(\n\t\t\tnew CF.ListOriginAccessControlsCommand({ ...(Marker ? { Marker } : {}) }),\n\t\t);\n\t\tconst match = page.OriginAccessControlList?.Items?.find(\n\t\t\t(o) => o.Name === input.name,\n\t\t);\n\t\tif (match?.Id) {\n\t\t\tif (!ctx.dryRun) await ctx.state.ready(entry, match.Id);\n\t\t\treturn match.Id;\n\t\t}\n\t\tMarker = page.OriginAccessControlList?.NextMarker;\n\t} while (Marker);\n\n\tlet id = PLANNED;\n\tawait ctx.change(\n\t\t{\n\t\t\tconstruct: input.id,\n\t\t\tresource: `origin access control ${input.name}`,\n\t\t\tchange: `create (CloudFront signs its reads of ${input.bucket})`,\n\t\t},\n\t\tasync () => {\n\t\t\tawait ctx.state.pending(entry);\n\t\t\tconst created = await cloudfront.send(\n\t\t\t\tnew CF.CreateOriginAccessControlCommand({\n\t\t\t\t\tOriginAccessControlConfig: {\n\t\t\t\t\t\tName: input.name,\n\t\t\t\t\t\tDescription: `gkm: CloudFront's reads of ${input.bucket}`,\n\t\t\t\t\t\tOriginAccessControlOriginType: 's3',\n\t\t\t\t\t\tSigningBehavior: 'always',\n\t\t\t\t\t\tSigningProtocol: 'sigv4',\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t\tid = created.OriginAccessControl!.Id!;\n\t\t\tawait ctx.state.ready(entry, id);\n\t\t},\n\t);\n\treturn id;\n}\n\n/** One response headers policy, as wanted. */\nasync function ensureHeadersPolicy(\n\tctx: Ctx,\n\tclients: CdnClients,\n\tinput: { id: string; kind: string; config: ResponseHeadersPolicyConfig },\n): Promise<string> {\n\tconst { CF, cloudfront } = clients;\n\tconst { config } = input;\n\tconst entry: StateEntry = {\n\t\tkey: `cloudfront-headers:${input.id}:${input.kind}`,\n\t\ttype: 'cloudfront-headers',\n\t\tdata: { name: config.Name },\n\t};\n\tconst read = (Id: string) =>\n\t\treadOr(\n\t\t\t() =>\n\t\t\t\tcloudfront.send(new CF.GetResponseHeadersPolicyConfigCommand({ Id })),\n\t\t\t['NoSuchResponseHeadersPolicy'],\n\t\t);\n\n\tlet id = ctx.state.record(entry.key)?.id;\n\tlet current = id ? await read(id) : undefined;\n\tif (!current) {\n\t\tid = undefined;\n\t\tlet Marker: string | undefined;\n\t\tdo {\n\t\t\tconst page = await cloudfront.send(\n\t\t\t\tnew CF.ListResponseHeadersPoliciesCommand({\n\t\t\t\t\tType: 'custom',\n\t\t\t\t\t...(Marker ? { Marker } : {}),\n\t\t\t\t}),\n\t\t\t);\n\t\t\tconst match = page.ResponseHeadersPolicyList?.Items?.find(\n\t\t\t\t(p) =>\n\t\t\t\t\tp.ResponseHeadersPolicy?.ResponseHeadersPolicyConfig?.Name ===\n\t\t\t\t\tconfig.Name,\n\t\t\t);\n\t\t\tif (match?.ResponseHeadersPolicy?.Id) {\n\t\t\t\tid = match.ResponseHeadersPolicy.Id;\n\t\t\t\tcurrent = await read(id);\n\t\t\t}\n\t\t\tMarker = page.ResponseHeadersPolicyList?.NextMarker;\n\t\t} while (!id && Marker);\n\t}\n\n\tif (id && current) {\n\t\tif (!ctx.dryRun) await ctx.state.ready(entry, id);\n\t\tif (sameHeadersPolicy(current.ResponseHeadersPolicyConfig, config)) {\n\t\t\treturn id;\n\t\t}\n\t\tconst existing = id;\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: input.id,\n\t\t\t\tresource: `response headers policy ${config.Name}`,\n\t\t\t\tchange: 'put back what drifted',\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait cloudfront.send(\n\t\t\t\t\tnew CF.UpdateResponseHeadersPolicyCommand({\n\t\t\t\t\t\tId: existing,\n\t\t\t\t\t\tIfMatch: current!.ETag,\n\t\t\t\t\t\tResponseHeadersPolicyConfig: config,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\treturn existing;\n\t}\n\n\tlet created = PLANNED;\n\tawait ctx.change(\n\t\t{\n\t\t\tconstruct: input.id,\n\t\t\tresource: `response headers policy ${config.Name}`,\n\t\t\tchange: 'create',\n\t\t},\n\t\tasync () => {\n\t\t\tawait ctx.state.pending(entry);\n\t\t\tconst out = await cloudfront.send(\n\t\t\t\tnew CF.CreateResponseHeadersPolicyCommand({\n\t\t\t\t\tResponseHeadersPolicyConfig: config,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tcreated = out.ResponseHeadersPolicy!.Id!;\n\t\t\tawait ctx.state.ready(entry, created);\n\t\t},\n\t);\n\treturn created;\n}\n\n/** The distribution: recorded, found by its comment, or created — as wanted. */\nasync function ensureDistribution(\n\tctx: Ctx,\n\tclients: CdnClients,\n\tinput: { id: string; comment: string; config: DistributionConfig },\n): Promise<{ arn: string; domainName: string }> {\n\tconst { CF, cloudfront } = clients;\n\tconst entry: StateEntry = {\n\t\tkey: `cloudfront-distribution:${input.id}`,\n\t\ttype: 'cloudfront-distribution',\n\t};\n\tconst get = (Id: string) =>\n\t\treadOr(\n\t\t\t() => cloudfront.send(new CF.GetDistributionCommand({ Id })),\n\t\t\t['NoSuchDistribution'],\n\t\t);\n\n\tlet found = ctx.state.record(entry.key)?.id\n\t\t? await get(ctx.state.record(entry.key)!.id!)\n\t\t: undefined;\n\tif (!found) {\n\t\tlet Marker: string | undefined;\n\t\tdo {\n\t\t\tconst page = await cloudfront.send(\n\t\t\t\tnew CF.ListDistributionsCommand({ ...(Marker ? { Marker } : {}) }),\n\t\t\t);\n\t\t\tconst match = page.DistributionList?.Items?.find(\n\t\t\t\t(d) => d.Comment === input.comment,\n\t\t\t);\n\t\t\tif (match?.Id) found = await get(match.Id);\n\t\t\tMarker = page.DistributionList?.NextMarker;\n\t\t} while (!found && Marker);\n\t}\n\n\tif (found?.Distribution) {\n\t\tconst distribution = found.Distribution;\n\t\tconst id = distribution.Id!;\n\t\tconst located = {\n\t\t\tarn: distribution.ARN!,\n\t\t\tdomainName: distribution.DomainName!,\n\t\t};\n\t\tif (!ctx.dryRun) {\n\t\t\tawait ctx.state.ready({ ...entry, data: located }, id);\n\t\t}\n\t\tconst current = await cloudfront.send(\n\t\t\tnew CF.GetDistributionConfigCommand({ Id: id }),\n\t\t);\n\t\tif (holds(current.DistributionConfig, input.config)) return located;\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: input.id,\n\t\t\t\tresource: `distribution ${id}`,\n\t\t\t\tchange: 'put back what drifted',\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait cloudfront.send(\n\t\t\t\t\tnew CF.UpdateDistributionCommand({\n\t\t\t\t\t\tId: id,\n\t\t\t\t\t\tIfMatch: current.ETag,\n\t\t\t\t\t\t// What else it holds — logging, a WAF — kept.\n\t\t\t\t\t\tDistributionConfig: {\n\t\t\t\t\t\t\t...current.DistributionConfig!,\n\t\t\t\t\t\t\t...input.config,\n\t\t\t\t\t\t\tCallerReference: current.DistributionConfig!.CallerReference,\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\treturn located;\n\t}\n\n\tlet created = {\n\t\tarn: `arn:aws:cloudfront::${PLANNED}`,\n\t\tdomainName: PLANNED,\n\t};\n\tconst host = input.config.Aliases?.Items?.[0] ?? input.id;\n\tawait ctx.change(\n\t\t{\n\t\t\tconstruct: input.id,\n\t\t\tresource: `distribution ${host}`,\n\t\t\tchange: 'create (CloudFront, takes minutes to reach every edge)',\n\t\t},\n\t\tasync () => {\n\t\t\tawait ctx.state.pending(entry);\n\t\t\tconst out = await cloudfront.send(\n\t\t\t\tnew CF.CreateDistributionWithTagsCommand({\n\t\t\t\t\tDistributionConfigWithTags: {\n\t\t\t\t\t\tDistributionConfig: input.config,\n\t\t\t\t\t\tTags: {\n\t\t\t\t\t\t\tItems: identityTags(ctx, input.id).map((t) => ({\n\t\t\t\t\t\t\t\tKey: t.Key,\n\t\t\t\t\t\t\t\tValue: t.Value,\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\tcreated = {\n\t\t\t\tarn: out.Distribution!.ARN!,\n\t\t\t\tdomainName: out.Distribution!.DomainName!,\n\t\t\t};\n\t\t\tawait ctx.state.ready({ ...entry, data: created }, out.Distribution!.Id!);\n\t\t},\n\t);\n\treturn created;\n}\n","/**\n * A bucket's changes, delivered — the `s3` provider's half of object events.\n *\n * S3 can tell only AWS services that an object changed, so for each bucket a\n * subscriber watches the deploy creates, in the stage's account:\n *\n * - **a topic**, `<bucket>-events`, that only this bucket may publish to;\n * - **a dead-letter queue**, `<bucket>-events-dlq`, for what SNS gives up\n * delivering — an outage longer than its retries would otherwise lose\n * uploads;\n * - **the bucket's notification entry**, `gkm-<id>`, sending every create and\n * delete to the topic — merged in, so an entry somebody added by hand stays;\n * - **the events key**, `<ID>_EVENTS_CONNECTION_STRING`, signed by the\n * bucket's own access key, whose policy gains `sns:ConfirmSubscription` on\n * this one topic and nothing more;\n * - **one HTTP subscription per subscriber**, to its route on its worker's\n * host. The deploy owns these — the worker cannot subscribe — and records\n * each ARN for the worker to accept deliveries under.\n *\n * Nothing is deleted except a subscription to the worker's own host that no\n * subscriber wants any more.\n */\n\nimport type {\n\tConstructManifest,\n\tObjectsDeclaration,\n} from '@geekmidas/manifest';\nimport { provideKey } from '@geekmidas/manifest';\nimport * as s3Url from '@geekmidas/storage/s3-url';\nimport {\n\tsubscriptionKey,\n\tsubscriptionResource,\n} from '../../deploy/snsSubscriptions.js';\nimport { GkmError } from '../../errors';\nimport { subscriberRoute } from '../../generators/subscriberRoute.js';\nimport type { BoundSubscriber } from '../../reconcile/discover.js';\nimport { eventsEdge } from '../../reconcile/edges.js';\nimport { NoDomainForStage } from '../../target/dokploy/domain.js';\nimport { appKey } from '../../workspace/derive.js';\nimport type { S3ObjectsConfig } from '../../workspace/types.js';\nimport { type AwsProvisioning, awsClientConfig, awsEndpoint } from '../aws.js';\nimport { deploysWithCompose } from '../dns.js';\nimport { identityTags } from '../iam.js';\nimport type { EnsureContext } from '../types.js';\nimport { canonicalPolicy, type PolicyDocument } from './policy.js';\n\ntype Ctx = EnsureContext<S3ObjectsConfig, AwsProvisioning>;\ntype SnsModule = typeof import('@aws-sdk/client-sns');\ntype SqsModule = typeof import('@aws-sdk/client-sqs');\ntype S3Module = typeof import('@aws-sdk/client-s3');\n\n/** What S3 tells the topic about: every object written, and every removed. */\nexport const BUCKET_EVENTS = ['s3:ObjectCreated:*', 's3:ObjectRemoved:*'];\n\n/** One subscriber watching a bucket: the worker that runs it, and its export. */\nexport interface BucketWatcher {\n\tworker: string;\n\tname: string;\n}\n\n/**\n * Each bucket a subscriber watches, with the subscribers discovery could name.\n *\n * A bucket is watched when a process consumes its events — discovery records\n * the edge, and the subscriber by its export — or when a build put a\n * subscriber in its declaration. Only a named subscriber can be subscribed: a\n * route is named after its export.\n */\nexport function bucketWatchers(\n\tmanifest: ConstructManifest,\n\trunnables: Readonly<Record<string, readonly string[]>>,\n\tsubscribers: Readonly<Record<string, readonly BoundSubscriber[]>> = {},\n): Map<string, BucketWatcher[]> {\n\tconst watched = new Map<string, BucketWatcher[]>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tif (declaration.kind !== 'objects') continue;\n\t\tconst key = provideKey(id, 'eventsConnectionString');\n\t\tconst named = Object.entries(subscribers)\n\t\t\t.flatMap(([worker, bound]) =>\n\t\t\t\tbound\n\t\t\t\t\t.filter((s) => s.connectionKey === key)\n\t\t\t\t\t.map((s) => ({ worker, name: s.name })),\n\t\t\t)\n\t\t\t.sort((a, b) =>\n\t\t\t\t`${a.worker}/${a.name}`.localeCompare(`${b.worker}/${b.name}`),\n\t\t\t);\n\t\tconst edged = Object.values(runnables).some((edges) =>\n\t\t\tedges.includes(eventsEdge(id)),\n\t\t);\n\t\tconst declared =\n\t\t\t((declaration as ObjectsDeclaration).subscribers?.length ?? 0) > 0;\n\t\tif (named.length > 0 || edged || declared) watched.set(id, named);\n\t}\n\treturn watched;\n}\n\n/** The topic a bucket's changes are published to. */\nexport function eventsTopicName(bucket: string): string {\n\t// A bucket name may hold dots; a topic or queue name may not.\n\treturn `${bucket.replaceAll('.', '-')}-events`;\n}\n\n/** What SNS gives up delivering, kept. */\nexport function eventsDeadLetterName(bucket: string): string {\n\treturn `${eventsTopicName(bucket)}-dlq`;\n}\n\n/** Only this bucket, in this account, may publish to its topic. */\nexport function eventsTopicPolicy(\n\ttopicArn: string,\n\tbucket: string,\n\taccount: string,\n): PolicyDocument {\n\treturn {\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tSid: 'GkmBucketPublishes',\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tPrincipal: { Service: 's3.amazonaws.com' },\n\t\t\t\tAction: 'sns:Publish',\n\t\t\t\tResource: topicArn,\n\t\t\t\tCondition: {\n\t\t\t\t\tArnLike: { 'aws:SourceArn': `arn:aws:s3:::${bucket}` },\n\t\t\t\t\tStringEquals: { 'aws:SourceAccount': account },\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** Only the bucket's topic may send to its dead-letter queue. */\nexport function eventsDeadLetterPolicy(\n\tqueueArn: string,\n\ttopicArn: string,\n): PolicyDocument {\n\treturn {\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tSid: 'GkmTopicDeadLetters',\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tPrincipal: { Service: 'sns.amazonaws.com' },\n\t\t\t\tAction: 'sqs:SendMessage',\n\t\t\t\tResource: queueArn,\n\t\t\t\tCondition: { ArnEquals: { 'aws:SourceArn': topicArn } },\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** A bucket's notification entry, as S3 spells it. */\nexport interface TopicNotification {\n\tId?: string;\n\tTopicArn: string | undefined;\n\tEvents: string[] | undefined;\n\tFilter?: unknown;\n}\n\n/** A bucket's notification configuration, as far as this provider reads it. */\nexport interface BucketNotifications {\n\tTopicConfigurations?: TopicNotification[];\n\t[other: string]: unknown;\n}\n\n/** The id this provider's notification entry goes under. */\nexport const notificationId = (id: string) => `gkm-${id}`;\n\n/**\n * The bucket's notifications with this provider's entry put back, and whether\n * that changed anything. Every other entry — a queue, a function, a topic\n * somebody added by hand — is kept exactly as it was.\n */\nexport function mergedNotifications(\n\tcurrent: BucketNotifications,\n\tid: string,\n\ttopicArn: string,\n): { config: BucketNotifications; changed: boolean } {\n\tconst own = notificationId(id);\n\tconst wanted: TopicNotification = {\n\t\tId: own,\n\t\tTopicArn: topicArn,\n\t\tEvents: [...BUCKET_EVENTS],\n\t};\n\tconst topics = current.TopicConfigurations ?? [];\n\tconst existing = topics.find((t) => t.Id === own);\n\tconst same =\n\t\texisting !== undefined &&\n\t\texisting.TopicArn === topicArn &&\n\t\tJSON.stringify([...(existing.Events ?? [])].sort()) ===\n\t\t\tJSON.stringify([...BUCKET_EVENTS].sort()) &&\n\t\texisting.Filter === undefined;\n\tconst { ResponseMetadata: _, ...rest } = current as BucketNotifications & {\n\t\tResponseMetadata?: unknown;\n\t};\n\treturn {\n\t\tconfig: {\n\t\t\t...rest,\n\t\t\tTopicConfigurations: [...topics.filter((t) => t.Id !== own), wanted],\n\t\t},\n\t\tchanged: !same,\n\t};\n}\n\n/** S3 refused the entry because another one already covers these events. */\nexport class BucketNotificationsOverlap extends GkmError {\n\tconstructor(\n\t\treadonly bucket: string,\n\t\treadonly detail: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${bucket}' already sends object creates or deletes somewhere else, ` +\n\t\t\t\t`and S3 sends each event to one place only, so the deploy cannot ` +\n\t\t\t\t`add its own entry. Remove the other notification from the bucket, ` +\n\t\t\t\t`or give it a prefix, and deploy again. S3 said: ${detail}`,\n\t\t);\n\t\tthis.name = 'BucketNotificationsOverlap';\n\t}\n}\n\n/** The topic and the dead-letter queue a watched bucket publishes through. */\nexport interface BucketEvents {\n\ttopicArn: string;\n\tdeadLetterArn: string;\n}\n\ninterface EventsClients {\n\tSNS: SnsModule;\n\tSQS: SqsModule;\n\tsns: InstanceType<SnsModule['SNSClient']>;\n\tsqs: InstanceType<SqsModule['SQSClient']>;\n\taccount: string;\n\tregion: string;\n\t/** An emulator's SNS endpoint, when the environment names one. */\n\tendpoint?: string;\n}\n\n/** Clients for a bucket's events, for tests to replace. */\nexport type EventsClientFactory = (\n\tcredential: AwsProvisioning,\n\tregion: string,\n) => Promise<EventsClients>;\n\nexport const defaultEventsClients: EventsClientFactory = async (\n\tcredential,\n\tregion,\n) => {\n\tconst SNS = await import('@aws-sdk/client-sns');\n\tconst SQS = await import('@aws-sdk/client-sqs');\n\tconst { STSClient, GetCallerIdentityCommand } = await import(\n\t\t'@aws-sdk/client-sts'\n\t);\n\tconst config = await awsClientConfig(credential, region);\n\tconst endpoint = awsEndpoint(process.env, 'SNS');\n\tconst sts = new STSClient({\n\t\t...config,\n\t\t...(awsEndpoint(process.env, 'STS')\n\t\t\t? { endpoint: awsEndpoint(process.env, 'STS') }\n\t\t\t: {}),\n\t});\n\tconst { Account } = await sts.send(new GetCallerIdentityCommand({}));\n\tsts.destroy();\n\treturn {\n\t\tSNS,\n\t\tSQS,\n\t\tsns: new SNS.SNSClient({ ...config, ...(endpoint ? { endpoint } : {}) }),\n\t\tsqs: new SQS.SQSClient({\n\t\t\t...config,\n\t\t\t...(awsEndpoint(process.env, 'SQS')\n\t\t\t\t? { endpoint: awsEndpoint(process.env, 'SQS') }\n\t\t\t\t: {}),\n\t\t}),\n\t\taccount: Account!,\n\t\tregion,\n\t\t...(endpoint ? { endpoint } : {}),\n\t};\n};\n\nlet makeEventsClients: EventsClientFactory = defaultEventsClients;\n\n/** Replace the client factory — a test intercepting a call. Returns the old one. */\nexport function useEventsClients(\n\tfactory: EventsClientFactory,\n): EventsClientFactory {\n\tconst previous = makeEventsClients;\n\tmakeEventsClients = factory;\n\treturn previous;\n}\n\nfunction errorName(error: unknown): string {\n\tconst e = error as { name?: string; Code?: string; code?: string };\n\treturn e?.name ?? e?.Code ?? e?.code ?? '';\n}\n\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\n/**\n * The topic, its policy, the dead-letter queue and the bucket's notification\n * entry for one watched bucket — created where missing, put back where they\n * drifted.\n */\nexport async function ensureBucketEvents(\n\tctx: Ctx,\n\ts3: { S3: S3Module; s3: InstanceType<S3Module['S3Client']> },\n\tinput: { id: string; bucket: string; region: string },\n): Promise<BucketEvents> {\n\tconst { id, bucket, region } = input;\n\tconst clients = await makeEventsClients(ctx.credential, region);\n\tconst { SNS, SQS, sns, sqs, account } = clients;\n\n\tconst topicName = eventsTopicName(bucket);\n\tconst topicArn = `arn:aws:sns:${region}:${account}:${topicName}`;\n\tconst topicEntry = { key: `sns-topic:${id}`, type: 'sns-topic' };\n\tconst topic = await readOr(\n\t\t() => sns.send(new SNS.GetTopicAttributesCommand({ TopicArn: topicArn })),\n\t\t['NotFound', 'NotFoundException'],\n\t);\n\tif (topic) {\n\t\tawait ctx.state.ready(topicEntry, topicArn);\n\t} else {\n\t\tawait ctx.change(\n\t\t\t{ construct: id, resource: `SNS topic ${topicName}`, change: 'create' },\n\t\t\tasync () => {\n\t\t\t\tawait ctx.state.pending(topicEntry);\n\t\t\t\tawait sns.send(\n\t\t\t\t\tnew SNS.CreateTopicCommand({\n\t\t\t\t\t\tName: topicName,\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(topicEntry, topicArn);\n\t\t\t},\n\t\t);\n\t}\n\n\tconst topicPolicy = eventsTopicPolicy(topicArn, bucket, account);\n\tconst currentTopicPolicy = topic?.Attributes?.Policy;\n\tif (\n\t\t!currentTopicPolicy ||\n\t\tcanonicalPolicy(JSON.parse(currentTopicPolicy)) !==\n\t\t\tcanonicalPolicy(topicPolicy)\n\t) {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `SNS topic ${topicName}`,\n\t\t\t\tchange: `publishable by '${bucket}' only`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait sns.send(\n\t\t\t\t\tnew SNS.SetTopicAttributesCommand({\n\t\t\t\t\t\tTopicArn: topicArn,\n\t\t\t\t\t\tAttributeName: 'Policy',\n\t\t\t\t\t\tAttributeValue: JSON.stringify(topicPolicy),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t}\n\n\tconst queueName = eventsDeadLetterName(bucket);\n\tconst deadLetterArn = `arn:aws:sqs:${region}:${account}:${queueName}`;\n\tconst queueEntry = { key: `sqs-queue:${id}-events-dlq`, type: 'sqs-queue' };\n\tconst queue = await readOr(\n\t\t() => sqs.send(new SQS.GetQueueUrlCommand({ QueueName: queueName })),\n\t\t['QueueDoesNotExist', 'AWS.SimpleQueueService.NonExistentQueue'],\n\t);\n\tlet queueUrl = queue?.QueueUrl;\n\tif (queueUrl) {\n\t\tawait ctx.state.ready(queueEntry, deadLetterArn);\n\t} else {\n\t\tawait ctx.change(\n\t\t\t{ construct: id, resource: `SQS queue ${queueName}`, change: 'create' },\n\t\t\tasync () => {\n\t\t\t\tawait ctx.state.pending(queueEntry);\n\t\t\t\tconst created = await sqs.send(\n\t\t\t\t\tnew SQS.CreateQueueCommand({\n\t\t\t\t\t\tQueueName: queueName,\n\t\t\t\t\t\t// The longest SQS keeps anything: a dead letter is read by a\n\t\t\t\t\t\t// person, later.\n\t\t\t\t\t\tAttributes: { MessageRetentionPeriod: '1209600' },\n\t\t\t\t\t\ttags: Object.fromEntries(\n\t\t\t\t\t\t\tidentityTags(ctx, id).map((t) => [t.Key, t.Value]),\n\t\t\t\t\t\t),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tqueueUrl = created.QueueUrl;\n\t\t\t\tawait ctx.state.ready(queueEntry, deadLetterArn);\n\t\t\t},\n\t\t);\n\t}\n\n\tconst queuePolicy = eventsDeadLetterPolicy(deadLetterArn, topicArn);\n\tconst currentQueuePolicy = queue?.QueueUrl\n\t\t? (\n\t\t\t\tawait sqs.send(\n\t\t\t\t\tnew SQS.GetQueueAttributesCommand({\n\t\t\t\t\t\tQueueUrl: queue.QueueUrl,\n\t\t\t\t\t\tAttributeNames: ['Policy'],\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t).Attributes?.Policy\n\t\t: undefined;\n\tif (\n\t\t!currentQueuePolicy ||\n\t\tcanonicalPolicy(JSON.parse(currentQueuePolicy)) !==\n\t\t\tcanonicalPolicy(queuePolicy)\n\t) {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `SQS queue ${queueName}`,\n\t\t\t\tchange: `receives what ${topicName} cannot deliver`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tawait sqs.send(\n\t\t\t\t\tnew SQS.SetQueueAttributesCommand({\n\t\t\t\t\t\tQueueUrl: queueUrl!,\n\t\t\t\t\t\tAttributes: { Policy: JSON.stringify(queuePolicy) },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t}\n\n\t// The bucket tells the topic last: S3 checks it may publish when the entry\n\t// is written, which the topic's policy above is what allows.\n\tconst current = (await readOr(\n\t\t() =>\n\t\t\ts3.s3.send(\n\t\t\t\tnew s3.S3.GetBucketNotificationConfigurationCommand({ Bucket: bucket }),\n\t\t\t),\n\t\t['NoSuchBucket'],\n\t)) as BucketNotifications | undefined;\n\tconst merged = mergedNotifications(current ?? {}, id, topicArn);\n\tif (merged.changed) {\n\t\tawait ctx.change(\n\t\t\t{\n\t\t\t\tconstruct: id,\n\t\t\t\tresource: `bucket ${bucket}`,\n\t\t\t\tchange: `send object creates and deletes to ${topicName}`,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait s3.s3.send(\n\t\t\t\t\t\tnew s3.S3.PutBucketNotificationConfigurationCommand({\n\t\t\t\t\t\t\tBucket: bucket,\n\t\t\t\t\t\t\tNotificationConfiguration: merged.config as never,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = (error as Error).message ?? '';\n\t\t\t\t\tif (/overlap/i.test(message)) {\n\t\t\t\t\t\tthrow new BucketNotificationsOverlap(bucket, message);\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}\n\n\tsns.destroy();\n\tsqs.destroy();\n\treturn { topicArn, deadLetterArn };\n}\n\n/**\n * The events key: the topic's address, signed by the bucket's own access key\n * — read off the bucket's URL, so a rotated key rotates this one with it.\n */\nexport async function ensureEventsKey(\n\tctx: Ctx,\n\tinput: { id: string; topicArn: string; region: string },\n): Promise<void> {\n\tconst { id, topicArn, region } = input;\n\tconst key = provideKey(id, 'eventsConnectionString');\n\tconst url = ctx.secrets[provideKey(id, 'url')];\n\tlet parsed: s3Url.S3Address | undefined;\n\ttry {\n\t\tparsed = url ? s3Url.parse(url) : undefined;\n\t} catch {\n\t\tparsed = undefined;\n\t}\n\tif (!parsed?.accessKeyId || !parsed.secretAccessKey) {\n\t\t// Only a dry run gets here: the key is issued above, before this.\n\t\tawait ctx.change(\n\t\t\t{ construct: id, resource: key, change: 'set to the topic’s address' },\n\t\t\tasync () => {},\n\t\t);\n\t\treturn;\n\t}\n\n\tconst { snsUrl } = await import('@geekmidas/events/sns');\n\tconst endpoint = awsEndpoint(process.env, 'SNS');\n\tconst address = new URL(\n\t\tsnsUrl.build({ topicArn, region, ...(endpoint ? { endpoint } : {}) }),\n\t);\n\taddress.searchParams.set('accessKeyId', parsed.accessKeyId);\n\taddress.searchParams.set('secretAccessKey', parsed.secretAccessKey);\n\tconst value = address.toString();\n\n\tconst entry = { key: `events-key:${id}`, type: 'url' };\n\tif (ctx.secrets[key] === value) {\n\t\tawait ctx.state.ready(entry, topicArn);\n\t\treturn;\n\t}\n\tawait ctx.change(\n\t\t{ construct: id, resource: key, change: `set to ${topicArn}` },\n\t\tasync () => {\n\t\t\tawait ctx.writeSecrets({ [key]: value });\n\t\t\tawait ctx.state.ready(entry, topicArn);\n\t\t},\n\t);\n}\n\n/** Where SNS pushes to a worker: its own host on the stage's domain. */\nexport function workerPushHost(worker: string, domain: string): string {\n\treturn `${appKey(worker)}.${domain}`;\n}\n\n/**\n * One HTTP subscription per subscriber to the bucket's topic, at its route on\n * its worker's host, with the bucket's dead-letter queue — and each ARN\n * recorded, which is what the worker accepts deliveries under.\n *\n * Unfiltered: a bucket's notifications carry no `type` attribute, and the\n * subscriber's own filter — events, prefix, suffix — is what decides. Only a\n * compose stage pushes to a worker; any other is told so and left alone.\n */\nexport async function ensurePushSubscriptions(\n\tctx: Ctx,\n\tinput: {\n\t\tid: string;\n\t\tevents: BucketEvents;\n\t\tregion: string;\n\t\twatchers: readonly BucketWatcher[];\n\t},\n): Promise<void> {\n\tconst { id, events, region, watchers } = input;\n\tif (!deploysWithCompose(ctx.workspace)) {\n\t\tctx.log(\n\t\t\t` '${id}' is watched, and only a compose stage pushes a bucket's changes to a worker: its subscribers receive nothing on '${ctx.stage}'`,\n\t\t);\n\t\treturn;\n\t}\n\tif (watchers.length === 0) return;\n\tconst domain = ctx.workspace.domains?.[ctx.stage];\n\tif (!domain) throw new NoDomainForStage(ctx.stage);\n\n\tconst { SNSConnection, reconcileHttpSubscriptions } = await import(\n\t\t'@geekmidas/events/sns'\n\t);\n\tconst { credentials } = await awsClientConfig(ctx.credential, region);\n\tconst endpoint = awsEndpoint(process.env, 'SNS');\n\n\tconst byWorker = new Map<string, BucketWatcher[]>();\n\tfor (const watcher of watchers) {\n\t\tbyWorker.set(watcher.worker, [\n\t\t\t...(byWorker.get(watcher.worker) ?? []),\n\t\t\twatcher,\n\t\t]);\n\t}\n\n\tfor (const [worker, own] of byWorker) {\n\t\tconst host = workerPushHost(worker, domain);\n\t\tconst endpoints = own.map(({ name }) => ({\n\t\t\tname,\n\t\t\tendpoint: `https://${host}${subscriberRoute(name)}`,\n\t\t\tdeadLetterQueueArn: events.deadLetterArn,\n\t\t}));\n\t\tconst unrecorded = own.filter(\n\t\t\t({ name }) =>\n\t\t\t\tctx.state.record(subscriptionKey(worker, name))?.status !== 'ready',\n\t\t);\n\t\tif (ctx.dryRun) {\n\t\t\tif (unrecorded.length > 0) {\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: `SNS subscriptions on ${host}`,\n\t\t\t\t\t\tchange: `subscribe ${unrecorded.map((w) => w.name).join(', ')}`,\n\t\t\t\t\t},\n\t\t\t\t\tasync () => {},\n\t\t\t\t);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst connection = new SNSConnection({\n\t\t\ttopicArn: events.topicArn,\n\t\t\tregion,\n\t\t\t...(endpoint ? { endpoint } : {}),\n\t\t\t...(credentials ? { credentials } : {}),\n\t\t});\n\t\tconst result = await reconcileHttpSubscriptions(connection, {\n\t\t\tendpoints,\n\t\t\townedHost: host,\n\t\t});\n\t\tawait connection.close();\n\n\t\tfor (const spec of endpoints) {\n\t\t\tconst arn = result.subscriptions[spec.name]!;\n\t\t\tconst pending = result.pending.includes(spec.name);\n\t\t\tconst recorded = ctx.state.record(subscriptionKey(worker, spec.name));\n\t\t\tif (recorded?.id !== arn) {\n\t\t\t\tctx.log(\n\t\t\t\t\t` ✓ '${spec.name}' subscribed to ${events.topicArn.split(':').pop()} at ${spec.endpoint}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst { key, type, data } = subscriptionResource(\n\t\t\t\t{\n\t\t\t\t\tworker,\n\t\t\t\t\tname: spec.name,\n\t\t\t\t\ttopicArn: events.topicArn,\n\t\t\t\t\tendpoint: spec.endpoint,\n\t\t\t\t\tdeadLetterQueueArn: events.deadLetterArn,\n\t\t\t\t\tpending,\n\t\t\t\t},\n\t\t\t\tarn,\n\t\t\t);\n\t\t\tawait ctx.state.ready({ key, type, ...(data ? { data } : {}) }, arn);\n\t\t}\n\t\tfor (const arn of result.removed) {\n\t\t\tctx.log(` – unsubscribed ${arn}: no subscriber wants it any more`);\n\t\t}\n\t}\n}\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 * `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 { bucketExpiry, 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 {\n\tensureAccessKey,\n\tensureIamUser,\n\tidentityTags,\n\tissuedJustNow,\n\tTAG_PROJECT,\n\twhileKeyIsNew,\n} from '../iam.js';\nimport type {\n\tEnsureContext,\n\tResourceProvider,\n\tStateEntry,\n\tVerifyContext,\n} from '../types.js';\nimport { ensureBucketCdn } from './cdn.js';\nimport { checkS3Config, S3_PROVISIONING } from './config.js';\nimport {\n\tBucketNameUnavailable,\n\tBucketOwnedByAnotherProject,\n\tBucketProbeFailed,\n\tBucketRegionMismatch,\n\tBucketRegionUnknown,\n\tProvisionedBucketUnreachable,\n\tRecordedBucketUnreachable,\n\tS3RegionRequired,\n} from './errors.js';\nimport {\n\ttype BucketWatcher,\n\tbucketWatchers,\n\tensureBucketEvents,\n\tensureEventsKey,\n\tensurePushSubscriptions,\n} from './events.js';\nimport { mergeLifecycle } from './lifecycle.js';\nimport {\n\tbucketName,\n\tIAM_POLICY_NAME,\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/** Each bucket construct, with the file servers over it. */\nexport interface BucketConstruct {\n\tid: string;\n\tversioned: boolean;\n\t/** Days kept under each prefix before the bucket deletes them. */\n\texpire?: Readonly<Record<string, number>>;\n\tservers: {\n\t\tid: string;\n\t\topen: readonly string[];\n\t\timmutable: readonly string[];\n\t\t/** Its processors' prefixes, each the CDN sends to the processor unit. */\n\t\tprocessors?: readonly string[];\n\t}[];\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\t...(bucketExpiry(manifest, id)\n\t\t\t\t? { expire: bucketExpiry(manifest, id) }\n\t\t\t\t: {}),\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\timmutable: (s as FileServerDeclaration).immutable ?? [],\n\t\t\t\t\t...((s as FileServerDeclaration).processors?.length\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tprocessors: [\n\t\t\t\t\t\t\t\t\t...new Set(\n\t\t\t\t\t\t\t\t\t\t(s as FileServerDeclaration).processors!.map(\n\t\t\t\t\t\t\t\t\t\t\t(p) => p.prefix,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t].sort(),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\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\tconst watched = bucketWatchers(ctx.manifest, ctx.runnables, ctx.subscribers);\n\tfor (const construct of bucketConstructs(ctx.manifest)) {\n\t\tawait ensureBucket(ctx, clients, construct, watched.get(construct.id));\n\t}\n}\n\nasync function ensureBucket(\n\tctx: Ctx,\n\tstageClients: Clients,\n\tconstruct: BucketConstruct,\n\t/** Who watches it, when a subscriber does — see `./events.ts`. */\n\twatchers?: readonly BucketWatcher[],\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\t// Its file servers behind a CDN, unless the stage said not to — first,\n\t// because the bucket's policy grants exactly the distributions it made.\n\tconst cdn =\n\t\tctx.config.cdn !== false && construct.servers.length > 0\n\t\t\t? await ensureBucketCdn(ctx, {\n\t\t\t\t\tbucket,\n\t\t\t\t\tregion: clients.region,\n\t\t\t\t\tservers: construct.servers,\n\t\t\t\t\torigins: bucketOrigins({\n\t\t\t\t\t\tworkspace: ctx.workspace,\n\t\t\t\t\t\tmanifest: ctx.manifest,\n\t\t\t\t\t\trunnables: ctx.runnables,\n\t\t\t\t\t\tstage: ctx.stage,\n\t\t\t\t\t\tbucket: id,\n\t\t\t\t\t}).origins,\n\t\t\t\t})\n\t\t\t: undefined;\n\tawait ensureBucketSettings(ctx, clients, {\n\t\tid,\n\t\tbucket,\n\t\texists,\n\t\tversioning,\n\t\topen,\n\t\t...(cdn ? { cdn } : {}),\n\t\t...(construct.expire ? { expire: construct.expire } : {}),\n\t});\n\n\t// Watched: the topic it publishes its changes to comes first, because the\n\t// bucket's key is allowed to confirm subscriptions to it.\n\tconst events = watchers\n\t\t? await ensureBucketEvents(ctx, clients, {\n\t\t\t\tid,\n\t\t\t\tbucket,\n\t\t\t\tregion: clients.region,\n\t\t\t})\n\t\t: undefined;\n\n\tconst user = await ensureIamUser(ctx, clients, {\n\t\tid,\n\t\tuser: iamUserName(nameInput),\n\t\tpolicyName: IAM_POLICY_NAME,\n\t\tpolicy: userPolicy(bucket, {\n\t\t\tversioning,\n\t\t\t...(events ? { eventsTopicArn: events.topicArn } : {}),\n\t\t}),\n\t\tdescribe: 'this bucket only',\n\t});\n\tawait ensureAccessKey(ctx, clients, {\n\t\tid,\n\t\tbucket,\n\t\turlKey: provideKey(id, 'url'),\n\t\t...user,\n\t});\n\n\tif (events && watchers) {\n\t\tawait ensureEventsKey(ctx, {\n\t\t\tid,\n\t\t\ttopicArn: events.topicArn,\n\t\t\tregion: clients.region,\n\t\t});\n\t\tawait ensurePushSubscriptions(ctx, {\n\t\t\tid,\n\t\t\tevents,\n\t\t\tregion: clients.region,\n\t\t\twatchers,\n\t\t});\n\t}\n\n\t// Each file server over it serves on its CDN, or on the bucket's own\n\t// endpoint — unless the stage set an address of its own for it, which is\n\t// kept.\n\tconst bucketUrl = bucketPublicUrl(bucket, clients.region, clients.endpoint);\n\tfor (const server of construct.servers) {\n\t\tconst publicUrl = cdn?.urls[server.id] ?? bucketUrl;\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/**\n * Tags, Block Public Access, encryption, policy, versioning, lifecycle and\n * CORS.\n */\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\t/** The distributions serving it, when a CDN does. */\n\t\tcdn?: { distributionArns: readonly string[] };\n\t\texpire?: Readonly<Record<string, number>>;\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\t// Behind a CDN the bucket is never public: CloudFront alone reads it.\n\tconst isOpen = input.open.length > 0 && !input.cdn;\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(\n\t\tbucket,\n\t\tinput.open,\n\t\tinput.cdn ? { cdn: input.cdn } : {},\n\t);\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: input.cdn && input.open.length > 0\n\t\t\t\t\t\t? `policy: TLS only, CloudFront reads ${input.open.join(', ')}`\n\t\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// Lifecycle: the declared expiry, beside whatever other rules the bucket\n\t// already has — one document per bucket, so gkm rewrites only its own.\n\tconst lifecycle = await read(\n\t\t() => s3.send(new S3.GetBucketLifecycleConfigurationCommand({ Bucket })),\n\t\t['NoSuchLifecycleConfiguration'],\n\t);\n\tconst merge = mergeLifecycle(lifecycle?.Rules, input.expire);\n\tif (merge.changed) {\n\t\tawait set(merge.describe, () =>\n\t\t\tmerge.rules.length > 0\n\t\t\t\t? s3.send(\n\t\t\t\t\t\tnew S3.PutBucketLifecycleConfigurationCommand({\n\t\t\t\t\t\t\tBucket,\n\t\t\t\t\t\t\tLifecycleConfiguration: { Rules: merge.rules },\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t: // A lifecycle with no rules is refused: gkm's were the last.\n\t\t\t\t\ts3.send(new S3.DeleteBucketLifecycleCommand({ Bucket })),\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/**\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\t// A key IAM issued moments ago is refused until it propagates.\n\t\t\tconst issuedAt = issuedJustNow(ctx.resources, id, address.accessKeyId);\n\t\t\tconst { answer: head, waited } = await whileKeyIsNew(\n\t\t\t\tawait headBucket(S3, client, address.bucket),\n\t\t\t\t{\n\t\t\t\t\tissuedAt,\n\t\t\t\t\trefused: (answer) => !answer.ok && answer.status === 403,\n\t\t\t\t\task: () => headBucket(S3, client, address.bucket),\n\t\t\t\t\tonWait: () =>\n\t\t\t\t\t\tctx.log?.(\n\t\t\t\t\t\t\t` ${id}: waiting for the new key ${address.accessKeyId} to become active…`,\n\t\t\t\t\t\t),\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, runnables = {}) {\n\t\tconst watched = bucketWatchers(manifest, runnables);\n\t\treturn bucketConstructs(manifest).flatMap((b) => [\n\t\t\tprovideKey(b.id, 'url'),\n\t\t\t...(watched.has(b.id)\n\t\t\t\t? [provideKey(b.id, 'eventsConnectionString')]\n\t\t\t\t: []),\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 { stageBackups } from '../backups/config.js';\nimport {\n\tensureStageBackups,\n\tverifyStageBackups,\n} from '../backups/provision.js';\nimport { BACKUPS_URL_KEY } from '../backups/service.js';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../deploy/credentials.js';\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 type { BoundSubscriber } from '../reconcile/discover.js';\nimport { initStageSecrets } from '../secrets/storage.js';\nimport type { StageSecrets } from '../secrets/types.js';\nimport type { DnsProvider } from '../target/dokploy/dns/DnsProvider.js';\nimport type {\n\tDnsProvider as DnsProviderConfig,\n\tNormalizedWorkspace,\n} from '../workspace/types.js';\nimport { stageProvider } from './config.js';\nimport { deploysWithCompose } from './dns.js';\nimport { writeProviderDns } from './dnsWriter.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\tif (await verifyStageBackups(input)) verified.push('backups: s3');\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/** Each Worker's subscribers, from discovery. */\n\tsubscribers?: Readonly<Record<string, readonly BoundSubscriber[]>>;\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\t/**\n\t * Where the DNS providers' tokens come from, for the records a provider\n\t * writes. Defaults to the environment and the stored logins.\n\t */\n\tcredentials?: CredentialProvider;\n\t/** The DNS provider for a domain — `createDnsProvider` by default. */\n\tdnsProviderFor?: (config: DnsProviderConfig) => Promise<DnsProvider | null>;\n\tlog?: (line: string) => void;\n}\n\n/** What one kind came to on a provisioning run. */\nexport interface KindReport {\n\t/** A provider kind, or the stage's backups. */\n\tkind: ProviderKind | 'backups';\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\t// The stage's backups: whether there are any is the stack's to say, and\n\t// a stage with none needs nothing of this run.\n\tconst backups = stageBackups(workspace, manifest, stage);\n\tif (configured.length === 0 && backups.mode !== 'on') {\n\t\tif (backups.mode === 'disabled') {\n\t\t\tlog(\n\t\t\t\t`💾 backups: off — deploy.backups.${stage} is false. Nothing is backed up, and nothing already backed up is deleted.`,\n\t\t\t);\n\t\t}\n\t\treturn reports;\n\t}\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, runnables)\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\t...(options.subscribers ? { subscribers: options.subscribers } : {}),\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\twriteDns: (records) =>\n\t\t\t\twriteProviderDns(records, {\n\t\t\t\t\tworkspace,\n\t\t\t\t\tstage,\n\t\t\t\t\tdryRun,\n\t\t\t\t\tcredentials:\n\t\t\t\t\t\toptions.credentials ??\n\t\t\t\t\t\tstoredCredentials({\n\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\t...(options.home ? { home: options.home } : {}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t...(options.dnsProviderFor\n\t\t\t\t\t\t? { providerFor: options.dnsProviderFor }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\tlog,\n\t\t\t\t}),\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\tif (backups.mode === 'on' || backups.mode === 'disabled') {\n\t\tconst report: KindReport = {\n\t\t\tkind: 'backups',\n\t\t\tmode: backups.mode === 'on' ? 'provider' : 'none',\n\t\t\tactions: [],\n\t\t\tplanned:\n\t\t\t\tbackups.mode === 'on' && secrets[BACKUPS_URL_KEY] === undefined\n\t\t\t\t\t? [BACKUPS_URL_KEY]\n\t\t\t\t\t: [],\n\t\t};\n\t\treports.push(report);\n\t\tawait ensureStageBackups({\n\t\t\tworkspace,\n\t\t\tmanifest,\n\t\t\tstage,\n\t\t\t...(options.profile ? { profile: options.profile } : {}),\n\t\t\t...(options.home ? { home: options.home } : {}),\n\t\t\tenv,\n\t\t\tctx: {\n\t\t\t\tidentity,\n\t\t\t\tstage,\n\t\t\t\tstate,\n\t\t\t\tdryRun,\n\t\t\t\tget secrets() {\n\t\t\t\t\treturn secrets;\n\t\t\t\t},\n\t\t\t\trotateKeys: options.rotateKeys === true,\n\t\t\t\tretireOldKeys: options.retireOldKeys === true,\n\t\t\t\tasync change(action, apply) {\n\t\t\t\t\tif (!dryRun) await apply();\n\t\t\t\t\treport.actions.push(action);\n\t\t\t\t\tlog(\n\t\t\t\t\t\t` ${dryRun ? 'would ' : ''}${action.change} — ${action.resource}`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\twriteSecrets,\n\t\t\t\tlog,\n\t\t\t},\n\t\t});\n\t\tif (backups.mode === 'on' && 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 { assertSitePasswordTarget } from '../compose/sitePassword.js';\nimport { GkmError } from '../errors';\nimport { provisionStage } from '../providers/index.js';\nimport { type BoundSubscriber, 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\t...(phaseCtx.subscribers ? { subscribers: phaseCtx.subscribers } : {}),\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\tcredentials: ctx.credentials,\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\t// A stage whose sites are meant to be private, on a target that would\n\t// serve them publicly, fails before anything is deployed.\n\tassertSitePasswordTarget(configured, stage, resolved.target.name);\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 subscribers: Record<string, BoundSubscriber[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(configured),\n\t\tcwd: configured.root,\n\t\trunnables,\n\t\tbackground,\n\t\tsubscribers,\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\t// The local stage's state is this machine's, always: it runs nothing\n\t// remote, so it never reads or writes the deployed stages' store — nor\n\t// needs that store's credentials.\n\tconst store = await createStateStore({\n\t\tconfig: stage === workspace.stages.local ? undefined : 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\tsubscribers,\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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"}