@geekmidas/cli 10.0.0-alpha.123 → 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 (265) hide show
  1. package/dist/{EndpointGenerator-BDa6pPgE.cjs → EndpointGenerator-BGxf9jWE.cjs} +8 -4
  2. package/dist/{EndpointGenerator-BDa6pPgE.cjs.map → EndpointGenerator-BGxf9jWE.cjs.map} +1 -1
  3. package/dist/{EndpointGenerator-CP_z_E3e.mjs → EndpointGenerator-errMeldx.mjs} +8 -4
  4. package/dist/{EndpointGenerator-CP_z_E3e.mjs.map → EndpointGenerator-errMeldx.mjs.map} +1 -1
  5. package/dist/{GoDaddyProvider-BlB5nJky.mjs → GoDaddyProvider-BN1dODm9.mjs} +3 -3
  6. package/dist/{GoDaddyProvider-BlB5nJky.mjs.map → GoDaddyProvider-BN1dODm9.mjs.map} +1 -1
  7. package/dist/{GoDaddyProvider-Dubq-pCc.cjs → GoDaddyProvider-BTdtqhI_.cjs} +3 -3
  8. package/dist/{GoDaddyProvider-Dubq-pCc.cjs.map → GoDaddyProvider-BTdtqhI_.cjs.map} +1 -1
  9. package/dist/{HostingerProvider-BNpS9aRJ.mjs → HostingerProvider-Cjh_2Ml6.mjs} +2 -2
  10. package/dist/{HostingerProvider-BNpS9aRJ.mjs.map → HostingerProvider-Cjh_2Ml6.mjs.map} +1 -1
  11. package/dist/{HostingerProvider-DR1iws1P.cjs → HostingerProvider-OdQmKXE3.cjs} +2 -2
  12. package/dist/{HostingerProvider-DR1iws1P.cjs.map → HostingerProvider-OdQmKXE3.cjs.map} +1 -1
  13. package/dist/{LegacyStateStore-ClvUC8qy.cjs → LegacyStateStore-C2S8TGwx.cjs} +3 -3
  14. package/dist/{LegacyStateStore-ClvUC8qy.cjs.map → LegacyStateStore-C2S8TGwx.cjs.map} +1 -1
  15. package/dist/{LegacyStateStore-DGALQGZu.mjs → LegacyStateStore-DgXmuG87.mjs} +3 -3
  16. package/dist/{LegacyStateStore-DGALQGZu.mjs.map → LegacyStateStore-DgXmuG87.mjs.map} +1 -1
  17. package/dist/{LocalStateStore-43kSYNpw.cjs → LocalStateStore-CaJw9H-3.cjs} +2 -2
  18. package/dist/{LocalStateStore-43kSYNpw.cjs.map → LocalStateStore-CaJw9H-3.cjs.map} +1 -1
  19. package/dist/{LocalStateStore-CBYUzVR5.mjs → LocalStateStore-ojY_BiMK.mjs} +2 -2
  20. package/dist/{LocalStateStore-CBYUzVR5.mjs.map → LocalStateStore-ojY_BiMK.mjs.map} +1 -1
  21. package/dist/{OpenApiTsGenerator-CsrukCE-.mjs → OpenApiTsGenerator-W_HRXH1X.mjs} +2 -2
  22. package/dist/{OpenApiTsGenerator-CsrukCE-.mjs.map → OpenApiTsGenerator-W_HRXH1X.mjs.map} +1 -1
  23. package/dist/{OpenApiTsGenerator-FNhY7Ssz.cjs → OpenApiTsGenerator-cQgtxWQo.cjs} +2 -2
  24. package/dist/{OpenApiTsGenerator-FNhY7Ssz.cjs.map → OpenApiTsGenerator-cQgtxWQo.cjs.map} +1 -1
  25. package/dist/{S3StateStore-DLHjDYYP.mjs → S3StateStore-BSPkxhrx.mjs} +2 -2
  26. package/dist/{S3StateStore-DLHjDYYP.mjs.map → S3StateStore-BSPkxhrx.mjs.map} +1 -1
  27. package/dist/{S3StateStore-ahE7hSNK.cjs → S3StateStore-BqugXIcb.cjs} +2 -2
  28. package/dist/{S3StateStore-ahE7hSNK.cjs.map → S3StateStore-BqugXIcb.cjs.map} +1 -1
  29. package/dist/{SSMStateStore-qIzIuazA.cjs → SSMStateStore-B0OsuT_k.cjs} +2 -2
  30. package/dist/{SSMStateStore-qIzIuazA.cjs.map → SSMStateStore-B0OsuT_k.cjs.map} +1 -1
  31. package/dist/{SSMStateStore-j5RuMkch.mjs → SSMStateStore-DM85OiH0.mjs} +2 -2
  32. package/dist/{SSMStateStore-j5RuMkch.mjs.map → SSMStateStore-DM85OiH0.mjs.map} +1 -1
  33. package/dist/{SubscriberGenerator-C8CPxrCK.cjs → SubscriberGenerator-BDUp7OeY.cjs} +237 -54
  34. package/dist/SubscriberGenerator-BDUp7OeY.cjs.map +1 -0
  35. package/dist/{SubscriberGenerator-y3pncae_.mjs → SubscriberGenerator-ocQ2yj0K.mjs} +227 -56
  36. package/dist/SubscriberGenerator-ocQ2yj0K.mjs.map +1 -0
  37. package/dist/{add-Bm-C56lH.mjs → add-C7ZBXIzM.mjs} +6 -6
  38. package/dist/{add-Bm-C56lH.mjs.map → add-C7ZBXIzM.mjs.map} +1 -1
  39. package/dist/{add-C2CvXrYw.cjs → add-CrxvmSpq.cjs} +7 -7
  40. package/dist/{add-C2CvXrYw.cjs.map → add-CrxvmSpq.cjs.map} +1 -1
  41. package/dist/{bundler-Dk7tAvAX.cjs → bundler-DVUXW95p.cjs} +5 -5
  42. package/dist/{bundler-Dk7tAvAX.cjs.map → bundler-DVUXW95p.cjs.map} +1 -1
  43. package/dist/{bundler-DnkFt4mn.mjs → bundler-DpZ9uBGN.mjs} +5 -5
  44. package/dist/{bundler-DnkFt4mn.mjs.map → bundler-DpZ9uBGN.mjs.map} +1 -1
  45. package/dist/{cli-Di464j1O.cjs → cli-BMRhE6cZ.cjs} +4 -4
  46. package/dist/{cli-Di464j1O.cjs.map → cli-BMRhE6cZ.cjs.map} +1 -1
  47. package/dist/{cli-CVeHFXNE.mjs → cli-BWfYyy1k.mjs} +4 -4
  48. package/dist/{cli-CVeHFXNE.mjs.map → cli-BWfYyy1k.mjs.map} +1 -1
  49. package/dist/{compose-cHkF---f.mjs → compose-BFmdLig3.mjs} +525 -55
  50. package/dist/compose-BFmdLig3.mjs.map +1 -0
  51. package/dist/{compose-ChVvb3xM.cjs → compose-Bqcy0lqo.cjs} +554 -84
  52. package/dist/compose-Bqcy0lqo.cjs.map +1 -0
  53. package/dist/{config-DrOX29sT.d.mts → config-CdytFgSR.d.cts} +3 -4
  54. package/dist/config-CdytFgSR.d.cts.map +1 -0
  55. package/dist/{config-B3iz9BtK.d.cts → config-_y1FGBWR.d.mts} +3 -4
  56. package/dist/config-_y1FGBWR.d.mts.map +1 -0
  57. package/dist/config.cjs +2 -2
  58. package/dist/config.d.cts +3 -3
  59. package/dist/config.d.mts +3 -3
  60. package/dist/config.mjs +2 -2
  61. package/dist/{credentialSchemas-B67WJOOm.cjs → credentialSchemas-DFxvGEwa.cjs} +2 -2
  62. package/dist/{credentialSchemas-B67WJOOm.cjs.map → credentialSchemas-DFxvGEwa.cjs.map} +1 -1
  63. package/dist/{credentialSchemas-DDOLRCLF.mjs → credentialSchemas-DaMpt-Dx.mjs} +2 -2
  64. package/dist/{credentialSchemas-DDOLRCLF.mjs.map → credentialSchemas-DaMpt-Dx.mjs.map} +1 -1
  65. package/dist/{credentials-Zqr3QQYB.cjs → credentials-D7XJypNd.cjs} +173 -3
  66. package/dist/credentials-D7XJypNd.cjs.map +1 -0
  67. package/dist/{credentials-B5N5yKk6.mjs → credentials-DpfnUvIR.mjs} +132 -4
  68. package/dist/credentials-DpfnUvIR.mjs.map +1 -0
  69. package/dist/deploy/public.cjs +16 -17
  70. package/dist/deploy/public.cjs.map +1 -1
  71. package/dist/deploy/public.d.cts +3 -5
  72. package/dist/deploy/public.d.cts.map +1 -1
  73. package/dist/deploy/public.d.mts +3 -5
  74. package/dist/deploy/public.d.mts.map +1 -1
  75. package/dist/deploy/public.mjs +11 -12
  76. package/dist/deploy/public.mjs.map +1 -1
  77. package/dist/{deploy-DO4djCHb.mjs → deploy-D8pUA9Y0.mjs} +1240 -130
  78. package/dist/deploy-D8pUA9Y0.mjs.map +1 -0
  79. package/dist/{deploy-BffR_uEN.cjs → deploy-DVrNjX1X.cjs} +1261 -169
  80. package/dist/deploy-DVrNjX1X.cjs.map +1 -0
  81. package/dist/{discover-C5roJuc9.mjs → discover-CzGM5P3p.mjs} +136 -14
  82. package/dist/discover-CzGM5P3p.mjs.map +1 -0
  83. package/dist/{discover-DozUKs8f.cjs → discover-DL6h-J97.cjs} +158 -12
  84. package/dist/discover-DL6h-J97.cjs.map +1 -0
  85. package/dist/{dokploy-BcZm93Cc.mjs → dokploy-CzDGNB6A.mjs} +2 -2
  86. package/dist/{dokploy-BcZm93Cc.mjs.map → dokploy-CzDGNB6A.mjs.map} +1 -1
  87. package/dist/{dokploy-CsdvfH3t.cjs → dokploy-TtK6Zyl3.cjs} +2 -2
  88. package/dist/{dokploy-CsdvfH3t.cjs.map → dokploy-TtK6Zyl3.cjs.map} +1 -1
  89. package/dist/{drivers-BjGDYfnC.mjs → drivers-C-VqMtld.mjs} +2 -2
  90. package/dist/{drivers-BjGDYfnC.mjs.map → drivers-C-VqMtld.mjs.map} +1 -1
  91. package/dist/{drivers-DbjiYpW6.cjs → drivers-L29WvE95.cjs} +2 -2
  92. package/dist/{drivers-DbjiYpW6.cjs.map → drivers-L29WvE95.cjs.map} +1 -1
  93. package/dist/{eas-CN_cUXth.cjs → eas-D3clzkni.cjs} +2 -2
  94. package/dist/{eas-CN_cUXth.cjs.map → eas-D3clzkni.cjs.map} +1 -1
  95. package/dist/{eas-CBShP20v.mjs → eas-DaobzDks.mjs} +2 -2
  96. package/dist/{eas-CBShP20v.mjs.map → eas-DaobzDks.mjs.map} +1 -1
  97. package/dist/{emit-Dmc1nvdS.cjs → emit-CYloptRS.cjs} +34 -1
  98. package/dist/emit-CYloptRS.cjs.map +1 -0
  99. package/dist/{emit-C1e8qD08.mjs → emit-CiJGdy_f.mjs} +34 -1
  100. package/dist/emit-CiJGdy_f.mjs.map +1 -0
  101. package/dist/{encryption-CPDM49Hi.cjs → encryption-DBkIFiR2.cjs} +3 -3
  102. package/dist/{encryption-CPDM49Hi.cjs.map → encryption-DBkIFiR2.cjs.map} +1 -1
  103. package/dist/{encryption-CITa6dXL.mjs → encryption-DV31gEY8.mjs} +3 -3
  104. package/dist/{encryption-CITa6dXL.mjs.map → encryption-DV31gEY8.mjs.map} +1 -1
  105. package/dist/{engine-CTnHmHjz.mjs → engine-CFOR9h6X.mjs} +140 -16
  106. package/dist/engine-CFOR9h6X.mjs.map +1 -0
  107. package/dist/{engine-D-jfMVj-.cjs → engine-CuZUGbEh.cjs} +143 -19
  108. package/dist/engine-CuZUGbEh.cjs.map +1 -0
  109. package/dist/{github-D56PSK39.cjs → github-CsvtWSBW.cjs} +115 -47
  110. package/dist/github-CsvtWSBW.cjs.map +1 -0
  111. package/dist/{github-9RlA7EjN.mjs → github-Nep8pI4_.mjs} +113 -45
  112. package/dist/github-Nep8pI4_.mjs.map +1 -0
  113. package/dist/{googlePlay-SX_jQeJf.cjs → googlePlay-C-UfBXJU.cjs} +5 -5
  114. package/dist/{googlePlay-SX_jQeJf.cjs.map → googlePlay-C-UfBXJU.cjs.map} +1 -1
  115. package/dist/{googlePlay-COi5LXON.mjs → googlePlay-lF7Atm_N.mjs} +4 -4
  116. package/dist/{googlePlay-COi5LXON.mjs.map → googlePlay-lF7Atm_N.mjs.map} +1 -1
  117. package/dist/{index-DcyRA5Rf.d.mts → index-DrkV7N5w.d.mts} +2 -2
  118. package/dist/{index-DcyRA5Rf.d.mts.map → index-DrkV7N5w.d.mts.map} +1 -1
  119. package/dist/{index-DjLSMgAL.d.cts → index-yaXZ9m-J.d.cts} +2 -2
  120. package/dist/{index-DjLSMgAL.d.cts.map → index-yaXZ9m-J.d.cts.map} +1 -1
  121. package/dist/index.cjs +166 -85
  122. package/dist/index.cjs.map +1 -1
  123. package/dist/index.mjs +149 -68
  124. package/dist/index.mjs.map +1 -1
  125. package/dist/{local-BwC2v2Y8.mjs → local-B7Zv1NoA.mjs} +2 -2
  126. package/dist/{local-BwC2v2Y8.mjs.map → local-B7Zv1NoA.mjs.map} +1 -1
  127. package/dist/{local-DNhnkugT.cjs → local-OPC9BCZt.cjs} +3 -3
  128. package/dist/{local-DNhnkugT.cjs.map → local-OPC9BCZt.cjs.map} +1 -1
  129. package/dist/{migrate-CrtxXeGY.cjs → migrate-Dp3GhFnf.cjs} +4 -4
  130. package/dist/{migrate-CrtxXeGY.cjs.map → migrate-Dp3GhFnf.cjs.map} +1 -1
  131. package/dist/{migrate-0J6gsfrQ.mjs → migrate-NfbPVhi9.mjs} +4 -4
  132. package/dist/{migrate-0J6gsfrQ.mjs.map → migrate-NfbPVhi9.mjs.map} +1 -1
  133. package/dist/{migrate-DJa_Dlsl.mjs → migrate-_sBX0pve.mjs} +3 -3
  134. package/dist/{migrate-DJa_Dlsl.mjs.map → migrate-_sBX0pve.mjs.map} +1 -1
  135. package/dist/{migrate-BCz1lkh_.cjs → migrate-hlNKNWmg.cjs} +3 -3
  136. package/dist/{migrate-BCz1lkh_.cjs.map → migrate-hlNKNWmg.cjs.map} +1 -1
  137. package/dist/openapi.cjs +3 -3
  138. package/dist/openapi.d.cts +1 -1
  139. package/dist/openapi.d.mts +1 -1
  140. package/dist/openapi.mjs +3 -3
  141. package/dist/{publish-CuQlOW5p.mjs → publish-BuUVaZVy.mjs} +2 -2
  142. package/dist/{publish-CuQlOW5p.mjs.map → publish-BuUVaZVy.mjs.map} +1 -1
  143. package/dist/{publish-qSpnvmdX.cjs → publish-ZOo4xEuZ.cjs} +2 -2
  144. package/dist/{publish-qSpnvmdX.cjs.map → publish-ZOo4xEuZ.cjs.map} +1 -1
  145. package/dist/{ready-BOfogqzr.mjs → ready-Ca883OvY.mjs} +6 -6
  146. package/dist/{ready-BOfogqzr.mjs.map → ready-Ca883OvY.mjs.map} +1 -1
  147. package/dist/{ready-BFFP838V.cjs → ready-qnqp6JAY.cjs} +6 -6
  148. package/dist/{ready-BFFP838V.cjs.map → ready-qnqp6JAY.cjs.map} +1 -1
  149. package/dist/reconcile/public.cjs +2 -2
  150. package/dist/reconcile/public.d.cts +1 -2
  151. package/dist/reconcile/public.d.cts.map +1 -1
  152. package/dist/reconcile/public.d.mts +1 -2
  153. package/dist/reconcile/public.d.mts.map +1 -1
  154. package/dist/reconcile/public.mjs +2 -2
  155. package/dist/{resolve-j8hUcbGz.mjs → resolve-BCU9pYDx.mjs} +4 -4
  156. package/dist/{resolve-j8hUcbGz.mjs.map → resolve-BCU9pYDx.mjs.map} +1 -1
  157. package/dist/{resolve-AsfohXd1.cjs → resolve-C9QqOl5t.cjs} +4 -4
  158. package/dist/{resolve-AsfohXd1.cjs.map → resolve-C9QqOl5t.cjs.map} +1 -1
  159. package/dist/{rollback-Bxq_URgL.cjs → rollback-CTWdDBgB.cjs} +7 -7
  160. package/dist/{rollback-Bxq_URgL.cjs.map → rollback-CTWdDBgB.cjs.map} +1 -1
  161. package/dist/{rollback-JgbAY43C.mjs → rollback-CWyyTQ0B.mjs} +7 -7
  162. package/dist/{rollback-JgbAY43C.mjs.map → rollback-CWyyTQ0B.mjs.map} +1 -1
  163. package/dist/{runtime-DIZTeGJV.d.cts → runtime-DCkfI2E7.d.mts} +2 -2
  164. package/dist/{runtime-DIZTeGJV.d.cts.map → runtime-DCkfI2E7.d.mts.map} +1 -1
  165. package/dist/{runtime-WMLJY-db.d.mts → runtime-Ie4znWIB.d.cts} +2 -2
  166. package/dist/{runtime-WMLJY-db.d.mts.map → runtime-Ie4znWIB.d.cts.map} +1 -1
  167. package/dist/{s3-B4FTQQkV.mjs → s3-BZzSnker.mjs} +2 -2
  168. package/dist/{s3-B4FTQQkV.mjs.map → s3-BZzSnker.mjs.map} +1 -1
  169. package/dist/{s3-DwKLXwUT.cjs → s3-pqgmCTOq.cjs} +2 -2
  170. package/dist/{s3-DwKLXwUT.cjs.map → s3-pqgmCTOq.cjs.map} +1 -1
  171. package/dist/sandbox/credentials-worker.cjs +2 -2
  172. package/dist/sandbox/credentials-worker.mjs +2 -2
  173. package/dist/sandbox/discover-worker.cjs +1 -1
  174. package/dist/sandbox/discover-worker.mjs +1 -1
  175. package/dist/sandbox/migrate-worker.cjs +1 -1
  176. package/dist/sandbox/migrate-worker.mjs +1 -1
  177. package/dist/{seeds-Dv78P9LS.mjs → seeds-CK7w79VC.mjs} +848 -61
  178. package/dist/seeds-CK7w79VC.mjs.map +1 -0
  179. package/dist/{seeds-BWC-qjSI.cjs → seeds-CPEcmoPn.cjs} +953 -64
  180. package/dist/seeds-CPEcmoPn.cjs.map +1 -0
  181. package/dist/{serverSetup-DB6sKwAy.mjs → serverSetup-BAPNuNEX.mjs} +6 -6
  182. package/dist/{serverSetup-DB6sKwAy.mjs.map → serverSetup-BAPNuNEX.mjs.map} +1 -1
  183. package/dist/{serverSetup-CtV80a5M.cjs → serverSetup-C6t6Vtt7.cjs} +6 -6
  184. package/dist/{serverSetup-CtV80a5M.cjs.map → serverSetup-C6t6Vtt7.cjs.map} +1 -1
  185. package/dist/{sniffer-ctpwBBkT.cjs → sniffer-DdX_WN_-.cjs} +9 -9
  186. package/dist/{sniffer-ctpwBBkT.cjs.map → sniffer-DdX_WN_-.cjs.map} +1 -1
  187. package/dist/{sniffer-qDFUQmWP.mjs → sniffer-g9v7cqDN.mjs} +9 -9
  188. package/dist/{sniffer-qDFUQmWP.mjs.map → sniffer-g9v7cqDN.mjs.map} +1 -1
  189. package/dist/{dns-Bmnuttja.cjs → snsSubscriptions-5Cqww8S7.cjs} +351 -3
  190. package/dist/snsSubscriptions-5Cqww8S7.cjs.map +1 -0
  191. package/dist/{dns-DFvO5a53.mjs → snsSubscriptions-BmYeeTH8.mjs} +280 -4
  192. package/dist/snsSubscriptions-BmYeeTH8.mjs.map +1 -0
  193. package/dist/{sst-C1pxbFEd.mjs → sst-CTqZZl1_.mjs} +3 -4
  194. package/dist/{sst-C1pxbFEd.mjs.map → sst-CTqZZl1_.mjs.map} +1 -1
  195. package/dist/{sst-B-Uz4cvm.cjs → sst-lEkBwzGc.cjs} +4 -5
  196. package/dist/{sst-B-Uz4cvm.cjs.map → sst-lEkBwzGc.cjs.map} +1 -1
  197. package/dist/{stage-C7lf36az.mjs → stage-C-I2dVw1.mjs} +6 -6
  198. package/dist/{stage-C7lf36az.mjs.map → stage-C-I2dVw1.mjs.map} +1 -1
  199. package/dist/{stage-DzALYUwY.cjs → stage-CUE5pMmw.cjs} +7 -7
  200. package/dist/{stage-DzALYUwY.cjs.map → stage-CUE5pMmw.cjs.map} +1 -1
  201. package/dist/{stages-B7mCWI_R.cjs → stages-3yUZaZeA.cjs} +2 -2
  202. package/dist/{stages-B7mCWI_R.cjs.map → stages-3yUZaZeA.cjs.map} +1 -1
  203. package/dist/{stages-DSltTW2d.mjs → stages-DTTv0NZW.mjs} +2 -2
  204. package/dist/{stages-DSltTW2d.mjs.map → stages-DTTv0NZW.mjs.map} +1 -1
  205. package/dist/target/public.cjs +1 -1
  206. package/dist/target/public.d.cts +2 -2
  207. package/dist/target/public.d.mts +2 -2
  208. package/dist/target/public.mjs +1 -1
  209. package/dist/{terminal-DJlqcW_U.cjs → terminal-PKhPAajN.cjs} +3 -3
  210. package/dist/{terminal-DJlqcW_U.cjs.map → terminal-PKhPAajN.cjs.map} +1 -1
  211. package/dist/{terminal-CW_dWeTe.mjs → terminal-bqY33lpN.mjs} +3 -3
  212. package/dist/{terminal-CW_dWeTe.mjs.map → terminal-bqY33lpN.mjs.map} +1 -1
  213. package/dist/{types-Q2SC_ly2.d.cts → types-Bmjs4jZV.d.mts} +248 -4
  214. package/dist/types-Bmjs4jZV.d.mts.map +1 -0
  215. package/dist/{types-C8gXOLWL.d.mts → types-D0IsQxES.d.cts} +249 -3
  216. package/dist/types-D0IsQxES.d.cts.map +1 -0
  217. package/dist/vitest.cjs +1 -1
  218. package/dist/vitest.mjs +1 -1
  219. package/dist/workspace/index.cjs +1 -1
  220. package/dist/workspace/index.d.cts +2 -2
  221. package/dist/workspace/index.d.mts +2 -2
  222. package/dist/workspace/index.mjs +1 -1
  223. package/dist/{workspace-DUnnVjqC.mjs → workspace-DBHF9Gba.mjs} +5 -3
  224. package/dist/workspace-DBHF9Gba.mjs.map +1 -0
  225. package/dist/{workspace-C82GLPnf.cjs → workspace-Du4Afb03.cjs} +5 -3
  226. package/dist/workspace-Du4Afb03.cjs.map +1 -0
  227. package/package.json +17 -15
  228. package/dist/SubscriberGenerator-C8CPxrCK.cjs.map +0 -1
  229. package/dist/SubscriberGenerator-y3pncae_.mjs.map +0 -1
  230. package/dist/compose-ChVvb3xM.cjs.map +0 -1
  231. package/dist/compose-cHkF---f.mjs.map +0 -1
  232. package/dist/config-B3iz9BtK.d.cts.map +0 -1
  233. package/dist/config-DrOX29sT.d.mts.map +0 -1
  234. package/dist/credentials-B5N5yKk6.mjs.map +0 -1
  235. package/dist/credentials-Zqr3QQYB.cjs.map +0 -1
  236. package/dist/deploy-BffR_uEN.cjs.map +0 -1
  237. package/dist/deploy-DO4djCHb.mjs.map +0 -1
  238. package/dist/discover-C08meHhu.d.mts +0 -125
  239. package/dist/discover-C08meHhu.d.mts.map +0 -1
  240. package/dist/discover-C5roJuc9.mjs.map +0 -1
  241. package/dist/discover-DipvfWpK.d.cts +0 -125
  242. package/dist/discover-DipvfWpK.d.cts.map +0 -1
  243. package/dist/discover-DozUKs8f.cjs.map +0 -1
  244. package/dist/dns-Bmnuttja.cjs.map +0 -1
  245. package/dist/dns-DFvO5a53.mjs.map +0 -1
  246. package/dist/emit-C1e8qD08.mjs.map +0 -1
  247. package/dist/emit-Dmc1nvdS.cjs.map +0 -1
  248. package/dist/engine-CTnHmHjz.mjs.map +0 -1
  249. package/dist/engine-D-jfMVj-.cjs.map +0 -1
  250. package/dist/github-9RlA7EjN.mjs.map +0 -1
  251. package/dist/github-D56PSK39.cjs.map +0 -1
  252. package/dist/run-BJLIerMM.mjs +0 -133
  253. package/dist/run-BJLIerMM.mjs.map +0 -1
  254. package/dist/run-fVZ-rLnc.cjs +0 -174
  255. package/dist/run-fVZ-rLnc.cjs.map +0 -1
  256. package/dist/sandbox-Co1y2CmF.d.mts +0 -104
  257. package/dist/sandbox-Co1y2CmF.d.mts.map +0 -1
  258. package/dist/sandbox-DvNqr6od.d.cts +0 -104
  259. package/dist/sandbox-DvNqr6od.d.cts.map +0 -1
  260. package/dist/seeds-BWC-qjSI.cjs.map +0 -1
  261. package/dist/seeds-Dv78P9LS.mjs.map +0 -1
  262. package/dist/types-C8gXOLWL.d.mts.map +0 -1
  263. package/dist/types-Q2SC_ly2.d.cts.map +0 -1
  264. package/dist/workspace-C82GLPnf.cjs.map +0 -1
  265. package/dist/workspace-DUnnVjqC.mjs.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
