@geekmidas/cli 10.0.0-alpha.117 → 10.0.0-alpha.119

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 (188) hide show
  1. package/README.md +7 -2
  2. package/dist/{EndpointGenerator-BwbYTMtB.cjs → EndpointGenerator-BDa6pPgE.cjs} +2 -2
  3. package/dist/{EndpointGenerator-BwbYTMtB.cjs.map → EndpointGenerator-BDa6pPgE.cjs.map} +1 -1
  4. package/dist/{EndpointGenerator-CvLX8bpx.mjs → EndpointGenerator-CP_z_E3e.mjs} +2 -2
  5. package/dist/{EndpointGenerator-CvLX8bpx.mjs.map → EndpointGenerator-CP_z_E3e.mjs.map} +1 -1
  6. package/dist/{GoDaddyProvider-I3WR0Irc.mjs → GoDaddyProvider-B4JKSuX-.mjs} +2 -2
  7. package/dist/{GoDaddyProvider-I3WR0Irc.mjs.map → GoDaddyProvider-B4JKSuX-.mjs.map} +1 -1
  8. package/dist/{GoDaddyProvider-DY4QFpCg.cjs → GoDaddyProvider-DMLcXGTd.cjs} +2 -2
  9. package/dist/{GoDaddyProvider-DY4QFpCg.cjs.map → GoDaddyProvider-DMLcXGTd.cjs.map} +1 -1
  10. package/dist/{LegacyStateStore-E2rUw9Vu.cjs → LegacyStateStore-88Etk3M3.cjs} +3 -3
  11. package/dist/{LegacyStateStore-E2rUw9Vu.cjs.map → LegacyStateStore-88Etk3M3.cjs.map} +1 -1
  12. package/dist/{LegacyStateStore-RG7min0B.mjs → LegacyStateStore-ByNEjBbh.mjs} +3 -3
  13. package/dist/{LegacyStateStore-RG7min0B.mjs.map → LegacyStateStore-ByNEjBbh.mjs.map} +1 -1
  14. package/dist/{LocalStateStore-kI2cUMCn.mjs → LocalStateStore-BoHhG3tu.mjs} +2 -2
  15. package/dist/{LocalStateStore-kI2cUMCn.mjs.map → LocalStateStore-BoHhG3tu.mjs.map} +1 -1
  16. package/dist/{LocalStateStore-CjzhVPcn.cjs → LocalStateStore-D1I3DJu2.cjs} +2 -2
  17. package/dist/{LocalStateStore-CjzhVPcn.cjs.map → LocalStateStore-D1I3DJu2.cjs.map} +1 -1
  18. package/dist/{OpenApiTsGenerator-DXXFXSbO.mjs → OpenApiTsGenerator-CsrukCE-.mjs} +2 -2
  19. package/dist/{OpenApiTsGenerator-DXXFXSbO.mjs.map → OpenApiTsGenerator-CsrukCE-.mjs.map} +1 -1
  20. package/dist/{OpenApiTsGenerator-BD6ZOQ51.cjs → OpenApiTsGenerator-FNhY7Ssz.cjs} +2 -2
  21. package/dist/{OpenApiTsGenerator-BD6ZOQ51.cjs.map → OpenApiTsGenerator-FNhY7Ssz.cjs.map} +1 -1
  22. package/dist/{S3StateStore-DZ8TCie0.mjs → S3StateStore-BE1Fl_cm.mjs} +2 -2
  23. package/dist/{S3StateStore-DZ8TCie0.mjs.map → S3StateStore-BE1Fl_cm.mjs.map} +1 -1
  24. package/dist/{S3StateStore-C-IrziGt.cjs → S3StateStore-DTLmfO3U.cjs} +2 -2
  25. package/dist/{S3StateStore-C-IrziGt.cjs.map → S3StateStore-DTLmfO3U.cjs.map} +1 -1
  26. package/dist/{SSMStateStore-WRcHtpTy.cjs → SSMStateStore-BaKk8zeI.cjs} +2 -2
  27. package/dist/{SSMStateStore-WRcHtpTy.cjs.map → SSMStateStore-BaKk8zeI.cjs.map} +1 -1
  28. package/dist/{SSMStateStore-BqCLuXrh.mjs → SSMStateStore-kEogq4Wx.mjs} +2 -2
  29. package/dist/{SSMStateStore-BqCLuXrh.mjs.map → SSMStateStore-kEogq4Wx.mjs.map} +1 -1
  30. package/dist/{SubscriberGenerator-CeH7wbYt.cjs → SubscriberGenerator-C8CPxrCK.cjs} +25 -4
  31. package/dist/SubscriberGenerator-C8CPxrCK.cjs.map +1 -0
  32. package/dist/{SubscriberGenerator-DHnIYwUU.mjs → SubscriberGenerator-y3pncae_.mjs} +20 -5
  33. package/dist/SubscriberGenerator-y3pncae_.mjs.map +1 -0
  34. package/dist/{add-CZYOIVw8.mjs → add-BZr_o-Xm.mjs} +5 -5
  35. package/dist/{add-CZYOIVw8.mjs.map → add-BZr_o-Xm.mjs.map} +1 -1
  36. package/dist/{add-D31_V4oL.cjs → add-C8mRgq2x.cjs} +5 -5
  37. package/dist/{add-D31_V4oL.cjs.map → add-C8mRgq2x.cjs.map} +1 -1
  38. package/dist/{bundler-BY_-iPge.cjs → bundler-7-pO7L0X.cjs} +5 -5
  39. package/dist/{bundler-BY_-iPge.cjs.map → bundler-7-pO7L0X.cjs.map} +1 -1
  40. package/dist/{bundler-BADrhw79.mjs → bundler-USaMrVEO.mjs} +5 -5
  41. package/dist/{bundler-BADrhw79.mjs.map → bundler-USaMrVEO.mjs.map} +1 -1
  42. package/dist/{cli-CfB5RjJS.cjs → cli-Bdf7CdQB.cjs} +3 -3
  43. package/dist/{cli-CfB5RjJS.cjs.map → cli-Bdf7CdQB.cjs.map} +1 -1
  44. package/dist/{cli-BI2wjJaB.mjs → cli-DWRYbsA2.mjs} +3 -3
  45. package/dist/{cli-BI2wjJaB.mjs.map → cli-DWRYbsA2.mjs.map} +1 -1
  46. package/dist/{compose-C9VN0iMJ.mjs → compose-DAPoyiny.mjs} +101 -19
  47. package/dist/compose-DAPoyiny.mjs.map +1 -0
  48. package/dist/{compose-BEMY3EwM.cjs → compose-tZLAZZp6.cjs} +101 -19
  49. package/dist/compose-tZLAZZp6.cjs.map +1 -0
  50. package/dist/config.cjs +1 -1
  51. package/dist/config.mjs +1 -1
  52. package/dist/{credentialSchemas-D_VUCDUh.cjs → credentialSchemas-B67WJOOm.cjs} +2 -2
  53. package/dist/{credentialSchemas-D_VUCDUh.cjs.map → credentialSchemas-B67WJOOm.cjs.map} +1 -1
  54. package/dist/{credentialSchemas-Cf5Pf8VE.mjs → credentialSchemas-DDOLRCLF.mjs} +2 -2
  55. package/dist/{credentialSchemas-Cf5Pf8VE.mjs.map → credentialSchemas-DDOLRCLF.mjs.map} +1 -1
  56. package/dist/deploy/public.cjs +7 -7
  57. package/dist/deploy/public.d.cts +2 -1
  58. package/dist/deploy/public.d.cts.map +1 -1
  59. package/dist/deploy/public.d.mts +2 -1
  60. package/dist/deploy/public.d.mts.map +1 -1
  61. package/dist/deploy/public.mjs +7 -7
  62. package/dist/{deploy-BD70bgTu.mjs → deploy-CyQ36GSx.mjs} +20 -9
  63. package/dist/deploy-CyQ36GSx.mjs.map +1 -0
  64. package/dist/{deploy-Ch45lV7q.cjs → deploy-rwfdH_Uw.cjs} +20 -9
  65. package/dist/deploy-rwfdH_Uw.cjs.map +1 -0
  66. package/dist/{discover-Ca8U75dl.mjs → discover-C5roJuc9.mjs} +25 -2
  67. package/dist/discover-C5roJuc9.mjs.map +1 -0
  68. package/dist/{discover-CvTtV5ZD.d.cts → discover-CSW_BMWa.d.cts} +18 -1
  69. package/dist/discover-CSW_BMWa.d.cts.map +1 -0
  70. package/dist/{discover-Bsr7HjqJ.cjs → discover-DozUKs8f.cjs} +25 -2
  71. package/dist/discover-DozUKs8f.cjs.map +1 -0
  72. package/dist/{discover-W2kab9Lc.d.mts → discover-xtT7fgWg.d.mts} +18 -1
  73. package/dist/discover-xtT7fgWg.d.mts.map +1 -0
  74. package/dist/{dns-thzjBFvQ.mjs → dns-BHveRzd8.mjs} +2 -2
  75. package/dist/{dns-thzjBFvQ.mjs.map → dns-BHveRzd8.mjs.map} +1 -1
  76. package/dist/{dns-0tfef9SR.cjs → dns-CJ3izGTo.cjs} +2 -2
  77. package/dist/{dns-0tfef9SR.cjs.map → dns-CJ3izGTo.cjs.map} +1 -1
  78. package/dist/{dokploy-QvxY0Ywi.mjs → dokploy-BaaNWN-B.mjs} +2 -2
  79. package/dist/{dokploy-QvxY0Ywi.mjs.map → dokploy-BaaNWN-B.mjs.map} +1 -1
  80. package/dist/{dokploy-B3wEC6-2.cjs → dokploy-BmlMt2Rb.cjs} +2 -2
  81. package/dist/{dokploy-B3wEC6-2.cjs.map → dokploy-BmlMt2Rb.cjs.map} +1 -1
  82. package/dist/{drivers-3klmg9Sk.mjs → drivers-BjGDYfnC.mjs} +2 -2
  83. package/dist/{drivers-3klmg9Sk.mjs.map → drivers-BjGDYfnC.mjs.map} +1 -1
  84. package/dist/{drivers-CoqD5zYP.cjs → drivers-DbjiYpW6.cjs} +2 -2
  85. package/dist/{drivers-CoqD5zYP.cjs.map → drivers-DbjiYpW6.cjs.map} +1 -1
  86. package/dist/{eas-C5UZCZER.mjs → eas-CKS1YxT3.mjs} +2 -2
  87. package/dist/{eas-C5UZCZER.mjs.map → eas-CKS1YxT3.mjs.map} +1 -1
  88. package/dist/{eas-C8lIhY8B.cjs → eas-ClEvznV9.cjs} +2 -2
  89. package/dist/{eas-C8lIhY8B.cjs.map → eas-ClEvznV9.cjs.map} +1 -1
  90. package/dist/{encryption-xgKJ_098.cjs → encryption-CpydNX0B.cjs} +2 -2
  91. package/dist/{encryption-xgKJ_098.cjs.map → encryption-CpydNX0B.cjs.map} +1 -1
  92. package/dist/{encryption-BhAA51gs.mjs → encryption-DxKJLlYn.mjs} +2 -2
  93. package/dist/{encryption-BhAA51gs.mjs.map → encryption-DxKJLlYn.mjs.map} +1 -1
  94. package/dist/{engine-BCC7wUqs.cjs → engine-C9qO5k6r.cjs} +12 -6
  95. package/dist/engine-C9qO5k6r.cjs.map +1 -0
  96. package/dist/{engine-CV0krWXP.mjs → engine-tmvpAPHz.mjs} +13 -7
  97. package/dist/engine-tmvpAPHz.mjs.map +1 -0
  98. package/dist/{github-CeeFKscD.cjs → github-BdVRMNzc.cjs} +8 -6
  99. package/dist/github-BdVRMNzc.cjs.map +1 -0
  100. package/dist/{github-BASpyAs7.mjs → github-vA9jAJjI.mjs} +8 -6
  101. package/dist/github-vA9jAJjI.mjs.map +1 -0
  102. package/dist/{googlePlay-C7sOjdR5.cjs → googlePlay-BafFoF13.cjs} +3 -3
  103. package/dist/{googlePlay-C7sOjdR5.cjs.map → googlePlay-BafFoF13.cjs.map} +1 -1
  104. package/dist/{googlePlay-CD2Y0j8c.mjs → googlePlay-Kr2etW2y.mjs} +3 -3
  105. package/dist/{googlePlay-CD2Y0j8c.mjs.map → googlePlay-Kr2etW2y.mjs.map} +1 -1
  106. package/dist/index.cjs +243 -141
  107. package/dist/index.cjs.map +1 -1
  108. package/dist/index.mjs +243 -141
  109. package/dist/index.mjs.map +1 -1
  110. package/dist/{migrate-BSnZFik_.mjs → migrate-4EdfUpjQ.mjs} +3 -3
  111. package/dist/{migrate-BSnZFik_.mjs.map → migrate-4EdfUpjQ.mjs.map} +1 -1
  112. package/dist/{migrate-D8HKeUGo.cjs → migrate-BMGpVvFg.cjs} +3 -3
  113. package/dist/{migrate-D8HKeUGo.cjs.map → migrate-BMGpVvFg.cjs.map} +1 -1
  114. package/dist/{migrate-Ba-pFRWc.mjs → migrate-C_IaJz8A.mjs} +2 -2
  115. package/dist/{migrate-Ba-pFRWc.mjs.map → migrate-C_IaJz8A.mjs.map} +1 -1
  116. package/dist/{migrate-Bmgy1mh4.cjs → migrate-DeIkRsXm.cjs} +2 -2
  117. package/dist/{migrate-Bmgy1mh4.cjs.map → migrate-DeIkRsXm.cjs.map} +1 -1
  118. package/dist/openapi.cjs +2 -2
  119. package/dist/openapi.mjs +2 -2
  120. package/dist/{publish-BOivOLLp.mjs → publish-AdbhYxX6.mjs} +2 -2
  121. package/dist/{publish-BOivOLLp.mjs.map → publish-AdbhYxX6.mjs.map} +1 -1
  122. package/dist/{publish-Cfe-drEb.cjs → publish-BWVQ9PZy.cjs} +2 -2
  123. package/dist/{publish-Cfe-drEb.cjs.map → publish-BWVQ9PZy.cjs.map} +1 -1
  124. package/dist/{ready-gc9IFByS.cjs → ready-BFFP838V.cjs} +6 -6
  125. package/dist/{ready-gc9IFByS.cjs.map → ready-BFFP838V.cjs.map} +1 -1
  126. package/dist/{ready-4hEoQ_cr.mjs → ready-BOfogqzr.mjs} +6 -6
  127. package/dist/{ready-4hEoQ_cr.mjs.map → ready-BOfogqzr.mjs.map} +1 -1
  128. package/dist/reconcile/public.cjs +1 -1
  129. package/dist/reconcile/public.d.cts +1 -1
  130. package/dist/reconcile/public.d.mts +1 -1
  131. package/dist/reconcile/public.mjs +1 -1
  132. package/dist/{resolve-CsJ1zX6m.mjs → resolve-CJwadE_F.mjs} +3 -3
  133. package/dist/{resolve-CsJ1zX6m.mjs.map → resolve-CJwadE_F.mjs.map} +1 -1
  134. package/dist/{resolve-BHR-Ewxo.cjs → resolve-Dtrp53jt.cjs} +3 -3
  135. package/dist/{resolve-BHR-Ewxo.cjs.map → resolve-Dtrp53jt.cjs.map} +1 -1
  136. package/dist/{rollback-j38F1Jn-.mjs → rollback-Cx89OK9S.mjs} +4 -4
  137. package/dist/{rollback-j38F1Jn-.mjs.map → rollback-Cx89OK9S.mjs.map} +1 -1
  138. package/dist/{rollback-B4yQkUSH.cjs → rollback-DAKtcSCy.cjs} +4 -4
  139. package/dist/{rollback-B4yQkUSH.cjs.map → rollback-DAKtcSCy.cjs.map} +1 -1
  140. package/dist/sandbox/credentials-worker.cjs +2 -2
  141. package/dist/sandbox/credentials-worker.mjs +2 -2
  142. package/dist/sandbox/discover-worker.cjs +6 -3
  143. package/dist/sandbox/discover-worker.cjs.map +1 -1
  144. package/dist/sandbox/discover-worker.mjs +6 -3
  145. package/dist/sandbox/discover-worker.mjs.map +1 -1
  146. package/dist/sandbox/migrate-worker.cjs +1 -1
  147. package/dist/sandbox/migrate-worker.mjs +1 -1
  148. package/dist/{seeds-h4Wf-_hA.mjs → seeds-BBnvSEgG.mjs} +164 -24
  149. package/dist/seeds-BBnvSEgG.mjs.map +1 -0
  150. package/dist/{seeds-DWaiMMi3.cjs → seeds-CPFoexOv.cjs} +180 -22
  151. package/dist/seeds-CPFoexOv.cjs.map +1 -0
  152. package/dist/{serverSetup-Dog5151C.cjs → serverSetup-BHoXbPit.cjs} +5 -5
  153. package/dist/{serverSetup-Dog5151C.cjs.map → serverSetup-BHoXbPit.cjs.map} +1 -1
  154. package/dist/{serverSetup-CKqCaDhI.mjs → serverSetup-BoD9Vp4B.mjs} +5 -5
  155. package/dist/{serverSetup-CKqCaDhI.mjs.map → serverSetup-BoD9Vp4B.mjs.map} +1 -1
  156. package/dist/{sniffer-Dilwm65v.mjs → sniffer-DDUAlVqp.mjs} +7 -7
  157. package/dist/{sniffer-Dilwm65v.mjs.map → sniffer-DDUAlVqp.mjs.map} +1 -1
  158. package/dist/{sniffer-B99iLT79.cjs → sniffer-DIVpELrO.cjs} +7 -7
  159. package/dist/{sniffer-B99iLT79.cjs.map → sniffer-DIVpELrO.cjs.map} +1 -1
  160. package/dist/{stage-dG5B6nC9.mjs → stage-D9R5j5Xa.mjs} +5 -5
  161. package/dist/{stage-dG5B6nC9.mjs.map → stage-D9R5j5Xa.mjs.map} +1 -1
  162. package/dist/{stage-D1Qmw-Pd.cjs → stage-ElqMbLNH.cjs} +5 -5
  163. package/dist/{stage-D1Qmw-Pd.cjs.map → stage-ElqMbLNH.cjs.map} +1 -1
  164. package/dist/target/public.cjs +1 -1
  165. package/dist/target/public.mjs +1 -1
  166. package/dist/{terminal-CybB-cjk.mjs → terminal-CW_dWeTe.mjs} +2 -2
  167. package/dist/{terminal-CybB-cjk.mjs.map → terminal-CW_dWeTe.mjs.map} +1 -1
  168. package/dist/{terminal-D_NRPW4W.cjs → terminal-DJlqcW_U.cjs} +2 -2
  169. package/dist/{terminal-D_NRPW4W.cjs.map → terminal-DJlqcW_U.cjs.map} +1 -1
  170. package/dist/vitest.cjs +1 -1
  171. package/dist/vitest.mjs +1 -1
  172. package/package.json +15 -15
  173. package/dist/SubscriberGenerator-CeH7wbYt.cjs.map +0 -1
  174. package/dist/SubscriberGenerator-DHnIYwUU.mjs.map +0 -1
  175. package/dist/compose-BEMY3EwM.cjs.map +0 -1
  176. package/dist/compose-C9VN0iMJ.mjs.map +0 -1
  177. package/dist/deploy-BD70bgTu.mjs.map +0 -1
  178. package/dist/deploy-Ch45lV7q.cjs.map +0 -1
  179. package/dist/discover-Bsr7HjqJ.cjs.map +0 -1
  180. package/dist/discover-Ca8U75dl.mjs.map +0 -1
  181. package/dist/discover-CvTtV5ZD.d.cts.map +0 -1
  182. package/dist/discover-W2kab9Lc.d.mts.map +0 -1
  183. package/dist/engine-BCC7wUqs.cjs.map +0 -1
  184. package/dist/engine-CV0krWXP.mjs.map +0 -1
  185. package/dist/github-BASpyAs7.mjs.map +0 -1
  186. package/dist/github-CeeFKscD.cjs.map +0 -1
  187. package/dist/seeds-DWaiMMi3.cjs.map +0 -1
  188. package/dist/seeds-h4Wf-_hA.mjs.map +0 -1
