@geekmidas/cli 10.0.0-alpha.64 → 10.0.0-alpha.66

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 (243) hide show
  1. package/README.md +15 -1
  2. package/dist/{HostingerProvider-Bx2lHHvu.cjs → HostingerProvider-BznqRC2S.cjs} +5 -5
  3. package/dist/HostingerProvider-BznqRC2S.cjs.map +1 -0
  4. package/dist/{HostingerProvider-Cd4aS5Kj.mjs → HostingerProvider-CY_VpVud.mjs} +4 -4
  5. package/dist/HostingerProvider-CY_VpVud.mjs.map +1 -0
  6. package/dist/{LegacyStateStore-C2abV49N.cjs → LegacyStateStore-BFcTT2QL.cjs} +2 -2
  7. package/dist/{LegacyStateStore-C2abV49N.cjs.map → LegacyStateStore-BFcTT2QL.cjs.map} +1 -1
  8. package/dist/{LegacyStateStore-DIgkGaUP.mjs → LegacyStateStore-CFheFo62.mjs} +2 -2
  9. package/dist/{LegacyStateStore-DIgkGaUP.mjs.map → LegacyStateStore-CFheFo62.mjs.map} +1 -1
  10. package/dist/{LocalStateStore-DiJqKyPy.cjs → LocalStateStore-BVUexSvu.cjs} +2 -2
  11. package/dist/{LocalStateStore-DiJqKyPy.cjs.map → LocalStateStore-BVUexSvu.cjs.map} +1 -1
  12. package/dist/{LocalStateStore-Cy1ZBW7U.mjs → LocalStateStore-Bm3x9oOg.mjs} +2 -2
  13. package/dist/{LocalStateStore-Cy1ZBW7U.mjs.map → LocalStateStore-Bm3x9oOg.mjs.map} +1 -1
  14. package/dist/{OpenApiTsGenerator-BWuDRHe9.cjs → OpenApiTsGenerator-B2zrdyP4.cjs} +2 -2
  15. package/dist/{OpenApiTsGenerator-BWuDRHe9.cjs.map → OpenApiTsGenerator-B2zrdyP4.cjs.map} +1 -1
  16. package/dist/{OpenApiTsGenerator-C6v-IeHt.mjs → OpenApiTsGenerator-BmUAcR7d.mjs} +2 -2
  17. package/dist/{OpenApiTsGenerator-C6v-IeHt.mjs.map → OpenApiTsGenerator-BmUAcR7d.mjs.map} +1 -1
  18. package/dist/{Route53Provider-DVILBsvV.cjs → Route53Provider-Bllus2NR.cjs} +2 -2
  19. package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
  20. package/dist/{Route53Provider-Cvj40A8I.mjs → Route53Provider-QXxjkZO1.mjs} +2 -2
  21. package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
  22. package/dist/{S3StateStore-D3x6ivBL.mjs → S3StateStore-BFHuctWM.mjs} +2 -2
  23. package/dist/{S3StateStore-D3x6ivBL.mjs.map → S3StateStore-BFHuctWM.mjs.map} +1 -1
  24. package/dist/{S3StateStore-Ds0V1Lgm.cjs → S3StateStore-CoXBhILd.cjs} +2 -2
  25. package/dist/{S3StateStore-Ds0V1Lgm.cjs.map → S3StateStore-CoXBhILd.cjs.map} +1 -1
  26. package/dist/{SSMStateStore-CLipvx47.cjs → SSMStateStore-BqCA9TP2.cjs} +2 -2
  27. package/dist/{SSMStateStore-CLipvx47.cjs.map → SSMStateStore-BqCA9TP2.cjs.map} +1 -1
  28. package/dist/{SSMStateStore-DfF174xQ.mjs → SSMStateStore-C1kvHScY.mjs} +2 -2
  29. package/dist/{SSMStateStore-DfF174xQ.mjs.map → SSMStateStore-C1kvHScY.mjs.map} +1 -1
  30. package/dist/{backup-provisioner-DIVCbfee.mjs → backup-provisioner-C8DnCmxK.mjs} +2 -2
  31. package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
  32. package/dist/{backup-provisioner-BmhIO_Yr.cjs → backup-provisioner-oDEsPj02.cjs} +2 -2
  33. package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
  34. package/dist/{bundler-DYgm9xsd.mjs → bundler-Dvaiud0h.mjs} +4 -4
  35. package/dist/{bundler-DYgm9xsd.mjs.map → bundler-Dvaiud0h.mjs.map} +1 -1
  36. package/dist/{bundler-C8uJf324.cjs → bundler-orRqUJNZ.cjs} +4 -4
  37. package/dist/{bundler-C8uJf324.cjs.map → bundler-orRqUJNZ.cjs.map} +1 -1
  38. package/dist/{cli-Bogz-zEj.mjs → cli-CfHm0AO7.mjs} +7 -6
  39. package/dist/cli-CfHm0AO7.mjs.map +1 -0
  40. package/dist/{cli-D3jofJ6j.cjs → cli-D1JkkOwg.cjs} +8 -7
  41. package/dist/cli-D1JkkOwg.cjs.map +1 -0
  42. package/dist/compose-CNQL8BnO.mjs +1398 -0
  43. package/dist/compose-CNQL8BnO.mjs.map +1 -0
  44. package/dist/compose-jrLy7KGO.cjs +1427 -0
  45. package/dist/compose-jrLy7KGO.cjs.map +1 -0
  46. package/dist/{config-Be-4_I6H.d.cts → config-4XFxX1al.d.cts} +3 -3
  47. package/dist/{config-Be-4_I6H.d.cts.map → config-4XFxX1al.d.cts.map} +1 -1
  48. package/dist/{config-DqNRiQOp.d.mts → config-UtKzhpFb.d.mts} +3 -3
  49. package/dist/{config-DqNRiQOp.d.mts.map → config-UtKzhpFb.d.mts.map} +1 -1
  50. package/dist/config.cjs +3 -3
  51. package/dist/config.d.cts +3 -3
  52. package/dist/config.d.mts +3 -3
  53. package/dist/config.mjs +3 -3
  54. package/dist/{credentials-B70vmLcm.cjs → credentials-Bzbg23n8.cjs} +176 -3
  55. package/dist/credentials-Bzbg23n8.cjs.map +1 -0
  56. package/dist/{credentials-s0wMeZBU.mjs → credentials-Dq1MnWQf.mjs} +128 -3
  57. package/dist/credentials-Dq1MnWQf.mjs.map +1 -0
  58. package/dist/databases-C2p5LGAp.cjs +419 -0
  59. package/dist/databases-C2p5LGAp.cjs.map +1 -0
  60. package/dist/databases-hUHTuwhx.mjs +346 -0
  61. package/dist/databases-hUHTuwhx.mjs.map +1 -0
  62. package/dist/{define-CYs0PEfZ.mjs → define-DR8xGYfL.mjs} +5 -1
  63. package/dist/define-DR8xGYfL.mjs.map +1 -0
  64. package/dist/{define-zUsP72ym.cjs → define-DzRz8FgH.cjs} +5 -1
  65. package/dist/define-DzRz8FgH.cjs.map +1 -0
  66. package/dist/deploy/public.cjs +35 -26
  67. package/dist/deploy/public.cjs.map +1 -1
  68. package/dist/deploy/public.d.cts +140 -20
  69. package/dist/deploy/public.d.cts.map +1 -1
  70. package/dist/deploy/public.d.mts +140 -20
  71. package/dist/deploy/public.d.mts.map +1 -1
  72. package/dist/deploy/public.mjs +13 -13
  73. package/dist/{terminal-Bdv--jhY.cjs → deploy-B7aJi_Ah.cjs} +146 -116
  74. package/dist/deploy-B7aJi_Ah.cjs.map +1 -0
  75. package/dist/{terminal-D7Ntz6WE.mjs → deploy-DWn7YfIc.mjs} +137 -89
  76. package/dist/deploy-DWn7YfIc.mjs.map +1 -0
  77. package/dist/{discover-LMrqsWSU.mjs → discover-BFoJWKGD.mjs} +4 -2
  78. package/dist/discover-BFoJWKGD.mjs.map +1 -0
  79. package/dist/{discover-DHdECueV.cjs → discover-OEfZ9OkA.cjs} +4 -2
  80. package/dist/discover-OEfZ9OkA.cjs.map +1 -0
  81. package/dist/dokploy-B4LcYG1E.cjs +38 -0
  82. package/dist/dokploy-B4LcYG1E.cjs.map +1 -0
  83. package/dist/dokploy-DalwLML5.mjs +38 -0
  84. package/dist/dokploy-DalwLML5.mjs.map +1 -0
  85. package/dist/{encryption-C9X98u2F.cjs → encryption-3KlGS1sl.cjs} +6 -8
  86. package/dist/{encryption-C9X98u2F.cjs.map → encryption-3KlGS1sl.cjs.map} +1 -1
  87. package/dist/{encryption-CKHjMpCr.mjs → encryption-CPfENwWO.mjs} +3 -5
  88. package/dist/{encryption-CKHjMpCr.mjs.map → encryption-CPfENwWO.mjs.map} +1 -1
  89. package/dist/{deploy-ZRXIPp1c.mjs → engine-CunvOG3s.mjs} +2116 -1855
  90. package/dist/engine-CunvOG3s.mjs.map +1 -0
  91. package/dist/{deploy-55rJkdKz.cjs → engine-DR6KurWX.cjs} +2172 -1869
  92. package/dist/engine-DR6KurWX.cjs.map +1 -0
  93. package/dist/{github-Dd3tMa1u.cjs → github-BJ5gh9bw.cjs} +7 -7
  94. package/dist/{github-Dd3tMa1u.cjs.map → github-BJ5gh9bw.cjs.map} +1 -1
  95. package/dist/{github-D-byNI7T.mjs → github-MXA9v7Ge.mjs} +3 -3
  96. package/dist/{github-D-byNI7T.mjs.map → github-MXA9v7Ge.mjs.map} +1 -1
  97. package/dist/{index-CfE9Y885.d.cts → index-CyApaHVe.d.cts} +16 -3
  98. package/dist/index-CyApaHVe.d.cts.map +1 -0
  99. package/dist/{index-CJ2qsSpp.d.mts → index-DD1FfUHh.d.mts} +16 -3
  100. package/dist/index-DD1FfUHh.d.mts.map +1 -0
  101. package/dist/index.cjs +465 -1691
  102. package/dist/index.cjs.map +1 -1
  103. package/dist/index.mjs +405 -1619
  104. package/dist/index.mjs.map +1 -1
  105. package/dist/{local-C7wnrcYK.cjs → local-BdH4XN0E.cjs} +1 -178
  106. package/dist/local-BdH4XN0E.cjs.map +1 -0
  107. package/dist/{local-Cd8ZYQG3.mjs → local-CWR4Y_kW.mjs} +3 -126
  108. package/dist/local-CWR4Y_kW.mjs.map +1 -0
  109. package/dist/{migrate-B4gngTLe.mjs → migrate-BJBcm4sG.mjs} +7 -6
  110. package/dist/{migrate-B4gngTLe.mjs.map → migrate-BJBcm4sG.mjs.map} +1 -1
  111. package/dist/{migrate-tx9-P9uz.cjs → migrate-CF4J4GQS.cjs} +20 -19
  112. package/dist/{migrate-tx9-P9uz.cjs.map → migrate-CF4J4GQS.cjs.map} +1 -1
  113. package/dist/openapi.cjs +1 -1
  114. package/dist/openapi.d.cts +1 -1
  115. package/dist/openapi.d.mts +1 -1
  116. package/dist/openapi.mjs +1 -1
  117. package/dist/provider-B3Sv_a74.cjs +173 -0
  118. package/dist/provider-B3Sv_a74.cjs.map +1 -0
  119. package/dist/provider-C9_-45d5.cjs +56 -0
  120. package/dist/provider-C9_-45d5.cjs.map +1 -0
  121. package/dist/provider-D7rQzzzf.mjs +138 -0
  122. package/dist/provider-D7rQzzzf.mjs.map +1 -0
  123. package/dist/provider-q4lsYzYG.mjs +45 -0
  124. package/dist/provider-q4lsYzYG.mjs.map +1 -0
  125. package/dist/{ready-bQfu9GES.mjs → ready-2s3-CndS.mjs} +3 -3
  126. package/dist/{ready-bQfu9GES.mjs.map → ready-2s3-CndS.mjs.map} +1 -1
  127. package/dist/{ready-brEhh68f.cjs → ready-B6uHr4sm.cjs} +3 -3
  128. package/dist/{ready-brEhh68f.cjs.map → ready-B6uHr4sm.cjs.map} +1 -1
  129. package/dist/reconcile/public.cjs +1 -1
  130. package/dist/reconcile/public.d.cts +1 -1
  131. package/dist/reconcile/public.d.mts +1 -1
  132. package/dist/reconcile/public.mjs +1 -1
  133. package/dist/resolve-CVmch0wI.cjs +315 -0
  134. package/dist/resolve-CVmch0wI.cjs.map +1 -0
  135. package/dist/resolve-Db0tNlrW.mjs +262 -0
  136. package/dist/resolve-Db0tNlrW.mjs.map +1 -0
  137. package/dist/rollback-DvAo4OKS.mjs +133 -0
  138. package/dist/rollback-DvAo4OKS.mjs.map +1 -0
  139. package/dist/rollback-DxJK84hy.cjs +162 -0
  140. package/dist/rollback-DxJK84hy.cjs.map +1 -0
  141. package/dist/{runtime-CJEYK4Gz.d.mts → runtime-BRqFOvPM.d.cts} +2 -2
  142. package/dist/{runtime-CJEYK4Gz.d.mts.map → runtime-BRqFOvPM.d.cts.map} +1 -1
  143. package/dist/{runtime-Cjq1jlVX.d.cts → runtime-CEk5n4VH.d.mts} +2 -2
  144. package/dist/{runtime-Cjq1jlVX.d.cts.map → runtime-CEk5n4VH.d.mts.map} +1 -1
  145. package/dist/sandbox/discover-worker.cjs +1 -1
  146. package/dist/sandbox/discover-worker.mjs +1 -1
  147. package/dist/sandbox/migrate-worker.cjs +61 -0
  148. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  149. package/dist/sandbox/migrate-worker.d.cts +1 -0
  150. package/dist/sandbox/migrate-worker.d.mts +1 -0
  151. package/dist/sandbox/migrate-worker.mjs +62 -0
  152. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  153. package/dist/{schemas-D2LCF689.mjs → schemas-Cfhtpdo0.mjs} +10 -2
  154. package/dist/{schemas-Ckm_aBnF.cjs.map → schemas-Cfhtpdo0.mjs.map} +1 -1
  155. package/dist/{schemas-Ckm_aBnF.cjs → schemas-RUlKHu27.cjs} +15 -1
  156. package/dist/{schemas-D2LCF689.mjs.map → schemas-RUlKHu27.cjs.map} +1 -1
  157. package/dist/sniffer-5xmrkh2a.cjs +1742 -0
  158. package/dist/sniffer-5xmrkh2a.cjs.map +1 -0
  159. package/dist/sniffer-BAQhLEsI.mjs +1617 -0
  160. package/dist/sniffer-BAQhLEsI.mjs.map +1 -0
  161. package/dist/{sst-Cper040I.mjs → sst-B2HbrDR3.mjs} +4 -4
  162. package/dist/{sst-Cper040I.mjs.map → sst-B2HbrDR3.mjs.map} +1 -1
  163. package/dist/{sst-BdALKEas.cjs → sst-DcfsVH6x.cjs} +4 -4
  164. package/dist/{sst-BdALKEas.cjs.map → sst-DcfsVH6x.cjs.map} +1 -1
  165. package/dist/{sniffer-ByhbEW5A.cjs → state-Y6ATakMX.cjs} +1769 -2759
  166. package/dist/state-Y6ATakMX.cjs.map +1 -0
  167. package/dist/{sniffer-49KPbDgq.mjs → state-uuYqnRVO.mjs} +1763 -2764
  168. package/dist/state-uuYqnRVO.mjs.map +1 -0
  169. package/dist/target/public.cjs +6 -6
  170. package/dist/target/public.d.cts +2 -2
  171. package/dist/target/public.d.mts +2 -2
  172. package/dist/target/public.mjs +3 -3
  173. package/dist/terminal-CHy_MdjG.cjs +84 -0
  174. package/dist/terminal-CHy_MdjG.cjs.map +1 -0
  175. package/dist/terminal-DUhcZ1ND.mjs +84 -0
  176. package/dist/terminal-DUhcZ1ND.mjs.map +1 -0
  177. package/dist/{types-DkrDOMxw.d.cts → types-CSw2w69a.d.mts} +110 -20
  178. package/dist/types-CSw2w69a.d.mts.map +1 -0
  179. package/dist/{types-B_bEQvb9.d.mts → types-D5WIxRDP.d.cts} +111 -19
  180. package/dist/types-D5WIxRDP.d.cts.map +1 -0
  181. package/dist/vitest.cjs +1 -1
  182. package/dist/vitest.mjs +1 -1
  183. package/dist/workspace/index.cjs +3 -1
  184. package/dist/workspace/index.d.cts +3 -3
  185. package/dist/workspace/index.d.mts +3 -3
  186. package/dist/workspace/index.mjs +2 -2
  187. package/dist/{workspace-Bwit4q9O.mjs → workspace-Be6uBhlF.mjs} +36 -6
  188. package/dist/workspace-Be6uBhlF.mjs.map +1 -0
  189. package/dist/{workspace-BwgWJK7h.cjs → workspace-ON-bqiJz.cjs} +47 -5
  190. package/dist/workspace-ON-bqiJz.cjs.map +1 -0
  191. package/package.json +13 -13
  192. package/dist/HostingerProvider-Bx2lHHvu.cjs.map +0 -1
  193. package/dist/HostingerProvider-Cd4aS5Kj.mjs.map +0 -1
  194. package/dist/Route53Provider-Cvj40A8I.mjs.map +0 -1
  195. package/dist/Route53Provider-DVILBsvV.cjs.map +0 -1
  196. package/dist/backup-provisioner-BmhIO_Yr.cjs.map +0 -1
  197. package/dist/backup-provisioner-DIVCbfee.mjs.map +0 -1
  198. package/dist/cli-Bogz-zEj.mjs.map +0 -1
  199. package/dist/cli-D3jofJ6j.cjs.map +0 -1
  200. package/dist/credentials-B70vmLcm.cjs.map +0 -1
  201. package/dist/credentials-s0wMeZBU.mjs.map +0 -1
  202. package/dist/define-CYs0PEfZ.mjs.map +0 -1
  203. package/dist/define-zUsP72ym.cjs.map +0 -1
  204. package/dist/deploy-55rJkdKz.cjs.map +0 -1
  205. package/dist/deploy-Dc2LBJaK.mjs +0 -136
  206. package/dist/deploy-Dc2LBJaK.mjs.map +0 -1
  207. package/dist/deploy-ZRXIPp1c.mjs.map +0 -1
  208. package/dist/deploy-yUcR2OlW.cjs +0 -141
  209. package/dist/deploy-yUcR2OlW.cjs.map +0 -1
  210. package/dist/discover-DHdECueV.cjs.map +0 -1
  211. package/dist/discover-LMrqsWSU.mjs.map +0 -1
  212. package/dist/dokploy-CepdXuMl.mjs +0 -32
  213. package/dist/dokploy-CepdXuMl.mjs.map +0 -1
  214. package/dist/dokploy-D1d37rvM.cjs +0 -32
  215. package/dist/dokploy-D1d37rvM.cjs.map +0 -1
  216. package/dist/index-CJ2qsSpp.d.mts.map +0 -1
  217. package/dist/index-CfE9Y885.d.cts.map +0 -1
  218. package/dist/local-C7wnrcYK.cjs.map +0 -1
  219. package/dist/local-Cd8ZYQG3.mjs.map +0 -1
  220. package/dist/resolve-BXsNQjMR.cjs +0 -220
  221. package/dist/resolve-BXsNQjMR.cjs.map +0 -1
  222. package/dist/resolve-DZ2IJ0qY.mjs +0 -173
  223. package/dist/resolve-DZ2IJ0qY.mjs.map +0 -1
  224. package/dist/runtime-BGNDrHzh.cjs +0 -163
  225. package/dist/runtime-BGNDrHzh.cjs.map +0 -1
  226. package/dist/runtime-Cmn-FeYO.mjs +0 -134
  227. package/dist/runtime-Cmn-FeYO.mjs.map +0 -1
  228. package/dist/sniffer-49KPbDgq.mjs.map +0 -1
  229. package/dist/sniffer-ByhbEW5A.cjs.map +0 -1
  230. package/dist/storage-BzaUxmqe.mjs +0 -124
  231. package/dist/storage-BzaUxmqe.mjs.map +0 -1
  232. package/dist/storage-CSGoC3bK.cjs +0 -152
  233. package/dist/storage-CSGoC3bK.cjs.map +0 -1
  234. package/dist/store-BaaonhkJ.mjs +0 -415
  235. package/dist/store-BaaonhkJ.mjs.map +0 -1
  236. package/dist/store-D_2ByRtW.cjs +0 -510
  237. package/dist/store-D_2ByRtW.cjs.map +0 -1
  238. package/dist/terminal-Bdv--jhY.cjs.map +0 -1
  239. package/dist/terminal-D7Ntz6WE.mjs.map +0 -1
  240. package/dist/types-B_bEQvb9.d.mts.map +0 -1
  241. package/dist/types-DkrDOMxw.d.cts.map +0 -1
  242. package/dist/workspace-BwgWJK7h.cjs.map +0 -1
  243. package/dist/workspace-Bwit4q9O.mjs.map +0 -1