3
- import { i as run$1, s as gkmHome } from "./run-BJLIerMM.mjs";
4
- import { B as LOGS_PORT, H as provisioningOf, R as stageSampleRate, U as stageProvider, _ as PUBLIC_ENV_PREFIXES, a as allConstructGlobs, ct as UnknownSecretsStoreProvider, ft as SERVER_IPV4_KEY, ht as isReservedStageKey, j as TEST_STAGE, pt as SERVER_IPV6_KEY, ut as s3SecretsLocation, v as getPublicEnvPrefix, z as telemetryEnv } from "./workspace-DUnnVjqC.mjs";
3
+ import { s as run$1, x as gkmHome } from "./credentials-DpfnUvIR.mjs";
4
+ import { B as LOGS_PORT, H as provisioningOf, R as stageSampleRate, U as stageProvider, _ as PUBLIC_ENV_PREFIXES, a as allConstructGlobs, ct as UnknownSecretsStoreProvider, ft as SERVER_IPV4_KEY, ht as isReservedStageKey, j as TEST_STAGE, pt as SERVER_IPV6_KEY, ut as s3SecretsLocation, v as getPublicEnvPrefix, z as telemetryEnv } from "./workspace-DBHF9Gba.mjs";
5
5
  import { t as appKey } from "./derive-B4vDpzgP.mjs";