@@ -3,12 +3,12 @@ const require_errors = require("./errors-DMC4Umsb.cjs");
3
3
  const require_run = require("./run-fVZ-rLnc.cjs");
4
4
  const require_workspace = require("./workspace-BwqQnool.cjs");
5
5
  const require_derive = require("./derive-DAbo49sm.cjs");
6
- const require_SubscriberGenerator = require("./SubscriberGenerator-CeH7wbYt.cjs");
6
+ const require_SubscriberGenerator = require("./SubscriberGenerator-C8CPxrCK.cjs");
7
7
  const require_identity = require("./identity-CbLfgQNT.cjs");
8
- const require_EndpointGenerator = require("./EndpointGenerator-BwbYTMtB.cjs");
9
- const require_discover = require("./discover-Bsr7HjqJ.cjs");
8
+ const require_EndpointGenerator = require("./EndpointGenerator-BDa6pPgE.cjs");
9
+ const require_discover = require("./discover-DozUKs8f.cjs");
10
10
  const require_config = require("./config.cjs");
11
- const require_resolve = require("./resolve-BHR-Ewxo.cjs");
11
+ const require_resolve = require("./resolve-Dtrp53jt.cjs");
12
12
  let node_path = require("node:path");
13
13
  let node_fs = require("node:fs");
