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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/dist/{EndpointGenerator-B2MUa4M2.cjs → EndpointGenerator-BGxf9jWE.cjs} +8 -4
  2. package/dist/{EndpointGenerator-B2MUa4M2.cjs.map → EndpointGenerator-BGxf9jWE.cjs.map} +1 -1
  3. package/dist/{EndpointGenerator-Z_BUTocT.mjs → EndpointGenerator-errMeldx.mjs} +8 -4
  4. package/dist/{EndpointGenerator-Z_BUTocT.mjs.map → EndpointGenerator-errMeldx.mjs.map} +1 -1
  5. package/dist/{GoDaddyProvider-55x4o-4z.mjs → GoDaddyProvider-BN1dODm9.mjs} +2 -2
  6. package/dist/{GoDaddyProvider-55x4o-4z.mjs.map → GoDaddyProvider-BN1dODm9.mjs.map} +1 -1
  7. package/dist/{GoDaddyProvider-0z5RAN1k.cjs → GoDaddyProvider-BTdtqhI_.cjs} +2 -2
  8. package/dist/{GoDaddyProvider-0z5RAN1k.cjs.map → GoDaddyProvider-BTdtqhI_.cjs.map} +1 -1
  9. package/dist/{LegacyStateStore-DRpB-yC5.cjs → LegacyStateStore-C2S8TGwx.cjs} +3 -3
  10. package/dist/{LegacyStateStore-DRpB-yC5.cjs.map → LegacyStateStore-C2S8TGwx.cjs.map} +1 -1
  11. package/dist/{LegacyStateStore-C-vumKSN.mjs → LegacyStateStore-DgXmuG87.mjs} +3 -3
  12. package/dist/{LegacyStateStore-C-vumKSN.mjs.map → LegacyStateStore-DgXmuG87.mjs.map} +1 -1
  13. package/dist/{LocalStateStore-C3ummuDT.cjs → LocalStateStore-CaJw9H-3.cjs} +2 -2
  14. package/dist/{LocalStateStore-C3ummuDT.cjs.map → LocalStateStore-CaJw9H-3.cjs.map} +1 -1
  15. package/dist/{LocalStateStore-CtOjpV1w.mjs → LocalStateStore-ojY_BiMK.mjs} +2 -2
  16. package/dist/{LocalStateStore-CtOjpV1w.mjs.map → LocalStateStore-ojY_BiMK.mjs.map} +1 -1
  17. package/dist/{OpenApiTsGenerator-MtnMQL_g.mjs → OpenApiTsGenerator-W_HRXH1X.mjs} +2 -2
  18. package/dist/{OpenApiTsGenerator-MtnMQL_g.mjs.map → OpenApiTsGenerator-W_HRXH1X.mjs.map} +1 -1
  19. package/dist/{OpenApiTsGenerator-t3_E98Fi.cjs → OpenApiTsGenerator-cQgtxWQo.cjs} +2 -2
  20. package/dist/{OpenApiTsGenerator-t3_E98Fi.cjs.map → OpenApiTsGenerator-cQgtxWQo.cjs.map} +1 -1
  21. package/dist/{S3StateStore-BC4Jm3Tw.mjs → S3StateStore-BSPkxhrx.mjs} +2 -2
  22. package/dist/{S3StateStore-BC4Jm3Tw.mjs.map → S3StateStore-BSPkxhrx.mjs.map} +1 -1
  23. package/dist/{S3StateStore-BeArp0aF.cjs → S3StateStore-BqugXIcb.cjs} +2 -2
  24. package/dist/{S3StateStore-BeArp0aF.cjs.map → S3StateStore-BqugXIcb.cjs.map} +1 -1
  25. package/dist/{SSMStateStore-DcstR6cW.cjs → SSMStateStore-B0OsuT_k.cjs} +2 -2
  26. package/dist/{SSMStateStore-DcstR6cW.cjs.map → SSMStateStore-B0OsuT_k.cjs.map} +1 -1
  27. package/dist/{SSMStateStore-Crl76aYZ.mjs → SSMStateStore-DM85OiH0.mjs} +2 -2
  28. package/dist/{SSMStateStore-Crl76aYZ.mjs.map → SSMStateStore-DM85OiH0.mjs.map} +1 -1
  29. package/dist/{SubscriberGenerator-C3QTae-R.cjs → SubscriberGenerator-BDUp7OeY.cjs} +3 -3
  30. package/dist/SubscriberGenerator-BDUp7OeY.cjs.map +1 -0
  31. package/dist/{SubscriberGenerator-COAVPgM-.mjs → SubscriberGenerator-ocQ2yj0K.mjs} +3 -3
  32. package/dist/{SubscriberGenerator-C3QTae-R.cjs.map → SubscriberGenerator-ocQ2yj0K.mjs.map} +1 -1
  33. package/dist/{add-CIjmgzkb.mjs → add-C7ZBXIzM.mjs} +6 -6
  34. package/dist/{add-CIjmgzkb.mjs.map → add-C7ZBXIzM.mjs.map} +1 -1
  35. package/dist/{add-BFjb6mMq.cjs → add-CrxvmSpq.cjs} +6 -6
  36. package/dist/{add-BFjb6mMq.cjs.map → add-CrxvmSpq.cjs.map} +1 -1
  37. package/dist/{bundler-CiUoIsku.cjs → bundler-DVUXW95p.cjs} +5 -5
  38. package/dist/{bundler-CiUoIsku.cjs.map → bundler-DVUXW95p.cjs.map} +1 -1
  39. package/dist/{bundler-D6KFNpQk.mjs → bundler-DpZ9uBGN.mjs} +5 -5
  40. package/dist/{bundler-D6KFNpQk.mjs.map → bundler-DpZ9uBGN.mjs.map} +1 -1
  41. package/dist/{cli-r4eUr98C.cjs → cli-BMRhE6cZ.cjs} +3 -3
  42. package/dist/{cli-r4eUr98C.cjs.map → cli-BMRhE6cZ.cjs.map} +1 -1
  43. package/dist/{cli-DNtSTtMc.mjs → cli-BWfYyy1k.mjs} +3 -3
  44. package/dist/{cli-DNtSTtMc.mjs.map → cli-BWfYyy1k.mjs.map} +1 -1
  45. package/dist/{compose-DJvvmF3X.mjs → compose-BFmdLig3.mjs} +232 -36
  46. package/dist/compose-BFmdLig3.mjs.map +1 -0
  47. package/dist/{compose-BfXXWJSp.cjs → compose-Bqcy0lqo.cjs} +232 -36
  48. package/dist/compose-Bqcy0lqo.cjs.map +1 -0
  49. package/dist/{config-IgK6YaGp.d.cts → config-CdytFgSR.d.cts} +3 -3
  50. package/dist/{config-IgK6YaGp.d.cts.map → config-CdytFgSR.d.cts.map} +1 -1
  51. package/dist/{config-kE-p5hxq.d.mts → config-_y1FGBWR.d.mts} +3 -3
  52. package/dist/{config-kE-p5hxq.d.mts.map → config-_y1FGBWR.d.mts.map} +1 -1
  53. package/dist/config.cjs +2 -2
  54. package/dist/config.d.cts +3 -3
  55. package/dist/config.d.mts +3 -3
  56. package/dist/config.mjs +2 -2
  57. package/dist/{credentialSchemas-AhIBuQxQ.cjs → credentialSchemas-DFxvGEwa.cjs} +2 -2
  58. package/dist/{credentialSchemas-AhIBuQxQ.cjs.map → credentialSchemas-DFxvGEwa.cjs.map} +1 -1
  59. package/dist/{credentialSchemas-DLKbxYBy.mjs → credentialSchemas-DaMpt-Dx.mjs} +2 -2
  60. package/dist/{credentialSchemas-DLKbxYBy.mjs.map → credentialSchemas-DaMpt-Dx.mjs.map} +1 -1
  61. package/dist/deploy/public.cjs +8 -8
  62. package/dist/deploy/public.d.cts +3 -3
  63. package/dist/deploy/public.d.cts.map +1 -1
  64. package/dist/deploy/public.d.mts +3 -3
  65. package/dist/deploy/public.d.mts.map +1 -1
  66. package/dist/deploy/public.mjs +8 -8
  67. package/dist/{deploy-CiRYwFmr.mjs → deploy-D8pUA9Y0.mjs} +797 -25
  68. package/dist/deploy-D8pUA9Y0.mjs.map +1 -0
  69. package/dist/{deploy-BbI1UMh3.cjs → deploy-DVrNjX1X.cjs} +796 -24
  70. package/dist/deploy-DVrNjX1X.cjs.map +1 -0
  71. package/dist/{discover-BvJOVsYG.mjs → discover-CzGM5P3p.mjs} +71 -1
  72. package/dist/discover-CzGM5P3p.mjs.map +1 -0
  73. package/dist/{discover-ojkcbxHw.cjs → discover-DL6h-J97.cjs} +71 -1
  74. package/dist/discover-DL6h-J97.cjs.map +1 -0
  75. package/dist/{dokploy-MM7c3IE0.mjs → dokploy-CzDGNB6A.mjs} +2 -2
  76. package/dist/{dokploy-MM7c3IE0.mjs.map → dokploy-CzDGNB6A.mjs.map} +1 -1
  77. package/dist/{dokploy-C0aQrCgs.cjs → dokploy-TtK6Zyl3.cjs} +2 -2
  78. package/dist/{dokploy-C0aQrCgs.cjs.map → dokploy-TtK6Zyl3.cjs.map} +1 -1
  79. package/dist/{drivers-Chb5Akov.mjs → drivers-C-VqMtld.mjs} +2 -2
  80. package/dist/{drivers-Chb5Akov.mjs.map → drivers-C-VqMtld.mjs.map} +1 -1
  81. package/dist/{drivers-CQ32PB5w.cjs → drivers-L29WvE95.cjs} +2 -2
  82. package/dist/{drivers-CQ32PB5w.cjs.map → drivers-L29WvE95.cjs.map} +1 -1
  83. package/dist/{eas-CJoys9yh.cjs → eas-D3clzkni.cjs} +2 -2
  84. package/dist/{eas-CJoys9yh.cjs.map → eas-D3clzkni.cjs.map} +1 -1
  85. package/dist/{eas-1Ee6kql0.mjs → eas-DaobzDks.mjs} +2 -2
  86. package/dist/{eas-1Ee6kql0.mjs.map → eas-DaobzDks.mjs.map} +1 -1
  87. package/dist/{emit-qvHxMV9b.cjs → emit-CYloptRS.cjs} +18 -1
  88. package/dist/emit-CYloptRS.cjs.map +1 -0
  89. package/dist/{emit-CNpuV_6Q.mjs → emit-CiJGdy_f.mjs} +18 -1
  90. package/dist/emit-CiJGdy_f.mjs.map +1 -0
  91. package/dist/{encryption-Bo9VlRnl.cjs → encryption-DBkIFiR2.cjs} +3 -3
  92. package/dist/{encryption-Bo9VlRnl.cjs.map → encryption-DBkIFiR2.cjs.map} +1 -1
  93. package/dist/{encryption-B8Bk1Mvu.mjs → encryption-DV31gEY8.mjs} +3 -3
  94. package/dist/{encryption-B8Bk1Mvu.mjs.map → encryption-DV31gEY8.mjs.map} +1 -1
  95. package/dist/{engine-BuinpJfS.mjs → engine-CFOR9h6X.mjs} +138 -13
  96. package/dist/engine-CFOR9h6X.mjs.map +1 -0
  97. package/dist/{engine-esxTxcIx.cjs → engine-CuZUGbEh.cjs} +138 -13
  98. package/dist/engine-CuZUGbEh.cjs.map +1 -0
  99. package/dist/{github-BEA4K3_X.cjs → github-CsvtWSBW.cjs} +41 -6
  100. package/dist/github-CsvtWSBW.cjs.map +1 -0
  101. package/dist/{github-BUlKJfOV.mjs → github-Nep8pI4_.mjs} +41 -6
  102. package/dist/github-Nep8pI4_.mjs.map +1 -0
  103. package/dist/{googlePlay-CiqAS2ma.cjs → googlePlay-C-UfBXJU.cjs} +3 -3
  104. package/dist/{googlePlay-CiqAS2ma.cjs.map → googlePlay-C-UfBXJU.cjs.map} +1 -1
  105. package/dist/{googlePlay-CK05QiTq.mjs → googlePlay-lF7Atm_N.mjs} +3 -3
  106. package/dist/{googlePlay-CK05QiTq.mjs.map → googlePlay-lF7Atm_N.mjs.map} +1 -1
  107. package/dist/{index-DhUf0B0m.d.mts → index-DrkV7N5w.d.mts} +2 -2
  108. package/dist/{index-4CO0HD27.d.cts.map → index-DrkV7N5w.d.mts.map} +1 -1
  109. package/dist/{index-4CO0HD27.d.cts → index-yaXZ9m-J.d.cts} +2 -2
  110. package/dist/{index-DhUf0B0m.d.mts.map → index-yaXZ9m-J.d.cts.map} +1 -1
  111. package/dist/index.cjs +147 -65
  112. package/dist/index.cjs.map +1 -1
  113. package/dist/index.mjs +147 -65
  114. package/dist/index.mjs.map +1 -1
  115. package/dist/{migrate-DeQJBexh.cjs → migrate-Dp3GhFnf.cjs} +4 -4
  116. package/dist/{migrate-DeQJBexh.cjs.map → migrate-Dp3GhFnf.cjs.map} +1 -1
  117. package/dist/{migrate-CnbvrVag.mjs → migrate-NfbPVhi9.mjs} +4 -4
  118. package/dist/{migrate-CnbvrVag.mjs.map → migrate-NfbPVhi9.mjs.map} +1 -1
  119. package/dist/{migrate-BzCHT9qs.mjs → migrate-_sBX0pve.mjs} +3 -3
  120. package/dist/{migrate-BzCHT9qs.mjs.map → migrate-_sBX0pve.mjs.map} +1 -1
  121. package/dist/{migrate-C-hmbjpG.cjs → migrate-hlNKNWmg.cjs} +3 -3
  122. package/dist/{migrate-C-hmbjpG.cjs.map → migrate-hlNKNWmg.cjs.map} +1 -1
  123. package/dist/openapi.cjs +3 -3
  124. package/dist/openapi.d.cts +1 -1
  125. package/dist/openapi.d.mts +1 -1
  126. package/dist/openapi.mjs +3 -3
  127. package/dist/{publish-BISBrrqR.mjs → publish-BuUVaZVy.mjs} +2 -2
  128. package/dist/{publish-BISBrrqR.mjs.map → publish-BuUVaZVy.mjs.map} +1 -1
  129. package/dist/{publish-DtSIB-hZ.cjs → publish-ZOo4xEuZ.cjs} +2 -2
  130. package/dist/{publish-DtSIB-hZ.cjs.map → publish-ZOo4xEuZ.cjs.map} +1 -1
  131. package/dist/{ready-DqsyadOs.mjs → ready-Ca883OvY.mjs} +6 -6
  132. package/dist/{ready-DqsyadOs.mjs.map → ready-Ca883OvY.mjs.map} +1 -1
  133. package/dist/{ready-IVGu-q18.cjs → ready-qnqp6JAY.cjs} +6 -6
  134. package/dist/{ready-IVGu-q18.cjs.map → ready-qnqp6JAY.cjs.map} +1 -1
  135. package/dist/reconcile/public.cjs +2 -2
  136. package/dist/reconcile/public.d.cts +1 -1
  137. package/dist/reconcile/public.d.cts.map +1 -1
  138. package/dist/reconcile/public.d.mts +1 -1
  139. package/dist/reconcile/public.d.mts.map +1 -1
  140. package/dist/reconcile/public.mjs +2 -2
  141. package/dist/{resolve-BT7fkPN5.mjs → resolve-BCU9pYDx.mjs} +3 -3
  142. package/dist/{resolve-BT7fkPN5.mjs.map → resolve-BCU9pYDx.mjs.map} +1 -1
  143. package/dist/{resolve-C7GKQcE4.cjs → resolve-C9QqOl5t.cjs} +3 -3
  144. package/dist/{resolve-C7GKQcE4.cjs.map → resolve-C9QqOl5t.cjs.map} +1 -1
  145. package/dist/{rollback-BEiB-Pje.cjs → rollback-CTWdDBgB.cjs} +5 -5
  146. package/dist/{rollback-BEiB-Pje.cjs.map → rollback-CTWdDBgB.cjs.map} +1 -1
  147. package/dist/{rollback-DbP0KuDw.mjs → rollback-CWyyTQ0B.mjs} +5 -5
  148. package/dist/{rollback-DbP0KuDw.mjs.map → rollback-CWyyTQ0B.mjs.map} +1 -1
  149. package/dist/{runtime-BFJQNqwd.d.mts → runtime-DCkfI2E7.d.mts} +2 -2
  150. package/dist/{runtime-BFJQNqwd.d.mts.map → runtime-DCkfI2E7.d.mts.map} +1 -1
  151. package/dist/{runtime-BJO-FFef.d.cts → runtime-Ie4znWIB.d.cts} +2 -2
  152. package/dist/{runtime-BJO-FFef.d.cts.map → runtime-Ie4znWIB.d.cts.map} +1 -1
  153. package/dist/{s3-B4FTQQkV.mjs → s3-BZzSnker.mjs} +2 -2
  154. package/dist/{s3-B4FTQQkV.mjs.map → s3-BZzSnker.mjs.map} +1 -1
  155. package/dist/{s3-DwKLXwUT.cjs → s3-pqgmCTOq.cjs} +2 -2
  156. package/dist/{s3-DwKLXwUT.cjs.map → s3-pqgmCTOq.cjs.map} +1 -1
  157. package/dist/sandbox/credentials-worker.cjs +2 -2
  158. package/dist/sandbox/credentials-worker.mjs +2 -2
  159. package/dist/sandbox/discover-worker.cjs +1 -1
  160. package/dist/sandbox/discover-worker.mjs +1 -1
  161. package/dist/sandbox/migrate-worker.cjs +1 -1
  162. package/dist/sandbox/migrate-worker.mjs +1 -1
  163. package/dist/{seeds-rG-Evfz9.mjs → seeds-CK7w79VC.mjs} +516 -39
  164. package/dist/seeds-CK7w79VC.mjs.map +1 -0
  165. package/dist/{seeds-DOfxmDRO.cjs → seeds-CPEcmoPn.cjs} +599 -38
  166. package/dist/seeds-CPEcmoPn.cjs.map +1 -0
  167. package/dist/{serverSetup-xGw1fxuZ.mjs → serverSetup-BAPNuNEX.mjs} +6 -6
  168. package/dist/{serverSetup-xGw1fxuZ.mjs.map → serverSetup-BAPNuNEX.mjs.map} +1 -1
  169. package/dist/{serverSetup-CWWVcU6Y.cjs → serverSetup-C6t6Vtt7.cjs} +6 -6
  170. package/dist/{serverSetup-CWWVcU6Y.cjs.map → serverSetup-C6t6Vtt7.cjs.map} +1 -1
  171. package/dist/{sniffer-C7O9Pna_.cjs → sniffer-DdX_WN_-.cjs} +8 -8
  172. package/dist/{sniffer-C7O9Pna_.cjs.map → sniffer-DdX_WN_-.cjs.map} +1 -1
  173. package/dist/{sniffer-DVPgfyHr.mjs → sniffer-g9v7cqDN.mjs} +8 -8
  174. package/dist/{sniffer-DVPgfyHr.mjs.map → sniffer-g9v7cqDN.mjs.map} +1 -1
  175. package/dist/{snsSubscriptions-CSkteK2J.cjs → snsSubscriptions-5Cqww8S7.cjs} +15 -3
  176. package/dist/snsSubscriptions-5Cqww8S7.cjs.map +1 -0
  177. package/dist/{snsSubscriptions-CvBIGGp0.mjs → snsSubscriptions-BmYeeTH8.mjs} +4 -4
  178. package/dist/snsSubscriptions-BmYeeTH8.mjs.map +1 -0
  179. package/dist/{stage-2EKpzPQ1.mjs → stage-C-I2dVw1.mjs} +6 -6
  180. package/dist/{stage-2EKpzPQ1.mjs.map → stage-C-I2dVw1.mjs.map} +1 -1
  181. package/dist/{stage-fRfFtLwj.cjs → stage-CUE5pMmw.cjs} +6 -6
  182. package/dist/{stage-fRfFtLwj.cjs.map → stage-CUE5pMmw.cjs.map} +1 -1
  183. package/dist/{stages-B7mCWI_R.cjs → stages-3yUZaZeA.cjs} +2 -2
  184. package/dist/{stages-B7mCWI_R.cjs.map → stages-3yUZaZeA.cjs.map} +1 -1
  185. package/dist/{stages-DSltTW2d.mjs → stages-DTTv0NZW.mjs} +2 -2
  186. package/dist/{stages-DSltTW2d.mjs.map → stages-DTTv0NZW.mjs.map} +1 -1
  187. package/dist/target/public.cjs +1 -1
  188. package/dist/target/public.d.cts +2 -2
  189. package/dist/target/public.d.mts +2 -2
  190. package/dist/target/public.mjs +1 -1
  191. package/dist/{terminal-D1aeTkgv.cjs → terminal-PKhPAajN.cjs} +2 -2
  192. package/dist/{terminal-D1aeTkgv.cjs.map → terminal-PKhPAajN.cjs.map} +1 -1
  193. package/dist/{terminal-BAVrDhhN.mjs → terminal-bqY33lpN.mjs} +2 -2
  194. package/dist/{terminal-BAVrDhhN.mjs.map → terminal-bqY33lpN.mjs.map} +1 -1
  195. package/dist/{types-CFU2uvrz.d.cts → types-Bmjs4jZV.d.mts} +8 -2
  196. package/dist/{types-D3BeGucy.d.mts.map → types-Bmjs4jZV.d.mts.map} +1 -1
  197. package/dist/{types-D3BeGucy.d.mts → types-D0IsQxES.d.cts} +9 -1
  198. package/dist/{types-CFU2uvrz.d.cts.map → types-D0IsQxES.d.cts.map} +1 -1
  199. package/dist/vitest.cjs +1 -1
  200. package/dist/vitest.mjs +1 -1
  201. package/dist/workspace/index.cjs +1 -1
  202. package/dist/workspace/index.d.cts +2 -2
  203. package/dist/workspace/index.d.mts +2 -2
  204. package/dist/workspace/index.mjs +1 -1
  205. package/dist/{workspace-DUnnVjqC.mjs → workspace-DBHF9Gba.mjs} +5 -3
  206. package/dist/workspace-DBHF9Gba.mjs.map +1 -0
  207. package/dist/{workspace-C82GLPnf.cjs → workspace-Du4Afb03.cjs} +5 -3
  208. package/dist/workspace-Du4Afb03.cjs.map +1 -0
  209. package/package.json +17 -15
  210. package/dist/SubscriberGenerator-COAVPgM-.mjs.map +0 -1
  211. package/dist/compose-BfXXWJSp.cjs.map +0 -1
  212. package/dist/compose-DJvvmF3X.mjs.map +0 -1
  213. package/dist/deploy-BbI1UMh3.cjs.map +0 -1
  214. package/dist/deploy-CiRYwFmr.mjs.map +0 -1
  215. package/dist/discover-BvJOVsYG.mjs.map +0 -1
  216. package/dist/discover-ojkcbxHw.cjs.map +0 -1
  217. package/dist/emit-CNpuV_6Q.mjs.map +0 -1
  218. package/dist/emit-qvHxMV9b.cjs.map +0 -1
  219. package/dist/engine-BuinpJfS.mjs.map +0 -1
  220. package/dist/engine-esxTxcIx.cjs.map +0 -1
  221. package/dist/github-BEA4K3_X.cjs.map +0 -1
  222. package/dist/github-BUlKJfOV.mjs.map +0 -1
  223. package/dist/seeds-DOfxmDRO.cjs.map +0 -1
  224. package/dist/seeds-rG-Evfz9.mjs.map +0 -1
  225. package/dist/snsSubscriptions-CSkteK2J.cjs.map +0 -1
  226. package/dist/snsSubscriptions-CvBIGGp0.mjs.map +0 -1
  227. package/dist/workspace-C82GLPnf.cjs.map +0 -1
  228. package/dist/workspace-DUnnVjqC.mjs.map +0 -1