6
- import { a as readFakes, c as DEFAULT_STORAGE, i as readCredentialFakes, l as holdsEveryCache, o as DEFAULT_CACHE, s as DEFAULT_EVENTS$1, t as SubscriberGenerator } from "./SubscriberGenerator-y3pncae_.mjs";
6
+ import { c as DEFAULT_CACHE, d as holdsEveryCache, i as readFakes, l as DEFAULT_EVENTS$1, o as objectsRoute, r as readCredentialFakes, t as SubscriberGenerator, u as DEFAULT_STORAGE } from "./SubscriberGenerator-ocQ2yj0K.mjs";
7
7
  import { n as deployIdentity } from "./identity-CBXr4wNi.mjs";
8
- import { a as startTelemetryCode, n as runtimeFor, s as writeTelemetryModule, u as telemetryArgs } from "./EndpointGenerator-CP_z_E3e.mjs";
9
- import { d as ConstructGenerator, f as output, i as discover } from "./discover-C5roJuc9.mjs";
8
+ import { a as startTelemetryCode, n as runtimeFor, s as writeTelemetryModule, u as telemetryArgs } from "./EndpointGenerator-errMeldx.mjs";
9
+ import { d as ConstructGenerator, f as output, h as eventsEdgeBucket, i as discover } from "./discover-CzGM5P3p.mjs";
10
10
  import { ConfigNotFound, NotInAnApp, loadWorkspaceAppInfo, loadWorkspaceConfig } from "./config.mjs";
11
- import { c as runtimeOf } from "./resolve-j8hUcbGz.mjs";
11
+ import { c as runtimeOf } from "./resolve-BCU9pYDx.mjs";
12
12
  import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
13
13
  import { constants, existsSync, readFileSync } from "node:fs";
14
14
  import { appendFile, chmod, copyFile, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
@@ -16,7 +16,7 @@ import { homedir, hostname, networkInterfaces, userInfo } from "node:os";
16
16
  import { execFile, spawn } from "node:child_process";
17
17
  import { createServer } from "node:net";
18
18
  import { createCipheriv, createDecipheriv, createHash, randomBytes, randomInt } from "node:crypto";
19
- import { CLIENT_IP_HEADER, DEFAULT_POSTGRES_VERSION, PUBLIC_PREFIX, TELEMETRY_KEYS, cacheTable, cookieDomain, dependenciesOf, dependentsOf, drawSecret, externalApiUrl, kebabCase, mobileOrigins, provideKey, providedKeyFor, provisionOrder, publicEnvFor, schemeBase } from "@geekmidas/manifest";
19
+ import { CLIENT_IP_HEADER, DEFAULT_POSTGRES_VERSION, PUBLIC_PREFIX, TELEMETRY_KEYS, bucketExpiry, cacheTable, cookieDomain, dependenciesOf, dependentsOf, drawSecret, externalApiUrl, kebabCase, mobileOrigins, provideKey, providedKeyFor, provisionOrder, publicEnvFor, schemeBase } from "@geekmidas/manifest";
20
20
  import { formatKeyring, generateKeyring } from "@geekmidas/constructs/encryption";
21
21
  import { ownerRole, readerRole, roleStatements } from "@geekmidas/db/pg/roles";
22
22
  import * as snsUrl from "@geekmidas/events/sns/url";
@@ -25,8 +25,9 @@ import { cacheTableStatements } from "@geekmidas/cache/postgres";
25
25
  import { config } from "dotenv";
26
26
  import { promisify } from "node:util";
27
27
  import { Cron } from "@geekmidas/constructs/crons";
28
+ import { Processor } from "@geekmidas/constructs/processors";
28
29
  import { Queue } from "@geekmidas/constructs/queue";
29
- import { CreateBucketCommand, DeleteBucketLifecycleCommand, GetBucketLifecycleConfigurationCommand, GetBucketPolicyCommand, HeadBucketCommand, ListBucketsCommand, PutBucketLifecycleConfigurationCommand, PutBucketPolicyCommand, S3Client } from "@aws-sdk/client-s3";
30
+ import { CreateBucketCommand, DeleteBucketLifecycleCommand, GetBucketLifecycleConfigurationCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, HeadBucketCommand, ListBucketsCommand, PutBucketLifecycleConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketPolicyCommand, S3Client } from "@aws-sdk/client-s3";
30
31
  import { CreateTopicCommand, GetTopicAttributesCommand, SNSClient } from "@aws-sdk/client-sns";
31
32
  import { CreateQueueCommand, GetQueueUrlCommand, SQSClient } from "@aws-sdk/client-sqs";
32
33
  import { Client } from "pg";
@@ -486,6 +487,21 @@ function volumeOf(container) {
486
487
  }[container];
487
488
  }
488
489
  //#endregion
490
+ //#region src/generators/processorRoute.ts
491
+ /**
492
+ * Where `gkm dev` serves a file server's processors, on the dev server of the
493
+ * app holding them: named after the file server.
494
+ *
495
+ * One definition for both sides — the dev server mounts it, and the local
496
+ * edge rewrites each processor pattern on the file server's host onto it — so
497
+ * the path the edge sends and the path the server answers cannot drift.
498
+ */
499
+ const PROCESSORS_DEV_PREFIX = "/__gkm/processors/";
500
+ /** The base a file server's processors answer under, in `gkm dev`. */
501
+ function processorsDevRoute(fileServerId) {
502
+ return `${PROCESSORS_DEV_PREFIX}${fileServerId}`;
503
+ }
504
+ //#endregion
489
505
  //#region src/reconcile/caddyfile.ts
490
506
  /**
491
507
  * The Caddy configuration a plan implies.
@@ -535,7 +551,7 @@ const EDGE_KINDS = {
535
551
  * Docker Desktop resolves this name already; on Linux the compose definition
536
552
  * maps it to the host gateway.
537
553
  */
538
- const HOST_GATEWAY = "host.docker.internal";
554
+ const HOST_GATEWAY$1 = "host.docker.internal";
539
555
  /**
540
556
  * The suffix every local host shares.
541
557
  *
@@ -552,19 +568,26 @@ const LOCAL_TLD = "localhost";
552
568
  * are a legitimate arrangement — two cache behaviours, one origin — and naming
553
569
  * the host after the bucket would make them collide.
554
570
  */