14
14
  let node_fs_promises = require("node:fs/promises");
@@ -329,8 +329,9 @@ function postgresImage(version) {
329
329
  * The default image for each container.
330
330
  *
331
331
  * Pinned to a major rather than `latest` where the image publishes one, so a
332
- * rebuild does not silently move a developer's Postgres a version. Overridable
333
- * per project: a project needing `postgis/postgis` says so in config.
332
+ * rebuild does not silently move a developer's Postgres a version. A database
333
+ * can name its own (`image: 'postgis/postgis:…'`); any other pin is the
334
+ * project's own `docker-compose.yml`.
334
335
  */
335
336
  const DEFAULT_IMAGES = {
336
337
  postgres: postgresImage(_geekmidas_manifest.DEFAULT_POSTGRES_VERSION),
@@ -1026,6 +1027,7 @@ function planFor(manifest, stage, order, options = {}) {
1026
1027
  ...declaration.scheme ? { scheme: declaration.scheme } : {}
1027
1028
  } : {},
1028
1029
  ...declaration.kind === "file-server" && declaration.open?.length ? { open: declaration.open } : {},
1030
+ ...declaration.kind === "objects" && declaration.expire ? { expire: declaration.expire } : {},
1029
1031
  ...(declaration.kind === "rest-api" || declaration.kind === "site") && declaration.subdomain ? { subdomain: declaration.subdomain } : {},
1030
1032
  ...fake ? { fake: {
1031
1033
  key: fake.key,
@@ -1040,6 +1042,8 @@ function planFor(manifest, stage, order, options = {}) {
1040
1042
  ..."of" in declaration && !detached ? { of: declaration.of } : {},
1041
1043
  ..."schema" in declaration && declaration.schema ? { schema: declaration.schema } : {},
1042
1044
  ..."version" in declaration && declaration.version ? { version: declaration.version } : {},
1045
+ ..."image" in declaration && declaration.image ? { image: declaration.image } : {},
1046
+ ..."extensions" in declaration && declaration.extensions?.length ? { extensions: declaration.extensions } : {},
1043
1047
  ..."roles" in declaration && declaration.roles === false ? { roles: false } : {},
1044
1048
  ..."table" in declaration && declaration.table && !detached ? { table: declaration.table } : {}
1045
1049
  });
@@ -2226,24 +2230,74 @@ async function withLock(lock, body) {
2226
2230
  }
2227
2231
  }
2228
2232
  //#endregion
2229
- //#region src/reconcile/provision.ts
2233
+ //#region src/providers/s3/lifecycle.ts
2230
2234
  /**
2231
- * Creating what the URLs name.
2235
+ * A bucket's lifecycle, as the constructs declare it: one expiry rule per
2236
+ * prefix, merged into whatever else the bucket's lifecycle already holds.
2232
2237
  *
2233
- * Convergent and idempotent: every statement asks whether the thing exists
2234
- * first, so reconciling repeatedly is free and a half-applied run recovers by
2235
- * being run again. That property is what lets `gkm dev` do this on every start.
2238
+ * S3 — and MinIO, which speaks the same API — keeps one lifecycle document
2239
+ * per bucket, and a write replaces all of it. So gkm owns only the rules it
2240
+ * names (`gkm-…`): every other rule is read and put back as it was, a rule of
2241
+ * gkm's that is no longer declared is dropped, and nothing is written when
2242
+ * gkm's rules already say what the manifest does.
2236
2243
  *
2237
- * The line the design draws is at data, not at side effects — this creates
2238
- * databases, schemas, and buckets, and it never seeds, resets, or drops. A
2239
- * developer who wants their data gone asks for it explicitly.
2244
+ * Shared by the `s3` provider and the MinIO a local or compose stack runs,
2245
+ * so a prefix expires the same way on both.
2246
+ */
2247
+ /** The id every rule gkm writes starts with — and the only ones it touches. */
2248
+ const GKM_RULE_PREFIX = "gkm-";
2249
+ /**
2250
+ * The rule id for one prefix: readable, and unique however the prefix is
2251
+ * spelled — `a/b` and `a-b` read alike once sanitised, so a short hash of the
2252
+ * prefix itself follows.
2253
+ */
2254
+ function expireRuleId(prefix) {
2255
+ const readable = prefix.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 200);
2256
+ const hash = (0, node_crypto.createHash)("sha256").update(prefix).digest("hex").slice(0, 8);
2257
+ return `${GKM_RULE_PREFIX}expire-${readable ? `${readable}-` : ""}${hash}`;
2258
+ }
2259
+ /** The rules a bucket's expiry asks for, in a stable order. */
2260
+ function expireRules(expire) {
2261
+ return Object.entries(expire ?? {}).map(([prefix, days]) => ({
2262
+ ID: expireRuleId(prefix),
2263
+ Status: "Enabled",
2264
+ Filter: { Prefix: prefix },
2265
+ Expiration: { Days: days }
2266
+ })).sort((a, b) => a.ID.localeCompare(b.ID));
2267
+ }
2268
+ /**
2269
+ * Merge the declared expiry into the bucket's current rules.
2240
2270
  *
2241
- * Statement generation is separated from application for the reason the design
2242
- * gives: the same DDL has to run in-process locally and from a provisioner in a
2243
- * VPC, and one implementation is what stops "works locally, fails deployed".
2244
- * When the role DDL lands in `@geekmidas/db` this delegates to it rather than
2245
- * growing its own.
2271
+ * @param current the bucket's rules, or nothing when it has no lifecycle
2246
2272
  */
2273
+ function mergeLifecycle(current, expire) {
2274
+ const wanted = expireRules(expire);
2275
+ const rules = current ?? [];
2276
+ const others = rules.filter((r) => !r.ID?.startsWith(GKM_RULE_PREFIX));
2277
+ const ours = rules.filter((r) => r.ID?.startsWith(GKM_RULE_PREFIX));
2278
+ return {
2279
+ changed: canonical(ours) !== canonical(wanted) || new Set(ours.map((r) => r.ID)).size !== ours.length,
2280
+ rules: [...others, ...wanted],
2281
+ describe: describeExpiry(expire)
2282
+ };
2283
+ }
2284
+ /** `expire quotes/ after 30 days, tmp/ after 1 day` — or what removing says. */
2285
+ function describeExpiry(expire) {
2286
+ const entries = Object.entries(expire ?? {}).sort(([a], [b]) => a.localeCompare(b));
2287
+ if (entries.length === 0) return "remove expiry rules";
2288
+ return `expire ${entries.map(([prefix, days]) => `${prefix} after ${days} day${days === 1 ? "" : "s"}`).join(", ")}`;
2289
+ }
2290
+ /** gkm's rules as the fields it sets, order-free. */
2291
+ function canonical(rules) {
2292
+ return JSON.stringify(rules.map((r) => ({
2293
+ id: r.ID,
2294
+ status: r.Status,
2295
+ prefix: r.Filter?.Prefix ?? r.Prefix ?? "",
2296
+ days: r.Expiration?.Days ?? null
2297
+ })).sort((a, b) => (a.id ?? "").localeCompare(b.id ?? "")));
2298
+ }
2299
+ //#endregion
2300
+ //#region src/reconcile/provision.ts
2247
2301
  /**
2248
2302
  * The Postgres work a plan implies.
2249
2303
  *
@@ -2343,6 +2397,7 @@ function rolesFor(resource, schema, plan, project, seed) {
2343
2397
  ...reader ? { reader } : {},
2344
2398
  schema,
2345
2399
  ...resource.kind === "database" ? { database: rootDatabase(resource, plan) } : {},
2400
+ ...resource.extensions ? { extensions: resource.extensions } : {},
2346
2401
  passwords: {
2347
2402
  runtime: localRolePassword(project, plan, runtime, seed),
2348
2403
  owner: localRolePassword(project, plan, owner, seed),
@@ -2428,6 +2483,20 @@ function bucketPolicies(plan) {
2428
2483
  })).sort((a, b) => a.bucket.localeCompare(b.bucket));
2429
2484
  }
2430
2485
  /**
2486
+ * What each bucket keeps, and for how long: the buckets that declare an
2487
+ * expiry, by their stage-scoped name.
2488
+ *
2489
+ * Every bucket in the plan, not only those that declare one, is what a
2490
+ * removed expiry needs — its rules are dropped from a bucket that no longer
2491
+ * asks for them — so a bucket with none is listed with an empty expiry.
2492
+ */
2493
+ function bucketLifecycles(plan) {
2494
+ return plan.resources.filter((r) => r.kind === "objects" && r.provisions).map((r) => ({
2495
+ bucket: r.name,
2496
+ expire: r.expire ?? {}
2497
+ })).sort((a, b) => a.bucket.localeCompare(b.bucket));
2498
+ }
2499
+ /**
2431
2500
  * One bucket's open paths as an S3 bucket policy.
2432
2501
  *
2433
2502
  * Anonymous `s3:GetObject` on the named prefixes and nothing else — which is
@@ -2515,6 +2584,34 @@ async function databasesExist(client, names) {
2515
2584
  }
2516
2585
  }
2517
2586
  /**
2587
+ * Apply each bucket's expiry, beside whatever other rules it has, skipping
2588
+ * those already correct — the same merge the `s3` provider makes deployed.
2589
+ */
2590
+ async function applyLifecycles(client, lifecycles) {
2591
+ const applied = [];
2592
+ for (const { bucket, expire } of lifecycles) {
2593
+ const merge = mergeLifecycle(await client.lifecycle(bucket), expire);
2594
+ const id = `${bucket}:lifecycle`;
2595
+ const describe = `${merge.describe} on ${bucket}`;
2596
+ if (!merge.changed && Object.keys(expire).length === 0) continue;
2597
+ if (!merge.changed) {
2598
+ applied.push({
2599
+ id,
2600
+ describe,
2601
+ created: false
2602
+ });
2603
+ continue;
2604
+ }
2605
+ await client.setLifecycle(bucket, merge.rules);
2606
+ applied.push({
2607
+ id,
2608
+ describe,
2609
+ created: true
2610
+ });
2611
+ }
2612
+ return applied;
2613
+ }
2614
+ /**
2518
2615
  * Apply each served bucket's open-path policy, skipping those already correct.
2519
2616
  *
2520
2617
  * Compared as parsed JSON rather than as text: the same policy re-serialised
@@ -4181,8 +4278,9 @@ function composeFor(plan, options) {
4181
4278
  const volumes = {};
4182
4279
  for (const container of [...plan.containers].sort()) {
4183
4280
  const declared = container === "postgres" ? plan.resources.find((r) => r.version)?.version : void 0;
4281
+ const named = container === "postgres" ? declaredPostgresImage(plan) : void 0;
4184
4282
  const fake = plan.fakes?.[container];
4185
- const image = declared ? postgresImage(declared) : fake?.image ?? DEFAULT_IMAGES[container];
4283
+ const image = named ?? (declared ? postgresImage(declared) : fake?.image ?? DEFAULT_IMAGES[container]);
4186
4284
  if (!image) throw new UnknownContainer(container);
4187
4285
  const published = publish(container, options.ports, plan.fakes);
4188
4286
  services[container] = fake ? {
@@ -4217,6 +4315,28 @@ function toYaml(file) {
4217
4315
  ${(0, yaml.stringify)(file, { lineWidth: 0 })}`;
4218
4316
  }
4219
4317
  /** A container with no image, from config or from the defaults. */
4318
+ /**
4319
+ * The image the databases in the plan named for the shared local cluster, if
4320
+ * any did.
4321
+ */
4322
+ function declaredPostgresImage(plan) {
4323
+ const named = plan.resources.filter((r) => r.kind === "database" && Boolean(r.image));
4324
+ const images = [...new Set(named.map((r) => r.image))];
4325
+ if (images.length > 1) throw new ConflictingPostgresImages(named.map((r) => ({
4326
+ id: r.id,
4327
+ image: r.image
4328
+ })));
4329
+ return images[0];
4330
+ }
4331
+ /** Two databases on the one local cluster named different images for it. */
4332
+ var ConflictingPostgresImages = class extends Error {
4333
+ databases;
4334
+ constructor(databases) {
4335
+ super(`Locally every database runs in one Postgres container, and these name different images for it: ${databases.map((d) => `${d.id} (${d.image})`).join(", ")}. Give them the same image — one that ships every extension they declare.`);
4336
+ this.databases = databases;
4337
+ this.name = "ConflictingPostgresImages";
4338
+ }
4339
+ };
4220
4340
  var UnknownContainer = class extends Error {
4221
4341
  /** The container that could not be resolved. */
4222
4342
  container;
@@ -4526,6 +4646,24 @@ function bucketClient(port, credentials) {
4526
4646
  Bucket: bucket,
4527
4647
  Policy: policy
4528
4648
  }));