@@ -1,12 +1,15 @@
1
- import { Dt as canPrompt, H as constructGlobs, Ot as prompt, P as createStateStore, Tt as validateDokployToken } from "./sniffer-49KPbDgq.mjs";
2
- import { g as storeDokployCredentials } from "./local-Cd8ZYQG3.mjs";
3
- import { d as output, r as discover } from "./discover-LMrqsWSU.mjs";
1
+ import { t as LocalSandbox, u as gkmHome } from "./local-CWR4Y_kW.mjs";
2
+ import { r as storedCredentials } from "./credentials-Dq1MnWQf.mjs";
3
+ import { f as withOutput, r as discover } from "./discover-BFoJWKGD.mjs";
4
+ import { c as withSandbox } from "./sandbox-Dm247NGx.mjs";
4
5
  import { n as derivedApps } from "./derive-B4vDpzgP.mjs";
5
- import { o as builtinTarget } from "./define-CYs0PEfZ.mjs";
6
- import { a as getAppBuildOrder } from "./workspace-Bwit4q9O.mjs";
7
- import { l as applicationName, n as secretsStoreFor, u as deployIdentity } from "./store-BaaonhkJ.mjs";
8
- import { a as parseTargetOptions, o as resolveTarget } from "./resolve-DZ2IJ0qY.mjs";
9
- import { n as chainCredentials, r as storedCredentials } from "./credentials-s0wMeZBU.mjs";
6
+ import { o as builtinTarget } from "./define-DR8xGYfL.mjs";
7
+ import { k as assertDeployedStage, s as getAppBuildOrder } from "./workspace-Be6uBhlF.mjs";
8
+ import { findWorkspaceRoot, loadWorkspaceConfig } from "./config.mjs";
9
+ import { O as constructGlobs, dt as secretsStoreFor, vt as applicationName, yt as deployIdentity } from "./state-uuYqnRVO.mjs";
10
+ import { g as createStateStore, v as eventError } from "./sniffer-BAQhLEsI.mjs";
11
+ import { a as parseTargetOptions, o as resolveTarget } from "./resolve-Db0tNlrW.mjs";
12
+ import { resolve } from "node:path";
10
13
  //#region src/target/secrets.ts
11
14
  /**
12
15
  * A stage's secrets as a target sees them: read and written through the
@@ -67,19 +70,6 @@ async function deploySecrets(workspace, stage, redactor, options = {}) {
67
70
  };
68
71
  }
69
72
  //#endregion
70
- //#region src/deploy/events.ts
71
- /** An error as an event carries it: its name and message, nothing else. */
72
- function eventError(error) {
73
- if (error instanceof Error) return {
74
- name: error.name,
75
- message: error.message
76
- };
77
- return {
78
- name: "Error",
79
- message: String(error)
80
- };
81
- }
82
- //#endregion
83
73
  //#region src/deploy/orchestrate.ts