@@ -1,21 +1,21 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
2
  const require_errors = require("./errors-DMC4Umsb.cjs");
3
3
  const require_credentials = require("./credentials-D7XJypNd.cjs");
4
- const require_workspace = require("./workspace-C82GLPnf.cjs");
5
- const require_snsSubscriptions = require("./snsSubscriptions-CSkteK2J.cjs");
4
+ const require_workspace = require("./workspace-Du4Afb03.cjs");
5
+ const require_snsSubscriptions = require("./snsSubscriptions-5Cqww8S7.cjs");
6
6
  const require_define = require("./define-crmMcXFS.cjs");
7
- const require_seeds = require("./seeds-DOfxmDRO.cjs");
7
+ const require_seeds = require("./seeds-CPEcmoPn.cjs");
8
8
  const require_derive = require("./derive-DAbo49sm.cjs");
9
- const require_SubscriberGenerator = require("./SubscriberGenerator-C3QTae-R.cjs");
9
+ const require_SubscriberGenerator = require("./SubscriberGenerator-BDUp7OeY.cjs");
10
10
  const require_identity = require("./identity-CbLfgQNT.cjs");
11
- const require_discover = require("./discover-ojkcbxHw.cjs");
11
+ const require_discover = require("./discover-DL6h-J97.cjs");
12
12
  const require_sandbox = require("./sandbox-CHv3OYXg.cjs");