4649
+ },
4650
+ async lifecycle(bucket) {
4651
+ try {
4652
+ return (await s3.send(new _aws_sdk_client_s3.GetBucketLifecycleConfigurationCommand({ Bucket: bucket }))).Rules;
4653
+ } catch (error) {
4654
+ if (error.name === "NoSuchLifecycleConfiguration") return;
4655
+ throw error;
4656
+ }
4657
+ },
4658
+ async setLifecycle(bucket, rules) {
4659
+ if (rules.length === 0) {
4660
+ await s3.send(new _aws_sdk_client_s3.DeleteBucketLifecycleCommand({ Bucket: bucket }));
4661
+ return;
4662
+ }
4663
+ await s3.send(new _aws_sdk_client_s3.PutBucketLifecycleConfigurationCommand({
4664
+ Bucket: bucket,
4665
+ LifecycleConfiguration: { Rules: rules }
4666
+ }));
4529
4667
  }
4530
4668
  };
4531
4669
  }
@@ -5465,10 +5603,12 @@ async function create(plan, ports, credentials, sql, buckets, emulatorCarriers,
5465
5603
  const minioPort = ports[primaryPortKey("minio")];
5466
5604
  const names = bucketNames(plan);
5467
5605
  const policies = bucketPolicies(plan);
5606
+ const lifecycles = bucketLifecycles(plan);
5468
5607
  if (minioPort !== void 0 && (names.length > 0 || policies.length > 0)) {
5469
5608
  const client = buckets(minioPort, credentials.minio);
5470
5609
  if (names.length > 0) applied.push(...await applyBuckets(client, names));
5471
5610
  if (policies.length > 0) applied.push(...await applyPolicies(client, policies));
5611
+ if (lifecycles.length > 0) applied.push(...await applyLifecycles(client, lifecycles));
5472
5612
  }
5473
5613
  const emulatorPort = ports[primaryPortKey("localstack")];
5474
5614
  const carriers = carrierNames(plan);
@@ -7358,7 +7498,7 @@ async function createDnsProvider(options) {
7358
7498
  });