84
74
  /**
85
75
  * The run around a target: what every deploy does whatever it deploys
@@ -267,12 +257,15 @@ async function validate(target, phaseCtx, emit) {
267
257
  async function prepare(source, request, ctx, emit, redactor) {
268
258
  const { stage } = request;
269
259
  const configured = typeof source === "function" ? await source() : source;
260
+ const local = stage === configured.stages.local;
261
+ if (!local) assertDeployedStage(configured.stages, stage);
270
262
  const targetName = request.target ?? configured.deploy?.default ?? "dokploy";
271
263
  const resolved = await resolveTarget(targetName, {
272
264
  workspace: configured,
273
265
  stage,
274
266
  ...ctx.targets ? { host: ctx.targets } : {}
275
267
  });
268
+ if (local && !resolved.target.capabilities.localStage) assertDeployedStage(configured.stages, stage);
276
269
  const options = await parseTargetOptions(resolved);
277
270
  const manifest = await discover({
278
271
  patterns: constructGlobs(configured),
@@ -284,7 +277,10 @@ async function prepare(source, request, ctx, emit, redactor) {
284
277
  apps: units
285
278
  } : configured;
286
279
  const identity = deployIdentity(workspace, stage);
287
- const tag = request.tag ?? generateTag(stage);
280
+ const tag = request.tag ?? (resolved.target.tag ? await resolved.target.tag({
281
+ cwd: workspace.root,
282
+ stage
283
+ }) : generateTag(stage));
288
284
  const buildOrder = getAppBuildOrder(workspace);
289
285
  let selected = buildOrder;
290
286
  if (request.apps && request.apps.length > 0) {
@@ -336,6 +332,7 @@ async function prepare(source, request, ctx, emit, redactor) {
336
332
  cwd: workspace.root,
337
333
  stage,
338
334
  tag,
335
+ tagGiven: request.tag !== void 0,
339
336
  apps,
340
337
  skipped,
341
338
  identity,
@@ -343,6 +340,7 @@ async function prepare(source, request, ctx, emit, redactor) {
343
340
  manifest,
344
341
  options,
345
342
  dryRun: ctx.dryRun,
343
+ atomic: request.atomic ?? false,
346
344
  credentials: ctx.credentials,
347
345
  state: store,
348
346
  secrets,
@@ -357,84 +355,134 @@ async function prepare(source, request, ctx, emit, redactor) {
357
355
  };
358
356
  }
359
357
  //#endregion
360
- //#region src/deploy/terminal.ts
358
+ //#region src/deploy/deploy.ts
361
359
  /**
362
- * The credentials `gkm deploy` can ask a person for. CLI layer only.
360
+ * `deploy()`: a deploy as a library call.
363
361
  *
364
- * `deploy()` asks its `CredentialProvider` and stops with `MissingCredential`
365
- * when the answer is nothing. At a terminal, `gkm deploy` would rather ask:
366
- * this provider reads the environment and the stored login first, and only
367
- * when both are empty prompts — and stores a Dokploy login it validated, so
368
- * the next deploy does not ask again. With no terminal it answers nothing, and
369
- * the deploy says what was missing instead of waiting on a prompt nobody sees.
362
+ * `gkm deploy` could only be driven from an interactive terminal: it prompted
363
+ * for what it lacked and exited the process on failure, worked out of
364
+ * `process.cwd()`, and reported progress by printing. Here the caller says
365
+ * where the project is, hands over the credentials and a signal, and gets back
366
+ * a run — events to iterate while it goes, and a structured result at the end.
367
+ * Nothing below this asks a person anything or ends the process; `gkm deploy`
368
+ * is a thin wrapper that does both.
370
369
  */