555
- function sitesFor(plan, project, addresses = {}) {
571
+ function sitesFor(plan, project, addresses = {}, processorAddresses = {}) {
556
572
  const byId = new Map(plan.resources.map((r) => [r.id, r]));
557
573
  const sites = [];
558
574
  for (const resource of plan.resources) {
559
575
  if (!EDGE_KINDS[resource.kind]) continue;
560
- const host = hostFor(resource, project);
576
+ const host = hostFor$1(resource, project);
561
577
  if (resource.kind === "file-server") {
562
578
  const origin = resource.of ? byId.get(resource.of) : void 0;
563
579
  if (!origin) continue;
580
+ const address = processorAddresses[resource.id];
581
+ const port = address ? portOf(address) : void 0;
564
582
  sites.push({
565
583
  host,
566
584
  upstream: "http://minio:9000",
567
- rewrite: `/${origin.name}{uri}`
585
+ rewrite: `/${origin.name}{uri}`,
586
+ ...resource.processors?.length && port ? { processors: {
587
+ prefixes: resource.processors,
588
+ upstream: `http://${HOST_GATEWAY$1}:${port}`,
589
+ under: processorsDevRoute(resource.id)
590
+ } } : {}
568
591
  });
569
592
  continue;
570
593
  }
@@ -574,7 +597,7 @@ function sitesFor(plan, project, addresses = {}) {
574
597
  if (!port) continue;
575
598
  sites.push({
576
599
  host,
577
- upstream: `http://${HOST_GATEWAY}:${port}`
600
+ upstream: `http://${HOST_GATEWAY$1}:${port}`
578
601
  });
579
602
  }
580
603
  return sites;
@@ -596,7 +619,7 @@ function portOf(address) {
596
619
  * name, because an empty label makes `uploads..localhost` — a host nothing
597
620
  * resolves and no certificate can be issued for.
598
621
  */
599
- function hostFor(resource, project) {
622
+ function hostFor$1(resource, project) {
600
623
  return [
601
624
  resource.root && project ? stageOf(resource) : labelOf(resource),
602
625
  project,
@@ -654,14 +677,24 @@ function toCaddyfile(sites) {
654
677
  if (sites.length === 0) return `${GENERATED}
655
678
  # No file server is declared in this stage, so it routes nothing.
656
679
  `;
657
- const blocks = sites.map(({ host, upstream, rewrite }) => `
680
+ const blocks = sites.map(({ host, upstream, rewrite, processors }) => `
658
681
  https://${host} {
659
682
  tls internal
660
683
 
661
684
  # gkm's own header, which only a service of this stack may send: the auth
662
685
  # server rate-limits by the client address it carries.
663
686
  request_header -${CLIENT_IP_HEADER}
664
-
687
+ ${processors ? `
688
+ # Its processors' patterns, to the dev server holding them — under the
689
+ # route it mounts them on. Answered there, so the bucket below never is.
690
+ @processors path ${processors.prefixes.map((prefix) => `${prefix}*`).join(" ")}
691
+ handle @processors {
692
+ reverse_proxy ${processors.upstream} {
693
+ rewrite ${processors.under}{uri}
694
+ header_up Host {host}
695
+ }
696
+ }
697
+ ` : ""}
665
698
  reverse_proxy ${upstream} {${rewrite ? `
666
699
  rewrite ${rewrite}
667
700
  # MinIO routes and signs on the Host header, so forwarding the requested
@@ -720,6 +753,108 @@ function emulatorQueueUrl(name, port) {
720
753
  return `${emulatorEndpoint(port)}/${EMULATOR_ACCOUNT}/${name}`;
721
754
  }
722
755
  //#endregion
756
+ //#region src/reconcile/objectEvents.ts
757
+ /**
758
+ * A bucket's object events, where the bucket is a local MinIO.
759
+ *
760
+ * S3 publishes a bucket's events to a topic the deploy creates; MinIO has no
761
+ * topic to publish to, but it can post each event to a webhook. So where MinIO
762
+ * holds a watched bucket, it posts the bucket's events to the process that
763
+ * runs the bucket's subscribers, on a route only it can use, and that process
764
+ * relays each one onto the events broker — under the bucket's name, as
765
+ * `object.created` or `object.deleted` — where every subscriber drains a queue
766
+ * of its own, as a topic's subscribers do.
767
+ *
768
+ * Declared to MinIO in two halves, both derived here so they cannot drift:
769
+ *
770
+ * - **a webhook target per bucket**, as container environment: where to post,
771
+ * the token to present, and a queue on disk, because MinIO starts before the
772
+ * process it posts to and must keep what it could not deliver;
773
+ * - **the bucket's notification**, written through the S3 API once the bucket
774
+ * exists: every created and removed object, to that target. Unfiltered —
775
+ * two subscribers watching overlapping prefixes are two rules S3 refuses on
776
+ * one bucket, and each subscriber filters what it is handed anyway.
777
+ */
778
+ /**
779
+ * The token MinIO presents when it posts a bucket's events.
780
+ *
781
+ * Derived, never stored: the container and the process it posts to are handed
782
+ * the same value by the same derivation — with the stage's random seed where a
783
+ * deployed stage's stack has one, so the token is a secret there, and from the
784
+ * project alone locally, where everything it would protect is on loopback.
785
+ * Not salted by the stage: one MinIO serves `gkm dev` and `gkm test`, and a
786
+ * target is declared once per container.
787
+ */
788
+ function objectsWebhookToken(project, bucket, seed) {
789
+ return createHash("sha256").update(`${seed ? `${seed}:` : ""}${project}:objects-webhook:${bucket}`).digest("base64url").slice(0, 32);
790
+ }
791
+ /**
792
+ * The target's id in MinIO's environment — `MINIO_NOTIFY_WEBHOOK_*_<ID>`.
793
+ *
794
+ * Upper-cased with nothing between words: a canonical id is letters and
795
+ * digits, and an underscore inside the id would read as part of the setting's
796
+ * name.
797
+ */
798
+ function minioTargetId(bucket) {
799
+ return bucket.toUpperCase();
800
+ }
801
+ /** The target as a notification names it. */
802
+ function minioTargetArn(bucket) {
803
+ return `arn:minio:sqs::${minioTargetId(bucket)}:webhook`;
804
+ }
805
+ /** How a container reaches a process on the host. */
806
+ const HOST_GATEWAY = "host.docker.internal";
807
+ /** Where MinIO keeps what it could not deliver yet, inside its container. */
808
+ const QUEUE_ROOT = "/gkm-object-events";
809
+ /** The id of the notification rule gkm owns on a bucket. */
810
+ const NOTIFICATION_RULE_PREFIX = "gkm-";
811
+ /**
812
+ * MinIO's environment for each watched bucket's webhook target.
813
+ *
814
+ * Sorted, so the same buckets always render the same environment and a
815
+ * reconcile that changed nothing does not recreate the container.
816
+ */
817
+ function minioWebhookEnv(hooks) {
818
+ const env = {};
819
+ for (const hook of [...hooks].sort((a, b) => a.bucket.localeCompare(b.bucket))) {
820
+ const id = minioTargetId(hook.bucket);
821
+ env[`MINIO_NOTIFY_WEBHOOK_ENABLE_${id}`] = "on";
822
+ env[`MINIO_NOTIFY_WEBHOOK_ENDPOINT_${id}`] = hook.endpoint;
823
+ env[`MINIO_NOTIFY_WEBHOOK_AUTH_TOKEN_${id}`] = hook.token;
824
+ env[`MINIO_NOTIFY_WEBHOOK_QUEUE_DIR_${id}`] = `${QUEUE_ROOT}/${id.toLowerCase()}`;
825
+ }
826
+ return env;
827
+ }
828
+ /** The rule that sends every created and removed object to the bucket's target. */
829
+ function minioNotificationRule(bucket) {
830
+ return {
831
+ Id: `${NOTIFICATION_RULE_PREFIX}${bucket}`,
832
+ QueueArn: minioTargetArn(bucket),
833
+ Events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"]
834
+ };
835
+ }
836
+ /**
837
+ * Each watched bucket, and the workers that run one of its subscribers.
838
+ *
839
+ * A bucket is watched when a subscriber reads its events key. MinIO posts a
840
+ * bucket's events to one place, and the relay fans them out to every
841
+ * subscriber whichever worker received them — so one worker per bucket is
842
+ * enough, and the first, by id, is the one chosen, so the choice is stable.
843
+ */
844
+ function watchedBuckets(manifest, subscribers) {
845
+ const byKey = /* @__PURE__ */ new Map();
846
+ for (const declaration of Object.values(manifest)) {
847
+ if (declaration.kind !== "objects") continue;
848
+ byKey.set(provideKey(declaration.id, "eventsConnectionString"), declaration.id);
849
+ }
850
+ const watched = /* @__PURE__ */ new Map();
851
+ for (const worker of Object.keys(subscribers).sort()) for (const { connectionKey } of subscribers[worker] ?? []) {
852
+ const bucket = byKey.get(connectionKey);
853
+ if (bucket && !watched.has(bucket)) watched.set(bucket, worker);
854
+ }
855
+ return watched;
856
+ }
857
+ //#endregion
723
858
  //#region src/telemetry/edges.ts
724
859
  /**
725
860
  * Which processes use a `Telemetry` node — read off the manifest's edges.
@@ -744,13 +879,14 @@ function nodeOf(manifest, id) {
744
879
  return node?.kind === "telemetry" ? node : void 0;
745
880
  }
746
881
  /**
747
- * The `Telemetry` node the process for `id` — a surface or a worker, by
748
- * construct id — emits through, or undefined when it has no edge to one.
882
+ * The `Telemetry` node the process for `id` — a surface, a worker, or a file
883
+ * server's processor unit, by construct id — emits through, or undefined
884
+ * when it has no edge to one.
749
885
  */
750
886
  function telemetryOf(manifest, id) {
751
887
  const declaration = manifest[id];
752
888
  if (!declaration) return void 0;
753
- if (declaration.kind === "worker") return nodeOf(manifest, declaration.telemetry);
889
+ if (declaration.kind === "worker" || declaration.kind === "file-server") return nodeOf(manifest, declaration.telemetry);
754
890
  if (declaration.kind !== "rest-api") return void 0;
755
891
  return nodeOf(manifest, declaration.telemetry);
756
892
  }
@@ -764,7 +900,7 @@ function appTelemetry(manifest, appName) {
764
900
  }
765
901
  /** Whether any process in the manifest emits through a `Telemetry` node. */
766
902
  function usesTelemetry(manifest) {
767
- return Object.entries(manifest).some(([id, d]) => (d.kind === "rest-api" || d.kind === "worker") && telemetryOf(manifest, id) !== void 0);
903
+ return Object.entries(manifest).some(([id, d]) => (d.kind === "rest-api" || d.kind === "worker" || d.kind === "file-server") && telemetryOf(manifest, id) !== void 0);
768
904
  }
769
905
  /**
770
906
  * One process's share of the telemetry keys a stage resolved: all of them,
@@ -1025,7 +1161,8 @@ function planFor(manifest, stage, order, options = {}) {
1025
1161
  ...declaration.scheme ? { scheme: declaration.scheme } : {}
1026
1162
  } : {},
1027
1163
  ...declaration.kind === "file-server" && declaration.open?.length ? { open: declaration.open } : {},
1028
- ...declaration.kind === "objects" && declaration.expire ? { expire: declaration.expire } : {},
1164
+ ...declaration.kind === "file-server" && declaration.processors?.length ? { processors: [...new Set(declaration.processors.map((p) => p.prefix))].sort() } : {},
1165
+ ...declaration.kind === "objects" && bucketExpiry(manifest, id) ? { expire: bucketExpiry(manifest, id) } : {},
1029
1166
  ...(declaration.kind === "rest-api" || declaration.kind === "site") && declaration.subdomain ? { subdomain: declaration.subdomain } : {},
1030
1167
  ...fake ? { fake: {
1031
1168
  key: fake.key,
@@ -1215,6 +1352,14 @@ function envFor(plan, options) {
1215
1352
  }
1216
1353
  Object.assign(env, publicEnv(plan, env, options.addresses));
1217
1354
  Object.assign(env, brokerEnv(plan, options.ports, credential));
1355
+ const relay = env.EVENT_PUBLISHER_CONNECTION_STRING;
1356
+ if (relay && options.relayedBuckets?.length) for (const resource of plan.resources) {
1357
+ if (resource.kind !== "objects" || resource.container !== "minio") continue;
1358
+ if (!options.relayedBuckets.includes(resource.id)) continue;
1359
+ if (!env[resource.envKey]) continue;
1360
+ env[provideKey(resource.id, "eventsConnectionString")] = relay;
1361
+ env[provideKey(resource.id, "eventsToken")] = objectsWebhookToken(options.project ?? "", resource.id, credential.seed);
1362
+ }
1218
1363
  if (plan.resources.some((r) => r.kind === "objects" && env[r.envKey])) Object.assign(env, storageCredentials(options.credentials));
1219
1364
  return env;
1220
1365
  }
@@ -1366,7 +1511,7 @@ function urlFor(resource, plan, ports, project, addresses, credential) {
1366
1511
  if (resource.kind === "rest-api" || resource.kind === "site") {
1367
1512
  const address = addresses?.[resource.id];
1368
1513
  const edge = plan.containers.includes("caddy") ? ports[primaryPortKey("caddy")] : void 0;
1369
- return address && edge !== void 0 ? `https://${hostFor(resource, project)}:${edge}` : address;
1514
+ return address && edge !== void 0 ? `https://${hostFor$1(resource, project)}:${edge}` : address;
1370
1515
  }
1371
1516
  if (!resource.container) return void 0;
1372
1517
  const port = ports[primaryPortKey(resource.container)];
@@ -1393,7 +1538,7 @@ function urlFor(resource, plan, ports, project, addresses, credential) {
1393
1538
  case "file-server": {
1394
1539
  const origin = plan.resources.find((r) => r.id === resource.of);
1395
1540
  if (!origin) return void 0;
1396
- return plan.containers.includes("caddy") ? `https://${hostFor(resource, project)}:${port}` : `http://${LOCAL_HOST}:${port}/${origin.name}`;
1541
+ return plan.containers.includes("caddy") ? `https://${hostFor$1(resource, project)}:${port}` : `http://${LOCAL_HOST}:${port}/${origin.name}`;
1397
1542
  }
1398
1543
  case "cache":
1399
1544
  if (resource.of) {
@@ -2582,6 +2727,56 @@ async function databasesExist(client, names) {
2582
2727
  }
2583
2728
  }
2584
2729
  /**
2730
+ * Point each watched bucket's events at its webhook target, and stop sending
2731
+ * an unwatched one's.
2732
+ *
2733
+ * Merged rather than written whole: only the rule gkm owns on a bucket
2734
+ * (`gkm-<Bucket>`) is added or removed, and every other rule — one somebody
2735
+ * added by hand — is kept. Compared before writing, so a converged reconcile
2736
+ * changes nothing.
2737
+ *
2738
+ * @param buckets - each bucket the plan names, by construct id and name
2739
+ * @param watched - the construct ids whose events are relayed
2740
+ */
2741
+ async function applyNotifications(client, buckets, watched) {
2742
+ const applied = [];
2743
+ for (const { id, name } of buckets) {
2744
+ const current = await client.notification(name);
2745
+ const queues = current.QueueConfigurations ?? [];
2746
+ const others = queues.filter((rule) => !rule.Id?.startsWith(NOTIFICATION_RULE_PREFIX));
2747
+ const wanted = watched.has(id) ? [...others, minioNotificationRule(id)] : others;
2748
+ if (!watched.has(id) && others.length === queues.length) continue;
2749
+ const describe = `object events from ${name}`;
2750
+ const ours = queues.filter((rule) => rule.Id?.startsWith(NOTIFICATION_RULE_PREFIX));
2751
+ if (watched.has(id) ? ours.length === 1 && sameRule(ours[0], minioNotificationRule(id)) : ours.length === 0) {
2752
+ applied.push({
2753
+ id: `${name}:events`,
2754
+ describe,
2755
+ created: false
2756
+ });
2757
+ continue;
2758
+ }
2759
+ await client.setNotification(name, {
2760
+ ...current,
2761
+ QueueConfigurations: wanted
2762
+ });
2763
+ applied.push({
2764
+ id: `${name}:events`,
2765
+ describe,
2766
+ created: true
2767
+ });
2768
+ }
2769
+ return applied;
2770
+ }
2771
+ /**
2772
+ * Whether a rule read back says what gkm wrote: the same target, the same
2773
+ * events in any order, and no filter — the store may hand back an empty one.
2774
+ */
2775
+ function sameRule(current, wanted) {
2776
+ const filter = current.Filter;
2777
+ return current.Id === wanted.Id && current.QueueArn === wanted.QueueArn && JSON.stringify([...current.Events ?? []].sort()) === JSON.stringify([...wanted.Events ?? []].sort()) && (filter?.Key?.FilterRules?.length ?? 0) === 0;
2778
+ }
2779
+ /**
2585
2780
  * Apply each bucket's expiry, beside whatever other rules it has, skipping
2586
2781
  * those already correct — the same merge the `s3` provider makes deployed.
2587
2782
  */
@@ -2703,14 +2898,7 @@ var WorkerNameTaken = class extends GkmError {
2703
2898
  * @param background Each worker's files, from discovery's `background`.
2704
2899
  */
2705
2900
  function workerUnits(workspace, manifest, background) {
2706
- const hosts = Object.entries(workspace.apps).filter(([, app]) => app.type === "backend" && !app.entry).map(([name, app]) => {
2707
- const surface = Object.entries(manifest).find(([id, d]) => d.kind === "rest-api" && appKey(id) === name)?.[1];
2708
- return {
2709
- name,
2710
- root: isAbsolute(app.path) ? app.path : join(workspace.root, app.path),
2711
- generated: !(surface?.kind === "rest-api" && surface.endpoints.length > 0)
2712
- };
2713
- }).sort((a, b) => a.name.localeCompare(b.name));
2901
+ const hosts = hostApps(workspace, manifest);
2714
2902
  const units = [];
2715
2903
  for (const [id, declaration] of Object.entries(manifest)) {
2716
2904
  if (declaration.kind !== "worker") continue;
@@ -2718,12 +2906,8 @@ function workerUnits(workspace, manifest, background) {
2718
2906
  if (files.length === 0) continue;
2719
2907
  const name = appKey(id);
2720
2908
  if (workspace.apps[name]) throw new WorkerNameTaken(id, name);
2721
- const ranked = hosts.map((host) => ({
2722
- host,
2723
- holds: files.filter((file) => isUnder(file, host.root)).length
2724
- })).sort((a, b) => b.holds - a.holds || Number(b.host.generated) - Number(a.host.generated));
2725
- const host = ranked[0]?.host;
2726
- if (!host || ranked[0].holds === 0 && !host.generated) throw new WorkerHasNoApp(id);
2909
+ const host = hostFor(hosts, files);
2910
+ if (!host) throw new WorkerHasNoApp(id);
2727
2911
  units.push({
2728
2912
  id,
2729
2913
  name,
@@ -2732,6 +2916,70 @@ function workerUnits(workspace, manifest, background) {
2732
2916
  }
2733
2917
  return units.sort((a, b) => a.name.localeCompare(b.name));
2734
2918
  }
2919
+ /** The service and image name of a file server's processors: `assets-processors`. */
2920
+ function processorUnitName(fileServerId) {
2921
+ return `${appKey(fileServerId.replace(/Server$/, ""))}-processors`;
2922
+ }
2923
+ /** A file server with processors and no backend app to build them from. */
2924
+ var ProcessorsHaveNoApp = class extends GkmError {
2925
+ fileServer;
2926
+ constructor(fileServer) {
2927
+ super(`The file server '${fileServer}' has processors, and the workspace has no backend app that builds a server to carry their entry. Declare a RestApi whose app holds the processors' code.`);
2928
+ this.fileServer = fileServer;
2929
+ this.name = "ProcessorsHaveNoApp";
2930
+ }
2931
+ };
2932
+ /**
2933
+ * The processor units a workspace deploys — each file server with processors
2934
+ * — and the app each is built from, chosen as a worker's is: the backend app
2935
+ * holding the most of its processors' files.
2936
+ */
2937
+ function processorUnits(workspace, manifest) {
2938
+ const hosts = hostApps(workspace, manifest);
2939
+ const units = [];
2940
+ for (const declaration of Object.values(manifest)) {
2941
+ if (declaration.kind !== "file-server") continue;
2942
+ const processors = declaration.processors ?? [];
2943
+ if (processors.length === 0) continue;
2944
+ const host = hostFor(hosts, processors.map(({ handler }) => {
2945
+ const file = handler.split("#")[0] ?? handler;
2946
+ return isAbsolute(file) ? file : join(workspace.root, file);
2947
+ }));
2948
+ if (!host) throw new ProcessorsHaveNoApp(declaration.id);
2949
+ const name = processorUnitName(declaration.id);
2950
+ if (workspace.apps[name]) throw new WorkerNameTaken(declaration.id, name);
2951
+ units.push({
2952
+ id: declaration.id,
2953
+ name,
2954
+ app: host.name
2955
+ });
2956
+ }
2957
+ return units.sort((a, b) => a.name.localeCompare(b.name));
2958
+ }
2959
+ /** The backend apps whose builds generate a server, each where it lives. */
2960
+ function hostApps(workspace, manifest) {
2961
+ return Object.entries(workspace.apps).filter(([, app]) => app.type === "backend" && !app.entry).map(([name, app]) => {
2962
+ const surface = Object.entries(manifest).find(([id, d]) => d.kind === "rest-api" && appKey(id) === name)?.[1];
2963
+ return {
2964
+ name,
2965
+ root: isAbsolute(app.path) ? app.path : join(workspace.root, app.path),
2966
+ generated: !(surface?.kind === "rest-api" && surface.endpoints.length > 0)
2967
+ };
2968
+ }).sort((a, b) => a.name.localeCompare(b.name));
2969
+ }
2970
+ /**
2971
+ * The app holding the most of these files; then one that generates a server;
2972
+ * then by name. None when no app holds any and none generates a server.
2973
+ */
2974
+ function hostFor(hosts, files) {
2975
+ const ranked = hosts.map((host) => ({
2976
+ host,
2977
+ holds: files.filter((file) => isUnder(file, host.root)).length
2978
+ })).sort((a, b) => b.holds - a.holds || Number(b.host.generated) - Number(a.host.generated));
2979
+ const host = ranked[0]?.host;
2980
+ if (!host || ranked[0].holds === 0 && !host.generated) return void 0;
2981
+ return host;
2982
+ }
2735
2983
  /** Whether `file` is inside `dir`. */
2736
2984
  function isUnder(file, dir) {
2737
2985
  const rel = relative(dir, file);
@@ -3381,6 +3629,8 @@ function generateBackendDockerfile(options) {
3381
3629
  }
3382
3630
  /** The port a worker answers its health check on, inside its container. */
3383
3631
  const WORKER_PORT = 3e3;
3632
+ /** The port a processor unit answers on, inside its container. */
3633
+ const PROCESSOR_PORT = 3e3;
3384
3634
  /**
3385
3635
  * A Worker's image: the same build as its host app's backend — a pruned
3386
3636
  * slice, `gkm build --provider server --production` in the image, with the
@@ -3397,6 +3647,19 @@ function generateWorkerDockerfile(options) {
3397
3647
  expose: false
3398
3648
  });
3399
3649
  }
3650
+ /**
3651
+ * A file server's processor unit: its host app's build, and the unit's bundle
3652
+ * as the runner. Its native packages — `sharp` — are installed for the image's
3653
+ * platform beside the bundle, at the versions the build resolved.
3654
+ */
3655
+ function generateProcessorDockerfile(options) {
3656
+ return gkmBundleDockerfile(options, {
3657
+ title: `Processors Dockerfile (${options.fileServer})`,
3658
+ bundle: options.bundle,
3659
+ as: "processors.mjs",
3660
+ expose: true
3661
+ });
3662
+ }
3400
3663
  function gkmBundleDockerfile(options, runner) {
3401
3664
  const { port, healthCheckPath = "/health" } = options;
3402
3665
  const { app } = layout(options);
@@ -3423,7 +3686,7 @@ RUN apk add --no-cache tini
3423
3686
  RUN addgroup --system --gid 1001 nodejs && \\
3424
3687
  adduser --system --uid 1001 hono
3425
3688
 
3426
- # The bundled ${runner.as === "server.mjs" ? "server" : "worker"}
3689
+ # The bundled ${runner.as.replace(/\.mjs$/, "")}
3427
3690
  COPY --from=builder --chown=hono:nodejs ${app}/.gkm/server/dist/${runner.bundle} ./${runner.as === runner.bundle ? "" : runner.as}${externals.copy}
3428
3691
 
3429
3692
  ENV NODE_ENV=production
@@ -3915,7 +4178,7 @@ async function storeFromConfig(workspace, config, options = {}) {
3915
4178
  const profile = options.profile ? { profile: options.profile } : {};
3916
4179
  switch (config.provider) {
3917
4180
  case "s3": {
3918
- const { S3SecretsStore } = await import("./s3-B4FTQQkV.mjs");
4181
+ const { S3SecretsStore } = await import("./s3-BZzSnker.mjs");
3919
4182
  const { deployIdentity } = await import("./identity-CBXr4wNi.mjs").then((n) => n.r);
3920
4183
  const location = s3SecretsLocation(config, workspace.state);
3921
4184
  return new S3SecretsStore({
@@ -4289,6 +4552,14 @@ function composeFor(plan, options) {
4289
4552
  const volume = volumeOf(container);
4290
4553
  if (volume) volumes[volume] = {};
4291
4554
  }
4555
+ const minio = services.minio;
4556
+ if (minio && options.objectWebhooks?.length) {
4557
+ minio.environment = {
4558
+ ...minio.environment,
4559
+ ...minioWebhookEnv(options.objectWebhooks)
4560
+ };
4561
+ if (options.objectWebhooks.some((hook) => hook.endpoint.includes(`//host.docker.internal:`))) minio.extra_hosts = [`${HOST_GATEWAY}:host-gateway`];
4562
+ }
4292
4563
  return {
4293
4564
  name: options.project,
4294
4565
  services: {
@@ -4662,6 +4933,16 @@ function bucketClient(port, credentials) {
4662
4933
  Bucket: bucket,
4663
4934
  LifecycleConfiguration: { Rules: rules }
4664
4935
  }));
4936
+ },
4937
+ async notification(bucket) {
4938
+ const { $metadata: _, ...notification } = await s3.send(new GetBucketNotificationConfigurationCommand({ Bucket: bucket }));
4939
+ return notification;
4940
+ },
4941
+ async setNotification(bucket, notification) {
4942
+ await s3.send(new PutBucketNotificationConfigurationCommand({
4943
+ Bucket: bucket,
4944
+ NotificationConfiguration: notification
4945
+ }));
4665
4946
  }
4666
4947
  };
4667
4948
  }
@@ -5498,9 +5779,10 @@ async function reconcile(options) {
5498
5779
  project,
5499
5780
  ports,
5500
5781
  credentials: options.credentials,
5501
- ...options.apps ? { apps: options.apps(plan.containers) } : {}
5782
+ ...options.apps ? { apps: options.apps(plan.containers) } : {},
5783
+ ...options.objectWebhooks?.length ? { objectWebhooks: options.objectWebhooks } : {}
5502
5784
  });
5503
- const caddyfile = toCaddyfile(sitesFor(plan, project, options.addresses));
5785
+ const caddyfile = toCaddyfile(sitesFor(plan, project, options.addresses, options.processorAddresses));
5504
5786
  const hash = planHash(plan, compose, {
5505
5787
  caddyfile,
5506
5788
  postgres: postgresStatements(plan, project, seed).map((statement) => statement.create).join(";\n")
@@ -5516,7 +5798,8 @@ async function reconcile(options) {
5516
5798
  ...options.mailFrom ? { mailFrom: options.mailFrom } : {},
5517
5799
  ...options.addresses ? { addresses: options.addresses } : {},
5518
5800
  ...lan ? { lanAddress: lan } : {},
5519
- ...options.metroPorts ? { metroPorts: options.metroPorts } : {}
5801
+ ...options.metroPorts ? { metroPorts: options.metroPorts } : {},
5802
+ ...options.objectWebhooks?.length ? { relayedBuckets: options.objectWebhooks.map((hook) => hook.bucket) } : {}
5520
5803
  });
5521
5804
  const env = exports ? resolved : scopeTelemetryEnv(resolved, {
5522
5805
  uses: false,
@@ -5573,7 +5856,7 @@ async function reconcile(options) {
5573
5856
  };
5574
5857
  const credentials = checked.credentials;
5575
5858
  if (start && provision) options.progress?.("🗄️ Creating what the constructs declare — databases, roles, buckets, topics");
5576
- const provisioned = start && provision ? await create(plan, ports, credentials, sql, buckets, carriers, project) : [];
5859
+ const provisioned = start && provision ? await create(plan, ports, credentials, sql, buckets, carriers, project, new Set(stage === (options.localStage ?? stage) ? (options.objectWebhooks ?? []).map((hook) => hook.bucket) : [])) : [];
5577
5860
  await saveState(root, {
5578
5861
  hash,
5579
5862
  stage
@@ -5593,7 +5876,7 @@ async function reconcile(options) {
5593
5876
  * Idempotent throughout, so this runs on every non-converged reconcile rather
5594
5877
  * than being something to remember.
5595
5878
  */
5596
- async function create(plan, ports, credentials, sql, buckets, emulatorCarriers, project) {
5879
+ async function create(plan, ports, credentials, sql, buckets, emulatorCarriers, project, watched) {
5597
5880
  const applied = [];
5598
5881
  const postgresPort = ports[primaryPortKey("postgres")];
5599
5882
  const statements = postgresStatements(plan, project, credentials.seed);
@@ -5607,6 +5890,10 @@ async function create(plan, ports, credentials, sql, buckets, emulatorCarriers,
5607
5890
  if (names.length > 0) applied.push(...await applyBuckets(client, names));
5608
5891
  if (policies.length > 0) applied.push(...await applyPolicies(client, policies));
5609
5892
  if (lifecycles.length > 0) applied.push(...await applyLifecycles(client, lifecycles));
5893
+ if (names.length > 0) applied.push(...await applyNotifications(client, plan.resources.filter((r) => r.provisions && r.kind === "objects").map((r) => ({
5894
+ id: r.id,
5895
+ name: r.name
5896
+ })), watched));
5610
5897
  }
5611
5898
  const emulatorPort = ports[primaryPortKey("localstack")];
5612
5899
  const carriers = carrierNames(plan);
@@ -5672,7 +5959,9 @@ var workspace_exports = /* @__PURE__ */ __exportAll({
5672
5959
  constructGlobs: () => constructGlobs,
5673
5960
  derivedContainers: () => derivedContainers,
5674
5961
  fakesApply: () => fakesApply,
5962
+ localObjectWebhooks: () => localObjectWebhooks,
5675
5963
  metroPorts: () => metroPorts,
5964
+ processorAddresses: () => processorAddresses,
5676
5965
  reconcileWorkspace: () => reconcileWorkspace,
5677
5966
  surfaceAddresses: () => surfaceAddresses
5678
5967
  });
@@ -5735,16 +6024,25 @@ function fakesApply(stage, fake, env = process.env) {
5735
6024
  */
5736
6025
  async function reconcileWorkspace(workspace, options) {
5737
6026
  const runnables = {};
6027
+ const background = {};
6028
+ const subscribers = {};
5738
6029
  const discovered = await discover({
5739
6030
  patterns: constructGlobs(workspace),
5740
6031
  cwd: workspace.root,
5741
- runnables
6032
+ runnables,
6033
+ background,
6034
+ subscribers
5742
6035
  });
5743
6036
  const manifest = options.manifest ?? discovered;
5744
6037
  const faked = fakesApply(options.stage, options.fake);
5745
6038
  const fakes = faked ? await readFakes(workspace.root, manifest) : {};
5746
6039
  const credentialFakes = faked ? await readCredentialFakes(workspace.root, manifest) : {};
5747
6040
  const { credentials } = await loadLocalCredentials(workspace);
6041
+ const objectWebhooks = localObjectWebhooks(workspace, manifest, {
6042
+ background,
6043
+ subscribers,
6044
+ seed: credentials.seed
6045
+ });
5748
6046
  const result = await reconcile({
5749
6047
  credentials,
5750
6048
  root: workspace.root,
@@ -5755,9 +6053,11 @@ async function reconcileWorkspace(workspace, options) {
5755
6053
  ...backendsOf(workspace),
5756
6054
  saved: await loadPortState(workspace.root),
5757
6055
  addresses: surfaceAddresses(workspace, manifest),
6056
+ processorAddresses: processorAddresses(workspace, manifest),
5758
6057
  metroPorts: metroPorts(workspace, manifest),
5759
6058
  fakes,
5760
6059
  credentialFakes,
6060
+ ...objectWebhooks.length > 0 ? { objectWebhooks } : {},
5761
6061
  apps: (containers) => appServices(workspace, manifest, containers, credentials, runnables, fakes, credentialFakes),
5762
6062
  ...options.start === void 0 ? {} : { start: options.start },
5763
6063
  ...options.progress ? { progress: options.progress } : {}
@@ -5772,6 +6072,40 @@ async function reconcileWorkspace(workspace, options) {
5772
6072
  };
5773
6073
  }
5774
6074
  /**
6075
+ * Where MinIO posts each watched bucket's events under `gkm dev`: the dev
6076
+ * server of the app that builds the worker running the bucket's subscribers,
6077
+ * on the host, on that app's port — the process that relays them onto the
6078
+ * broker.
6079
+ *
6080
+ * None where the broker is SNS: there a bucket's events come from a topic, and
6081
+ * nothing relays them. None for a worker no app can build — `gkm build` says
6082
+ * so; a dev loop has nothing to post to.
6083
+ */
6084
+ function localObjectWebhooks(workspace, manifest, options) {
6085
+ if (backendsOf(workspace).events === "sns") return [];
6086
+ const watched = watchedBuckets(manifest, options.subscribers);
6087
+ if (watched.size === 0) return [];
6088
+ let units;
6089
+ try {
6090
+ units = workerUnits(workspace, manifest, options.background);
6091
+ } catch (error) {
6092
+ if (error instanceof WorkerHasNoApp) return [];
6093
+ throw error;
6094
+ }
6095
+ const hooks = [];
6096
+ for (const [bucket, worker] of watched) {
6097
+ const app = units.find((unit) => unit.id === worker)?.app;
6098
+ const port = app ? workspace.apps[app]?.port : void 0;
6099
+ if (!port) continue;
6100
+ hooks.push({
6101
+ bucket,
6102
+ endpoint: `http://${HOST_GATEWAY}:${port}${objectsRoute(bucket)}`,
6103
+ token: objectsWebhookToken(workspace.name, bucket, options.seed)
6104
+ });
6105
+ }
6106
+ return hooks;
6107
+ }
6108
+ /**
5775
6109
  * Where each mobile app's Metro runs: its app's port, which `gkm exec` hands
5776
6110
  * Expo as `RCT_METRO_PORT`. Kept apart from the surfaces' addresses — a phone
5777
6111
  * reaches Metro by `exp://`, not through the edge.
@@ -5786,6 +6120,19 @@ function metroPorts(workspace, manifest) {
5786
6120
  return ports;
5787
6121
  }
5788
6122
  /**
6123
+ * Where each file server's processors answer locally: the dev server of the
6124
+ * app holding them, which `gkm dev` mounts them on — the same app whose build
6125
+ * writes their unit deployed.
6126
+ */
6127
+ function processorAddresses(workspace, manifest) {
6128
+ const addresses = {};
6129
+ for (const unit of processorUnits(workspace, manifest)) {
6130
+ const port = workspace.apps[unit.app]?.port;
6131
+ if (port) addresses[unit.id] = localAddress(port);
6132
+ }
6133
+ return addresses;
6134
+ }
6135
+ /**
5789
6136
  * Where each declared surface and site answers locally.
5790
6137
  *
5791
6138
  * The addresses come from the ports the workspace already assigns; which
@@ -5964,8 +6311,31 @@ function workerEnvKeys(manifest, workerId, runnables = {}) {
5964
6311
  return keys;
5965
6312
  }
5966
6313
  /** What each construct an edge reaches hands the process that reaches it. */
6314
+ /**
6315
+ * The keys a file server's processor unit reads: its bucket's, and what each
6316
+ * of its processors depends on. `undefined` for a file server with none.
6317
+ */
6318
+ function processorEnvKeys(manifest, fileServerId, runnables = {}) {
6319
+ const server = manifest[fileServerId];
6320
+ if (server?.kind !== "file-server" || !server.processors?.length) return;
6321
+ const keys = /* @__PURE__ */ new Set();
6322
+ addEdgeKeys(manifest, [
6323
+ server.of,
6324
+ ...server.processors.flatMap((p) => p.dependencies.map((d) => d.target)),
6325
+ ...runnables[fileServerId] ?? []
6326
+ ], keys);
6327
+ return keys;
6328
+ }
5967
6329
  function addEdgeKeys(manifest, edges, keys) {
5968
6330
  for (const id of edges) {
6331
+ const bucket = eventsEdgeBucket(id);
6332
+ if (bucket) {
6333
+ if (manifest[bucket]?.kind === "objects") {
6334
+ keys.add(provideKey(bucket, "eventsConnectionString"));
6335
+ keys.add(provideKey(bucket, "eventsToken"));
6336
+ }
6337
+ continue;
6338
+ }
5969
6339
  const target = manifest[id];
5970
6340
  if (!target) continue;
5971
6341
  if (target.kind === "rest-api") {
@@ -6423,6 +6793,308 @@ function validateImageRef(ref) {
6423
6793
  return ref;
6424
6794
  }
6425
6795
  //#endregion
6796
+ //#region src/providers/processorOrigin.ts
6797
+ /**
6798
+ * A file server's processors as a CDN origin: the names both sides agree on.
6799
+ *
6800
+ * On a compose stage whose bucket is on S3, the CDN serves the bucket and
6801
+ * sends each processor pattern to the stack's processor unit, at a host of
6802
+ * its own. That host is public — a CDN reaches its origin over the internet —
6803
+ * so the CDN adds a secret header and the edge refuses any request without
6804
+ * it. One definition, read by the CDN that sends the header and by the stack
6805
+ * whose edge checks it, so the two cannot drift.
6806
+ */
6807
+ /** The header the CDN adds to every request it sends a processor. */
6808
+ const ORIGIN_VERIFY_HEADER = "X-Gkm-Origin-Verify";
6809
+ /** Where a file server's processors answer the CDN: `<fileserver>-processors.<domain>`. */
6810
+ function processorOriginHost(serverId, domain) {
6811
+ return `${appKey(serverId)}-processors.${domain}`.toLowerCase();
6812
+ }
6813
+ /** The stage secret holding the header's value: `ASSETS_SERVER_ORIGIN_SECRET`. */
6814
+ function originSecretKey(serverId) {
6815
+ return provideKey(serverId, "originSecret");
6816
+ }
6817
+ /**
6818
+ * What the processor unit reads that secret from. Set wherever the CDN fronts
6819
+ * it, so the unit refuses a request without the header itself — on Dokploy,
6820
+ * whose edge cannot match a header, the only check; behind the stack's own
6821
+ * edge, a second one.
6822
+ */
6823
+ const PROCESSOR_ORIGIN_SECRET_ENV = "GKM_PROCESSOR_ORIGIN_SECRET";
6824
+ /** A new value for that secret: random, generated once, kept in the stage. */
6825
+ function newOriginSecret() {
6826
+ return randomBytes(32).toString("base64url");
6827
+ }
6828
+ //#endregion
6829
+ //#region src/generators/ProcessorGenerator.ts
6830
+ /** Where a file server's processor entry lives, under an app's `.gkm/server`. */
6831
+ function processorEntryDir(serverDir, fileServerId) {
6832
+ return join(serverDir, "processors", processorUnitName(fileServerId));
6833
+ }
6834
+ /** The file its bundle is written to, beside the server's. */
6835
+ function processorBundleName(fileServerId) {
6836
+ return `${processorUnitName(fileServerId)}.mjs`;
6837
+ }
6838
+ /**
6839
+ * A file server's processors, as the build generates them.
6840
+ *
6841
+ * On AWS each is a Lambda behind a function URL — the CDN's origin for its
6842
+ * pattern. On a server they are one process per file server, the processor
6843
+ * unit (see {@link ProcessorGenerator.buildEntry}), so the `server` target
6844
+ * generates nothing per processor here.
6845
+ */
6846
+ var ProcessorGenerator = class extends ConstructGenerator {
6847
+ isConstruct(value) {
6848
+ return Processor.isProcessor(value);
6849
+ }
6850
+ async build(context, constructs, outputDir, options) {
6851
+ if ((options?.target ?? "aws") !== "aws" || constructs.length === 0) return [];
6852
+ const dir = join(outputDir, "processors");
6853
+ await mkdir(dir, { recursive: true });
6854
+ const infos = [];
6855
+ for (const { key, construct, path } of constructs) {
6856
+ const file = join(dir, `${key}.ts`);
6857
+ const importPath = relative(dirname(file), path.relative).replace(/\.ts$/, ".js");
6858
+ await writeFile(file, `import { AWSLambdaProcessor } from '@geekmidas/constructs/processors';
6859
+ import { ${key} } from '${importPath}';
6860
+ ${context.storageDrivers?.imports ?? ""}
6861
+ ${context.storageDrivers?.setup ? `\n// The handler registers the drivers its target needs.\n${context.storageDrivers.setup}\n` : ""}
6862
+ const adapter = new AWSLambdaProcessor(${key});
6863
+
6864
+ export const handler = adapter.handler;
6865
+ `);
6866
+ infos.push(await processorInfo(key, construct, relative(options?.root ?? process.cwd(), file).replace(/\.ts$/, ".handler"), context));
6867
+ }
6868
+ return infos;
6869
+ }
6870
+ /**
6871
+ * `gkm dev`'s half: `processors.ts` beside the dev server's app, mounting
6872
+ * each file server's processors under `/__gkm/processors/<FileServer>`.
6873
+ * The local edge sends each pattern on the file server's host there, so
6874
+ * `processedUrl()` answers locally as it does deployed.
6875
+ *
6876
+ * In the dev server's own process rather than a unit of its own: locally
6877
+ * there is no CPU to protect, and the dev server already reloads on change.
6878
+ */
6879
+ async buildDev(outputDir, processors) {
6880
+ await mkdir(outputDir, { recursive: true });
6881
+ const file = join(outputDir, "processors.ts");
6882
+ const imports = processors.map(({ key, path }) => {
6883
+ const specifier = relative(outputDir, path.absolute).replace(/\.ts$/, ".js");
6884
+ return `import { ${key} } from '${specifier.startsWith(".") ? specifier : `./${specifier}`}';`;
6885
+ }).join("\n");
6886
+ const byServer = /* @__PURE__ */ new Map();
6887
+ for (const { key, construct } of processors) byServer.set(construct.surfaceId, [...byServer.get(construct.surfaceId) ?? [], key]);
6888
+ const units = [...byServer.entries()].map(([id, keys]) => ` ${JSON.stringify(id)}: [${keys.join(", ")}],`).join("\n");
6889
+ await writeFile(file, `/**
6890
+ * Generated processors setup for \`gkm dev\`.
6891
+ *
6892
+ * Each file server's processors, under ${PROCESSORS_DEV_PREFIX}<FileServer>: the
6893
+ * local edge rewrites each processor pattern on the file server's host here.
6894
+ */
6895
+ import type { EnvironmentParser } from '@geekmidas/envkit';
6896
+ import { processorServer } from '@geekmidas/constructs/processors';
6897
+ ${imports}
6898
+
6899
+ export function setupProcessors(
6900
+ app: { all: (path: string, handler: (c: any) => unknown) => unknown },
6901
+ envParser: EnvironmentParser<any>,
6902
+ ): void {
6903
+ const units: Record<string, ReturnType<typeof processorServer>> = Object.fromEntries(
6904
+ Object.entries({
6905
+ ${units}
6906
+ }).map(([id, processors]) => [id, processorServer(processors, envParser)]),
6907
+ );
6908
+
6909
+ app.all('${PROCESSORS_DEV_PREFIX}:server/*', async (c: any) => {
6910
+ const server = c.req.param('server') as string;
6911
+ const serve = units[server];
6912
+ if (!serve) return c.notFound();
6913
+ const path = c.req.path.slice(\`${PROCESSORS_DEV_PREFIX}\${server}\`.length) || '/';
6914
+ const response = await serve({ method: c.req.method, path });
6915
+ if (!response) {
6916
+ return new Response(null, {
6917
+ status: 404,
6918
+ headers: { 'cache-control': 'public, max-age=60' },
6919
+ });
6920
+ }
6921
+ return new Response(c.req.method === 'HEAD' ? null : response.body, {
6922
+ status: response.status,
6923
+ headers: response.headers,
6924
+ });
6925
+ });
6926
+ }
6927
+ `);
6928
+ return file;
6929
+ }
6930
+ /**
6931
+ * A file server's processor unit: one process answering each of its
6932
+ * processors' patterns, and `/health`. Returns its entry, `processors.ts`.
6933
+ *
6934
+ * Its own process because making a derivative is CPU-bound — a resize
6935
+ * spike in the API's process would be every request's latency.
6936
+ */
6937
+ async buildEntry(input) {
6938
+ const { context, outputDir, processors } = input;
6939
+ await mkdir(outputDir, { recursive: true });
6940
+ await writeTelemetryModule(outputDir, input.telemetry);
6941
+ const healthCheck = context.production?.healthCheck ?? "/health";
6942
+ const imports = processors.map(({ key, path }) => {
6943
+ const specifier = relative(outputDir, path.absolute).replace(/\.ts$/, ".js");
6944
+ return `import { ${key} } from '${specifier.startsWith(".") ? specifier : `./${specifier}`}';`;
6945
+ }).join("\n");
6946
+ const entry = join(outputDir, "processors.ts");
6947
+ await writeFile(entry, `#!/usr/bin/env node
6948
+ /**
6949
+ * Production entry for ${input.fileServerId}'s processors.
6950
+ * Generated by 'gkm build --production'.
6951
+ *
6952
+ * Answers each processor's pattern, and ${healthCheck} on PORT. The edge
6953
+ * routes only those patterns here; everything else on the file server's
6954
+ * domain is the bucket.
6955
+ */
6956
+ import { timingSafeEqual } from 'node:crypto';
6957
+ import { createServer } from 'node:http';
6958
+ import { runShutdownHooks } from '@geekmidas/constructs';
6959
+ import { processorServer } from '@geekmidas/constructs/processors';
6960
+ ${context.storageDrivers?.imports ?? ""}
6961
+ ${imports}
6962
+
6963
+ ${startTelemetryCode([healthCheck])}
6964
+ ${context.storageDrivers?.setup ? `// The entry point registers the drivers its target needs.\n${context.storageDrivers.setup}\n` : ""}
6965
+ process.env.GKM_APP_NAME ??= ${JSON.stringify(processorUnitName(input.fileServerId))};
6966
+
6967
+ const processors = [${processors.map(({ key }) => key).join(", ")}];
6968
+ const serve = processorServer(processors);
6969
+ const port = Number(process.env.PORT) || 3000;
6970
+ let stopping = false;
6971
+
6972
+ ${input.telemetry ? REQUEST_SPANS : NO_REQUEST_SPANS}
6973
+ // Where the CDN fronts this unit, the secret it adds to every request: one
6974
+ // without it is refused here, whatever the edge in front did or could not.
6975
+ const originSecret = process.env.${PROCESSOR_ORIGIN_SECRET_ENV}
6976
+ ? Buffer.from(process.env.${PROCESSOR_ORIGIN_SECRET_ENV})
6977
+ : undefined;
6978
+ const fromOrigin = (header: string | string[] | undefined) => {
6979
+ if (!originSecret) return true;
6980
+ const given = Buffer.from(typeof header === 'string' ? header : '');
6981
+ return given.length === originSecret.length && timingSafeEqual(given, originSecret);
6982
+ };
6983
+
6984
+ const server = createServer(async (req, res) => {
6985
+ const method = req.method ?? 'GET';
6986
+ const path = (req.url ?? '/').split('?')[0] ?? '/';
6987
+ if (path === ${JSON.stringify(healthCheck)}) {
6988
+ res.writeHead(stopping ? 503 : 200, { 'content-type': 'application/json' });
6989
+ res.end(JSON.stringify({ status: stopping ? 'stopping' : 'ok' }));
6990
+ return;
6991
+ }
6992
+ if (!fromOrigin(req.headers[${JSON.stringify(ORIGIN_VERIFY_HEADER.toLowerCase())}])) {
6993
+ res.writeHead(403, { 'cache-control': 'no-store' }).end();
6994
+ return;
6995
+ }
6996
+ await traced(method, path, async () => {
6997
+ try {
6998
+ const response = await serve({ method, path });
6999
+ if (!response) {
7000
+ res.writeHead(404, { 'cache-control': 'public, max-age=60' }).end();
7001
+ return 404;
7002
+ }
7003
+ res.writeHead(response.status, response.headers);
7004
+ res.end(method === 'HEAD' ? undefined : response.body);
7005
+ return response.status;
7006
+ } catch (error) {
7007
+ console.error(error);
7008
+ res.writeHead(500, { 'cache-control': 'no-store' }).end();
7009
+ return 500;
7010
+ }
7011
+ });
7012
+ });
7013
+ server.listen(port);
7014
+
7015
+ const shutdown = async () => {
7016
+ if (stopping) return;
7017
+ stopping = true;
7018
+ setTimeout(() => process.exit(1), Number(process.env.GKM_SHUTDOWN_TIMEOUT_MS) || 8000).unref();
7019
+ server.close();
7020
+ await runShutdownHooks((error) => console.error(error));
7021
+ process.exit(0);
7022
+ };
7023
+ process.on('SIGTERM', shutdown);
7024
+ process.on('SIGINT', shutdown);
7025
+ `);
7026
+ return entry;
7027
+ }
7028
+ };
7029
+ /**
7030
+ * A SERVER span per request, once telemetry has started — opened by the unit
7031
+ * rather than by hooking node:http, which sees nothing inside a bundle. Named
7032
+ * after the processor's pattern, never the key, which has no bound.
7033
+ *
7034
+ * Only in an entry whose file server has a `Telemetry` node: the bundle
7035
+ * follows the import, and an app without one need not install the API.
7036
+ */
7037
+ const REQUEST_SPANS = `const tracing = requestSpans ? await import('@opentelemetry/api') : undefined;
7038
+ const routeOf = (path: string) =>
7039
+ processors.find((processor) => path.startsWith(processor.prefix))?.pattern;
7040
+
7041
+ async function traced(
7042
+ method: string,
7043
+ path: string,
7044
+ run: () => Promise<number>,
7045
+ ): Promise<void> {
7046
+ if (!tracing) {
7047
+ await run();
7048
+ return;
7049
+ }
7050
+ const route = routeOf(path);
7051
+ await tracing.trace.getTracer('@geekmidas/processors').startActiveSpan(
7052
+ route ? \`\${method} \${route}\` : method,
7053
+ {
7054
+ kind: tracing.SpanKind.SERVER,
7055
+ attributes: {
7056
+ 'http.request.method': method,
7057
+ 'url.path': path,
7058
+ ...(route ? { 'http.route': route } : {}),
7059
+ },
7060
+ },
7061
+ async (span) => {
7062
+ try {
7063
+ const status = await run();
7064
+ span.setAttribute('http.response.status_code', status);
7065
+ if (status >= 500) span.setStatus({ code: tracing.SpanStatusCode.ERROR });
7066
+ } finally {
7067
+ span.end();
7068
+ }
7069
+ },
7070
+ );
7071
+ }
7072
+ `;
7073
+ /** The same shape without telemetry: each request just runs. */
7074
+ const NO_REQUEST_SPANS = `async function traced(
7075
+ _method: string,
7076
+ _path: string,
7077
+ run: () => Promise<number>,
7078
+ ): Promise<void> {
7079
+ await run();
7080
+ }
7081
+ `;
7082
+ /** What the manifest records of one processor. */
7083
+ async function processorInfo(name, processor, handler, context) {
7084
+ return {
7085
+ name,
7086
+ handler,
7087
+ fileServer: processor.surfaceId,
7088
+ path: processor.pattern,
7089
+ prefix: processor.prefix,
7090
+ ...processor.native.length ? { native: [...processor.native] } : {},
7091
+ ...processor.timeout !== void 0 ? { timeout: processor.timeout } : {},
7092
+ ...processor.memorySize !== void 0 ? { memorySize: processor.memorySize } : {},
7093
+ environment: await processor.getEnvironment({ markOptional: context.markOptional }),
7094
+ dependencies: processor.constructs
7095
+ };
7096
+ }
7097
+ //#endregion
6426
7098
  //#region src/generators/CronGenerator.ts
6427
7099
  var CronGenerator = class extends ConstructGenerator {
6428
7100
  async build(context, constructs, outputDir, options) {
@@ -7001,17 +7673,59 @@ async function answers(connection: unknown): Promise<boolean> {
7001
7673
  }
7002
7674
  }
7003
7675
 
7676
+ /** A request to a route this worker mounted, and what it answered. */
7677
+ export interface WorkerRequest {
7678
+ headers: Record<string, string | string[] | undefined>;
7679
+ body: string;
7680
+ }
7681
+ export interface WorkerAnswer {
7682
+ status: number;
7683
+ body: unknown;
7684
+ }
7685
+
7686
+ // The routes something pushes to: an SNS subscriber's, and the one a local
7687
+ // object store posts a bucket's events to. Mounted by the subscribers, served
7688
+ // by the entry's HTTP server beside the health check.
7689
+ const routes = new Map<string, (c: any) => unknown>();
7690
+ const app = {
7691
+ post: (path: string, handler: (c: any) => unknown) => {
7692
+ routes.set(path, handler);
7693
+ },
7694
+ };
7695
+
7696
+ /** Run one mounted route, as the subscribers' handlers expect to be called. */
7697
+ async function route(path: string, request: WorkerRequest): Promise<WorkerAnswer | undefined> {
7698
+ const handler = routes.get(path);
7699
+ if (!handler) return undefined;
7700
+ let answer: WorkerAnswer | undefined;
7701
+ const c = {
7702
+ req: {
7703
+ text: async () => request.body,
7704
+ header: (name: string) => {
7705
+ const value = request.headers[name.toLowerCase()];
7706
+ return Array.isArray(value) ? value[0] : value;
7707
+ },
7708
+ },
7709
+ json: (body: unknown, status = 200) => {
7710
+ answer = { status, body };
7711
+ return answer;
7712
+ },
7713
+ };
7714
+ await handler(c);
7715
+ return answer ?? { status: 204, body: null };
7716
+ }
7717
+
7004
7718
  /** Start everything this worker runs. */
7005
7719
  export async function startWorker(): Promise<{
7006
7720
  health: () => Promise<WorkerHealth>;
7007
7721
  stop: () => Promise<void>;
7722
+ route: typeof route;
7723
+ /** Subscribe the pushed routes, once the server answers on \`port\`. */
7724
+ subscribeForPush: (port: number) => Promise<void>;
7008
7725
  }> {
7009
- // An app object with no routes: on a server target nothing is pushed to a
7010
- // subscriber, so there is nothing to mount.
7011
- const noRoutes = { post: () => undefined };
7012
-
7013
- await setupSubscribers(noRoutes, envParser, logger).catch((error) => {
7726
+ const subscribeForPush = await setupSubscribers(app, envParser, logger).catch((error) => {
7014
7727
  logger.error({ err: error }, 'Failed to start subscribers');
7728
+ return async (_port: number) => {};
7015
7729
  });
7016
7730
  await setupQueues(envParser, logger).catch((error) => {
7017
7731
  logger.error({ err: error }, 'Failed to start queue consumers');
@@ -7023,6 +7737,8 @@ export async function startWorker(): Promise<{
7023
7737
  const statuses = () => [subscribersStatus(), queuesStatus(), cronsStatus()];
7024
7738
 
7025
7739
  return {
7740
+ route,
7741
+ subscribeForPush,
7026
7742
  async health() {
7027
7743
  const all = statuses();
7028
7744
  const failed = all.flatMap((s) => s.failed);
@@ -7053,8 +7769,10 @@ function workerEntry(healthCheck) {
7053
7769
  * Generated by 'gkm build --production'.
7054
7770
  *
7055
7771
  * Runs this worker's crons, queue consumers and topic subscribers, and serves
7056
- * one route: ${healthCheck}, on PORT — 200 when every consumer started and
7057
- * every broker connection answers, 503 otherwise.
7772
+ * its health check: ${healthCheck}, on PORT — 200 when every consumer started
7773
+ * and every broker connection answers, 503 otherwise. Beside it, on the same
7774
+ * port, the POST routes its subscribers mounted: where a local object store
7775
+ * posts a bucket's events.
7058
7776
  *
7059
7777
  * On SIGTERM it stops pulling messages and scheduling crons, lets the handlers
7060
7778
  * in flight finish, closes its broker connections and database pools, and
@@ -7073,15 +7791,39 @@ let worker: Awaited<ReturnType<typeof startWorker>> | undefined;
7073
7791
  let stopping = false;
7074
7792
 
7075
7793
  const server = createServer((req, res) => {
7076
- const path = (req.url ?? '/').split('?')[0];
7077
- if (path !== ${JSON.stringify(healthCheck)} || (req.method !== 'GET' && req.method !== 'HEAD')) {
7078
- res.writeHead(404).end();
7079
- return;
7080
- }
7794
+ const path = (req.url ?? '/').split('?')[0] ?? '/';
7081
7795
  const answer = (status: number, body: unknown) => {
7082
7796
  res.writeHead(status, { 'content-type': 'application/json' });
7083
7797
  res.end(JSON.stringify(body));
7084
7798
  };
7799
+
7800
+ // A route a subscriber mounted: what SNS pushes to, or what a local object
7801
+ // store posts a bucket's events to. Refused while starting or stopping, so
7802
+ // the sender keeps the message and sends it again.
7803
+ if (req.method === 'POST') {
7804
+ let body = '';
7805
+ req.setEncoding('utf8');
7806
+ req.on('data', (chunk) => {
7807
+ body += chunk;
7808
+ });
7809
+ req.on('end', () => {
7810
+ if (stopping) return answer(503, { status: 'stopping' });
7811
+ if (!worker) return answer(503, { status: 'starting' });
7812
+ worker.route(path, { headers: req.headers, body }).then(
7813
+ (routed) => (routed ? answer(routed.status, routed.body) : answer(404, { status: 'not found' })),
7814
+ (error) => {
7815
+ logger.error({ err: error, path }, 'Route failed');
7816
+ answer(500, { status: 'failed' });
7817
+ },
7818
+ );
7819
+ });
7820
+ return;
7821
+ }
7822
+
7823
+ if (path !== ${JSON.stringify(healthCheck)} || (req.method !== 'GET' && req.method !== 'HEAD')) {
7824
+ res.writeHead(404).end();
7825
+ return;
7826
+ }
7085
7827
  if (stopping) return answer(503, { status: 'stopping' });
7086
7828
  if (!worker) return answer(503, { status: 'starting' });
7087
7829
  worker.health().then(
@@ -7115,6 +7857,9 @@ process.on('SIGINT', shutdown);
7115
7857
 
7116
7858
  worker = await startWorker();
7117
7859
  logger.info({ port }, 'Worker started');
7860
+ await worker.subscribeForPush(port).catch((error) => {
7861
+ logger.error({ err: error }, 'Failed to subscribe for push');
7862
+ });
7118
7863
  `;
7119
7864
  }
7120
7865
  //#endregion
@@ -7260,6 +8005,25 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
7260
8005
  imageName: imageNames[worker.name] ?? worker.name
7261
8006
  });
7262
8007
  }
8008
+ for (const unit of manifest ? processorUnits(workspace, manifest) : []) {
8009
+ logger$1.log(`\n 📄 Generating Dockerfile for ${unit.name} (processors of ${unit.id}, built from ${unit.app})`);
8010
+ const dockerfile = processorDockerfile(unit, workspace.apps[unit.app], {
8011
+ layout,
8012
+ workspaceRoot: workspace.root,
8013
+ native: processorNative(manifest, unit.id)
8014
+ });
8015
+ const path = workerDockerfileOf(unit.name);
8016
+ const dockerfilePath = join(workspace.root, path);
8017
+ await mkdir(dirname(dockerfilePath), { recursive: true });
8018
+ await writeFile(dockerfilePath, dockerfile);
8019
+ logger$1.log(` Generated: ${path}`);
8020
+ results.push({
8021
+ appName: unit.name,
8022
+ type: "backend",
8023
+ dockerfile: dockerfilePath,
8024
+ imageName: imageNames[unit.name] ?? unit.name
8025
+ });
8026
+ }
7263
8027
  const dockerignorePath = await ensureDockerignore(layout.buildRoot);
7264
8028
  logger$1.log(`\n Ensured: ${dockerignorePath}`);
7265
8029
  const composePath = await writeConstructsCompose(workspace);
@@ -7319,6 +8083,29 @@ function workerDockerfile(worker, host, options) {
7319
8083
  ...options.cache ? { cache: options.cache } : {}
7320
8084
  });
7321
8085
  }
8086
+ /** The native packages a file server's processors named, once each. */
8087
+ function processorNative(manifest, fileServerId) {
8088
+ const server = manifest[fileServerId];
8089
+ if (server?.kind !== "file-server") return [];
8090
+ return [...new Set((server.processors ?? []).flatMap((p) => p.native ?? []))].sort();
8091
+ }
8092
+ /**
8093
+ * A file server's processor unit's Dockerfile: its host app's build, and the
8094
+ * unit's bundle as the runner, with its processors' native packages
8095
+ * installed beside it — see `generateProcessorDockerfile`.
8096
+ */
8097
+ function processorDockerfile(unit, host, options) {
8098
+ return generateProcessorDockerfile({
8099
+ ...appImageOptions(options.layout, unit.app, host, options.workspaceRoot),
8100
+ imageName: unit.name,
8101
+ port: PROCESSOR_PORT,
8102
+ fileServer: unit.id,
8103
+ bundle: processorBundleName(unit.id),
8104
+ healthCheckPath: "/health",
8105
+ ...options.native.length ? { external: [...options.native] } : {},
8106
+ ...options.cache ? { cache: options.cache } : {}
8107
+ });
8108
+ }
7322
8109
  /**
7323
8110
  * A site's Dockerfile, with an `ARG` for every key its bundler inlines.
7324
8111
  *
@@ -7483,7 +8270,7 @@ async function createDnsProvider(options) {
7483
8270
  if (isDnsProvider(config.provider)) return config.provider;
7484
8271
  const provider = config.provider;
7485
8272
  if (provider === "hostinger") {
7486
- const { HostingerProvider } = await import("./HostingerProvider-BNpS9aRJ.mjs");
8273
+ const { HostingerProvider } = await import("./HostingerProvider-Cjh_2Ml6.mjs");
7487
8274
  return new HostingerProvider(options.hostinger);
7488
8275
  }
7489
8276
  if (provider === "route53") {
@@ -7496,7 +8283,7 @@ async function createDnsProvider(options) {
7496
8283
  });
7497
8284
  }
7498
8285
  if (provider === "godaddy") {
7499
- const { GoDaddyProvider } = await import("./GoDaddyProvider-BlB5nJky.mjs");
8286
+ const { GoDaddyProvider } = await import("./GoDaddyProvider-BN1dODm9.mjs");
7500
8287
  return new GoDaddyProvider(options.godaddy ?? {});
7501
8288
  }
7502
8289
  if (provider === "cloudflare") throw new DnsProviderNotImplemented("cloudflare");
@@ -8345,6 +9132,6 @@ function reportPlannedSeeds(planned, log) {
8345
9132
  for (const { folder, seeds } of planned) log(`🌱 ${folder}: would run ${seeds.length} (${seeds.join(", ")})`);
8346
9133
  }
8347
9134
  //#endregion
8348
- export { assertDevServicesFlag as $, stackLogs as $n, publicBuildValues as $t, StageProviderDisabled as A, localRolePassword as An, findAvailablePort as At, workerDockerfile as B, EMULATOR_ACCESS_KEY_ID as Bn, initStageSecrets as Bt, recordRollback as C, REDIS_SERVICE as Cn, composeFor as Ct, setPostgresBackupId as D, stackRedis as Dn, storageBackendFor as Dt, setGeneratedSecret as E, runsRedis as En, providerOf as Et, DockerBuildFailed as F, isTelemetryKey as Fn, prepareEntryCredentials as Ft, QueueGenerator as G, portKeys as Gn, composeBuildPaths as Gt, WorkerGenerator as H, DEFAULT_IMAGES as Hn, storage_exports as Ht, DockerPushFailed as I, scopeTelemetryEnv as In, isRemoteStore as It, AllowDevServicesTakesNoValue as J, primaryPortKey as Jn, WORKER_PORT as Jt, CronGenerator as K, portsOf as Kn, imageLayout as Kt, appDockerfile as L, surfaceClientTraced as Ln, secretsStoreFor as Lt, provisionCommand as M, planFor as Mn, loadEnvFiles as Mt, stageProviderNotes as N, resourceName as Nn, loadPortState as Nt, DnsRecordsUnreadable as O, withRedisPassword as On, createCredentialsPreload as Ot, PROVIDER_KINDS as P, appTelemetry as Pn, loadSecretsForApp as Pt, STORAGE_KEY_PAIR as Q, logsService as Qn, isImageBuild as Qt, dockerCommand as R, telemetryOf as Rn, storeFromConfig as Rt, recordRelease as S, withGeneratedSecrets as Sn, CLUSTER_DATABASE as St, setBackupState as T, redisService as Tn, eventsBackendFor as Tt, workerBundleName as U, describeServices as Un, toEmbeddableSecrets as Ut, workerDockerfileOf as V, hostFor as Vn, maskPassword as Vt, workerEntryDir as W, fakeKey as Wn, withCustomSecret as Wt, DevServicesNeedServerTarget as X, LOGS_SERVICE as Xn, findBuildRoot as Xt, DEV_SERVICES as Y, LOCAL_LOGS_EMAIL as Yn, detectPackageManager as Yt, ExternalServicesNotConfigured as Z, logsAccess as Zn, imageBuildCredentials as Zt, asDokployState as _, FileSecretsStore as _n, forgetState as _t, dnsResources as a, applyPostgres as an, suppliedOnly as at, getBackupState as b, projectKey as bn, bucketClient as bt, currentActor as c, postgresDatabaseNames as cn, networkEnv as ct, DeployJournal as d, mergeLifecycle as dn, backendsOf as dt, isUnder as en, withLogsPassword as er, devServicesUsed as et, extractSubdomain as f, LOCAL_RABBITMQ_USER as fn, constructGlobs as ft, verifyDnsRecords as g, readLocalCredentials as gn, LOCAL_CA_PATH as gt, orchestrateDns as h, postgresSuperuser as hn, workspace_exports as ht, dnsRecordResource as i, applyPolicies as in, stageServiceDeclarations as it, assertStageProvidersEnabled as j, TELEMETRY_CONTAINER as jn, isPortAvailable as jt, createDnsProvider as k, envFor as kn, createEntryWrapper as kt, describeActor as l, postgresStatements as ln, workerEnvKeys as lt, normalizeDnsConfig as m, postgresRoleSlug as mn, reconcileWorkspace as mt, reportDatabaseRuns as n, applyBuckets as nn, isMainFrontendApp as nr, reportDevServices as nt, forgetDnsResource as o, bucketLifecycles as on, appEnvKeys as ot, findRootDomain as p, loadLocalCredentials as pn, derivedContainers as pt, validateImageRef as q, postgresImage as qn, TURBO_VERSION as qt, reportPlannedSeeds as r, applyLifecycles as rn, resolveHost as rr, requiredStageKeys as rt, recordDnsChanges as s, bucketPolicies as sn, dockerfileOf as st, DeploySeedsFailed as t, workerUnits as tn, NoDomainForStage as tr, externalServices as tt, isCi as u, quoteIdentifier as un, FAKE_ENV as ut, createComposeState as v, getKeyPath as vn, LEGACY_LOCAL_LOGIN as vt, setApplicationId as w, STACK_CACHE as wn, cacheBackendFor as wt, getGeneratedSecret as x, readKey as xn, pgClient as xt, createEmptyState as y, keystoreProject as yn, ensurePostgresLogin as yt, ensureDockerignore as z, usesTelemetry as zn, store_exports as zt };
9135
+ export { ORIGIN_VERIFY_HEADER as $, telemetryOf as $n, maskPassword as $t, StageProviderDisabled as A, postgresSuperuser as An, LEGACY_LOCAL_LOGIN as At, processorDockerfile as B, redisService as Bn, createCredentialsPreload as Bt, recordRollback as C, postgresDatabaseNames as Cn, backendsOf as Ct, setPostgresBackupId as D, LOCAL_RABBITMQ_USER as Dn, workspace_exports as Dt, setGeneratedSecret as E, mergeLifecycle as En, reconcileWorkspace as Et, DockerBuildFailed as F, projectKey as Fn, composeFor as Ft, workerBundleName as G, localRolePassword as Gn, loadPortState as Gt, workerDockerfile as H, stackRedis as Hn, findAvailablePort as Ht, DockerPushFailed as I, readKey as In, cacheBackendFor as It, CronGenerator as J, resourceName as Jn, isRemoteStore as Jt, workerEntryDir as K, TELEMETRY_CONTAINER as Kn, loadSecretsForApp as Kt, appDockerfile as L, withGeneratedSecrets as Ln, eventsBackendFor as Lt, provisionCommand as M, FileSecretsStore as Mn, bucketClient as Mt, stageProviderNotes as N, getKeyPath as Nn, pgClient as Nt, DnsRecordsUnreadable as O, loadLocalCredentials as On, LOCAL_CA_PATH as Ot, PROVIDER_KINDS as P, keystoreProject as Pn, CLUSTER_DATABASE as Pt, processorInfo as Q, surfaceClientTraced as Qn, initStageSecrets as Qt, dockerCommand as R, REDIS_SERVICE as Rn, providerOf as Rt, recordRelease as S, bucketPolicies as Sn, FAKE_ENV as St, setBackupState as T, quoteIdentifier as Tn, derivedContainers as Tt, workerDockerfileOf as U, withRedisPassword as Un, isPortAvailable as Ut, processorNative as V, runsRedis as Vn, createEntryWrapper as Vt, WorkerGenerator as W, envFor as Wn, loadEnvFiles as Wt, processorBundleName as X, isTelemetryKey as Xn, storeFromConfig as Xt, ProcessorGenerator as Y, appTelemetry as Yn, secretsStoreFor as Yt, processorEntryDir as Z, scopeTelemetryEnv as Zn, store_exports as Zt, asDokployState as _, applyLifecycles as _n, withLogsPassword as _r, appEnvKeys as _t, dnsResources as a, PROCESSOR_PORT as an, DEFAULT_IMAGES as ar, AllowDevServicesTakesNoValue as at, getBackupState as b, applyPostgres as bn, resolveHost as br, processorEnvKeys as bt, currentActor as c, detectPackageManager as cn, portKeys as cr, ExternalServicesNotConfigured as ct, DeployJournal as d, isImageBuild as dn, primaryPortKey as dr, devServicesUsed as dt, storage_exports as en, usesTelemetry as er, PROCESSOR_ORIGIN_SECRET_ENV as et, extractSubdomain as f, publicBuildValues as fn, LOCAL_LOGS_EMAIL as fr, externalServices as ft, verifyDnsRecords as g, applyBuckets as gn, stackLogs as gr, suppliedOnly as gt, orchestrateDns as h, workerUnits as hn, logsService as hr, stageServiceDeclarations as ht, dnsRecordResource as i, imageLayout as in, hostFor$1 as ir, validateImageRef as it, assertStageProvidersEnabled as j, readLocalCredentials as jn, ensurePostgresLogin as jt, createDnsProvider as k, postgresRoleSlug as kn, forgetState as kt, describeActor as l, findBuildRoot as ln, portsOf as lr, STORAGE_KEY_PAIR as lt, normalizeDnsConfig as m, processorUnits as mn, logsAccess as mr, requiredStageKeys as mt, reportDatabaseRuns as n, withCustomSecret as nn, watchedBuckets as nr, originSecretKey as nt, forgetDnsResource as o, TURBO_VERSION as on, describeServices as or, DEV_SERVICES as ot, findRootDomain as p, isUnder as pn, LOGS_SERVICE as pr, reportDevServices as pt, QueueGenerator as q, planFor as qn, prepareEntryCredentials as qt, reportPlannedSeeds as r, composeBuildPaths as rn, EMULATOR_ACCESS_KEY_ID as rr, processorOriginHost as rt, recordDnsChanges as s, WORKER_PORT as sn, fakeKey as sr, DevServicesNeedServerTarget as st, DeploySeedsFailed as t, toEmbeddableSecrets as tn, minioWebhookEnv as tr, newOriginSecret as tt, isCi as u, imageBuildCredentials as un, postgresImage as ur, assertDevServicesFlag as ut, createComposeState as v, applyNotifications as vn, NoDomainForStage as vr, dockerfileOf as vt, setApplicationId as w, postgresStatements as wn, constructGlobs as wt, getGeneratedSecret as x, bucketLifecycles as xn, workerEnvKeys as xt, createEmptyState as y, applyPolicies as yn, isMainFrontendApp as yr, networkEnv as yt, ensureDockerignore as z, STACK_CACHE as zn, storageBackendFor as zt };
8349
9136
 
8350
- //# sourceMappingURL=seeds-Dv78P9LS.mjs.map
9137
+ //# sourceMappingURL=seeds-CK7w79VC.mjs.map