7359
7499
  }
7360
7500
  if (provider === "godaddy") {
7361
- const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-DY4QFpCg.cjs"));
7501
+ const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-DMLcXGTd.cjs"));
7362
7502
  return new GoDaddyProvider(options.godaddy ?? {});
7363
7503
  }
7364
7504
  if (provider === "cloudflare") throw new DnsProviderNotImplemented("cloudflare");
@@ -8429,6 +8569,12 @@ Object.defineProperty(exports, "applyBuckets", {
8429
8569
  return applyBuckets;
8430
8570
  }
8431
8571
  });
8572
+ Object.defineProperty(exports, "applyLifecycles", {
8573
+ enumerable: true,
8574
+ get: function() {
8575
+ return applyLifecycles;
8576
+ }
8577
+ });
8432
8578
  Object.defineProperty(exports, "applyPolicies", {
8433
8579
  enumerable: true,
8434
8580
  get: function() {
@@ -8471,6 +8617,12 @@ Object.defineProperty(exports, "bucketClient", {
8471
8617
  return bucketClient;
8472
8618
  }
8473
8619
  });
8620
+ Object.defineProperty(exports, "bucketLifecycles", {
8621
+ enumerable: true,
8622
+ get: function() {
8623
+ return bucketLifecycles;
8624
+ }
8625
+ });
8474
8626
  Object.defineProperty(exports, "bucketPolicies", {
8475
8627
  enumerable: true,
8476
8628
  get: function() {
@@ -8795,6 +8947,12 @@ Object.defineProperty(exports, "maskPassword", {
8795
8947
  return maskPassword;
8796
8948
  }
8797
8949
  });
8950
+ Object.defineProperty(exports, "mergeLifecycle", {
8951
+ enumerable: true,
8952
+ get: function() {
8953
+ return mergeLifecycle;
8954
+ }
8955
+ });
8798
8956
  Object.defineProperty(exports, "networkEnv", {
8799
8957
  enumerable: true,
8800
8958
  get: function() {
@@ -9186,4 +9344,4 @@ Object.defineProperty(exports, "workspace_exports", {
9186
9344
  }
9187
9345
  });
9188
9346
 
9189
- //# sourceMappingURL=seeds-DWaiMMi3.cjs.map
9347
+ //# sourceMappingURL=seeds-CPFoexOv.cjs.map