371
- const logger = output;
372
- /** What answers a deploy prompt without a terminal. */
373
- const INSTEAD = "Please configure manually.";
374
- /** The Dokploy URL typed at the prompt is not a URL. */
375
- var DokployEndpointInvalid = class extends Error {
376
- endpoint;
377
- constructor(endpoint) {
378
- super("Invalid URL format");
379
- this.endpoint = endpoint;
380
- this.name = "DokployEndpointInvalid";
370
+ /**
371
+ * Every event a run emits, kept so that each iteration — however late it
372
+ * starts — sees the run from its first event to its last.
373
+ */
374
+ var EventLog = class {
375
+ events = [];
376
+ closed = false;
377
+ waiting = [];
378
+ push(event) {
379
+ this.events.push(event);
380
+ this.wake();
381
381
  }
382
- };
383
- /** Dokploy refused the token typed at the prompt; nothing was stored. */
384
- var DokployTokenRejected = class extends Error {
385
- endpoint;
386
- constructor(endpoint) {
387
- super("Invalid credentials. Please check your token.");
388
- this.endpoint = endpoint;
389
- this.name = "DokployTokenRejected";
382
+ close() {
383
+ this.closed = true;
384
+ this.wake();
385
+ }
386
+ wake() {
387
+ const waiting = this.waiting;
388
+ this.waiting = [];
389
+ for (const resume of waiting) resume();
390
+ }
391
+ async *iterate() {
392
+ let next = 0;
393
+ while (true) if (next < this.events.length) yield this.events[next++];
394
+ else if (this.closed) return;
395
+ else await new Promise((resume) => this.waiting.push(resume));
390
396
  }
391
397
  };
392
- /** Asks the person at the terminal for what nothing else supplied. */
393
- function asking() {
394
- return { async get(asked) {
395
- if (!canPrompt()) return void 0;
396
- const request = asked;
397
- if (request.kind === "dokploy") {
398
- logger.log("\n📋 Dokploy credentials not found. Let's set them up.");
399
- const endpoint = (await prompt("Dokploy URL (e.g., https://dokploy.example.com): ", { instead: INSTEAD })).replace(/\/$/, "");
400
- try {
401
- new URL(endpoint);
402
- } catch {
403
- throw new DokployEndpointInvalid(endpoint);
404
- }
405
- logger.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
406
- const token = await prompt("API Token: ", {
407
- hidden: true,
408
- instead: INSTEAD
398
+ function forward(logger, level, message) {
399
+ if (!logger) return;
400
+ if (level === "info") logger.info(message);
401
+ else if (level === "error" && logger.error) logger.error(message);
402
+ else logger.warn(message);
403
+ }
404
+ /**
405
+ * Deploy a project's stage.
406
+ *
407
+ * ```ts
408
+ * import { deploy } from '@geekmidas/cli/deploy';
409
+ *
410
+ * const run = deploy({ cwd: '/srv/checkouts/shop', stage: 'production' });
411
+ * for await (const event of run) {
412
+ * if (event.type === 'app.deployed') console.log(event.app, event.url);
413
+ * }
414
+ * const result = await run.result;
415
+ * ```
416
+ *
417
+ * The run starts at once; iterating it is optional, and an iteration started
418
+ * late still sees every event from the first.
419
+ */
420
+ function deploy(input) {
421
+ const log = new EventLog();
422
+ const redactor = new Redactor();
423
+ const emit = (event) => {
424
+ const masked = event.type === "log" ? {
425
+ ...event,
426
+ message: redactor.redact(event.message)
427
+ } : event;
428
+ log.push(masked);
429
+ if (masked.type === "log") forward(input.logger, masked.level, masked.message);
430
+ };
431
+ const ctx = {
432
+ emit,
433
+ credentials: input.credentials ?? storedCredentials({ home: input.home ?? gkmHome() }),
434
+ dryRun: input.dryRun ?? false,
435
+ home: input.home ?? gkmHome(),
436
+ redactor,
437
+ ...input.signal ? { signal: input.signal } : {},
438
+ ...input.childOutput ? { childOutput: input.childOutput } : {},
439
+ ...input.targets ? { targets: input.targets } : {}
440
+ };
441
+ const result = withOutput((level, message) => emit({
442
+ type: "log",
443
+ level,
444
+ message
445
+ }), async () => {
446
+ try {
447
+ input.signal?.throwIfAborted();
448
+ const sandbox = input.sandbox ?? new LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });
449
+ const deployed = await withSandbox(sandbox, () => runDeploy(() => load(input, sandbox), {
450
+ stage: input.stage,
451
+ ...input.target ? { target: input.target } : {},
452
+ ...input.tag ? { tag: input.tag } : {},
453
+ ...input.apps ? { apps: input.apps } : {},
454
+ ...input.atomic ? { atomic: true } : {}
455
+ }, ctx));
456
+ emit({
457
+ type: "deploy.finished",
458
+ result: deployed
409
459
  });
410
- logger.log("\nValidating credentials...");
411
- if (!await validateDokployToken(endpoint, token)) throw new DokployTokenRejected(endpoint);
412
- await storeDokployCredentials(token, endpoint);
413
- logger.log("✓ Credentials saved");
414
- return {
415
- endpoint,
416
- token
417
- };
460
+ return deployed;
461
+ } catch (error) {
462
+ emit({
463
+ type: "deploy.failed",
464
+ error: eventError(error)
465
+ });
466
+ throw error;
467
+ } finally {
468
+ log.close();
418
469
  }
419
- if (request.kind !== "registry") return void 0;
420
- logger.log(` Dokploy has no registry for ${request.url}. Let's create one.`);
421
- return {
422
- username: await prompt("Registry username: ", { instead: INSTEAD }),
423
- password: await prompt("Registry password/token: ", {
424
- hidden: true,
425
- instead: INSTEAD
426
- })
427
- };
428
- } };
470
+ });
471
+ result.catch(() => {});
472
+ return {
473
+ result,
474
+ [Symbol.asyncIterator]: () => log.iterate()
475
+ };
429
476
  }
430
477
  /**
431
- * The environment, then the stored login, then — at a terminal — the person
432
- * running the command.
478
+ * The workspace at `input.cwd`. The stage is checked by the run, once it
479
+ * knows the target: one that runs on this machine may take the local stage.
433
480
  */
434
- function terminalCredentials(base = storedCredentials()) {
435
- return chainCredentials(base, asking());
481
+ async function load(input, sandbox) {
482
+ const { workspace } = await loadWorkspaceConfig(resolve(input.cwd), { sandbox });
483
+ return workspace;
436
484
  }
437
485
  //#endregion
438
- export { runDeploy as a, UnknownDeployApps as i, NoDeployableApps as n, eventError as o, RollbackFailed as r, Redactor as s, terminalCredentials as t };
486
+ export { UnknownDeployApps as i, NoDeployableApps as n, RollbackFailed as r, deploy as t };
439
487
 
440
- //# sourceMappingURL=terminal-D7Ntz6WE.mjs.map
488
+ //# sourceMappingURL=deploy-DWn7YfIc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-DWn7YfIc.mjs","names":[],"sources":["../src/target/secrets.ts","../src/deploy/orchestrate.ts","../src/deploy/deploy.ts"],"sourcesContent":["/**\n * A stage's secrets as a target sees them: read and written through the\n * stage's own store, and masked in everything the run prints once read.\n */\n\nimport { secretsStoreFor } from '../secrets/store';\nimport type { StageSecrets } from '../secrets/types';\nimport type { NormalizedWorkspace } from '../workspace/types';\nimport type { DeploySecrets } from './types';\n\n/**\n * Shorter values are left alone: what a progress line legitimately prints —\n * a port, a stage, an app name — would otherwise come out as `***` wherever\n * a secret happened to share it.\n */\nconst SHORTEST_MASKED = 6;\n\n/** The values a run must never print, and the rewrite that keeps it so. */\nexport class Redactor {\n\tprivate readonly values = new Set<string>();\n\n\tadd(value: string | undefined): void {\n\t\tif (value && value.length >= SHORTEST_MASKED) this.values.add(value);\n\t}\n\n\t/** `text` with every masked value replaced by `***`, longest first. */\n\tredact(text: string): string {\n\t\tif (this.values.size === 0) return text;\n\t\tlet out = text;\n\t\tconst longestFirst = [...this.values].sort((a, b) => b.length - a.length);\n\t\tfor (const value of longestFirst) out = out.replaceAll(value, '***');\n\t\treturn out;\n\t}\n}\n\n/** Every value in `secrets` that is a secret rather than a label. */\nfunction secretValues(secrets: StageSecrets): string[] {\n\treturn [\n\t\tsecrets.seed,\n\t\t...Object.values(secrets.custom ?? {}),\n\t\t...Object.values(secrets.urls ?? {}),\n\t\t...Object.values(secrets.services ?? {}).map(\n\t\t\t(service) => service?.password,\n\t\t),\n\t].filter((value): value is string => typeof value === 'string');\n}\n\n/**\n * The stage's secrets through the store `secrets.store` names for it. Opening\n * one builds a client and makes no request, so a target that never reads them\n * costs nothing.\n */\nexport async function deploySecrets(\n\tworkspace: NormalizedWorkspace,\n\tstage: string,\n\tredactor: Redactor,\n\toptions: { home?: string } = {},\n): Promise<DeploySecrets> {\n\tconst store = await secretsStoreFor(workspace, stage, options);\n\tconst mask = (secrets: StageSecrets) => {\n\t\tfor (const value of secretValues(secrets)) redactor.add(value);\n\t};\n\n\treturn {\n\t\tstore: store.name,\n\t\tasync read() {\n\t\t\tconst secrets = await store.read(stage);\n\t\t\tif (secrets) mask(secrets);\n\t\t\treturn secrets;\n\t\t},\n\t\tasync write(secrets) {\n\t\t\tmask(secrets);\n\t\t\tawait store.write(stage, secrets);\n\t\t},\n\t\tmask: (value) => redactor.add(value),\n\t};\n}\n","/**\n * The run around a target: what every deploy does whatever it deploys\n * through.\n *\n * It loads the workspace, resolves the target, works out the apps and the\n * identity, takes the stage's lock, and calls the target's phases in order,\n * reporting each as it starts, finishes or fails. Everything that is about\n * *where* the stage goes is the target's.\n */\n\nimport { discover } from '../reconcile/discover.js';\nimport { constructGlobs } from '../reconcile/workspace.js';\nimport { builtinTarget } from '../target/builtins';\nimport {\n\tparseTargetOptions,\n\ttype ResolvedTarget,\n\tresolveTarget,\n} from '../target/resolve';\nimport { deploySecrets, Redactor } from '../target/secrets';\nimport type {\n\tAnyDeployTarget,\n\tDeployPhaseContext,\n\tDeployTargetLogger,\n} from '../target/types';\nimport { derivedApps } from '../workspace/derive.js';\nimport { getAppBuildOrder } from '../workspace/index.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport type { CredentialProvider } from './credentials';\nimport { type DeployEvent, type DeployPhase, eventError } from './events';\nimport { applicationName, deployIdentity } from './identity.js';\nimport { createStateStore } from './StateStore.js';\nimport type { DeployResult } from './types';\n\n/** What a run deploys, once the workspace is loaded. */\nexport interface DeployRequest {\n\t/** Deployment stage (e.g., 'production', 'staging') */\n\tstage: string;\n\t/** Image tag (default: stage-timestamp) */\n\ttag?: string;\n\t/** Specific apps to deploy (default: all) */\n\tapps?: string[];\n\t/** The target to deploy through. Defaults to `deploy.default`. */\n\ttarget?: string;\n\t/** On a failed release, roll back every app rather than the failed ones. */\n\tatomic?: boolean;\n}\n\n/**\n * What a run is handed by whoever started it: where its events go, where it\n * gets credentials, and whether it may change anything. Nothing in a run\n * reads a terminal or exits the process — that is its caller's business.\n */\nexport interface DeployContext {\n\temit: (event: DeployEvent) => void;\n\tcredentials: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Look everything up, create, build and push nothing. */\n\tdryRun: boolean;\n\t/** The CLI's home, for the stage's keys. Defaults to `GKM_HOME`. */\n\thome?: string;\n\t/** Where spawned processes' output goes. Defaults to the terminal. */\n\tchildOutput?: 'inherit' | 'stderr' | 'ignore';\n\t/** The host's own targets, which win over every other by the same name. */\n\ttargets?: Record<string, AnyDeployTarget>;\n\t/**\n\t * What the run masks in what it prints. `deploy()` passes the one its\n\t * progress lines go through; a run without one masks only its events.\n\t */\n\tredactor?: Redactor;\n}\n\n/** Apps were asked for by name that the workspace does not have. */\nexport class UnknownDeployApps extends Error {\n\tconstructor(\n\t\treadonly apps: readonly string[],\n\t\treadonly available: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Unknown apps: ${apps.join(', ')}\\n` +\n\t\t\t\t`Available apps: ${available.join(', ')}`,\n\t\t);\n\t\tthis.name = 'UnknownDeployApps';\n\t}\n}\n\n/** Every app asked for deploys through some other target. */\nexport class NoDeployableApps extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly target: string,\n\t) {\n\t\tsuper(\n\t\t\t`No apps to deploy through \"${target}\": every selected app deploys somewhere else. Pick the target with --target, or set each app's deploy in gkm.config.ts.`,\n\t\t);\n\t\tthis.name = 'NoDeployableApps';\n\t}\n}\n\n/** A failed rollback, after the failure that called for it. */\nexport class RollbackFailed extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\t/** What failed first, and was being rolled back. */\n\t\treadonly failure: unknown,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Deploying through \"${target}\" failed, and so did rolling it back: ${cause instanceof Error ? cause.message : String(cause)}. The stage may be part-released; deploy again, or roll it back by hand. The first failure: ${failure instanceof Error ? failure.message : String(failure)}`,\n\t\t\t{ cause },\n\t\t);\n\t\tthis.name = 'RollbackFailed';\n\t}\n}\n\n/**\n * Generate image tag from stage and timestamp\n */\nexport function generateTag(stage: string): string {\n\tconst timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n\treturn `${stage}-${timestamp}`;\n}\n\n/** Why an app that deploys through another target is left out. */\nfunction elsewhere(target: string, stage: string): string {\n\tconst instead = builtinTarget(target)?.instead?.(stage);\n\tif (instead) return `it deploys through \"${target}\" — ${instead}`;\n\treturn `it deploys through \"${target}\" — run \\`gkm deploy --target ${target} --stage ${stage}\\``;\n}\n\n/**\n * Deploy a workspace's stage through its target.\n *\n * The engine under `deploy()` and `gkm deploy`. It never prompts and never\n * exits: credentials come from `ctx.credentials`, progress goes to\n * `ctx.emit` and to `output`, and every failure is thrown.\n *\n * @internal\n */\nexport async function runDeploy(\n\tsource: NormalizedWorkspace | (() => Promise<NormalizedWorkspace>),\n\trequest: DeployRequest,\n\tctx: DeployContext,\n): Promise<DeployResult> {\n\tconst { stage } = request;\n\tconst redactor = ctx.redactor ?? new Redactor();\n\tconst emit = (event: DeployEvent) =>\n\t\tctx.emit(\n\t\t\tevent.type === 'log'\n\t\t\t\t? { ...event, message: redactor.redact(event.message) }\n\t\t\t\t: event,\n\t\t);\n\n\t/** Run one phase between its events. */\n\tconst phase = async <T>(name: DeployPhase, body: () => Promise<T>) => {\n\t\tctx.signal?.throwIfAborted();\n\t\temit({ type: 'phase.started', phase: name });\n\t\ttry {\n\t\t\tconst value = await body();\n\t\t\temit({ type: 'phase.finished', phase: name });\n\t\t\treturn value;\n\t\t} catch (error) {\n\t\t\temit({ type: 'phase.failed', phase: name, error: eventError(error) });\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tctx.signal?.throwIfAborted();\n\temit({ type: 'phase.started', phase: 'validate' });\n\n\tlet prepared: Prepared;\n\ttry {\n\t\tprepared = await prepare(source, request, ctx, emit, redactor);\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n\tconst { resolved, phaseCtx, store } = prepared;\n\tconst { target } = resolved;\n\n\t// A dry run takes no lock: it writes nothing a lock would protect, and it\n\t// should not stop a real deploy that starts while it is looking.\n\tif (ctx.dryRun) {\n\t\tconst run = await validate(target, phaseCtx, emit);\n\t\tawait phase('plan', () => target.plan(phaseCtx, run));\n\t\treturn target.result(phaseCtx, run);\n\t}\n\n\t// One deploy of a stage at a time. Taken before the target generates,\n\t// provisions or records anything, and held until the run ends however it\n\t// ends. A second run of the stage — another CI job, a laptop — gets\n\t// `StateLocked` naming this one instead of racing it; a run killed with\n\t// the lock held is released with `gkm state:unlock`.\n\tlet lock: Awaited<ReturnType<typeof store.lock>>;\n\ttry {\n\t\tlock = await store.lock(stage, { operation: 'deploy' });\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n\n\ttry {\n\t\tconst run = await validate(target, phaseCtx, emit);\n\t\tif (target.provision) {\n\t\t\tawait phase('provision', () => target.provision!(phaseCtx, run));\n\t\t}\n\t\tif (target.build) {\n\t\t\tawait phase('build', () => target.build!(phaseCtx, run));\n\t\t}\n\n\t\tlet releasing: 'release' | 'verify' = 'release';\n\t\ttry {\n\t\t\tawait phase('release', () => target.release(phaseCtx, run));\n\t\t\treleasing = 'verify';\n\t\t\tif (target.verify) {\n\t\t\t\tawait phase('verify', () => target.verify!(phaseCtx, run));\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// The caller stopping the run is not a release to undo.\n\t\t\tif (ctx.signal?.aborted || !target.capabilities.rollback) throw error;\n\t\t\tif (!target.rollback) throw error;\n\t\t\ttry {\n\t\t\t\tawait phase('rollback', () =>\n\t\t\t\t\ttarget.rollback!(phaseCtx, run, { phase: releasing, error }),\n\t\t\t\t);\n\t\t\t} catch (rollbackError) {\n\t\t\t\tthrow new RollbackFailed(resolved.name, error, rollbackError);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn await target.result(phaseCtx, run);\n\t} finally {\n\t\tawait lock.release();\n\t}\n}\n\n/** `validate`, then the run's `deploy.started`, inside the validate phase. */\nasync function validate(\n\ttarget: AnyDeployTarget,\n\tphaseCtx: DeployPhaseContext<unknown>,\n\temit: (event: DeployEvent) => void,\n): Promise<unknown> {\n\ttry {\n\t\tconst run = await target.validate(phaseCtx);\n\t\tconst skipped = new Set(phaseCtx.skipped.map((s) => s.app));\n\t\temit({\n\t\t\ttype: 'deploy.started',\n\t\t\tstage: phaseCtx.stage,\n\t\t\ttarget: phaseCtx.target,\n\t\t\tidentity: phaseCtx.identity.key,\n\t\t\ttag: phaseCtx.tag,\n\t\t\tapps: phaseCtx.apps.filter((app) => !skipped.has(app)),\n\t\t\tdryRun: phaseCtx.dryRun,\n\t\t});\n\t\temit({ type: 'phase.finished', phase: 'validate' });\n\t\treturn run;\n\t} catch (error) {\n\t\temit({ type: 'phase.failed', phase: 'validate', error: eventError(error) });\n\t\tthrow error;\n\t}\n}\n\ninterface Prepared {\n\tresolved: ResolvedTarget;\n\tphaseCtx: DeployPhaseContext<unknown>;\n\tstore: Awaited<ReturnType<typeof createStateStore>>;\n}\n\n/** Everything the phases are handed, worked out before the first of them. */\nasync function prepare(\n\tsource: NormalizedWorkspace | (() => Promise<NormalizedWorkspace>),\n\trequest: DeployRequest,\n\tctx: DeployContext,\n\temit: (event: DeployEvent) => void,\n\tredactor: Redactor,\n): Promise<Prepared> {\n\tconst { stage } = request;\n\tconst configured = typeof source === 'function' ? await source() : source;\n\n\t// Before anything is provisioned: a typo'd stage would otherwise create a\n\t// whole second environment under the wrong name. The local stage is left\n\t// to the target, which says whether it can run it.\n\tconst local = stage === configured.stages.local;\n\tif (!local) assertDeployedStage(configured.stages, stage);\n\n\t// Before anything is discovered or derived: a target that cannot be found\n\t// — or a package that would not load — fails a deploy that has done\n\t// nothing yet.\n\tconst targetName = request.target ?? configured.deploy?.default ?? 'dokploy';\n\tconst resolved = await resolveTarget(targetName, {\n\t\tworkspace: configured,\n\t\tstage,\n\t\t...(ctx.targets ? { host: ctx.targets } : {}),\n\t});\n\tif (local && !resolved.target.capabilities.localStage) {\n\t\tassertDeployedStage(configured.stages, stage);\n\t}\n\tconst options = await parseTargetOptions(resolved);\n\n\t// What to deploy comes from the manifest.\n\t//\n\t// Discovered here rather than by the target, because the list of things\n\t// to deploy is the *declarations* — one `rest-api` is one server, one\n\t// `site` is one site — and the config only says how to run each. A project\n\t// that declares no surfaces keeps its configured apps, so adopting\n\t// constructs stays something you do a piece at a time.\n\tconst manifest = await discover({\n\t\tpatterns: constructGlobs(configured),\n\t\tcwd: configured.root,\n\t});\n\tconst units = derivedApps(manifest, configured);\n\tconst workspace: NormalizedWorkspace =\n\t\tObject.keys(units).length > 0 ? { ...configured, apps: units } : configured;\n\n\t// What every resource this deploy touches is named and claimed by —\n\t// resolved first, so a namespace that cannot be a name fails before\n\t// anything is built.\n\tconst identity = deployIdentity(workspace, stage);\n\tconst tag =\n\t\trequest.tag ??\n\t\t(resolved.target.tag\n\t\t\t? await resolved.target.tag({ cwd: workspace.root, stage })\n\t\t\t: generateTag(stage));\n\n\t// The apps asked for, in dependency order.\n\tconst buildOrder = getAppBuildOrder(workspace);\n\tlet selected = buildOrder;\n\tif (request.apps && request.apps.length > 0) {\n\t\tconst unknown = request.apps.filter((name) => !workspace.apps[name]);\n\t\tif (unknown.length > 0) {\n\t\t\tthrow new UnknownDeployApps(unknown, Object.keys(workspace.apps));\n\t\t}\n\t\tselected = buildOrder.filter((name) => request.apps!.includes(name));\n\t}\n\n\tconst skipped: { app: string; reason: string }[] = [];\n\tconst skip = (app: string, reason: string) => {\n\t\tskipped.push({ app, reason });\n\t\temit({ type: 'app.skipped', app, reason });\n\t};\n\n\t// An app that names another target deploys there, in a run of its own.\n\t// One on the default follows the run, so `--target` moves the stage\n\t// without every app having to be told.\n\tconst byDefault = configured.deploy?.default ?? 'dokploy';\n\tconst apps = selected.filter((name) => {\n\t\tconst own = workspace.apps[name]!.resolvedDeployTarget;\n\t\tconst deploysThrough = own === byDefault ? targetName : own;\n\t\tif (deploysThrough === targetName) return true;\n\t\tskip(name, elsewhere(deploysThrough, stage));\n\t\treturn false;\n\t});\n\tif (apps.length === 0) throw new NoDeployableApps(stage, targetName);\n\n\tconst store = await createStateStore({\n\t\tconfig: workspace.state,\n\t\tworkspaceRoot: workspace.root,\n\t\tworkspaceName: workspace.name,\n\t});\n\tconst secrets = await deploySecrets(workspace, stage, redactor, {\n\t\t...(ctx.home ? { home: ctx.home } : {}),\n\t});\n\n\tconst line =\n\t\t(level: 'info' | 'warn' | 'error') =>\n\t\t(message: string): void =>\n\t\t\temit({ type: 'log', level, message });\n\tconst logger: DeployTargetLogger = {\n\t\tinfo: line('info'),\n\t\twarn: line('warn'),\n\t\terror: line('error'),\n\t};\n\n\tconst phaseCtx: DeployPhaseContext<unknown> = {\n\t\ttarget: targetName,\n\t\tcwd: workspace.root,\n\t\tstage,\n\t\ttag,\n\t\ttagGiven: request.tag !== undefined,\n\t\tapps,\n\t\tskipped,\n\t\tidentity,\n\t\tworkspace,\n\t\tmanifest,\n\t\toptions,\n\t\tdryRun: ctx.dryRun,\n\t\tatomic: request.atomic ?? false,\n\t\tcredentials: ctx.credentials,\n\t\tstate: store,\n\t\tsecrets,\n\t\tlogger,\n\t\tsignal: ctx.signal ?? new AbortController().signal,\n\t\tchildOutput: ctx.childOutput ?? 'inherit',\n\t\temit,\n\t\tskip,\n\t\tname: (resource) => applicationName(identity, resource),\n\t};\n\n\treturn { resolved, phaseCtx, store };\n}\n","/**\n * `deploy()`: a deploy as a library call.\n *\n * `gkm deploy` could only be driven from an interactive terminal: it prompted\n * for what it lacked and exited the process on failure, worked out of\n * `process.cwd()`, and reported progress by printing. Here the caller says\n * where the project is, hands over the credentials and a signal, and gets back\n * a run — events to iterate while it goes, and a structured result at the end.\n * Nothing below this asks a person anything or ends the process; `gkm deploy`\n * is a thin wrapper that does both.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../config';\nimport { gkmHome } from '../home';\nimport { type OutputLevel, withOutput } from '../output';\nimport { LocalSandbox } from '../sandbox/local';\nimport { type Sandbox, withSandbox } from '../sandbox/sandbox';\nimport { Redactor } from '../target/secrets';\nimport type { AnyDeployTarget } from '../target/types';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport { type CredentialProvider, storedCredentials } from './credentials';\nimport { type DeployEvent, eventError } from './events';\nimport { type DeployContext, runDeploy } from './orchestrate';\nimport type { DeployResult } from './types';\n\n/**\n * Where a run's progress lines go, besides its events. `@geekmidas/logger`'s\n * `Logger` is one.\n */\nexport interface DeployLogger {\n\tinfo(message: string): void;\n\twarn(message: string): void;\n\terror?(message: string): void;\n}\n\nexport interface DeployInput {\n\t/**\n\t * The project to deploy: the directory holding `gkm.config.ts`, or any\n\t * directory inside it. Never assumed to be `process.cwd()`.\n\t */\n\tcwd: string;\n\t/**\n\t * The stage to deploy — one of the config's deployed stages, or its local\n\t * stage through a target that runs one (`compose`).\n\t */\n\tstage: string;\n\t/**\n\t * The target to deploy through, by name. Defaults to `deploy.default`,\n\t * else `dokploy`.\n\t */\n\ttarget?: string;\n\t/**\n\t * The host's own targets, by name. Consulted before the built-ins and the\n\t * config's `deploy.targets`, so a host can deploy through an\n\t * implementation of its own — `{ dokploy: myDokploy }` included.\n\t */\n\ttargets?: Record<string, AnyDeployTarget>;\n\t/** The image tag. Defaults to `<stage>-<timestamp>`. */\n\ttag?: string;\n\t/** Deploy only these apps (in dependency order). Defaults to all. */\n\tapps?: string[];\n\t/**\n\t * Look everything up and report what would happen — as `resource.planned`\n\t * events — without taking the lock, writing state, generating secrets,\n\t * changing Dokploy or building and pushing images.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * When a release or its verification fails, roll back every app the run\n\t * released rather than only the ones that failed — on a target that can\n\t * roll back. For apps that must move together.\n\t */\n\tatomic?: boolean;\n\t/**\n\t * Where credentials come from. Defaults to the environment, then the\n\t * logins `gkm login` stored. A credential no provider has stops the run\n\t * with `MissingCredential`; nothing prompts.\n\t */\n\tcredentials?: CredentialProvider;\n\t/** Receives each progress line as it is written. Defaults to none. */\n\tlogger?: DeployLogger;\n\t/**\n\t * Stops the run: in-flight Dokploy requests and docker children are\n\t * cancelled, the stage's lock is released, and `result` rejects with the\n\t * signal's reason.\n\t */\n\tsignal?: AbortSignal;\n\t/**\n\t * The CLI's home: stage keys and stored logins. Defaults to `GKM_HOME`,\n\t * else `~/.gkm`.\n\t */\n\thome?: string;\n\t/**\n\t * Where docker's own output goes: the host's terminal (`inherit`, the\n\t * default), its stderr, or nowhere.\n\t */\n\tchildOutput?: 'inherit' | 'stderr' | 'ignore';\n\t/**\n\t * Where the project's own code runs: loading `gkm.config.ts`, discovering\n\t * its constructs, sniffing each app's environment. Defaults to a\n\t * `LocalSandbox` on the project — a child process here with an\n\t * allowlisted environment, for a project the host trusts.\n\t *\n\t * A host deploying repositories it does not trust passes one that\n\t * isolates — a container per build — and the config then reaches the\n\t * deploy only as data. Credentials never enter a sandbox: they go from\n\t * `credentials` to the steps that provision, push and release.\n\t */\n\tsandbox?: Sandbox;\n}\n\n/** A deploy in progress. */\nexport interface DeployRun extends AsyncIterable<DeployEvent> {\n\t/**\n\t * What the deploy did, once it is done. Rejects with the error that\n\t * stopped it — `MissingCredential`, `StateLocked`, `ProjectNotOwned`, … —\n\t * after a `deploy.failed` event carrying the same.\n\t */\n\treadonly result: Promise<DeployResult>;\n}\n\n/**\n * Every event a run emits, kept so that each iteration — however late it\n * starts — sees the run from its first event to its last.\n */\nclass EventLog {\n\tprivate readonly events: DeployEvent[] = [];\n\tprivate closed = false;\n\tprivate waiting: (() => void)[] = [];\n\n\tpush(event: DeployEvent): void {\n\t\tthis.events.push(event);\n\t\tthis.wake();\n\t}\n\n\tclose(): void {\n\t\tthis.closed = true;\n\t\tthis.wake();\n\t}\n\n\tprivate wake(): void {\n\t\tconst waiting = this.waiting;\n\t\tthis.waiting = [];\n\t\tfor (const resume of waiting) resume();\n\t}\n\n\tasync *iterate(): AsyncGenerator<DeployEvent> {\n\t\tlet next = 0;\n\t\twhile (true) {\n\t\t\tif (next < this.events.length) {\n\t\t\t\tyield this.events[next++]!;\n\t\t\t} else if (this.closed) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tawait new Promise<void>((resume) => this.waiting.push(resume));\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction forward(\n\tlogger: DeployLogger | undefined,\n\tlevel: OutputLevel,\n\tmessage: string,\n): void {\n\tif (!logger) return;\n\tif (level === 'info') logger.info(message);\n\telse if (level === 'error' && logger.error) logger.error(message);\n\telse logger.warn(message);\n}\n\n/**\n * Deploy a project's stage.\n *\n * ```ts\n * import { deploy } from '@geekmidas/cli/deploy';\n *\n * const run = deploy({ cwd: '/srv/checkouts/shop', stage: 'production' });\n * for await (const event of run) {\n * if (event.type === 'app.deployed') console.log(event.app, event.url);\n * }\n * const result = await run.result;\n * ```\n *\n * The run starts at once; iterating it is optional, and an iteration started\n * late still sees every event from the first.\n */\nexport function deploy(input: DeployInput): DeployRun {\n\tconst log = new EventLog();\n\t// Every secret the run reads is masked in every line it reports — in the\n\t// events and in what the logger is handed.\n\tconst redactor = new Redactor();\n\tconst emit = (event: DeployEvent) => {\n\t\tconst masked =\n\t\t\tevent.type === 'log'\n\t\t\t\t? { ...event, message: redactor.redact(event.message) }\n\t\t\t\t: event;\n\t\tlog.push(masked);\n\t\tif (masked.type === 'log') {\n\t\t\tforward(input.logger, masked.level, masked.message);\n\t\t}\n\t};\n\n\tconst ctx: DeployContext = {\n\t\temit,\n\t\tcredentials:\n\t\t\tinput.credentials ?? storedCredentials({ home: input.home ?? gkmHome() }),\n\t\tdryRun: input.dryRun ?? false,\n\t\thome: input.home ?? gkmHome(),\n\t\tredactor,\n\t\t...(input.signal ? { signal: input.signal } : {}),\n\t\t...(input.childOutput ? { childOutput: input.childOutput } : {}),\n\t\t...(input.targets ? { targets: input.targets } : {}),\n\t};\n\n\t// Every line anything in the run writes through `output` — the deploy's\n\t// own, the Dockerfile generator's, discovery's warnings — becomes an event\n\t// of this run, and of no other.\n\tconst result = withOutput(\n\t\t(level, message) => emit({ type: 'log', level, message }),\n\t\tasync () => {\n\t\t\ttry {\n\t\t\t\tinput.signal?.throwIfAborted();\n\t\t\t\tconst sandbox =\n\t\t\t\t\tinput.sandbox ??\n\t\t\t\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\t\t\t\t// Every step of the run that executes the project's code — the\n\t\t\t\t// engine's own discoveries and sniffs included — runs in it.\n\t\t\t\tconst deployed = await withSandbox(sandbox, () =>\n\t\t\t\t\trunDeploy(\n\t\t\t\t\t\t() => load(input, sandbox),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstage: input.stage,\n\t\t\t\t\t\t\t...(input.target ? { target: input.target } : {}),\n\t\t\t\t\t\t\t...(input.tag ? { tag: input.tag } : {}),\n\t\t\t\t\t\t\t...(input.apps ? { apps: input.apps } : {}),\n\t\t\t\t\t\t\t...(input.atomic ? { atomic: true } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tctx,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\temit({ type: 'deploy.finished', result: deployed });\n\t\t\t\treturn deployed;\n\t\t\t} catch (error) {\n\t\t\t\temit({ type: 'deploy.failed', error: eventError(error) });\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tlog.close();\n\t\t\t}\n\t\t},\n\t);\n\n\t// A caller that only iterates still learns of the failure from the\n\t// `deploy.failed` event; the rejection must not also crash its process as\n\t// unhandled. Awaiting `result` still rejects.\n\tresult.catch(() => {});\n\n\treturn {\n\t\tresult,\n\t\t[Symbol.asyncIterator]: () => log.iterate(),\n\t};\n}\n\n/**\n * The workspace at `input.cwd`. The stage is checked by the run, once it\n * knows the target: one that runs on this machine may take the local stage.\n */\nasync function load(\n\tinput: DeployInput,\n\tsandbox: Sandbox,\n): Promise<NormalizedWorkspace> {\n\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\tsandbox,\n\t});\n\treturn workspace;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import { a as discriminatedUnion, c as object, l as record, n as array, o as literal, u as string } from "./schemas-D2LCF689.mjs";
2
+ import { a as discriminatedUnion, d as string, l as object, n as array, o as literal, u as record } from "./schemas-Cfhtpdo0.mjs";
3
3
  import { i as activeSandbox, s as oncePerRun } from "./sandbox-Dm247NGx.mjs";
4
4
  import { t as WORKER_RESULT_MARKER } from "./workerRuntime-CsOyBRx2.mjs";
5
5
  import { createRequire } from "node:module";
@@ -207,6 +207,7 @@ var SandboxWorkerFailed = class extends Error {
207
207
  * though it had run again.
208
208
  */
209
209
  async function runWorker(sandbox, step, options) {
210
+ if (options.secrets) return startWorker(sandbox, step, options);
210
211
  const key = JSON.stringify([
211
212
  options.name,
212
213
  options.cwd,
@@ -225,6 +226,7 @@ async function startWorker(sandbox, step, options) {
225
226
  },
226
227
  timeoutMs: options.timeoutMs,
227
228
  output: "capture",
229
+ ...options.secrets ? { secrets: options.secrets } : {},
228
230
  ...options.signal ? { signal: options.signal } : {}
229
231
  });
230
232
  const line = result.stdout.split("\n").reverse().find((l) => l.startsWith(WORKER_RESULT_MARKER));
@@ -502,4 +504,4 @@ var DuplicateConstruct = class extends Error {
502
504
  //#endregion
503
505
  export { isDeclarable as a, runWorker as c, output as d, withOutput as f, discover_exports as i, withOwningTsconfigJsx as l, ConstructsNotSerializable as n, SandboxWorkerFailed as o, discover as r, nodeWithTsx as s, ConstructDiscoveryFailed as t, ConstructGenerator as u };
504
506
 
505
- //# sourceMappingURL=discover-LMrqsWSU.mjs.map
507
+ //# sourceMappingURL=discover-BFoJWKGD.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-BFoJWKGD.mjs","names":["kebabCase","z.discriminatedUnion","z.object","z.literal","z.record","z.string","z.array","z\n\t\t\t.object"],"sources":["../src/output.ts","../src/generators/Generator.ts","../src/owningTsconfigJsx.ts","../src/sandbox/worker.ts","../src/reconcile/discover.ts"],"sourcesContent":["/**\n * Where the CLI's progress lines go.\n *\n * Commands write their progress through `output` rather than `console`. Run\n * from the terminal that is the same thing. Run inside `deploy()`, each line\n * goes to the run that wrote it instead — as an event its caller can iterate,\n * and to the logger it was handed — so a deploy embedded in another program\n * does not print over that program's own output.\n *\n * Carried by `AsyncLocalStorage` rather than passed down, because the lines\n * come from everywhere a deploy reaches — the Dockerfile generator, the env\n * sniffer, construct discovery — and two deploys running in one process must\n * not hear each other.\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { format } from 'node:util';\n\n/** How loud a line is. */\nexport type OutputLevel = 'info' | 'warn' | 'error';\n\n/** Receives each line written while it is the current sink. */\nexport type OutputSink = (level: OutputLevel, message: string) => void;\n\nconst current = new AsyncLocalStorage<OutputSink>();\n\n/** Runs `fn` with every line written through `output` sent to `sink`. */\nexport function withOutput<T>(sink: OutputSink, fn: () => T): T {\n\treturn current.run(sink, fn);\n}\n\nfunction write(\n\tlevel: OutputLevel,\n\tfallback: (...args: unknown[]) => void,\n): (...args: unknown[]) => void {\n\treturn (...args) => {\n\t\tconst sink = current.getStore();\n\t\tif (sink) sink(level, format(...args));\n\t\telse fallback(...args);\n\t};\n}\n\n/**\n * `console`, for the methods the CLI logs through — routed to the current\n * run's sink when there is one.\n */\nexport const output = {\n\tlog: write('info', (...args) => console.log(...args)),\n\tinfo: write('info', (...args) => console.info(...args)),\n\twarn: write('warn', (...args) => console.warn(...args)),\n\terror: write('error', (...args) => console.error(...args)),\n};\n","import { relative } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\nimport fg from 'fast-glob';\nimport kebabCase from 'lodash.kebabcase';\nimport type { BuildContext } from '../build/types';\nimport type { MainProvider, Routes } from '../types';\n\n/**\n * Zod v4 maintains a process-wide registry of schemas registered via\n * `.meta({ id })`. When we cache-bust user module imports (by appending a\n * `?t=timestamp` query), those modules re-execute and try to register the\n * same ids again, which throws `ID X already exists in the registry`.\n *\n * Clearing the registry in the CLI process is safe: the user's running\n * server lives in a subprocess and has its own isolated registry.\n *\n * Exported for tests.\n */\nexport function clearZodGlobalRegistry(): void {\n\tconst registry = (\n\t\tglobalThis as { __zod_globalRegistry?: { clear?: () => void } }\n\t).__zod_globalRegistry;\n\tif (registry && typeof registry.clear === 'function') {\n\t\tregistry.clear();\n\t}\n}\n\nexport interface GeneratorOptions {\n\t/** Where the build deploys: one Lambda per construct, or one process. */\n\ttarget?: MainProvider;\n\t/**\n\t * What a handler path in the manifest is relative to — the workspace root,\n\t * which is where `sst.config.ts` runs and resolves it from.\n\t */\n\troot?: string;\n\t[key: string]: any;\n}\n\nexport abstract class ConstructGenerator<T extends Construct, R = void> {\n\tabstract isConstruct(value: any): value is T;\n\n\tstatic async build<T extends Construct, R = void>(\n\t\tcontext: BuildContext,\n\t\toutputDir: string,\n\t\tgenerator: ConstructGenerator<T, R>,\n\t\tpatterns?: Routes,\n\t\toptions?: GeneratorOptions,\n\t): Promise<R> {\n\t\tconst constructs = await generator.load(patterns);\n\t\treturn generator.build(context, constructs, outputDir, options);\n\t}\n\n\tabstract build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<T>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<R>;\n\n\tasync load(\n\t\tpatterns?: Routes,\n\t\tcwd = process.cwd(),\n\t\tbustCache = false,\n\t): Promise<GeneratedConstruct<T>[]> {\n\t\tconst logger = console;\n\n\t\tconst globPatterns = Array.isArray(patterns)\n\t\t\t? patterns\n\t\t\t: patterns\n\t\t\t\t? [patterns]\n\t\t\t\t: [];\n\n\t\t// Find all files\n\t\tconst files = fg.stream(globPatterns, {\n\t\t\tcwd,\n\t\t\tabsolute: true,\n\t\t});\n\n\t\t// Cache-busted re-imports re-execute user modules, which would try to\n\t\t// re-register Zod schemas with the same `.meta({ id })`. Clear the\n\t\t// global registry once per load to prevent duplicate-id errors.\n\t\tif (bustCache) {\n\t\t\tclearZodGlobalRegistry();\n\t\t}\n\n\t\t// Load constructs\n\t\tconst constructs: GeneratedConstruct<T>[] = [];\n\n\t\tfor await (const f of files) {\n\t\t\ttry {\n\t\t\t\tconst file = f.toString();\n\t\t\t\t// Append cache-busting query param to force re-import of changed modules\n\t\t\t\tconst importPath = bustCache ? `${file}?t=${Date.now()}` : file;\n\t\t\t\tconst module = await import(importPath);\n\n\t\t\t\t// Check all exports for constructs\n\t\t\t\tfor (const [key, construct] of Object.entries(module)) {\n\t\t\t\t\tif (this.isConstruct(construct)) {\n\t\t\t\t\t\tconstructs.push({\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tname: kebabCase(key),\n\t\t\t\t\t\t\tconstruct,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tabsolute: file,\n\t\t\t\t\t\t\t\trelative: relative(process.cwd(), file),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as Error;\n\t\t\t\tlogger.error(`Failed to load ${f}: ${err.message}`);\n\t\t\t\tif (err.stack) {\n\t\t\t\t\tlogger.error(err.stack);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn constructs;\n\t}\n}\n\nexport interface GeneratedConstruct<T extends Construct> {\n\tkey: string;\n\tname: string;\n\tconstruct: T;\n\tpath: {\n\t\tabsolute: string;\n\t\trelative: string;\n\t};\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nconst REGISTER = 'owning-tsconfig-jsx-register.mjs';\n\n/** The CLI's `bin/` was not found above the module looking for it. */\nexport class OwningTsconfigJsxHookMissing extends Error {\n\tconstructor(readonly from: string) {\n\t\tsuper(\n\t\t\t`Could not find bin/${REGISTER} in any directory above '${from}'. ` +\n\t\t\t\t'It ships with @geekmidas/cli beside bin/gkm.mjs; reinstall the ' +\n\t\t\t\t'package if it is missing.',\n\t\t);\n\t\tthis.name = 'OwningTsconfigJsxHookMissing';\n\t}\n}\n\n/**\n * The CLI's `bin/owning-tsconfig-jsx-register.mjs`, as a file URL. Searched\n * upward because this module runs from `src/` in the repo and from a chunk in\n * `dist/` once built, and `bin/` sits beside both.\n */\nfunction registerUrl(): string {\n\tconst from = dirname(fileURLToPath(import.meta.url));\n\tfor (let dir = from; ; dir = dirname(dir)) {\n\t\tconst candidate = join(dir, 'bin', REGISTER);\n\t\tif (existsSync(candidate)) return pathToFileURL(candidate).href;\n\t\tif (dirname(dir) === dir) throw new OwningTsconfigJsxHookMissing(from);\n\t}\n}\n\n/**\n * `NODE_OPTIONS` for a process that runs app code through tsx, with the hook\n * that compiles each `.tsx` with its own tsconfig's JSX settings (see\n * `bin/owning-tsconfig-jsx.mjs`) put in front of every other `--import`, so it\n * is registered before tsx and reads the source on tsx's behalf.\n *\n * `bin/gkm.mjs` already starts the CLI this way, and its children inherit it;\n * this is for those that set `NODE_OPTIONS` themselves, or whose CLI was\n * started with tsx already imported.\n */\nexport function withOwningTsconfigJsx(nodeOptions = ''): string {\n\tif (nodeOptions.includes(REGISTER)) return nodeOptions;\n\treturn [`--import=${registerUrl()}`, nodeOptions].filter(Boolean).join(' ');\n}\n","/**\n * Running one of the CLI's own worker scripts inside a sandbox, and reading\n * back the one JSON value it answers with.\n *\n * The worker imports the project's TypeScript — `gkm.config.ts`, construct\n * modules, an app's entry — so it starts with the CLI's own tsx and the two\n * hooks `gkm` itself runs with (JSX by the owning tsconfig, path aliases by\n * the adjacent one). The host process needs none of them loaded: a program\n * calling `deploy()` without `--import tsx` still loads a TypeScript config.\n */\n\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport type { z } from 'zod';\nimport { withOwningTsconfigJsx } from '../owningTsconfigJsx';\nimport { oncePerRun, type Sandbox } from './sandbox';\nimport { WORKER_RESULT_MARKER } from './workerRuntime';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n/**\n * A worker's file: `dist/sandbox/<name>.mjs` once built — whether this module\n * was bundled into `dist/` or sits beside it — or the `.ts` source under tsx.\n */\nexport function workerFile(name: string): string {\n\tconst candidates = [\n\t\tjoin(here, 'sandbox', `${name}.mjs`),\n\t\tjoin(here, `${name}.mjs`),\n\t\tjoin(here, '..', 'sandbox', `${name}.mjs`),\n\t\tjoin(here, `${name}.ts`),\n\t];\n\treturn (\n\t\tcandidates.find((path) => existsSync(path)) ?? join(here, `${name}.ts`)\n\t);\n}\n\n/** tsx, from the CLI's own dependencies — never the project's. */\nexport function tsxUrl(): string {\n\treturn pathToFileURL(createRequire(import.meta.url).resolve('tsx')).href;\n}\n\n/**\n * `node`'s arguments for `script`: the CLI's TypeScript loaders, then any\n * further `imports`, then the script and its `args` — an argument array, so\n * nothing about a path is read by a shell.\n */\nexport function nodeWithTsx(\n\tscript: string,\n\targs: readonly string[],\n\timports: readonly string[] = [],\n): string[] {\n\treturn [\n\t\t...withOwningTsconfigJsx(`--import=${tsxUrl()}`).split(' '),\n\t\t...imports.map((path) => `--import=${pathToFileURL(path).href}`),\n\t\tscript,\n\t\t...args,\n\t];\n}\n\n/** A worker ended without the answer it exists to give. */\nexport class SandboxWorkerFailed extends Error {\n\tconstructor(\n\t\treadonly step: string,\n\t\treadonly exitCode: number | null,\n\t\treadonly stderr: string,\n\t) {\n\t\tsuper(\n\t\t\t`The sandboxed ${step} ended (exit code ${exitCode}) without an ` +\n\t\t\t\t`answer.${stderr.trim() ? `\\n${stderr.trim()}` : ''}\\nIts output ` +\n\t\t\t\t'above says why; the sandbox must be able to run `node` with the ' +\n\t\t\t\t\"CLI's own files at the paths they have here.\",\n\t\t);\n\t\tthis.name = 'SandboxWorkerFailed';\n\t}\n}\n\nexport interface WorkerRun<T> {\n\t/** What the worker answered, as the schema reads it. */\n\tvalue: T;\n\t/** What it wrote to stderr: warnings a caller may pass on. */\n\tstderr: string;\n}\n\n/**\n * Run worker `name` in `sandbox`, and parse its answer with `schema`.\n *\n * The answer is the last marked line on stdout. Anything else the project's\n * code printed is ignored, and an answer the schema refuses is a failure\n * rather than data — a worker in an isolating sandbox runs code the host does\n * not trust.\n *\n * Within a run (`withSandbox`), the same worker asked the same question is\n * started once; every ask gets its own copy of the answer, and its stderr, as\n * though it had run again.\n */\nexport async function runWorker<S extends z.ZodType>(\n\tsandbox: Sandbox,\n\tstep: string,\n\toptions: WorkerOptions<S>,\n): Promise<WorkerRun<z.infer<S>>> {\n\t// A step handed secrets acts on something — a database it migrates — and\n\t// is not a question whose answer can be reused; nor do its secrets belong\n\t// in a cache key.\n\tif (options.secrets) return startWorker(sandbox, step, options);\n\n\tconst key = JSON.stringify([\n\t\toptions.name,\n\t\toptions.cwd,\n\t\toptions.args,\n\t\toptions.env ?? {},\n\t]);\n\tconst answer = await oncePerRun(sandbox, key, () =>\n\t\tstartWorker(sandbox, step, options),\n\t);\n\treturn structuredClone(answer);\n}\n\ninterface WorkerOptions<S extends z.ZodType> {\n\tname: string;\n\targs: readonly string[];\n\tcwd: string;\n\ttimeoutMs: number;\n\tenv?: Readonly<Record<string, string>>;\n\t/** Mounted as files, named by `GKM_SECRETS_DIR` — never variables. */\n\tsecrets?: Readonly<Record<string, string>>;\n\tsignal?: AbortSignal;\n\tschema: S;\n}\n\nasync function startWorker<S extends z.ZodType>(\n\tsandbox: Sandbox,\n\tstep: string,\n\toptions: WorkerOptions<S>,\n): Promise<WorkerRun<z.infer<S>>> {\n\tconst result = await sandbox.exec(\n\t\t'node',\n\t\tnodeWithTsx(workerFile(options.name), options.args),\n\t\t{\n\t\t\tcwd: options.cwd,\n\t\t\tenv: { ...sandbox.env, ...options.env },\n\t\t\ttimeoutMs: options.timeoutMs,\n\t\t\toutput: 'capture',\n\t\t\t...(options.secrets ? { secrets: options.secrets } : {}),\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t},\n\t);\n\n\tconst line = result.stdout\n\t\t.split('\\n')\n\t\t.reverse()\n\t\t.find((l) => l.startsWith(WORKER_RESULT_MARKER));\n\tif (line) {\n\t\ttry {\n\t\t\tconst parsed = options.schema.safeParse(\n\t\t\t\tJSON.parse(line.slice(WORKER_RESULT_MARKER.length)),\n\t\t\t);\n\t\t\tif (parsed.success) return { value: parsed.data, stderr: result.stderr };\n\t\t} catch {\n\t\t\t// Not JSON: as good as no answer.\n\t\t}\n\t}\n\n\tthrow new SandboxWorkerFailed(step, result.exitCode, result.stderr);\n}\n","/**\n * Discovery — one glob, one structural test.\n *\n * A glob per kind is the same specialness the construct model removes, and\n * resources have no kind to be listed under: a declared `ObjectStorage` would\n * never be found by `routes:` or `crons:`. So there is one `constructs` glob,\n * every export of every matching module is inspected, and the per-kind\n * `isConstruct` checks collapse into a single question — does it have an id and\n * can it declare?\n *\n * Structural rather than `instanceof` on purpose. A construct from a different\n * copy of `@geekmidas/constructs` — a linked workspace, two versions in a\n * lockfile — is still a construct, and `instanceof` is exactly the check that\n * says otherwise.\n */\n\nimport { relative } from 'node:path';\nimport {\n\tassertDerivations,\n\ttype ConstructManifest,\n\tcanonicalId,\n\ttype Declaration,\n} from '@geekmidas/manifest';\nimport fg from 'fast-glob';\nimport { z } from 'zod';\nimport { clearZodGlobalRegistry } from '../generators/Generator';\nimport { output } from '../output';\nimport { activeSandbox, type Sandbox } from '../sandbox/sandbox';\nimport { runWorker } from '../sandbox/worker';\n\n/** `console`, or the deploy run discovering the manifest. */\nconst logger = output;\n\n/** The construct face discovery needs: an id, and the ability to declare. */\ninterface Declarable {\n\tid: string;\n\tdeclare(): Declaration[];\n}\n\n/**\n * Whether a module export is a construct.\n *\n * Deliberately loose about what else it carries — a construct that also has a\n * `service` is still a construct, and requiring one would exclude the kinds that\n * own no address.\n */\nexport function isDeclarable(value: unknown): value is Declarable {\n\tif (typeof value !== 'object' || value === null) return false;\n\n\tconst candidate = value as Partial<Declarable>;\n\n\treturn (\n\t\ttypeof candidate.id === 'string' &&\n\t\tcandidate.id.length > 0 &&\n\t\ttypeof candidate.declare === 'function'\n\t);\n}\n\nexport interface DiscoverOptions {\n\t/** The glob(s) to search. One pattern, not one per kind. */\n\tpatterns: string | readonly string[];\n\tcwd?: string;\n\t/**\n\t * Re-import changed modules, for the dev watcher.\n\t *\n\t * A single glob makes discovery more central, not less: a new construct file\n\t * has to be picked up on `add`, not only on `change`.\n\t */\n\tbustCache?: boolean;\n\t/**\n\t * Filled in with where each construct was found, when provided.\n\t *\n\t * Discovery is the only thing that knows: it globbed the files and imported\n\t * them. Everything downstream that needs to *write* an import — the build,\n\t * generating a server entry that reads a surface's logger — would otherwise\n\t * have to be told the path in config, which is the string this removes.\n\t *\n\t * An out-parameter rather than a second return value so that every existing\n\t * caller, which wants the manifest and nothing else, is unchanged.\n\t */\n\tsources?: Record<string, ConstructSource>;\n\t/**\n\t * Filled in, when provided, with the ids each owner's runnables declared an\n\t * edge to — keyed by the surface an endpoint was built from, or the worker\n\t * a cron or subscriber was.\n\t *\n\t * A runnable is not a declaration: a surface's endpoints are found by the\n\t * glob, not listed by the surface, so its node says `endpoints: []` until a\n\t * build folds the routes in. Anything deciding what an app's process reaches\n\t * — which keys its container is given — needs those edges before any build,\n\t * and discovery is already importing the files they are in.\n\t */\n\trunnables?: Record<string, string[]>;\n\t/**\n\t * Import the construct modules in this sandbox rather than in this\n\t * process. Defaults to the run's own (`withSandbox`), so a deploy's every\n\t * discovery — the engine's included — happens there; with neither, they\n\t * are imported here, as before.\n\t */\n\tsandbox?: Sandbox;\n}\n\n/** What the discovery worker answers. Checked: the worker ran project code. */\nconst DiscoverAnswer = z.discriminatedUnion('reason', [\n\tz.object({\n\t\treason: z.literal('discovered'),\n\t\tmanifest: z.record(\n\t\t\tz.string(),\n\t\t\tz.object({ id: z.string(), kind: z.string() }).loose(),\n\t\t),\n\t\trunnables: z.record(z.string(), z.array(z.string())),\n\t}),\n\tz.object({ reason: z.literal('live'), paths: z.array(z.string()) }),\n\tz.object({\n\t\treason: z.literal('failed'),\n\t\terror: z\n\t\t\t.object({\n\t\t\t\tname: z.string(),\n\t\t\t\tmessage: z.string(),\n\t\t\t\tid: z.string().optional(),\n\t\t\t\tsources: z.array(z.string()).optional(),\n\t\t\t})\n\t\t\t.loose(),\n\t}),\n]);\n\n/**\n * The manifest, discovered in `sandbox` and handed back as JSON — or\n * `undefined` when it holds something JSON cannot carry and the sandbox is\n * not isolating, for the caller to discover here as before.\n */\nasync function discoverInSandbox(\n\tsandbox: Sandbox,\n\toptions: DiscoverOptions,\n): Promise<ConstructManifest | undefined> {\n\tconst cwd = options.cwd ?? sandbox.root;\n\tconst patterns =\n\t\ttypeof options.patterns === 'string'\n\t\t\t? [options.patterns]\n\t\t\t: [...options.patterns];\n\n\tconst { value, stderr } = await runWorker(sandbox, 'construct discovery', {\n\t\tname: 'discover-worker',\n\t\targs: [JSON.stringify({ patterns, cwd })],\n\t\tcwd,\n\t\ttimeoutMs: DISCOVER_TIMEOUT_MS,\n\t\tschema: DiscoverAnswer,\n\t});\n\n\t// Discovery's own warnings — a glob that matched nothing — are the\n\t// run's, as they would be had it discovered in-process: as written, one\n\t// message, less the newline the worker's `console.warn` ended it with.\n\tif (stderr.trim()) logger.warn(stderr.replace(/\\n$/, ''));\n\n\tswitch (value.reason) {\n\t\tcase 'discovered':\n\t\t\tif (options.runnables) {\n\t\t\t\tfor (const [owner, edges] of Object.entries(value.runnables)) {\n\t\t\t\t\toptions.runnables[owner] = edges;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value.manifest as unknown as ConstructManifest;\n\t\tcase 'failed':\n\t\t\tif (value.error.name === 'DuplicateConstruct' && value.error.id) {\n\t\t\t\tthrow new DuplicateConstruct(value.error.id, value.error.sources ?? []);\n\t\t\t}\n\t\t\tthrow new ConstructDiscoveryFailed(value.error.name, value.error.message);\n\t\tcase 'live':\n\t\t\tif (sandbox.isolating) throw new ConstructsNotSerializable(value.paths);\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * A caller asked for the construct objects (`sources`) or a watcher's\n * re-import under an isolating sandbox, where only data comes back.\n */\nexport class LiveConstructsUnavailable extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'Discovery was asked for the construct objects themselves under an ' +\n\t\t\t\t'isolating sandbox, which hands back only data. Run this step ' +\n\t\t\t\t'without one, or ask only for the manifest.',\n\t\t);\n\t\tthis.name = 'LiveConstructsUnavailable';\n\t}\n}\n\n/** How long discovering a project's constructs may take in a sandbox. */\nconst DISCOVER_TIMEOUT_MS = 60_000;\n\n/** Importing a construct module, or declaring one, threw in the sandbox. */\nexport class ConstructDiscoveryFailed extends Error {\n\tconstructor(\n\t\treadonly errorName: string,\n\t\treadonly detail: string,\n\t) {\n\t\tsuper(`Discovering constructs failed (${errorName}): ${detail}`);\n\t\tthis.name = 'ConstructDiscoveryFailed';\n\t}\n}\n\n/**\n * The constructs' declarations hold something that is not data, and the\n * sandbox they were discovered in hands the deploy nothing but data.\n */\nexport class ConstructsNotSerializable extends Error {\n\tconstructor(readonly paths: readonly string[]) {\n\t\tsuper(\n\t\t\t`The construct manifest holds values that are not plain data at: ` +\n\t\t\t\t`${paths.join(', ')}. Under an isolating sandbox the deploy only ` +\n\t\t\t\t'receives what JSON can carry; deploy with a sandbox that is not ' +\n\t\t\t\t'isolating if the host trusts this project.',\n\t\t);\n\t\tthis.name = 'ConstructsNotSerializable';\n\t}\n}\n\n/** Where a construct was declared, and under what name. */\nexport interface ConstructSource {\n\t/** Absolute path to the module that exported it. */\n\tfile: string;\n\t/** The name it was exported as — what an import statement has to say. */\n\texportName: string;\n\t/**\n\t * The exported construct itself.\n\t *\n\t * What a declaration cannot say — whether it serves itself — the object can\n\t * be asked, and discovery already imported it.\n\t */\n\tconstruct: unknown;\n}\n\n/**\n * Build the construct manifest for a project.\n *\n * Runs the manifest's own validation before returning, so an app is wrong here\n * — where the error names a file — rather than at deploy.\n *\n * @throws {DuplicateConstruct} when two exports claim one id.\n */\nexport async function discover(\n\toptions: DiscoverOptions,\n): Promise<ConstructManifest> {\n\tconst sandbox = options.sandbox ?? activeSandbox();\n\tif (sandbox) {\n\t\tif (!options.sources && !options.bustCache) {\n\t\t\tconst sandboxed = await discoverInSandbox(sandbox, options);\n\t\t\tif (sandboxed) return sandboxed;\n\t\t} else if (sandbox.isolating) {\n\t\t\t// The construct objects themselves, or a re-import for the watcher:\n\t\t\t// neither can cross a sandbox that hands back only data.\n\t\t\tthrow new LiveConstructsUnavailable();\n\t\t}\n\t}\n\n\tconst {\n\t\tpatterns,\n\t\tcwd = process.cwd(),\n\t\tbustCache = false,\n\t\tsources: out,\n\t} = options;\n\n\t// Re-importing user modules re-executes them, and Zod v4 throws on a\n\t// re-registered `.meta({ id })`. Same reason the generators clear it.\n\tif (bustCache) clearZodGlobalRegistry();\n\n\tconst manifest: Record<string, Declaration> = {};\n\t/** Which file declared each id, for the error when two of them do. */\n\tconst sources: Record<string, string> = {};\n\t/**\n\t * Constructs already seen, by identity.\n\t *\n\t * A re-export is the *same object* reached through a second file — ESM\n\t * bindings are live, so `export * from './database.js'` hands back the\n\t * binding rather than a copy. Without this, a barrel file made every\n\t * construct in it appear declared twice, and `constructs/index.ts` is the\n\t * first thing anyone writes in a shared folder.\n\t *\n\t * Identity rather than file is also the more honest rule: what may not\n\t * happen twice is two *different* constructs claiming one id, and that is\n\t * still an error below.\n\t */\n\tconst seen = new WeakSet<object>();\n\n\tconst globs = Array.isArray(patterns) ? [...patterns] : [patterns as string];\n\tconst files = fg.stream(globs, { cwd, absolute: true });\n\n\t/** Matched files, for the diagnostic below. */\n\tlet matched = 0;\n\n\tfor await (const found of files) {\n\t\tmatched++;\n\t\tconst file = found.toString();\n\t\tconst module = await import(bustCache ? `${file}?t=${Date.now()}` : file);\n\n\t\tfor (const [exportName, exported] of Object.entries(module)) {\n\t\t\tif (!isDeclarable(exported)) {\n\t\t\t\tif (options.runnables) recordRunnable(options.runnables, exported);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// The same construct, reached again through a re-export. Skipped\n\t\t\t// rather than re-declared: it has already claimed its id, from the\n\t\t\t// file that defined it.\n\t\t\tif (seen.has(exported as object)) continue;\n\t\t\tseen.add(exported as object);\n\n\t\t\t// A construct that is also something a process runs — a queue and its\n\t\t\t// consumer, built from a worker — reaches what it depends on through\n\t\t\t// that process, exactly as an endpoint or a cron does.\n\t\t\tif (\n\t\t\t\toptions.runnables &&\n\t\t\t\ttypeof (exported as { owner?: unknown }).owner === 'string'\n\t\t\t) {\n\t\t\t\trecordRunnable(options.runnables, exported);\n\t\t\t}\n\n\t\t\tfor (const declaration of exported.declare()) {\n\t\t\t\t// Canonicalise here too: a construct built by hand rather than through\n\t\t\t\t// a constructor is still subject to the same identity rule.\n\t\t\t\tconst id = canonicalId(declaration.id);\n\t\t\t\tconst source = relative(cwd, file);\n\n\t\t\t\tconst claimed = sources[id];\n\t\t\t\tif (claimed !== undefined && claimed !== source) {\n\t\t\t\t\tthrow new DuplicateConstruct(id, [claimed, source]);\n\t\t\t\t}\n\n\t\t\t\tmanifest[id] = { ...declaration, id };\n\t\t\t\tsources[id] = source;\n\t\t\t\tif (out) out[id] = { file, exportName, construct: exported };\n\t\t\t}\n\t\t}\n\t}\n\n\t// Reference integrity before anyone reads it — a schema tenant naming a\n\t// database that was deleted is a manifest error, not a reconcile failure.\n\tassertDerivations(manifest);\n\n\twarnIfNothingFound(globs, matched, Object.keys(manifest).length);\n\n\treturn manifest;\n}\n\n/**\n * Record a runnable's edges under the construct that owns it — the surface an\n * endpoint was built from, or the worker a cron or subscriber was. Anything\n * with no owner, or that is not a runnable at all, is left alone.\n */\nfunction recordRunnable(\n\trunnables: Record<string, string[]>,\n\texported: unknown,\n): void {\n\tif (typeof exported !== 'object' || exported === null) return;\n\n\tconst runnable = exported as {\n\t\tsurface?: { id?: unknown };\n\t\towner?: unknown;\n\t\tconstructs?: unknown;\n\t};\n\tconst owner =\n\t\ttypeof runnable.surface?.id === 'string'\n\t\t\t? runnable.surface.id\n\t\t\t: typeof runnable.owner === 'string'\n\t\t\t\t? runnable.owner\n\t\t\t\t: undefined;\n\tif (!owner || !Array.isArray(runnable.constructs)) return;\n\n\tconst key = canonicalId(owner);\n\tconst edges = runnables[key] ?? [];\n\trunnables[key] = edges;\n\tfor (const id of runnable.constructs) {\n\t\tif (typeof id !== 'string') continue;\n\t\tconst target = canonicalId(id);\n\t\tif (!edges.includes(target)) edges.push(target);\n\t}\n}\n\n/**\n * Say so when a glob was configured and found nothing.\n *\n * The glob is not a filter over declarations already known — it is *how they\n * are found*, by importing what it matches. So a file it misses is a\n * declaration that does not exist, and every symptom of that appears somewhere\n * other than the cause: no container starts, no env key is written, and the\n * application fails on first use against a resource it can see in its own\n * source.\n *\n * Nothing reported it before, because an unmatched file is indistinguishable\n * from a file nobody wrote. These two cases are the ones that are *not*\n * ambiguous — a glob was configured, so something was expected.\n *\n * Silent when no glob is configured at all: that is a project which has not\n * adopted constructs, and has nothing to be missing.\n */\nfunction warnIfNothingFound(\n\tglobs: readonly string[],\n\tmatched: number,\n\tdeclared: number,\n): void {\n\tif (globs.length === 0) return;\n\n\tif (matched === 0) {\n\t\tlogger.warn(\n\t\t\t`\\n⚠️ The constructs glob matched no files, so nothing was declared.\\n` +\n\t\t\t\t` Patterns: ${globs.join(', ')}\\n` +\n\t\t\t\t` Nothing will be provisioned — no containers, no env keys, no ` +\n\t\t\t\t`resources.\\n` +\n\t\t\t\t` A common cause is depth: '*.ts' matches one level, '**/*.ts' ` +\n\t\t\t\t`matches any.`,\n\t\t);\n\t\treturn;\n\t}\n\n\tif (declared === 0) {\n\t\tlogger.warn(\n\t\t\t`\\n⚠️ The constructs glob matched ${matched} file(s) but none declared ` +\n\t\t\t\t`anything.\\n` +\n\t\t\t\t` Patterns: ${globs.join(', ')}\\n` +\n\t\t\t\t` Discovery keeps exports with an 'id' that can 'declare()'. A ` +\n\t\t\t\t`construct that is\\n` +\n\t\t\t\t` built but never exported is invisible to it.`,\n\t\t);\n\t}\n}\n\n/** Two constructs claiming one id. */\nexport class DuplicateConstruct extends Error {\n\t/** The id claimed twice. */\n\treadonly id: string;\n\t/** The files that claimed it. */\n\treadonly sources: readonly string[];\n\n\tconstructor(id: string, sources: readonly string[]) {\n\t\tsuper('Two constructs declare the same id');\n\t\tthis.name = 'DuplicateConstruct';\n\t\tthis.id = id;\n\t\tthis.sources = sources;\n\t}\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
- const require_schemas = require("./schemas-Ckm_aBnF.cjs");
2
+ const require_schemas = require("./schemas-RUlKHu27.cjs");
3
3
  const require_sandbox = require("./sandbox-CL--ZDui.cjs");
4
4
  const require_workerRuntime = require("./workerRuntime-BXfhbe13.cjs");
5
5
  let node_path = require("node:path");
@@ -209,6 +209,7 @@ var SandboxWorkerFailed = class extends Error {
209
209
  * though it had run again.
210
210
  */
211
211
  async function runWorker(sandbox, step, options) {
212
+ if (options.secrets) return startWorker(sandbox, step, options);
212
213
  const key = JSON.stringify([
213
214
  options.name,
214
215
  options.cwd,
@@ -227,6 +228,7 @@ async function startWorker(sandbox, step, options) {
227
228
  },
228
229
  timeoutMs: options.timeoutMs,
229
230
  output: "capture",
231
+ ...options.secrets ? { secrets: options.secrets } : {},
230
232
  ...options.signal ? { signal: options.signal } : {}
231
233
  });
232
234
  const line = result.stdout.split("\n").reverse().find((l) => l.startsWith(require_workerRuntime.WORKER_RESULT_MARKER));
@@ -575,4 +577,4 @@ Object.defineProperty(exports, "withOwningTsconfigJsx", {
575
577
  }
576
578
  });
577
579
 
578
- //# sourceMappingURL=discover-DHdECueV.cjs.map
580
+ //# sourceMappingURL=discover-OEfZ9OkA.cjs.map