13
13
  const require_config = require("./config.cjs");
14
- const require_resolve = require("./resolve-C7GKQcE4.cjs");
14
+ const require_resolve = require("./resolve-C9QqOl5t.cjs");
15
15
  const require_local = require("./local-OPC9BCZt.cjs");
16
- const require_sniffer = require("./sniffer-C7O9Pna_.cjs");
16
+ const require_sniffer = require("./sniffer-DdX_WN_-.cjs");
17
17
  const require_projectBucket = require("./projectBucket-BBbQ1lHF.cjs");
18
- const require_credentialSchemas = require("./credentialSchemas-AhIBuQxQ.cjs");
18
+ const require_credentialSchemas = require("./credentialSchemas-DFxvGEwa.cjs");
19
19
  let node_path = require("node:path");
20
20
  let node_crypto = require("node:crypto");
21
21
  let _geekmidas_manifest = require("@geekmidas/manifest");
@@ -221,10 +221,13 @@ function openResource(bucket, pattern) {
221
221
  }
222
222
  /**
223
223
  * The bucket's own policy: every request refused unless it came over TLS,
224
- * and — only when a file server opens paths on it — anonymous `s3:GetObject`
225
- * on exactly those prefixes.
224
+ * and — only when a file server opens paths on it — `s3:GetObject` on
225
+ * exactly those prefixes: to anyone, or, when a CDN serves them, to
226
+ * CloudFront alone, for exactly the stage's distributions. Behind a CDN the
227
+ * bucket is never public: a key outside the open prefixes is refused to
228
+ * CloudFront too, so the edge answers it 403.
226
229
  */
227
- function bucketPolicy(bucket, open = []) {
230
+ function bucketPolicy(bucket, open = [], options = {}) {
228
231
  const statements = [{
229
232
  Sid: "GkmDenyInsecureTransport",
230
233
  Effect: "Deny",
@@ -233,12 +236,21 @@ function bucketPolicy(bucket, open = []) {
233
236
  Resource: [bucketArn(bucket), `${bucketArn(bucket)}/*`],
234
237
  Condition: { Bool: { "aws:SecureTransport": "false" } }
235
238
  }];
236
- if (open.length > 0) statements.push({
239
+ const resources = [...new Set(open.map((p) => openResource(bucket, p)))].sort();
240
+ if (open.length > 0 && options.cdn) statements.push({
241
+ Sid: "GkmCdnRead",
242
+ Effect: "Allow",
243
+ Principal: { Service: "cloudfront.amazonaws.com" },
244
+ Action: "s3:GetObject",
245
+ Resource: resources,
246
+ Condition: { StringEquals: { "AWS:SourceArn": [...new Set(options.cdn.distributionArns)].sort() } }
247
+ });
248
+ else if (open.length > 0) statements.push({
237
249
  Sid: "GkmOpenPaths",
238
250
  Effect: "Allow",
239
251
  Principal: "*",
240
252
  Action: "s3:GetObject",
241
- Resource: [...new Set(open.map((p) => openResource(bucket, p)))].sort()
253
+ Resource: resources
242
254
  });
243
255
  return {
244
256
  Version: "2012-10-17",
@@ -287,7 +299,7 @@ function canonical(value, key) {
287
299
  }
288
300
  if (value && typeof value === "object") return Object.fromEntries(Object.keys(value).sort().map((k) => {
289
301
  const v = value[k];
290
- return [k, canonical(k === "Action" || k === "Resource" || k === "AWS" ? Array.isArray(v) ? v : [v] : v, k)];
302
+ return [k, canonical(k === "Action" || k === "Resource" || k === "AWS" || k === "AWS:SourceArn" ? Array.isArray(v) ? v : [v] : v, k)];
291
303
  }));
292
304
  return value;
293
305
  }
@@ -333,7 +345,7 @@ function identityTags(ctx, id) {
333
345
  ];
334
346
  }
335
347
  /** A read whose "there is none" answer is one of `missing`. */
336
- async function readOr$2(read, missing) {
348
+ async function readOr$3(read, missing) {
337
349
  try {
338
350
  return await read();
339
351
  } catch (error) {
@@ -363,7 +375,7 @@ async function ensureIamUser(ctx, clients, input) {
363
375
  key: `iam-user:${id}`,
364
376
  type: "iam-user"
365
377
  };
366
- const found = await readOr$2(() => iam.send(new IAM.GetUserCommand({ UserName: user })), ["NoSuchEntity", "NoSuchEntityException"]);
378
+ const found = await readOr$3(() => iam.send(new IAM.GetUserCommand({ UserName: user })), ["NoSuchEntity", "NoSuchEntityException"]);
367
379
  if (found?.User) {
368
380
  const tags = await iam.send(new IAM.ListUserTagsCommand({ UserName: user }));
369
381
  const tag = (key) => tags.Tags?.find((t) => t.Key === key)?.Value;
@@ -383,7 +395,7 @@ async function ensureIamUser(ctx, clients, input) {
383
395
  await ctx.state.ready(entry, user);
384
396
  });
385
397
  const exists = Boolean(found?.User) || !ctx.dryRun;
386
- const current = exists ? await readOr$2(() => iam.send(new IAM.GetUserPolicyCommand({
398
+ const current = exists ? await readOr$3(() => iam.send(new IAM.GetUserPolicyCommand({
387
399
  UserName: user,
388
400
  PolicyName: input.policyName
389
401
  })), ["NoSuchEntity", "NoSuchEntityException"]) : void 0;
@@ -797,6 +809,738 @@ async function verifyStageBackups(input) {
797
809
  }
798
810
  }
799
811
  //#endregion
812
+ //#region src/providers/dnsWriter.ts
813
+ /**
814
+ * The DNS records a provider asks for — a certificate's validation record, a
815
+ * CDN's name — written through the stage's own DNS providers.
816
+ *
817
+ * The same machinery the deploy's DNS step uses for the stack's hosts
818
+ * (`settleStackDns`), handed a plan of CNAMEs instead of the server's
819
+ * addresses: a record holding its value is left alone, one with another value
820
+ * is replaced and printed, and what is written is read back. A host under no
821
+ * domain in `dns`, or under a `manual` one, is printed for the person to
822
+ * create and reported back, so the provider can say what it is waiting on.
823
+ */
824
+ async function writeProviderDns(records, options) {
825
+ const { log } = options;
826
+ const dns = options.workspace.dns ? require_seeds.normalizeDnsConfig(options.workspace.dns) : {};
827
+ const manual = [];
828
+ const domains = /* @__PURE__ */ new Map();
829
+ for (const record of records) {
830
+ const host = record.host.toLowerCase().replace(/\.$/, "");
831
+ const value = record.value.replace(/\.$/, "");
832
+ const domain = require_seeds.findRootDomain(host, dns);
833
+ if (!domain) {
834
+ log(` create at its DNS host: ${host} CNAME ${value}`);
835
+ manual.push(host);
836
+ continue;
837
+ }
838
+ const config = dns[domain];
839
+ const plan = domains.get(domain) ?? {
840
+ domain,
841
+ provider: typeof config.provider === "string" ? config.provider : "custom",
842
+ config,
843
+ records: []
844
+ };
845
+ const planned = {
846
+ host,
847
+ domain,
848
+ name: require_seeds.extractSubdomain(host, domain),
849
+ type: record.type,
850
+ value,
851
+ ttl: require_snsSubscriptions.recordTtl(config)
852
+ };
853
+ plan.records.push(planned);
854
+ domains.set(domain, plan);
855
+ }
856
+ if (domains.size === 0) return { manual };
857
+ const plans = [...domains.values()];
858
+ const tokens = await require_snsSubscriptions.dnsCredentials(options.stage, plans.map(({ domain, config }) => ({
859
+ domain,
860
+ config
861
+ })), options.credentials);
862
+ const applied = await require_snsSubscriptions.settleStackDns({
863
+ stage: options.stage,
864
+ server: { ipv4: "" },
865
+ domains: plans,
866
+ uncovered: []
867
+ }, {
868
+ ...options.dryRun ? { dryRun: true } : { confirm: true },
869
+ log,
870
+ credentials: {
871
+ ...tokens.godaddy ? { credential: tokens.godaddy } : {},
872
+ log
873
+ },
874
+ ...tokens.hostinger ? { hostinger: tokens.hostinger } : {},
875
+ ...options.providerFor ? { providerFor: options.providerFor } : {}
876
+ });
877
+ for (const change of applied.changes) {
878
+ if (change.action !== "manual") continue;
879
+ const host = plans.find((p) => p.domain === change.domain)?.records.find((r) => r.name === change.name)?.host;
880
+ if (host) manual.push(host);
881
+ }
882
+ return { manual: [...new Set(manual)].sort() };
883
+ }
884
+ //#endregion
885
+ //#region src/providers/s3/cdn.ts
886
+ /** AWS's managed `CachingOptimized` cache policy: path-keyed, gzip and brotli. */
887
+ const CACHING_OPTIMIZED = "658327ea-f89d-4fab-a63d-7e88639e58f6";
888
+ /** What an immutable path is served with. */
889
+ const IMMUTABLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
890
+ /** The only region CloudFront reads a certificate from. */
891
+ const CDN_REGION = "us-east-1";
892
+ /** The distribution's bucket origin. */
893
+ const ORIGIN_ID = "bucket";
894
+ /** Its processors' origin: the stack's processor unit, at a host of its own. */
895
+ const PROCESSORS_ORIGIN_ID = "processors";
896
+ /**
897
+ * AWS's managed `CachingOptimizedForUncompressedObjects`: keyed on the path
898
+ * alone, and nothing re-compressed — a derivative is an image, already
899
+ * compressed, and its width is in the path, so nothing else may fragment it.
900
+ */
901
+ const CACHING_OPTIMIZED_UNCOMPRESSED = "b2884449-e4de-46a7-ac36-70bc7f1ddd6d";
902
+ /** A CDN is a name on the stage's domain, and the stage has none. */
903
+ var FileServerCdnNeedsDomain = class extends require_errors.GkmError {
904
+ server;
905
+ stage;
906
+ constructor(server, stage) {
907
+ super(`'${server}' is served through a CDN on '${stage}', which answers on <fileserver>.<domain> — and '${stage}' has no domain. Set domains.${stage} in gkm.config.ts, or set deploy.objects.${stage}.cdn to false to serve it from the bucket's own endpoint.`);
908
+ this.server = server;
909
+ this.stage = stage;
910
+ this.name = "FileServerCdnNeedsDomain";
911
+ }
912
+ };
913
+ /**
914
+ * The certificate is waiting on its validation record: one the person has to
915
+ * create, or one that has not propagated yet. Everything up to it is
916
+ * recorded, so the next deploy carries on from here.
917
+ */
918
+ var CdnCertificatePending = class extends require_errors.GkmError {
919
+ server;
920
+ host;
921
+ record;
922
+ reason;
923
+ constructor(server, host, record, reason) {
924
+ super((reason === "manual" ? `The certificate for ${host} ('${server}') is validated by a DNS record no DNS provider in gkm.config.ts can write. Create it at the domain's DNS host:
925
+ ` : `The certificate for ${host} ('${server}') is not issued yet: ACM has not seen its validation record. It is written; DNS can take a while to answer with it. Check it resolves:
926
+ `) + ` ${record.name} CNAME ${record.value}\nthen deploy again — the certificate and everything before it are recorded, and the deploy carries on from there.`);
927
+ this.server = server;
928
+ this.host = host;
929
+ this.record = record;
930
+ this.reason = reason;
931
+ this.name = "CdnCertificatePending";
932
+ }
933
+ };
934
+ /** ACM gave up on the certificate. */
935
+ var CdnCertificateFailed = class extends require_errors.GkmError {
936
+ server;
937
+ host;
938
+ status;
939
+ reason;
940
+ constructor(server, host, status, reason) {
941
+ super(`ACM did not issue the certificate for ${host} ('${server}'): ${status}` + (reason ? ` (${reason})` : "") + ". A CAA record on the domain that does not allow amazon.com, or a validation record removed before it was checked, are the usual causes. Fix it and deploy again: a new certificate is requested.");
942
+ this.server = server;
943
+ this.host = host;
944
+ this.status = status;
945
+ this.reason = reason;
946
+ this.name = "CdnCertificateFailed";
947
+ }
948
+ };
949
+ /** Where a file server answers: `<fileserver>.<domain>`. */
950
+ function cdnHost(serverId, domain) {
951
+ return `${require_derive.appKey(serverId)}.${domain}`.toLowerCase();
952
+ }
953
+ /**
954
+ * The name the stage's CDN resources go by, within CloudFront's limits:
955
+ * letters, digits, `-` and `_`, and at most 64 characters (an origin access
956
+ * control's). Kept whole where it fits; otherwise shortened with a hash of
957
+ * the whole, so two long names never meet.
958
+ */
959
+ function cdnName(scope, stage, serverId) {
960
+ const whole = `gkm-${scope}-${stage}-${require_derive.appKey(serverId)}`.replace(/[^A-Za-z0-9_-]/g, "-");
961
+ if (whole.length <= 56) return whole;
962
+ return `${whole.slice(0, 47)}-${hash(whole)}`;
963
+ }
964
+ function hash(value) {
965
+ let h = 2166136261;
966
+ for (let i = 0; i < value.length; i++) {
967
+ h ^= value.charCodeAt(i);
968
+ h = Math.imul(h, 16777619);
969
+ }
970
+ return (h >>> 0).toString(36).padStart(8, "0").slice(0, 8);
971
+ }
972
+ /**
973
+ * An open or immutable glob as a CloudFront path pattern. CloudFront's `*`
974
+ * crosses `/`, so a single star is as wide as a double one — the bucket
975
+ * policy reads it the same way, and the construct's own check is the
976
+ * stricter of the three.
977
+ */
978
+ function pathPattern(glob) {
979
+ return glob.replace(/^\/+/, "").replace(/\*\*/g, "*");
980
+ }
981
+ /** A CloudFront list: its `Quantity` and, when it has some, its `Items`. */
982
+ function list(items) {
983
+ return items.length > 0 ? {
984
+ Quantity: items.length,
985
+ Items: [...items]
986
+ } : { Quantity: 0 };
987
+ }
988
+ /** One of the stage's response headers policies. */
989
+ function headersPolicyConfig(input) {
990
+ return {
991
+ Name: input.name,
992
+ Comment: input.comment,
993
+ ...input.origins.length > 0 ? { CorsConfig: {
994
+ AccessControlAllowOrigins: list([...input.origins].sort()),
995
+ AccessControlAllowHeaders: {
996
+ Quantity: 1,
997
+ Items: ["*"]
998
+ },
999
+ AccessControlAllowMethods: {
1000
+ Quantity: 3,
1001
+ Items: [
1002
+ "GET",
1003
+ "HEAD",
1004
+ "OPTIONS"
1005
+ ]
1006
+ },
1007
+ AccessControlAllowCredentials: false,
1008
+ AccessControlMaxAgeSec: 86400,
1009
+ OriginOverride: false
1010
+ } } : {},
1011
+ ...input.immutable ? { CustomHeadersConfig: {
1012
+ Quantity: 1,
1013
+ Items: [{
1014
+ Header: "Cache-Control",
1015
+ Value: IMMUTABLE_CACHE_CONTROL,
1016
+ Override: true
1017
+ }]
1018
+ } } : {}
1019
+ };
1020
+ }
1021
+ /** The parts of a distribution's config this provider owns. */
1022
+ function distributionConfig(input) {
1023
+ const behaviour = (policy) => ({
1024
+ TargetOriginId: ORIGIN_ID,
1025
+ ViewerProtocolPolicy: "redirect-to-https",
1026
+ AllowedMethods: {
1027
+ Quantity: 3,
1028
+ Items: [
1029
+ "GET",
1030
+ "HEAD",
1031
+ "OPTIONS"
1032
+ ],
1033
+ CachedMethods: {
1034
+ Quantity: 2,
1035
+ Items: ["GET", "HEAD"]
1036
+ }
1037
+ },
1038
+ Compress: true,
1039
+ CachePolicyId: CACHING_OPTIMIZED,
1040
+ ...policy ? { ResponseHeadersPolicyId: policy } : {}
1041
+ });
1042
+ const patterns = [...new Set(input.immutable.map(pathPattern))].sort();
1043
+ const processors = input.processors;
1044
+ const processorPatterns = processors ? [...new Set(processors.prefixes.map((p) => `${pathPattern(p)}*`))].sort() : [];
1045
+ return {
1046
+ CallerReference: input.callerReference,
1047
+ Comment: input.comment,
1048
+ Enabled: true,
1049
+ Aliases: {
1050
+ Quantity: 1,
1051
+ Items: [input.host]
1052
+ },
1053
+ Origins: list([{
1054
+ Id: ORIGIN_ID,
1055
+ DomainName: input.bucketDomain,
1056
+ OriginPath: "",
1057
+ S3OriginConfig: { OriginAccessIdentity: "" },
1058
+ OriginAccessControlId: input.originAccessControlId
1059
+ }, ...processors ? [{
1060
+ Id: PROCESSORS_ORIGIN_ID,
1061
+ DomainName: processors.host,
1062
+ OriginPath: "",
1063
+ CustomOriginConfig: {
1064
+ HTTPPort: 80,
1065
+ HTTPSPort: 443,
1066
+ OriginProtocolPolicy: "https-only",
1067
+ OriginSslProtocols: {
1068
+ Quantity: 1,
1069
+ Items: ["TLSv1.2"]
1070
+ },
1071
+ OriginReadTimeout: 30,
1072
+ OriginKeepaliveTimeout: 5
1073
+ },
1074
+ CustomHeaders: {
1075
+ Quantity: 1,
1076
+ Items: [{
1077
+ HeaderName: require_seeds.ORIGIN_VERIFY_HEADER,
1078
+ HeaderValue: processors.secret
1079
+ }]
1080
+ }
1081
+ }] : []]),
1082
+ DefaultCacheBehavior: behaviour(input.corsPolicyId),
1083
+ CacheBehaviors: list([...processorPatterns.map((PathPattern) => ({
1084
+ ...behaviour(input.corsPolicyId),
1085
+ TargetOriginId: PROCESSORS_ORIGIN_ID,
1086
+ Compress: false,
1087
+ CachePolicyId: CACHING_OPTIMIZED_UNCOMPRESSED,
1088
+ PathPattern
1089
+ })), ...patterns.map((PathPattern) => ({
1090
+ ...behaviour(input.immutablePolicyId),
1091
+ PathPattern
1092
+ }))]),
1093
+ ViewerCertificate: {
1094
+ ACMCertificateArn: input.certificateArn,
1095
+ SSLSupportMethod: "sni-only",
1096
+ MinimumProtocolVersion: "TLSv1.2_2021",
1097
+ CloudFrontDefaultCertificate: false
1098
+ },
1099
+ HttpVersion: "http2and3",
1100
+ IsIPV6Enabled: true,
1101
+ DefaultRootObject: ""
1102
+ };
1103
+ }
1104
+ /**
1105
+ * Whether `current` already holds everything in `wanted`: each key `wanted`
1106
+ * names, recursively, with lists compared as sets. What else `current` holds
1107
+ * — logging, a WAF, geo restrictions set by hand — is left alone, and a
1108
+ * `CallerReference`, fixed at creation, is never compared.
1109
+ */
1110
+ function holds(current, wanted, key) {
1111
+ if (key === "CallerReference") return true;
1112
+ if (Array.isArray(wanted)) return Array.isArray(current) && current.length === wanted.length && wanted.every((w) => current.some((c) => holds(c, w)));
1113
+ if (wanted && typeof wanted === "object") {
1114
+ if (!current || typeof current !== "object") return false;
1115
+ return Object.entries(wanted).every(([k, v]) => holds(current[k], v, k));
1116
+ }
1117
+ return current === wanted;
1118
+ }
1119
+ /** Header configs a policy may hold that this provider never sets. */
1120
+ const FOREIGN_HEADER_CONFIGS = [
1121
+ "CorsConfig",
1122
+ "CustomHeadersConfig",
1123
+ "SecurityHeadersConfig",
1124
+ "RemoveHeadersConfig",
1125
+ "ServerTimingHeadersConfig"
1126
+ ];
1127
+ /** Whether a policy is exactly what is wanted: nothing missing, nothing more. */
1128
+ function sameHeadersPolicy(current, wanted) {
1129
+ if (!current || !holds(current, wanted)) return false;
1130
+ return FOREIGN_HEADER_CONFIGS.every((k) => {
1131
+ if (k in wanted) return true;
1132
+ const extra = current[k];
1133
+ return !extra || extra.Quantity === 0;
1134
+ });
1135
+ }
1136
+ const defaultCdnClients = async (credential) => {
1137
+ const CF = await import("@aws-sdk/client-cloudfront");
1138
+ const ACM = await import("@aws-sdk/client-acm");
1139
+ const config = await require_snsSubscriptions.awsClientConfig(credential, CDN_REGION);
1140
+ const cloudfront = require_snsSubscriptions.awsEndpoint(process.env, "CLOUDFRONT");
1141
+ const acm = require_snsSubscriptions.awsEndpoint(process.env, "ACM");
1142
+ return {
1143
+ CF,
1144
+ ACM,
1145
+ cloudfront: new CF.CloudFrontClient({
1146
+ ...config,
1147
+ ...cloudfront ? { endpoint: cloudfront } : {}
1148
+ }),
1149
+ acm: new ACM.ACMClient({
1150
+ ...config,
1151
+ ...acm ? { endpoint: acm } : {}
1152
+ }),
1153
+ wait: {
1154
+ timeoutMs: 9e5,
1155
+ intervalMs: 1e4
1156
+ }
1157
+ };
1158
+ };
1159
+ let makeCdnClients = defaultCdnClients;
1160
+ /** What an AWS SDK error is called, whichever field carries it. */
1161
+ function errorName$2(error) {
1162
+ const e = error;
1163
+ return e?.Code ?? e?.name ?? "";
1164
+ }
1165
+ async function readOr$2(read, missing) {
1166
+ try {
1167
+ return await read();
1168
+ } catch (error) {
1169
+ if (missing.includes(errorName$2(error))) return void 0;
1170
+ throw error;
1171
+ }
1172
+ }
1173
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1174
+ /** What stands in for an id a dry run would create. */
1175
+ const PLANNED = "(created by this deploy)";
1176
+ /** Each file server over a bucket, behind its own distribution. */
1177
+ async function ensureBucketCdn(ctx, input) {
1178
+ const domain = ctx.workspace.domains?.[ctx.stage];
1179
+ if (!domain) throw new FileServerCdnNeedsDomain(input.servers[0].id, ctx.stage);
1180
+ const clients = await makeCdnClients(ctx.credential);
1181
+ const out = {
1182
+ distributionArns: [],
1183
+ urls: {}
1184
+ };
1185
+ for (const server of input.servers) {
1186
+ const { arn, url } = await ensureServerCdn(ctx, clients, {
1187
+ ...input,
1188
+ server,
1189
+ host: cdnHost(server.id, domain),
1190
+ processorHost: require_seeds.processorOriginHost(server.id, domain)
1191
+ });
1192
+ out.distributionArns.push(arn);
1193
+ out.urls[server.id] = url;
1194
+ }
1195
+ return out;
1196
+ }
1197
+ async function ensureServerCdn(ctx, clients, input) {
1198
+ const { server, host } = input;
1199
+ const name = cdnName(ctx.identity.scope, ctx.stage, server.id);
1200
+ const comment = `gkm ${ctx.identity.key} ${ctx.stage} ${server.id}`.slice(0, 128);
1201
+ const certificateArn = await ensureCertificate(ctx, clients, {
1202
+ id: server.id,
1203
+ host,
1204
+ name
1205
+ });
1206
+ const originAccessControlId = await ensureOriginAccessControl(ctx, clients, {
1207
+ id: server.id,
1208
+ name,
1209
+ bucket: input.bucket
1210
+ });
1211
+ const corsPolicyId = input.origins.length > 0 ? await ensureHeadersPolicy(ctx, clients, {
1212
+ id: server.id,
1213
+ kind: "cors",
1214
+ config: headersPolicyConfig({
1215
+ name: `${name}-cors`,
1216
+ comment: `${comment}: CORS`,
1217
+ origins: input.origins,
1218
+ immutable: false
1219
+ })
1220
+ }) : void 0;
1221
+ const immutablePolicyId = server.immutable.length > 0 ? await ensureHeadersPolicy(ctx, clients, {
1222
+ id: server.id,
1223
+ kind: "immutable",
1224
+ config: headersPolicyConfig({
1225
+ name: `${name}-immutable`,
1226
+ comment: `${comment}: CORS and Cache-Control immutable`,
1227
+ origins: input.origins,
1228
+ immutable: true
1229
+ })
1230
+ }) : void 0;
1231
+ const processors = server.processors?.length ? {
1232
+ prefixes: server.processors,
1233
+ host: input.processorHost,
1234
+ secret: await ensureOriginSecret(ctx, server.id)
1235
+ } : void 0;
1236
+ const distribution = await ensureDistribution(ctx, clients, {
1237
+ id: server.id,
1238
+ comment,
1239
+ config: distributionConfig({
1240
+ comment,
1241
+ callerReference: name,
1242
+ host,
1243
+ certificateArn,
1244
+ bucketDomain: `${input.bucket}.s3.${input.region}.amazonaws.com`,
1245
+ originAccessControlId,
1246
+ ...corsPolicyId ? { corsPolicyId } : {},
1247
+ ...immutablePolicyId ? { immutablePolicyId } : {},
1248
+ immutable: server.immutable,
1249
+ ...processors ? { processors } : {}
1250
+ })
1251
+ });
1252
+ if (distribution.domainName !== PLANNED) {
1253
+ if ((await ctx.writeDns([{
1254
+ host,
1255
+ type: "CNAME",
1256
+ value: distribution.domainName
1257
+ }])).manual.includes(host)) ctx.log(` ${host} answers once that record exists — ${server.id}'s URL is https://${host}`);
1258
+ }
1259
+ return {
1260
+ arn: distribution.arn,
1261
+ url: `https://${host}`
1262
+ };
1263
+ }
1264
+ /**
1265
+ * The secret the CDN sends a file server's processors: the one in the stage's
1266
+ * secrets, or a new one written there — read by the stack, whose edge checks
1267
+ * it, when it composes.
1268
+ */
1269
+ async function ensureOriginSecret(ctx, serverId) {
1270
+ const key = require_seeds.originSecretKey(serverId);
1271
+ const kept = ctx.secrets[key];
1272
+ if (kept) return kept;
1273
+ const secret = require_seeds.newOriginSecret();
1274
+ ctx.log(` ${serverId}: a new processor origin secret, kept as ${key}`);
1275
+ await ctx.writeSecrets({ [key]: secret });
1276
+ return secret;
1277
+ }
1278
+ /** The certificate for `host`: recorded, adopted, or requested — then issued. */
1279
+ async function ensureCertificate(ctx, clients, input) {
1280
+ const { ACM, acm } = clients;
1281
+ const { id, host } = input;
1282
+ const entry = {
1283
+ key: `acm-certificate:${id}`,
1284
+ type: "acm-certificate",
1285
+ data: { host }
1286
+ };
1287
+ const describe = (arn) => readOr$2(() => acm.send(new ACM.DescribeCertificateCommand({ CertificateArn: arn })), ["ResourceNotFoundException"]).then((out) => out?.Certificate);
1288
+ let arn;
1289
+ const recorded = ctx.state.record(entry.key);
1290
+ if (recorded?.id && recorded.data?.host === host) {
1291
+ const found = await describe(recorded.id);
1292
+ if (found && found.Status !== "FAILED" && found.Status !== "VALIDATION_TIMED_OUT" && found.Status !== "REVOKED" && found.Status !== "EXPIRED") arn = recorded.id;
1293
+ }
1294
+ if (!arn) {
1295
+ arn = await findCertificate(clients, host);
1296
+ if (arn) ctx.log(` adopting the certificate for ${host} — ${arn}`);
1297
+ }
1298
+ if (!arn) {
1299
+ if (ctx.dryRun) {
1300
+ await ctx.change({
1301
+ construct: id,
1302
+ resource: `certificate ${host}`,
1303
+ change: "request (ACM, us-east-1, DNS-validated)"
1304
+ }, async () => {});
1305
+ return PLANNED;
1306
+ }
1307
+ await ctx.state.pending(entry);
1308
+ arn = (await acm.send(new ACM.RequestCertificateCommand({
1309
+ DomainName: host,
1310
+ ValidationMethod: "DNS",
1311
+ IdempotencyToken: input.name.replace(/[^A-Za-z0-9]/g, "").slice(0, 32),
1312
+ Tags: identityTags(ctx, id).map((t) => ({
1313
+ Key: t.Key,
1314
+ Value: t.Value
1315
+ }))
1316
+ }))).CertificateArn;
1317
+ await ctx.change({
1318
+ construct: id,
1319
+ resource: `certificate ${host}`,
1320
+ change: "request (ACM, us-east-1, DNS-validated)"
1321
+ }, async () => {});
1322
+ }
1323
+ if (!ctx.dryRun) await ctx.state.ready(entry, arn);
1324
+ let certificate = await describe(arn);
1325
+ let record = certificate?.DomainValidationOptions?.[0]?.ResourceRecord;
1326
+ for (let i = 0; !record && i < 15; i++) {
1327
+ await sleep(Math.min(clients.wait.intervalMs, 2e3));
1328
+ certificate = await describe(arn);
1329
+ record = certificate?.DomainValidationOptions?.[0]?.ResourceRecord;
1330
+ }
1331
+ const validation = record ? {
1332
+ name: record.Name.replace(/\.$/, ""),
1333
+ value: record.Value.replace(/\.$/, "")
1334
+ } : void 0;
1335
+ const written = validation ? await ctx.writeDns([{
1336
+ host: validation.name,
1337
+ type: "CNAME",
1338
+ value: validation.value
1339
+ }]) : { manual: [] };
1340
+ if (certificate?.Status === "ISSUED" || ctx.dryRun) return arn;
1341
+ if (validation && written.manual.includes(validation.name.toLowerCase())) throw new CdnCertificatePending(id, host, validation, "manual");
1342
+ ctx.log(` waiting for ACM to issue the certificate for ${host}…`);
1343
+ const deadline = Date.now() + clients.wait.timeoutMs;
1344
+ while (certificate?.Status === "PENDING_VALIDATION" && Date.now() < deadline) {
1345
+ await sleep(clients.wait.intervalMs);
1346
+ certificate = await describe(arn);
1347
+ }
1348
+ if (certificate?.Status === "ISSUED") return arn;
1349
+ if (certificate?.Status === "PENDING_VALIDATION" || !certificate) throw new CdnCertificatePending(id, host, validation ?? {
1350
+ name: `(not published yet) ${host}`,
1351
+ value: ""
1352
+ }, "timeout");
1353
+ throw new CdnCertificateFailed(id, host, certificate.Status ?? "unknown", certificate.FailureReason);
1354
+ }
1355
+ /** An issued or pending certificate for exactly `host`, if the account has one. */
1356
+ async function findCertificate(clients, host) {
1357
+ const { ACM, acm } = clients;
1358
+ let NextToken;
1359
+ do {
1360
+ const page = await acm.send(new ACM.ListCertificatesCommand({
1361
+ CertificateStatuses: ["ISSUED", "PENDING_VALIDATION"],
1362
+ ...NextToken ? { NextToken } : {}
1363
+ }));
1364
+ const match = page.CertificateSummaryList?.find((c) => c.DomainName?.toLowerCase() === host);
1365
+ if (match?.CertificateArn) return match.CertificateArn;
1366
+ NextToken = page.NextToken;
1367
+ } while (NextToken);
1368
+ }
1369
+ /** The origin access control CloudFront signs its bucket requests with. */
1370
+ async function ensureOriginAccessControl(ctx, clients, input) {
1371
+ const { CF, cloudfront } = clients;
1372
+ const entry = {
1373
+ key: `cloudfront-oac:${input.id}`,
1374
+ type: "cloudfront-oac",
1375
+ data: { name: input.name }
1376
+ };
1377
+ const recorded = ctx.state.record(entry.key)?.id;
1378
+ if (recorded) {
1379
+ if (await readOr$2(() => cloudfront.send(new CF.GetOriginAccessControlCommand({ Id: recorded })), ["NoSuchOriginAccessControl"])) return recorded;
1380
+ }
1381
+ let Marker;
1382
+ do {
1383
+ const page = await cloudfront.send(new CF.ListOriginAccessControlsCommand({ ...Marker ? { Marker } : {} }));
1384
+ const match = page.OriginAccessControlList?.Items?.find((o) => o.Name === input.name);
1385
+ if (match?.Id) {
1386
+ if (!ctx.dryRun) await ctx.state.ready(entry, match.Id);
1387
+ return match.Id;
1388
+ }
1389
+ Marker = page.OriginAccessControlList?.NextMarker;
1390
+ } while (Marker);
1391
+ let id = PLANNED;
1392
+ await ctx.change({
1393
+ construct: input.id,
1394
+ resource: `origin access control ${input.name}`,
1395
+ change: `create (CloudFront signs its reads of ${input.bucket})`
1396
+ }, async () => {
1397
+ await ctx.state.pending(entry);
1398
+ id = (await cloudfront.send(new CF.CreateOriginAccessControlCommand({ OriginAccessControlConfig: {
1399
+ Name: input.name,
1400
+ Description: `gkm: CloudFront's reads of ${input.bucket}`,
1401
+ OriginAccessControlOriginType: "s3",
1402
+ SigningBehavior: "always",
1403
+ SigningProtocol: "sigv4"
1404
+ } }))).OriginAccessControl.Id;
1405
+ await ctx.state.ready(entry, id);
1406
+ });
1407
+ return id;
1408
+ }
1409
+ /** One response headers policy, as wanted. */
1410
+ async function ensureHeadersPolicy(ctx, clients, input) {
1411
+ const { CF, cloudfront } = clients;
1412
+ const { config } = input;
1413
+ const entry = {
1414
+ key: `cloudfront-headers:${input.id}:${input.kind}`,
1415
+ type: "cloudfront-headers",
1416
+ data: { name: config.Name }
1417
+ };
1418
+ const read = (Id) => readOr$2(() => cloudfront.send(new CF.GetResponseHeadersPolicyConfigCommand({ Id })), ["NoSuchResponseHeadersPolicy"]);
1419
+ let id = ctx.state.record(entry.key)?.id;
1420
+ let current = id ? await read(id) : void 0;
1421
+ if (!current) {
1422
+ id = void 0;
1423
+ let Marker;
1424
+ do {
1425
+ const page = await cloudfront.send(new CF.ListResponseHeadersPoliciesCommand({
1426
+ Type: "custom",
1427
+ ...Marker ? { Marker } : {}
1428
+ }));
1429
+ const match = page.ResponseHeadersPolicyList?.Items?.find((p) => p.ResponseHeadersPolicy?.ResponseHeadersPolicyConfig?.Name === config.Name);
1430
+ if (match?.ResponseHeadersPolicy?.Id) {
1431
+ id = match.ResponseHeadersPolicy.Id;
1432
+ current = await read(id);
1433
+ }
1434
+ Marker = page.ResponseHeadersPolicyList?.NextMarker;
1435
+ } while (!id && Marker);
1436
+ }
1437
+ if (id && current) {
1438
+ if (!ctx.dryRun) await ctx.state.ready(entry, id);
1439
+ if (sameHeadersPolicy(current.ResponseHeadersPolicyConfig, config)) return id;
1440
+ const existing = id;
1441
+ await ctx.change({
1442
+ construct: input.id,
1443
+ resource: `response headers policy ${config.Name}`,
1444
+ change: "put back what drifted"
1445
+ }, async () => {
1446
+ await cloudfront.send(new CF.UpdateResponseHeadersPolicyCommand({
1447
+ Id: existing,
1448
+ IfMatch: current.ETag,
1449
+ ResponseHeadersPolicyConfig: config
1450
+ }));
1451
+ });
1452
+ return existing;
1453
+ }
1454
+ let created = PLANNED;
1455
+ await ctx.change({
1456
+ construct: input.id,
1457
+ resource: `response headers policy ${config.Name}`,
1458
+ change: "create"
1459
+ }, async () => {
1460
+ await ctx.state.pending(entry);
1461
+ created = (await cloudfront.send(new CF.CreateResponseHeadersPolicyCommand({ ResponseHeadersPolicyConfig: config }))).ResponseHeadersPolicy.Id;
1462
+ await ctx.state.ready(entry, created);
1463
+ });
1464
+ return created;
1465
+ }
1466
+ /** The distribution: recorded, found by its comment, or created — as wanted. */
1467
+ async function ensureDistribution(ctx, clients, input) {
1468
+ const { CF, cloudfront } = clients;
1469
+ const entry = {
1470
+ key: `cloudfront-distribution:${input.id}`,
1471
+ type: "cloudfront-distribution"
1472
+ };
1473
+ const get = (Id) => readOr$2(() => cloudfront.send(new CF.GetDistributionCommand({ Id })), ["NoSuchDistribution"]);
1474
+ let found = ctx.state.record(entry.key)?.id ? await get(ctx.state.record(entry.key).id) : void 0;
1475
+ if (!found) {
1476
+ let Marker;
1477
+ do {
1478
+ const page = await cloudfront.send(new CF.ListDistributionsCommand({ ...Marker ? { Marker } : {} }));
1479
+ const match = page.DistributionList?.Items?.find((d) => d.Comment === input.comment);
1480
+ if (match?.Id) found = await get(match.Id);
1481
+ Marker = page.DistributionList?.NextMarker;
1482
+ } while (!found && Marker);
1483
+ }
1484
+ if (found?.Distribution) {
1485
+ const distribution = found.Distribution;
1486
+ const id = distribution.Id;
1487
+ const located = {
1488
+ arn: distribution.ARN,
1489
+ domainName: distribution.DomainName
1490
+ };
1491
+ if (!ctx.dryRun) await ctx.state.ready({
1492
+ ...entry,
1493
+ data: located
1494
+ }, id);
1495
+ const current = await cloudfront.send(new CF.GetDistributionConfigCommand({ Id: id }));
1496
+ if (holds(current.DistributionConfig, input.config)) return located;
1497
+ await ctx.change({
1498
+ construct: input.id,
1499
+ resource: `distribution ${id}`,
1500
+ change: "put back what drifted"
1501
+ }, async () => {
1502
+ await cloudfront.send(new CF.UpdateDistributionCommand({
1503
+ Id: id,
1504
+ IfMatch: current.ETag,
1505
+ DistributionConfig: {
1506
+ ...current.DistributionConfig,
1507
+ ...input.config,
1508
+ CallerReference: current.DistributionConfig.CallerReference
1509
+ }
1510
+ }));
1511
+ });
1512
+ return located;
1513
+ }
1514
+ let created = {
1515
+ arn: `arn:aws:cloudfront::${PLANNED}`,
1516
+ domainName: PLANNED
1517
+ };
1518
+ const host = input.config.Aliases?.Items?.[0] ?? input.id;
1519
+ await ctx.change({
1520
+ construct: input.id,
1521
+ resource: `distribution ${host}`,
1522
+ change: "create (CloudFront, takes minutes to reach every edge)"
1523
+ }, async () => {
1524
+ await ctx.state.pending(entry);
1525
+ const out = await cloudfront.send(new CF.CreateDistributionWithTagsCommand({ DistributionConfigWithTags: {
1526
+ DistributionConfig: input.config,
1527
+ Tags: { Items: identityTags(ctx, input.id).map((t) => ({
1528
+ Key: t.Key,
1529
+ Value: t.Value
1530
+ })) }
1531
+ } }));
1532
+ created = {
1533
+ arn: out.Distribution.ARN,
1534
+ domainName: out.Distribution.DomainName
1535
+ };
1536
+ await ctx.state.ready({
1537
+ ...entry,
1538
+ data: created
1539
+ }, out.Distribution.Id);
1540
+ });
1541
+ return created;
1542
+ }
1543
+ //#endregion
800
1544
  //#region src/providers/s3/events.ts
801
1545
  /** What S3 tells the topic about: every object written, and every removed. */
802
1546
  const BUCKET_EVENTS = ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"];
@@ -1225,10 +1969,12 @@ function bucketConstructs(manifest) {
1225
1969
  return Object.entries(manifest).filter(([, d]) => d.kind === "objects").map(([id, d]) => ({
1226
1970
  id,
1227
1971
  versioned: d.versioned === true,
1228
- ...d.expire ? { expire: d.expire } : {},
1972
+ ...(0, _geekmidas_manifest.bucketExpiry)(manifest, id) ? { expire: (0, _geekmidas_manifest.bucketExpiry)(manifest, id) } : {},
1229
1973
  servers: Object.entries(manifest).filter(([, s]) => s.kind === "file-server" && s.of === id).map(([sid, s]) => ({
1230
1974
  id: sid,
1231
- open: s.open ?? []
1975
+ open: s.open ?? [],
1976
+ immutable: s.immutable ?? [],
1977
+ ...s.processors?.length ? { processors: [...new Set(s.processors.map((p) => p.prefix))].sort() } : {}
1232
1978
  })).sort((a, b) => a.id.localeCompare(b.id))
1233
1979
  })).sort((a, b) => a.id.localeCompare(b.id));
1234
1980
  }
@@ -1379,12 +2125,25 @@ async function ensureBucket(ctx, stageClients, construct, watchers) {
1379
2125
  clients = await makeClients(ctx.credential, located.region);
1380
2126
  ctx.log(` '${bucket}' is in ${located.region}, not ${stageClients.region}: '${id}' is reached and addressed there`);
1381
2127
  }
2128
+ const cdn = ctx.config.cdn !== false && construct.servers.length > 0 ? await ensureBucketCdn(ctx, {
2129
+ bucket,
2130
+ region: clients.region,
2131
+ servers: construct.servers,
2132
+ origins: bucketOrigins({
2133
+ workspace: ctx.workspace,
2134
+ manifest: ctx.manifest,
2135
+ runnables: ctx.runnables,
2136
+ stage: ctx.stage,
2137
+ bucket: id
2138
+ }).origins
2139
+ }) : void 0;
1382
2140
  await ensureBucketSettings(ctx, clients, {
1383
2141
  id,
1384
2142
  bucket,
1385
2143
  exists,
1386
2144
  versioning,
1387
2145
  open,
2146
+ ...cdn ? { cdn } : {},
1388
2147
  ...construct.expire ? { expire: construct.expire } : {}
1389
2148
  });
1390
2149
  const events = watchers ? await ensureBucketEvents(ctx, clients, {
@@ -1421,8 +2180,9 @@ async function ensureBucket(ctx, stageClients, construct, watchers) {
1421
2180
  watchers
1422
2181
  });
1423
2182
  }
1424
- const publicUrl = bucketPublicUrl(bucket, clients.region, clients.endpoint);
2183
+ const bucketUrl = bucketPublicUrl(bucket, clients.region, clients.endpoint);
1425
2184
  for (const server of construct.servers) {
2185
+ const publicUrl = cdn?.urls[server.id] ?? bucketUrl;
1426
2186
  const key = (0, _geekmidas_manifest.provideKey)(server.id, "url");
1427
2187
  const entry = {
1428
2188
  key: `file-server:${server.id}`,
@@ -1580,7 +2340,7 @@ async function ensureBucketSettings(ctx, clients, input) {
1580
2340
  Value: t.Value
1581
2341
  })) }
1582
2342
  })));
1583
- const isOpen = input.open.length > 0;
2343
+ const isOpen = input.open.length > 0 && !input.cdn;
1584
2344
  const block = publicAccessBlock(isOpen);
1585
2345
  const ensureBlock = async () => {
1586
2346
  const now = (await read(() => s3.send(new S3.GetPublicAccessBlockCommand({ Bucket })), ["NoSuchPublicAccessBlockConfiguration"]))?.PublicAccessBlockConfiguration;
@@ -1589,10 +2349,10 @@ async function ensureBucketSettings(ctx, clients, input) {
1589
2349
  PublicAccessBlockConfiguration: block
1590
2350
  })));
1591
2351
  };
1592
- const policy = bucketPolicy(bucket, input.open);
2352
+ const policy = bucketPolicy(bucket, input.open, input.cdn ? { cdn: input.cdn } : {});
1593
2353
  const ensurePolicy = async () => {
1594
2354
  const current = await read(() => s3.send(new S3.GetBucketPolicyCommand({ Bucket })), ["NoSuchBucketPolicy"]);
1595
- if (!(current?.Policy !== void 0 && canonicalPolicy(JSON.parse(current.Policy)) === canonicalPolicy(policy))) await set(isOpen ? `policy: TLS only, public read on ${input.open.join(", ")}` : "policy: TLS only", () => s3.send(new S3.PutBucketPolicyCommand({
2355
+ if (!(current?.Policy !== void 0 && canonicalPolicy(JSON.parse(current.Policy)) === canonicalPolicy(policy))) await set(isOpen ? `policy: TLS only, public read on ${input.open.join(", ")}` : input.cdn && input.open.length > 0 ? `policy: TLS only, CloudFront reads ${input.open.join(", ")}` : "policy: TLS only", () => s3.send(new S3.PutBucketPolicyCommand({
1596
2356
  Bucket,
1597
2357
  Policy: JSON.stringify(policy)
1598
2358
  })));
@@ -1894,6 +2654,17 @@ async function provisionStage(options) {
1894
2654
  log(` ${dryRun ? "would " : ""}${action.change} — ${action.resource}`);
1895
2655
  },
1896
2656
  writeSecrets,
2657
+ writeDns: (records) => writeProviderDns(records, {
2658
+ workspace,
2659
+ stage,
2660
+ dryRun,
2661
+ credentials: options.credentials ?? require_credentials.storedCredentials({
2662
+ env,
2663
+ ...options.home ? { home: options.home } : {}
2664
+ }),
2665
+ ...options.dnsProviderFor ? { providerFor: options.dnsProviderFor } : {},
2666
+ log
2667
+ }),
1897
2668
  log
1898
2669
  });
1899
2670
  if (entry.report.actions.length === 0) log(" up to date");
@@ -2336,6 +3107,7 @@ async function provisionResources(phaseCtx, request, ctx, store, emit) {
2336
3107
  ...request.rotateKeys ? { rotateKeys: true } : {},
2337
3108
  ...request.retireOldKeys ? { retireOldKeys: true } : {},
2338
3109
  ...ctx.home ? { home: ctx.home } : {},
3110
+ credentials: ctx.credentials,
2339
3111
  log: (line) => phaseCtx.logger.info(line)
2340
3112
  });
2341
3113
  if (!ctx.dryRun) return;
@@ -2719,4 +3491,4 @@ Object.defineProperty(exports, "iamUserName", {
2719
3491
  }
2720
3492
  });
2721
3493
 
2722
- //# sourceMappingURL=deploy-BbI1UMh3.cjs.map
3494
+ //# sourceMappingURL=deploy-DVrNjX1X.cjs.map