@geekmidas/cli 10.0.0-alpha.61 → 10.0.0-alpha.63

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 (202) hide show
  1. package/README.md +2 -0
  2. package/dist/{HostingerProvider-DI_Pr2VE.mjs → HostingerProvider-DBBwpDjn.mjs} +2 -2
  3. package/dist/{HostingerProvider-DI_Pr2VE.mjs.map → HostingerProvider-DBBwpDjn.mjs.map} +1 -1
  4. package/dist/{HostingerProvider-CgDaD8VR.cjs → HostingerProvider-mJ7YruxH.cjs} +2 -2
  5. package/dist/{HostingerProvider-CgDaD8VR.cjs.map → HostingerProvider-mJ7YruxH.cjs.map} +1 -1
  6. package/dist/{LegacyStateStore-JbBVFp_2.cjs → LegacyStateStore-CP7SZwTP.cjs} +2 -2
  7. package/dist/{LegacyStateStore-JbBVFp_2.cjs.map → LegacyStateStore-CP7SZwTP.cjs.map} +1 -1
  8. package/dist/{LegacyStateStore-C7vFAxbu.mjs → LegacyStateStore-Q3GmKOdw.mjs} +2 -2
  9. package/dist/{LegacyStateStore-C7vFAxbu.mjs.map → LegacyStateStore-Q3GmKOdw.mjs.map} +1 -1
  10. package/dist/{LocalStateStore-DfUwQsL8.mjs → LocalStateStore-BGIXcrvX.mjs} +2 -2
  11. package/dist/{LocalStateStore-DfUwQsL8.mjs.map → LocalStateStore-BGIXcrvX.mjs.map} +1 -1
  12. package/dist/{LocalStateStore-DHj_-CQB.cjs → LocalStateStore-sS8mvLeq.cjs} +2 -2
  13. package/dist/{LocalStateStore-DHj_-CQB.cjs.map → LocalStateStore-sS8mvLeq.cjs.map} +1 -1
  14. package/dist/{OpenApiTsGenerator-BSrgw7B0.cjs → OpenApiTsGenerator-CjHWFRDd.cjs} +2 -2
  15. package/dist/{OpenApiTsGenerator-BSrgw7B0.cjs.map → OpenApiTsGenerator-CjHWFRDd.cjs.map} +1 -1
  16. package/dist/{OpenApiTsGenerator-q5B0z8Xg.mjs → OpenApiTsGenerator-CnAwhGxi.mjs} +2 -2
  17. package/dist/{OpenApiTsGenerator-q5B0z8Xg.mjs.map → OpenApiTsGenerator-CnAwhGxi.mjs.map} +1 -1
  18. package/dist/{S3StateStore-xqnpUrzy.cjs → S3StateStore-6jqITH2F.cjs} +2 -2
  19. package/dist/{S3StateStore-xqnpUrzy.cjs.map → S3StateStore-6jqITH2F.cjs.map} +1 -1
  20. package/dist/{S3StateStore-Dq6hHtzY.mjs → S3StateStore-D7l_lWJ3.mjs} +2 -2
  21. package/dist/{S3StateStore-Dq6hHtzY.mjs.map → S3StateStore-D7l_lWJ3.mjs.map} +1 -1
  22. package/dist/{SSMStateStore-5dBRwVlJ.cjs → SSMStateStore-B__F7IJa.cjs} +2 -2
  23. package/dist/{SSMStateStore-5dBRwVlJ.cjs.map → SSMStateStore-B__F7IJa.cjs.map} +1 -1
  24. package/dist/{SSMStateStore-SUmvAbLi.mjs → SSMStateStore-CAQDVpoc.mjs} +2 -2
  25. package/dist/{SSMStateStore-SUmvAbLi.mjs.map → SSMStateStore-CAQDVpoc.mjs.map} +1 -1
  26. package/dist/{bundler-DXATpO1T.cjs → bundler-DLfOn0ls.cjs} +3 -3
  27. package/dist/{bundler-DXATpO1T.cjs.map → bundler-DLfOn0ls.cjs.map} +1 -1
  28. package/dist/{bundler-B5VsKW-_.mjs → bundler-DyWI41Iy.mjs} +2 -2
  29. package/dist/{bundler-B5VsKW-_.mjs.map → bundler-DyWI41Iy.mjs.map} +1 -1
  30. package/dist/{cli-DQdrVkj2.cjs → cli-D-ZM-X2s.cjs} +12 -16
  31. package/dist/cli-D-ZM-X2s.cjs.map +1 -0
  32. package/dist/{cli-DEA_J3Sa.mjs → cli-PkVF28LM.mjs} +10 -14
  33. package/dist/cli-PkVF28LM.mjs.map +1 -0
  34. package/dist/{config-DXnkCEq0.cjs → config-BEJYKd4s.cjs} +132 -18
  35. package/dist/config-BEJYKd4s.cjs.map +1 -0
  36. package/dist/config-C2BUosLm.d.mts +256 -0
  37. package/dist/config-C2BUosLm.d.mts.map +1 -0
  38. package/dist/config-CemHVcIr.d.cts +256 -0
  39. package/dist/config-CemHVcIr.d.cts.map +1 -0
  40. package/dist/{config-C5-EEdmr.mjs → config-LKKCVCnC.mjs} +109 -19
  41. package/dist/config-LKKCVCnC.mjs.map +1 -0
  42. package/dist/config.cjs +6 -2
  43. package/dist/config.d.cts +4 -211
  44. package/dist/config.d.mts +4 -211
  45. package/dist/config.mjs +3 -3
  46. package/dist/define-CHBIEc5j.mjs +94 -0
  47. package/dist/define-CHBIEc5j.mjs.map +1 -0
  48. package/dist/define-Cv_QvDrg.cjs +141 -0
  49. package/dist/define-Cv_QvDrg.cjs.map +1 -0
  50. package/dist/deploy/public.cjs +174 -13
  51. package/dist/deploy/public.cjs.map +1 -0
  52. package/dist/deploy/public.d.cts +200 -292
  53. package/dist/deploy/public.d.cts.map +1 -1
  54. package/dist/deploy/public.d.mts +200 -292
  55. package/dist/deploy/public.d.mts.map +1 -1
  56. package/dist/deploy/public.mjs +136 -3
  57. package/dist/deploy/public.mjs.map +1 -0
  58. package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
  59. package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
  60. package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
  61. package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
  62. package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
  63. package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
  64. package/dist/{deploy-BbJdgQ2b.cjs → deploy-ABBI0lf1.cjs} +169 -561
  65. package/dist/deploy-ABBI0lf1.cjs.map +1 -0
  66. package/dist/deploy-BiMrP9i7.cjs +140 -0
  67. package/dist/deploy-BiMrP9i7.cjs.map +1 -0
  68. package/dist/{deploy-BJcLmVTc.mjs → deploy-CG8bfFij.mjs} +152 -532
  69. package/dist/deploy-CG8bfFij.mjs.map +1 -0
  70. package/dist/deploy-CGW-QY9D.mjs +135 -0
  71. package/dist/deploy-CGW-QY9D.mjs.map +1 -0
  72. package/dist/discover-B6yPpvRV.d.mts +99 -0
  73. package/dist/discover-B6yPpvRV.d.mts.map +1 -0
  74. package/dist/discover-B_IkPukx.d.cts +99 -0
  75. package/dist/discover-B_IkPukx.d.cts.map +1 -0
  76. package/dist/discover-BaT6bpnA.mjs +614 -0
  77. package/dist/discover-BaT6bpnA.mjs.map +1 -0
  78. package/dist/discover-C_6COHEv.cjs +729 -0
  79. package/dist/discover-C_6COHEv.cjs.map +1 -0
  80. package/dist/dokploy-CwdmlyQL.mjs +32 -0
  81. package/dist/dokploy-CwdmlyQL.mjs.map +1 -0
  82. package/dist/dokploy-QJxMhxdf.cjs +32 -0
  83. package/dist/dokploy-QJxMhxdf.cjs.map +1 -0
  84. package/dist/{encryption-DaA9gRXr.mjs → encryption-CbQG_ayW.mjs} +4 -4
  85. package/dist/{encryption-DaA9gRXr.mjs.map → encryption-CbQG_ayW.mjs.map} +1 -1
  86. package/dist/{encryption-ojzUo7-z.cjs → encryption-DXw3jj0c.cjs} +4 -4
  87. package/dist/{encryption-ojzUo7-z.cjs.map → encryption-DXw3jj0c.cjs.map} +1 -1
  88. package/dist/fakes-C9RiT6XG.mjs.map +1 -1
  89. package/dist/fakes-zW-jNAbQ.cjs.map +1 -1
  90. package/dist/{github-Cq57poPj.cjs → github-BH_mETav.cjs} +3 -3
  91. package/dist/{github-Cq57poPj.cjs.map → github-BH_mETav.cjs.map} +1 -1
  92. package/dist/{github-DmCj2u95.mjs → github-ciwbIwVa.mjs} +3 -3
  93. package/dist/{github-DmCj2u95.mjs.map → github-ciwbIwVa.mjs.map} +1 -1
  94. package/dist/{index-UiWCaGzU.d.cts → index-BtXDZQuF.d.cts} +2 -2
  95. package/dist/{index-Da1-oa9W.d.mts.map → index-BtXDZQuF.d.cts.map} +1 -1
  96. package/dist/{index-Da1-oa9W.d.mts → index-DrKzpHl-.d.mts} +2 -2
  97. package/dist/{index-UiWCaGzU.d.cts.map → index-DrKzpHl-.d.mts.map} +1 -1
  98. package/dist/index.cjs +60 -52
  99. package/dist/index.cjs.map +1 -1
  100. package/dist/index.mjs +57 -49
  101. package/dist/index.mjs.map +1 -1
  102. package/dist/{migrate-BScRpCEx.cjs → migrate-6oa9y_f2.cjs} +5 -5
  103. package/dist/{migrate-BScRpCEx.cjs.map → migrate-6oa9y_f2.cjs.map} +1 -1
  104. package/dist/{migrate-5_J5JySj.mjs → migrate-ImBKTBcW.mjs} +5 -5
  105. package/dist/{migrate-5_J5JySj.mjs.map → migrate-ImBKTBcW.mjs.map} +1 -1
  106. package/dist/openapi.cjs +3 -3
  107. package/dist/openapi.d.cts +1 -1
  108. package/dist/openapi.d.mts +1 -1
  109. package/dist/openapi.mjs +3 -3
  110. package/dist/{ready-XlNx-Gbo.cjs → ready-BiG0rt4h.cjs} +3 -3
  111. package/dist/{ready-XlNx-Gbo.cjs.map → ready-BiG0rt4h.cjs.map} +1 -1
  112. package/dist/{ready-DQIy21W5.mjs → ready-Bpdnn2ON.mjs} +3 -3
  113. package/dist/{ready-DQIy21W5.mjs.map → ready-Bpdnn2ON.mjs.map} +1 -1
  114. package/dist/reconcile/public.cjs +1 -1
  115. package/dist/reconcile/public.d.cts +4 -77
  116. package/dist/reconcile/public.d.cts.map +1 -1
  117. package/dist/reconcile/public.d.mts +4 -77
  118. package/dist/reconcile/public.d.mts.map +1 -1
  119. package/dist/reconcile/public.mjs +1 -1
  120. package/dist/resolve-B1T0hUaR.mjs +170 -0
  121. package/dist/resolve-B1T0hUaR.mjs.map +1 -0
  122. package/dist/resolve-xytBTtG4.cjs +217 -0
  123. package/dist/resolve-xytBTtG4.cjs.map +1 -0
  124. package/dist/runtime-CMwtq0AL.cjs +163 -0
  125. package/dist/runtime-CMwtq0AL.cjs.map +1 -0
  126. package/dist/runtime-CXPlkZzs.d.mts +90 -0
  127. package/dist/runtime-CXPlkZzs.d.mts.map +1 -0
  128. package/dist/runtime-DbakJS8u.mjs +134 -0
  129. package/dist/runtime-DbakJS8u.mjs.map +1 -0
  130. package/dist/runtime-Dn_n-29S.d.cts +90 -0
  131. package/dist/runtime-Dn_n-29S.d.cts.map +1 -0
  132. package/dist/sandbox/config-worker.cjs +43 -0
  133. package/dist/sandbox/config-worker.cjs.map +1 -0
  134. package/dist/sandbox/config-worker.d.cts +1 -0
  135. package/dist/sandbox/config-worker.d.mts +1 -0
  136. package/dist/sandbox/config-worker.mjs +44 -0
  137. package/dist/sandbox/config-worker.mjs.map +1 -0
  138. package/dist/sandbox/discover-worker.cjs +44 -0
  139. package/dist/sandbox/discover-worker.cjs.map +1 -0
  140. package/dist/sandbox/discover-worker.d.cts +1 -0
  141. package/dist/sandbox/discover-worker.d.mts +1 -0
  142. package/dist/sandbox/discover-worker.mjs +45 -0
  143. package/dist/sandbox/discover-worker.mjs.map +1 -0
  144. package/dist/sandbox-M8UnLhXE.d.cts +126 -0
  145. package/dist/sandbox-M8UnLhXE.d.cts.map +1 -0
  146. package/dist/sandbox-M8UnLhXE.d.mts +126 -0
  147. package/dist/sandbox-M8UnLhXE.d.mts.map +1 -0
  148. package/dist/{workspace-Bp1xVaOz.mjs → schemas-Ckm_aBnF.cjs} +264 -969
  149. package/dist/schemas-Ckm_aBnF.cjs.map +1 -0
  150. package/dist/{workspace-B64Xk1Mb.cjs → schemas-D2LCF689.mjs} +195 -1155
  151. package/dist/schemas-D2LCF689.mjs.map +1 -0
  152. package/dist/{sniffer-CQmJnNJM.cjs → sniffer-D_SYc_pO.cjs} +379 -214
  153. package/dist/sniffer-D_SYc_pO.cjs.map +1 -0
  154. package/dist/{sniffer-bdleks5l.mjs → sniffer-aO_-s5vq.mjs} +346 -211
  155. package/dist/sniffer-aO_-s5vq.mjs.map +1 -0
  156. package/dist/target/public.cjs +15 -0
  157. package/dist/target/public.d.cts +28 -0
  158. package/dist/target/public.d.cts.map +1 -0
  159. package/dist/target/public.d.mts +28 -0
  160. package/dist/target/public.d.mts.map +1 -0
  161. package/dist/target/public.mjs +4 -0
  162. package/dist/terminal-D0f1u0LG.cjs +576 -0
  163. package/dist/terminal-D0f1u0LG.cjs.map +1 -0
  164. package/dist/terminal-gMxAo9Dj.mjs +517 -0
  165. package/dist/terminal-gMxAo9Dj.mjs.map +1 -0
  166. package/dist/{types-efNLu9xu.d.cts → types-CfLKGfC_.d.mts} +624 -34
  167. package/dist/types-CfLKGfC_.d.mts.map +1 -0
  168. package/dist/{types-Bp1mVxG0.d.mts → types-DIA7Li-J.d.cts} +626 -34
  169. package/dist/types-DIA7Li-J.d.cts.map +1 -0
  170. package/dist/vitest.cjs +2 -2
  171. package/dist/vitest.mjs +2 -2
  172. package/dist/workerRuntime-BXfhbe13.cjs +108 -0
  173. package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
  174. package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
  175. package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
  176. package/dist/workspace/index.cjs +1 -1
  177. package/dist/workspace/index.d.cts +3 -3
  178. package/dist/workspace/index.d.mts +3 -3
  179. package/dist/workspace/index.mjs +1 -1
  180. package/dist/workspace-Dh7rr7l4.mjs +1024 -0
  181. package/dist/workspace-Dh7rr7l4.mjs.map +1 -0
  182. package/dist/workspace-Kl4NG9IH.cjs +1196 -0
  183. package/dist/workspace-Kl4NG9IH.cjs.map +1 -0
  184. package/package.json +23 -13
  185. package/dist/cli-DEA_J3Sa.mjs.map +0 -1
  186. package/dist/cli-DQdrVkj2.cjs.map +0 -1
  187. package/dist/config-C5-EEdmr.mjs.map +0 -1
  188. package/dist/config-DXnkCEq0.cjs.map +0 -1
  189. package/dist/config.d.cts.map +0 -1
  190. package/dist/config.d.mts.map +0 -1
  191. package/dist/deploy-BJcLmVTc.mjs.map +0 -1
  192. package/dist/deploy-BbJdgQ2b.cjs.map +0 -1
  193. package/dist/discover-Bc-4eA_p.cjs +0 -299
  194. package/dist/discover-Bc-4eA_p.cjs.map +0 -1
  195. package/dist/discover-FrYvzkeC.mjs +0 -262
  196. package/dist/discover-FrYvzkeC.mjs.map +0 -1
  197. package/dist/sniffer-CQmJnNJM.cjs.map +0 -1
  198. package/dist/sniffer-bdleks5l.mjs.map +0 -1
  199. package/dist/types-Bp1mVxG0.d.mts.map +0 -1
  200. package/dist/types-efNLu9xu.d.cts.map +0 -1
  201. package/dist/workspace-B64Xk1Mb.cjs.map +0 -1
  202. package/dist/workspace-Bp1xVaOz.mjs.map +0 -1
@@ -1,10 +1,10 @@
1
- const require_sniffer = require("./sniffer-CQmJnNJM.cjs");
2
- const require_home = require("./home-DOzBaWaL.cjs");
3
- const require_discover = require("./discover-Bc-4eA_p.cjs");
4
- const require_config = require("./config-DXnkCEq0.cjs");
5
- const require_workspace = require("./workspace-B64Xk1Mb.cjs");
1
+ const require_sniffer = require("./sniffer-D_SYc_pO.cjs");
2
+ const require_discover = require("./discover-C_6COHEv.cjs");
3
+ const require_config = require("./config-BEJYKd4s.cjs");
4
+ const require_workspace = require("./workspace-Kl4NG9IH.cjs");
6
5
  const require_storage = require("./storage-CSGoC3bK.cjs");
7
6
  const require_store = require("./store-KvNQwYaB.cjs");
7
+ const require_terminal = require("./terminal-D0f1u0LG.cjs");
8
8
  let node_path = require("node:path");
9
9
  let node_fs_promises = require("node:fs/promises");
10
10
  let node_os = require("node:os");
@@ -14,96 +14,6 @@ let _geekmidas_db_pg_roles = require("@geekmidas/db/pg/roles");
14
14
  let pg = require("pg");
15
15
  let _geekmidas_cache_postgres = require("@geekmidas/cache/postgres");
16
16
  let node_dns_promises = require("node:dns/promises");
17
- //#region src/deploy/credentials.ts
18
- /**
19
- * How a deploy gets the credentials it acts with.
20
- *
21
- * `deploy()` never prompts and never reads a terminal: it asks a
22
- * `CredentialProvider` and, when the provider has nothing, stops with
23
- * `MissingCredential` naming what it needed and how to supply it. Whether to
24
- * ask a person, read a vault or fail is the caller's decision — `gkm deploy`
25
- * prompts at a terminal and stores what was typed; a CI job sets the
26
- * environment; a host passes its own provider.
27
- */
28
- /** How to supply each kind, for the error that says it is missing. */
29
- const HOW_TO_PROVIDE = {
30
- dokploy: "Set DOKPLOY_API_TOKEN (and DOKPLOY_ENDPOINT, or deploy.dokploy.endpoint in gkm.config.ts), run `gkm login --provider dokploy`, or pass them through the deploy's CredentialProvider.",
31
- registry: "Add the registry in Dokploy (Settings → Docker Registry) and set deploy.dokploy.registryId, set DOCKER_REGISTRY_USERNAME and DOCKER_REGISTRY_PASSWORD, or run `gkm deploy` at a terminal to be asked for them."
32
- };
33
- /** A deploy needed a credential, and its provider had none. */
34
- var MissingCredential = class extends Error {
35
- kind;
36
- target;
37
- howToProvide;
38
- constructor(kind, target, howToProvide = HOW_TO_PROVIDE[kind]) {
39
- const what = kind === "dokploy" ? `No Dokploy credentials${target ? ` for ${target}` : ""}.` : `Dokploy has no registry for ${target ?? "the configured registry"}, and there are no credentials to create one with.`;
40
- super(`${what} ${howToProvide}`);
41
- this.kind = kind;
42
- this.target = target;
43
- this.howToProvide = howToProvide;
44
- this.name = "MissingCredential";
45
- }
46
- };
47
- /** Whatever was asked for, from the first provider that has it. */
48
- function chainCredentials(...providers) {
49
- return { async get(request, options) {
50
- for (const provider of providers) {
51
- const found = await provider.get(request, options);
52
- if (found) return found;
53
- }
54
- } };
55
- }
56
- /**
57
- * Credentials from the environment, then from what `gkm login` stored. What
58
- * `deploy()` uses when it is handed no provider.
59
- *
60
- * - Dokploy: `DOKPLOY_API_TOKEN` / `DOKPLOY_ENDPOINT`, each falling back to
61
- * the stored login, and the endpoint finally to `deploy.dokploy.endpoint`.
62
- * Each half is read on its own: a token is a secret and belongs in the
63
- * environment, an endpoint is configuration and belongs in the config.
64
- * - Registry: `DOCKER_REGISTRY_USERNAME` / `DOCKER_REGISTRY_PASSWORD`.
65
- */
66
- function storedCredentials(options = {}) {
67
- const env = options.env ?? process.env;
68
- return { async get(asked) {
69
- const request = asked;
70
- switch (request.kind) {
71
- case "dokploy": {
72
- const stored = (await require_sniffer.readCredentials(options.home ? { home: options.home } : void 0)).dokploy;
73
- const token = env.DOKPLOY_API_TOKEN ?? stored?.token;
74
- const endpoint = env.DOKPLOY_ENDPOINT ?? stored?.endpoint ?? request.endpoint;
75
- if (!token || !endpoint) return void 0;
76
- return {
77
- endpoint: endpoint.replace(/\/$/, ""),
78
- token
79
- };
80
- }
81
- case "registry": {
82
- const username = env.DOCKER_REGISTRY_USERNAME;
83
- const password = env.DOCKER_REGISTRY_PASSWORD;
84
- if (!username || !password) return void 0;
85
- return {
86
- username,
87
- password
88
- };
89
- }
90
- }
91
- } };
92
- }
93
- //#endregion
94
- //#region src/deploy/events.ts
95
- /** An error as an event carries it: its name and message, nothing else. */
96
- function eventError(error) {
97
- if (error instanceof Error) return {
98
- name: error.name,
99
- message: error.message
100
- };
101
- return {
102
- name: "Error",
103
- message: String(error)
104
- };
105
- }
106
- //#endregion
107
17
  //#region src/deploy/fromManifest.ts
108
18
  /**
109
19
  * The Dokploy target, read off the construct manifest.
@@ -875,7 +785,7 @@ async function createDnsProvider(options) {
875
785
  if (isDnsProvider(config.provider)) return config.provider;
876
786
  const provider = config.provider;
877
787
  if (provider === "hostinger") {
878
- const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-CgDaD8VR.cjs"));
788
+ const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-mJ7YruxH.cjs"));
879
789
  return new HostingerProvider();
880
790
  }
881
791
  if (provider === "route53") {
@@ -897,7 +807,7 @@ async function createDnsProvider(options) {
897
807
  *
898
808
  * Handles automatic DNS record creation for deployed applications.
899
809
  */
900
- const logger$3 = require_discover.output;
810
+ const logger$2 = require_discover.output;
901
811
  /**
902
812
  * Check if DNS config is legacy format (single domain with `domain` property)
903
813
  */
@@ -934,7 +844,7 @@ function groupHostnamesByDomain(appHostnames, dnsConfig) {
934
844
  for (const [appName, hostname] of appHostnames) {
935
845
  const rootDomain = findRootDomain(hostname, dnsConfig);
936
846
  if (!rootDomain) {
937
- logger$3.log(` ⚠ No DNS config found for hostname: ${hostname}`);
847
+ logger$2.log(` ⚠ No DNS config found for hostname: ${hostname}`);
938
848
  continue;
939
849
  }
940
850
  if (!grouped.has(rootDomain)) grouped.set(rootDomain, /* @__PURE__ */ new Map());
@@ -984,10 +894,10 @@ function generateRequiredRecords(appHostnames, rootDomain, serverIp) {
984
894
  * Print DNS records table
985
895
  */
986
896
  function printDnsRecordsTable(records, rootDomain) {
987
- logger$3.log(`\n 📋 DNS Records for ${rootDomain}:`);
988
- logger$3.log(" ┌─────────────────────────────────────┬──────┬─────────────────┬────────┐");
989
- logger$3.log(" │ Subdomain │ Type │ Value │ Status │");
990
- logger$3.log(" ├─────────────────────────────────────┼──────┼─────────────────┼────────┤");
897
+ logger$2.log(`\n 📋 DNS Records for ${rootDomain}:`);
898
+ logger$2.log(" ┌─────────────────────────────────────┬──────┬─────────────────┬────────┐");
899
+ logger$2.log(" │ Subdomain │ Type │ Value │ Status │");
900
+ logger$2.log(" ├─────────────────────────────────────┼──────┼─────────────────┼────────┤");
991
901
  for (const record of records) {
992
902
  const subdomain = record.subdomain.padEnd(35);
993
903
  const type = record.type.padEnd(4);
@@ -997,18 +907,18 @@ function printDnsRecordsTable(records, rootDomain) {
997
907
  else if (record.created) status = "✓ new";
998
908
  else if (record.existed) status = "✓";
999
909
  else status = "?";
1000
- logger$3.log(` │ ${subdomain} │ ${type} │ ${value} │ ${status.padEnd(6)} │`);
910
+ logger$2.log(` │ ${subdomain} │ ${type} │ ${value} │ ${status.padEnd(6)} │`);
1001
911
  }
1002
- logger$3.log(" └─────────────────────────────────────┴──────┴─────────────────┴────────┘");
912
+ logger$2.log(" └─────────────────────────────────────┴──────┴─────────────────┴────────┘");
1003
913
  }
1004
914
  /**
1005
915
  * Print DNS records in a simple format for manual setup
1006
916
  */
1007
917
  function printDnsRecordsSimple(records, rootDomain) {
1008
- logger$3.log("\n 📋 Required DNS Records:");
1009
- logger$3.log(` Add these A records to your DNS provider (${rootDomain}):\n`);
1010
- for (const record of records) logger$3.log(` ${record.subdomain} → ${record.value} (A record)`);
1011
- logger$3.log("");
918
+ logger$2.log("\n 📋 Required DNS Records:");
919
+ logger$2.log(` Add these A records to your DNS provider (${rootDomain}):\n`);
920
+ for (const record of records) logger$2.log(` ${record.subdomain} → ${record.value} (A record)`);
921
+ logger$2.log("");
1012
922
  }
1013
923
  /**
1014
924
  * Create DNS records for a single domain using its configured provider
@@ -1020,7 +930,7 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
1020
930
  provider = await createDnsProvider({ config: providerConfig });
1021
931
  } catch (error) {
1022
932
  const message = error instanceof Error ? error.message : "Unknown error";
1023
- logger$3.log(` ⚠ Failed to create DNS provider for ${rootDomain}: ${message}`);
933
+ logger$2.log(` ⚠ Failed to create DNS provider for ${rootDomain}: ${message}`);
1024
934
  return records.map((r) => ({
1025
935
  ...r,
1026
936
  error: message
@@ -1074,7 +984,7 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
1074
984
  }
1075
985
  } catch (error) {
1076
986
  const message = error instanceof Error ? error.message : "Unknown error";
1077
- logger$3.log(` ⚠ Failed to create DNS records for ${rootDomain}: ${message}`);
987
+ logger$2.log(` ⚠ Failed to create DNS records for ${rootDomain}: ${message}`);
1078
988
  return records.map((r) => ({
1079
989
  hostname: r.hostname,
1080
990
  subdomain: r.subdomain,
@@ -1101,20 +1011,20 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
1101
1011
  async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
1102
1012
  if (!dnsConfig) return null;
1103
1013
  const normalizedConfig = normalizeDnsConfig(dnsConfig);
1104
- logger$3.log("\n🌐 Setting up DNS records...");
1014
+ logger$2.log("\n🌐 Setting up DNS records...");
1105
1015
  let serverIp;
1106
1016
  try {
1107
1017
  const endpointUrl = new URL(dokployEndpoint);
1108
1018
  serverIp = await resolveHostnameToIp(endpointUrl.hostname);
1109
- logger$3.log(` Server IP: ${serverIp} (from ${endpointUrl.hostname})`);
1019
+ logger$2.log(` Server IP: ${serverIp} (from ${endpointUrl.hostname})`);
1110
1020
  } catch (error) {
1111
1021
  const message = error instanceof Error ? error.message : "Unknown error";
1112
- logger$3.log(` ⚠ Failed to resolve server IP: ${message}`);
1022
+ logger$2.log(` ⚠ Failed to resolve server IP: ${message}`);
1113
1023
  return null;
1114
1024
  }
1115
1025
  const groupedHostnames = groupHostnamesByDomain(appHostnames, normalizedConfig);
1116
1026
  if (groupedHostnames.size === 0) {
1117
- logger$3.log(" No DNS records needed (no hostnames match configured domains)");
1027
+ logger$2.log(" No DNS records needed (no hostnames match configured domains)");
1118
1028
  return {
1119
1029
  records: [],
1120
1030
  success: true,
@@ -1126,22 +1036,22 @@ async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
1126
1036
  for (const [rootDomain, domainHostnames] of groupedHostnames) {
1127
1037
  const providerConfig = normalizedConfig[rootDomain];
1128
1038
  if (!providerConfig) {
1129
- logger$3.log(` ⚠ No provider config for ${rootDomain}`);
1039
+ logger$2.log(` ⚠ No provider config for ${rootDomain}`);
1130
1040
  continue;
1131
1041
  }
1132
1042
  const providerName = typeof providerConfig.provider === "string" ? providerConfig.provider : "custom";
1133
1043
  const requiredRecords = generateRequiredRecords(domainHostnames, rootDomain, serverIp);
1134
1044
  if (requiredRecords.length === 0) continue;
1135
- logger$3.log(` Creating DNS records for ${rootDomain} (${providerName})...`);
1045
+ logger$2.log(` Creating DNS records for ${rootDomain} (${providerName})...`);
1136
1046
  const domainRecords = await createDnsRecordsForDomain(requiredRecords, rootDomain, providerConfig);
1137
1047
  allRecords.push(...domainRecords);
1138
1048
  const created = domainRecords.filter((r) => r.created).length;
1139
1049
  const existed = domainRecords.filter((r) => r.existed).length;
1140
1050
  const failed = domainRecords.filter((r) => r.error).length;
1141
- if (created > 0) logger$3.log(` ✓ Created ${created} DNS record(s) for ${rootDomain}`);
1142
- if (existed > 0) logger$3.log(` ✓ ${existed} record(s) already exist for ${rootDomain}`);
1051
+ if (created > 0) logger$2.log(` ✓ Created ${created} DNS record(s) for ${rootDomain}`);
1052
+ if (existed > 0) logger$2.log(` ✓ ${existed} record(s) already exist for ${rootDomain}`);
1143
1053
  if (failed > 0) {
1144
- logger$3.log(` ⚠ ${failed} record(s) failed for ${rootDomain}`);
1054
+ logger$2.log(` ⚠ ${failed} record(s) failed for ${rootDomain}`);
1145
1055
  hasFailures = true;
1146
1056
  }
1147
1057
  if (state) {
@@ -1178,10 +1088,10 @@ async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
1178
1088
  */
1179
1089
  async function verifyDnsRecords(appHostnames, serverIp, state) {
1180
1090
  const results = [];
1181
- logger$3.log("\n🔍 Verifying DNS records...");
1091
+ logger$2.log("\n🔍 Verifying DNS records...");
1182
1092
  for (const [appName, hostname] of appHostnames) {
1183
1093
  if (require_sniffer.isDnsVerified(state, hostname, serverIp)) {
1184
- logger$3.log(` ✓ ${hostname} (previously verified)`);
1094
+ logger$2.log(` ✓ ${hostname} (previously verified)`);
1185
1095
  results.push({
1186
1096
  hostname,
1187
1097
  appName,
@@ -1195,7 +1105,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
1195
1105
  const resolvedIp = await resolveHostnameToIp(hostname);
1196
1106
  if (resolvedIp === serverIp) {
1197
1107
  require_sniffer.setDnsVerification(state, hostname, serverIp);
1198
- logger$3.log(` ✓ ${hostname} → ${resolvedIp}`);
1108
+ logger$2.log(` ✓ ${hostname} → ${resolvedIp}`);
1199
1109
  results.push({
1200
1110
  hostname,
1201
1111
  appName,
@@ -1204,7 +1114,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
1204
1114
  expectedIp: serverIp
1205
1115
  });
1206
1116
  } else {
1207
- logger$3.log(` ⚠ ${hostname} resolves to ${resolvedIp}, expected ${serverIp}`);
1117
+ logger$2.log(` ⚠ ${hostname} resolves to ${resolvedIp}, expected ${serverIp}`);
1208
1118
  results.push({
1209
1119
  hostname,
1210
1120
  appName,
@@ -1215,7 +1125,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
1215
1125
  }
1216
1126
  } catch (error) {
1217
1127
  const message = error instanceof Error ? error.message : "Unknown error";
1218
- logger$3.log(` ⚠ ${hostname} DNS not propagated (${message})`);
1128
+ logger$2.log(` ⚠ ${hostname} DNS not propagated (${message})`);
1219
1129
  results.push({
1220
1130
  hostname,
1221
1131
  appName,
@@ -1229,14 +1139,14 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
1229
1139
  const skipped = results.filter((r) => r.skipped).length;
1230
1140
  const pending = results.filter((r) => !r.verified).length;
1231
1141
  if (pending > 0) {
1232
- logger$3.log(`\n ${verified} verified, ${pending} pending propagation`);
1233
- logger$3.log(" DNS changes may take 5-30 minutes to propagate");
1234
- } else if (skipped > 0) logger$3.log(` ${verified} verified (${skipped} from cache)`);
1142
+ logger$2.log(`\n ${verified} verified, ${pending} pending propagation`);
1143
+ logger$2.log(" DNS changes may take 5-30 minutes to propagate");
1144
+ } else if (skipped > 0) logger$2.log(` ${verified} verified (${skipped} from cache)`);
1235
1145
  return results;
1236
1146
  }
1237
1147
  //#endregion
1238
1148
  //#region src/deploy/docker.ts
1239
- const logger$2 = require_discover.output;
1149
+ const logger$1 = require_discover.output;
1240
1150
  /**
1241
1151
  * The id the Dockerfile templates mount the encrypted credentials under:
1242
1152
  * `RUN --mount=type=secret,id=gkm_credentials`.
@@ -1299,8 +1209,8 @@ async function writeCredentialsFile(credentials) {
1299
1209
  * @param credentials - Encrypted credentials, passed as a build secret
1300
1210
  */
1301
1211
  async function buildImage(imageRef, buildArgs, credentials, { cwd, signal, stdio }) {
1302
- logger$2.log(`\n🔨 Building Docker image: ${imageRef}`);
1303
- logger$2.log(" Generating Dockerfile for the pre-built bundle...");
1212
+ logger$1.log(`\n🔨 Building Docker image: ${imageRef}`);
1213
+ logger$1.log(" Generating Dockerfile for the pre-built bundle...");
1304
1214
  await require_sniffer.dockerCommand({
1305
1215
  slim: true,
1306
1216
  cwd
@@ -1322,7 +1232,7 @@ async function buildImage(imageRef, buildArgs, credentials, { cwd, signal, stdio
1322
1232
  ...signal ? { signal } : {},
1323
1233
  ...stdio ? { stdio } : {}
1324
1234
  });
1325
- logger$2.log(`✅ Image built: ${imageRef}`);
1235
+ logger$1.log(`✅ Image built: ${imageRef}`);
1326
1236
  } catch (error) {
1327
1237
  throw new require_sniffer.DockerBuildFailed(imageRef, error);
1328
1238
  } finally {
@@ -1333,14 +1243,14 @@ async function buildImage(imageRef, buildArgs, credentials, { cwd, signal, stdio
1333
1243
  * Push Docker image to registry
1334
1244
  */
1335
1245
  async function pushImage(imageRef, { cwd, signal, stdio }) {
1336
- logger$2.log(`\n☁️ Pushing image: ${imageRef}`);
1246
+ logger$1.log(`\n☁️ Pushing image: ${imageRef}`);
1337
1247
  try {
1338
1248
  await require_sniffer.run("docker", ["push", imageRef], {
1339
1249
  cwd,
1340
1250
  ...signal ? { signal } : {},
1341
1251
  ...stdio ? { stdio } : {}
1342
1252
  });
1343
- logger$2.log(`✅ Image pushed: ${imageRef}`);
1253
+ logger$1.log(`✅ Image pushed: ${imageRef}`);
1344
1254
  } catch (error) {
1345
1255
  throw new require_sniffer.DockerPushFailed(imageRef, error);
1346
1256
  }
@@ -1390,17 +1300,17 @@ async function deployDocker(options) {
1390
1300
  await buildImage(imageRef, buildArgs, credentials, docker);
1391
1301
  let digest;
1392
1302
  if (!skipPush) {
1393
- if (!config.registry) logger$2.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
1303
+ if (!config.registry) logger$1.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
1394
1304
  else {
1395
1305
  await pushImage(imageRef, docker);
1396
1306
  digest = await pushedDigest(imageRef, docker);
1397
1307
  }
1398
1308
  }
1399
- logger$2.log("\n✅ Docker deployment ready!");
1400
- logger$2.log(`\n📋 Deployment details:`);
1401
- logger$2.log(` Image: ${imageRef}`);
1402
- logger$2.log(` Stage: ${stage}`);
1403
- if (masterKey) logger$2.log(`\n🔐 Run the container with GKM_MASTER_KEY set to the key with fingerprint ${require_sniffer.keyFingerprint(masterKey)}.`);
1309
+ logger$1.log("\n✅ Docker deployment ready!");
1310
+ logger$1.log(`\n📋 Deployment details:`);
1311
+ logger$1.log(` Image: ${imageRef}`);
1312
+ logger$1.log(` Stage: ${stage}`);
1313
+ if (masterKey) logger$1.log(`\n🔐 Run the container with GKM_MASTER_KEY set to the key with fingerprint ${require_sniffer.keyFingerprint(masterKey)}.`);
1404
1314
  return {
1405
1315
  imageRef,
1406
1316
  ...digest ? { digest } : {},
@@ -1911,83 +1821,6 @@ function generateSecretsReport(encryptedApps, sniffedApps) {
1911
1821
  };
1912
1822
  }
1913
1823
  //#endregion
1914
- //#region src/deploy/terminal.ts
1915
- /**
1916
- * The credentials `gkm deploy` can ask a person for. CLI layer only.
1917
- *
1918
- * `deploy()` asks its `CredentialProvider` and stops with `MissingCredential`
1919
- * when the answer is nothing. At a terminal, `gkm deploy` would rather ask:
1920
- * this provider reads the environment and the stored login first, and only
1921
- * when both are empty prompts — and stores a Dokploy login it validated, so
1922
- * the next deploy does not ask again. With no terminal it answers nothing, and
1923
- * the deploy says what was missing instead of waiting on a prompt nobody sees.
1924
- */
1925
- const logger$1 = require_discover.output;
1926
- /** What answers a deploy prompt without a terminal. */
1927
- const INSTEAD = "Please configure manually.";
1928
- /** The Dokploy URL typed at the prompt is not a URL. */
1929
- var DokployEndpointInvalid = class extends Error {
1930
- endpoint;
1931
- constructor(endpoint) {
1932
- super("Invalid URL format");
1933
- this.endpoint = endpoint;
1934
- this.name = "DokployEndpointInvalid";
1935
- }
1936
- };
1937
- /** Dokploy refused the token typed at the prompt; nothing was stored. */
1938
- var DokployTokenRejected = class extends Error {
1939
- endpoint;
1940
- constructor(endpoint) {
1941
- super("Invalid credentials. Please check your token.");
1942
- this.endpoint = endpoint;
1943
- this.name = "DokployTokenRejected";
1944
- }
1945
- };
1946
- /** Asks the person at the terminal for what nothing else supplied. */
1947
- function asking() {
1948
- return { async get(asked) {
1949
- if (!require_sniffer.canPrompt()) return void 0;
1950
- const request = asked;
1951
- if (request.kind === "dokploy") {
1952
- logger$1.log("\n📋 Dokploy credentials not found. Let's set them up.");
1953
- const endpoint = (await require_sniffer.prompt("Dokploy URL (e.g., https://dokploy.example.com): ", { instead: INSTEAD })).replace(/\/$/, "");
1954
- try {
1955
- new URL(endpoint);
1956
- } catch {
1957
- throw new DokployEndpointInvalid(endpoint);
1958
- }
1959
- logger$1.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
1960
- const token = await require_sniffer.prompt("API Token: ", {
1961
- hidden: true,
1962
- instead: INSTEAD
1963
- });
1964
- logger$1.log("\nValidating credentials...");
1965
- if (!await require_sniffer.validateDokployToken(endpoint, token)) throw new DokployTokenRejected(endpoint);
1966
- await require_sniffer.storeDokployCredentials(token, endpoint);
1967
- logger$1.log("✓ Credentials saved");
1968
- return {
1969
- endpoint,
1970
- token
1971
- };
1972
- }
1973
- logger$1.log(` Dokploy has no registry for ${request.url}. Let's create one.`);
1974
- return {
1975
- username: await require_sniffer.prompt("Registry username: ", { instead: INSTEAD }),
1976
- password: await require_sniffer.prompt("Registry password/token: ", {
1977
- hidden: true,
1978
- instead: INSTEAD
1979
- })
1980
- };
1981
- } };
1982
- }
1983
- /**
1984
- * The environment, then the stored login, then — at a terminal — the person
1985
- * running the command.
1986
- */
1987
- function terminalCredentials(base = storedCredentials()) {
1988
- return chainCredentials(base, asking());
1989
- }
1990
- //#endregion
1991
1824
  //#region src/deploy/index.ts
1992
1825
  /**
1993
1826
  * Deploy Module
@@ -2188,22 +2021,6 @@ function getServerHostname(endpoint) {
2188
2021
  return new URL(endpoint).hostname;
2189
2022
  }
2190
2023
  /**
2191
- * Generate image tag from stage and timestamp
2192
- */
2193
- function generateTag(stage) {
2194
- return `${stage}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}`;
2195
- }
2196
- /**
2197
- * The things this deploy creates a container for.
2198
- *
2199
- * A deploy unit is a *declaration*, not a config entry — and since that is now
2200
- * true of every app, not just the ones being deployed, this is the workspace's
2201
- * own derivation under the name the deploy phases call it by.
2202
- */
2203
- function deployUnits(manifest, workspace) {
2204
- return require_config.derivedApps(manifest, workspace);
2205
- }
2206
- /**
2207
2024
  * The variables an app cannot start without.
2208
2025
  *
2209
2026
  * The sniffer reports every key it saw in `requiredEnvVars` and says which of
@@ -2221,26 +2038,6 @@ function requiredOf(requirements) {
2221
2038
  const optional = new Set(requirements.optionalEnvVars);
2222
2039
  return requirements.requiredEnvVars.map((name) => name.endsWith("?") ? name.slice(0, -1) : name).filter((name) => !optional.has(name));
2223
2040
  }
2224
- /** Apps were asked for by name that the workspace does not have. */
2225
- var UnknownDeployApps = class extends Error {
2226
- apps;
2227
- available;
2228
- constructor(apps, available) {
2229
- super(`Unknown apps: ${apps.join(", ")}\nAvailable apps: ${available.join(", ")}`);
2230
- this.apps = apps;
2231
- this.available = available;
2232
- this.name = "UnknownDeployApps";
2233
- }
2234
- };
2235
- /** Every app asked for deploys somewhere other than Dokploy. */
2236
- var NoDeployableApps = class extends Error {
2237
- stage;
2238
- constructor(stage) {
2239
- super("No apps to deploy. All selected apps have unsupported deploy targets.");
2240
- this.stage = stage;
2241
- this.name = "NoDeployableApps";
2242
- }
2243
- };
2244
2041
  /** A backend failed, so the run stopped before deploying anything after it. */
2245
2042
  var BackendDeployFailed = class extends Error {
2246
2043
  app;
@@ -2263,23 +2060,24 @@ var MissingEnvVars = class extends Error {
2263
2060
  this.name = "MissingEnvVars";
2264
2061
  }
2265
2062
  };
2266
- /** Workspace deploys go to Dokploy; another provider was asked for. */
2267
- var DeployProviderUnsupported = class extends Error {
2268
- provider;
2269
- constructor(provider) {
2270
- super(`Workspace deployment only supports Dokploy. Got: ${provider}`);
2271
- this.provider = provider;
2272
- this.name = "DeployProviderUnsupported";
2273
- }
2274
- };
2275
2063
  /** How `resolveProject` found a project, in the journal's words. */
2276
2064
  const PROJECT_VIA = {
2277
2065
  state: "recorded",
2278
2066
  marker: "found",
2279
2067
  created: "created"
2280
2068
  };
2069
+ /** `childOutput` as `spawn` reads it, where it is not the default. */
2070
+ const CHILD_STDIO = {
2071
+ stderr: [
2072
+ "ignore",
2073
+ 2,
2074
+ 2
2075
+ ],
2076
+ ignore: "ignore"
2077
+ };
2281
2078
  /**
2282
- * Deploy every app in a workspace to Dokploy.
2079
+ * Deploy every app in a workspace to Dokploy: the engine under the built-in
2080
+ * `dokploy` target.
2283
2081
  *
2284
2082
  * Two-phase orchestration:
2285
2083
  * - PHASE 1: Deploy backend apps (with encrypted secrets)
@@ -2290,119 +2088,60 @@ const PROJECT_VIA = {
2290
2088
  * - Only GKM_MASTER_KEY is injected as Dokploy env var
2291
2089
  * - Frontend apps get public URLs baked in at build time (no secrets)
2292
2090
  *
2293
- * The engine under `deploy()` and `gkm deploy`. It never prompts and never
2294
- * exits: credentials come from `ctx.credentials`, progress goes to
2295
- * `ctx.emit` and to `output`, and every failure is thrown.
2091
+ * The run around it — the target, the apps, the lock, the phase events — is
2092
+ * `runDeploy`'s. This says what it is doing and checks what Dokploy needs.
2296
2093
  *
2297
2094
  * @internal
2298
2095
  */
2299
- async function runDeploy(source, request, ctx) {
2300
- const { stage, tag, apps: selectedApps } = request;
2301
- ctx.emit({
2302
- type: "phase.started",
2303
- phase: "validate"
2304
- });
2305
- const configured = typeof source === "function" ? await source() : source;
2306
- const manifest = await require_discover.discover({
2307
- patterns: require_sniffer.constructGlobs(configured),
2308
- cwd: configured.root
2309
- });
2310
- const units = deployUnits(manifest, configured);
2311
- const workspace = Object.keys(units).length > 0 ? {
2312
- ...configured,
2313
- apps: units
2314
- } : configured;
2315
- const identity = require_store.deployIdentity(workspace, stage);
2096
+ async function validateDokploy(phase) {
2097
+ const { workspace, stage, identity, tag: imageTag } = phase;
2098
+ const ctx = {
2099
+ emit: phase.emit,
2100
+ credentials: phase.credentials,
2101
+ signal: phase.signal,
2102
+ dryRun: phase.dryRun,
2103
+ ...phase.childOutput !== "inherit" ? { stdio: CHILD_STDIO[phase.childOutput] } : {}
2104
+ };
2316
2105
  logger.log(`\n🚀 Deploying workspace "${workspace.name}" to Dokploy...`);
2317
2106
  logger.log(` Stage: ${stage}`);
2318
- const imageTag = tag ?? generateTag(stage);
2319
2107
  logger.log(` Tag: ${imageTag}`);
2320
- const buildOrder = require_workspace.getAppBuildOrder(workspace);
2321
- let appsToDeployNames = buildOrder;
2322
- if (selectedApps && selectedApps.length > 0) {
2323
- const invalidApps = selectedApps.filter((name) => !workspace.apps[name]);
2324
- if (invalidApps.length > 0) throw new UnknownDeployApps(invalidApps, Object.keys(workspace.apps));
2325
- appsToDeployNames = buildOrder.filter((name) => selectedApps.includes(name));
2326
- logger.log(` Deploying apps: ${appsToDeployNames.join(", ")}`);
2327
- } else logger.log(` Deploying all apps: ${appsToDeployNames.join(", ")}`);
2328
- const skipped = [];
2329
- const skip = (app, reason) => {
2330
- skipped.push({
2331
- app,
2332
- reason
2333
- });
2334
- ctx.emit({
2335
- type: "app.skipped",
2336
- app,
2337
- reason
2338
- });
2339
- };
2340
- const dokployApps = appsToDeployNames.filter((name) => {
2341
- const target = workspace.apps[name].resolvedDeployTarget;
2342
- if (target === "sst") {
2343
- const reason = `it deploys with SST — run \`gkm build && sst deploy --stage ${stage}\``;
2344
- logger.log(` ⚠️ Skipping ${name}: ${reason}`);
2345
- skip(name, reason);
2346
- return false;
2347
- }
2348
- if (!require_workspace.isDeployTargetSupported(target)) {
2349
- const reason = require_workspace.getDeployTargetError(target, name);
2350
- logger.log(` ⚠️ Skipping ${name}: ${reason}`);
2351
- skip(name, reason);
2352
- return false;
2353
- }
2354
- return true;
2355
- });
2356
- if (dokployApps.length === 0) throw new NoDeployableApps(stage);
2357
- appsToDeployNames = dokployApps;
2358
- for (const name of appsToDeployNames) if (workspace.apps[name].type === "mobile") skip(name, MOBILE_SKIP_REASON);
2359
- ctx.emit({
2360
- type: "deploy.started",
2361
- stage,
2362
- identity: identity.key,
2363
- tag: imageTag,
2364
- apps: appsToDeployNames.filter((name) => workspace.apps[name].type !== "mobile"),
2365
- dryRun: ctx.dryRun
2366
- });
2367
- const store = await require_sniffer.createStateStore({
2368
- config: workspace.state,
2369
- workspaceRoot: workspace.root,
2370
- workspaceName: workspace.name
2371
- });
2108
+ const askedFor = /* @__PURE__ */ new Set([...phase.apps, ...phase.skipped.map((skipped) => skipped.app)]);
2109
+ const asked = require_workspace.getAppBuildOrder(workspace).filter((name) => askedFor.has(name));
2110
+ logger.log(asked.length === Object.keys(workspace.apps).length ? ` Deploying all apps: ${asked.join(", ")}` : ` Deploying apps: ${asked.join(", ")}`);
2111
+ for (const { app, reason } of phase.skipped) logger.log(` ⚠️ Skipping ${app}: ${reason}`);
2112
+ const appsToDeployNames = [...phase.apps];
2113
+ for (const name of appsToDeployNames) if (workspace.apps[name].type === "mobile") phase.skip(name, MOBILE_SKIP_REASON);
2372
2114
  const run = {
2373
2115
  workspace,
2374
- manifest,
2116
+ manifest: phase.manifest,
2375
2117
  stage,
2376
2118
  imageTag,
2377
2119
  appsToDeployNames,
2378
2120
  identity,
2379
- store,
2380
- skipped,
2121
+ store: phase.state,
2122
+ skipped: phase.skipped,
2123
+ secrets: phase.secrets,
2381
2124
  ctx
2382
2125
  };
2383
- if (ctx.dryRun) return planDeploy(run);
2384
- const lock = await store.lock(stage, { operation: "deploy" });
2385
- try {
2386
- return await deployLocked(run);
2387
- } finally {
2388
- await lock.release();
2389
- }
2126
+ return {
2127
+ ...run,
2128
+ preflight: await preflight(run)
2129
+ };
2390
2130
  }
2391
2131
  /**
2392
2132
  * The stage's secrets and every app's environment requirements. A dry run
2393
2133
  * reads the secrets and generates nothing into the store.
2394
2134
  */
2395
- async function preflight({ workspace, manifest, stage, ctx }) {
2135
+ async function preflight({ workspace, manifest, stage, secrets: secretsStore, ctx }) {
2396
2136
  logger.log("\n🔐 Loading secrets and analyzing environment requirements...");
2397
- const secretsStore = await require_store.secretsStoreFor(workspace, stage, { ...ctx.home ? { home: ctx.home } : {} });
2398
- const stored = await secretsStore.read(stage);
2137
+ const stored = await secretsStore.read();
2399
2138
  if (!stored) logger.log(` ⚠️ No secrets found for stage "${stage}"; starting them`);
2400
2139
  const { secrets: stageSecrets, generated } = require_sniffer.withGeneratedSecrets(stored ?? require_storage.initStageSecrets(stage), manifest);
2401
2140
  if (generated.length > 0) {
2402
- if (ctx.dryRun) logger.log(` 🔑 Would generate for "${stage}" (${secretsStore.name}): ${generated.join(", ")}`);
2141
+ if (ctx.dryRun) logger.log(` 🔑 Would generate for "${stage}" (${secretsStore.store}): ${generated.join(", ")}`);
2403
2142
  else {
2404
- await secretsStore.write(stage, stageSecrets);
2405
- logger.log(` 🔑 Generated for "${stage}" (${secretsStore.name}): ${generated.join(", ")}`);
2143
+ await secretsStore.write(stageSecrets);
2144
+ logger.log(` 🔑 Generated for "${stage}" (${secretsStore.store}): ${generated.join(", ")}`);
2406
2145
  }
2407
2146
  }
2408
2147
  const sniffedApps = await require_sniffer.sniffAllApps(workspace.apps, workspace.root);
@@ -2418,14 +2157,14 @@ async function preflight({ workspace, manifest, stage, ctx }) {
2418
2157
  encryptedSecrets
2419
2158
  };
2420
2159
  }
2421
- /** Everything a deploy does while it holds the stage's lock. */
2422
- async function deployLocked(run) {
2423
- const { workspace, manifest, stage, imageTag, appsToDeployNames, identity, store, ctx } = run;
2424
- const { stageSecrets, sniffedApps, encryptedSecrets } = await preflight(run);
2425
- ctx.emit({
2426
- type: "phase.finished",
2427
- phase: "validate"
2428
- });
2160
+ /**
2161
+ * The project, environment and registry, then what the manifest declares.
2162
+ * Each is looked up — by the id the stage's state recorded, else by name —
2163
+ * before it is created, so a run stopped part way is finished by the next.
2164
+ */
2165
+ async function provisionDokploy(run) {
2166
+ const { workspace, manifest, stage, appsToDeployNames, identity, store, ctx } = run;
2167
+ const { stageSecrets } = run.preflight;
2429
2168
  const changes = [];
2430
2169
  const applied = (change, via) => {
2431
2170
  changes.push(change);
@@ -2435,11 +2174,6 @@ async function deployLocked(run) {
2435
2174
  via
2436
2175
  });
2437
2176
  };
2438
- ctx.signal?.throwIfAborted();
2439
- ctx.emit({
2440
- type: "phase.started",
2441
- phase: "provision"
2442
- });
2443
2177
  const { api, endpoint } = await dokployApi(workspace, ctx);
2444
2178
  logger.log("\n📋 Loading deploy state...");
2445
2179
  const journal = await DeployJournal.open(store, stage, () => require_sniffer.createEmptyState(stage, "", ""));
@@ -2511,7 +2245,7 @@ async function deployLocked(run) {
2511
2245
  kind: "registry",
2512
2246
  url
2513
2247
  }, { signal: ctx.signal });
2514
- if (!login) throw new MissingCredential("registry", url);
2248
+ if (!login) throw new require_terminal.MissingCredential("registry", url);
2515
2249
  const created = await api.createRegistry("Default Registry", url, login.username, login.password);
2516
2250
  registryCreated = true;
2517
2251
  logger.log(` ✓ Registry created: ${created.registryId}`);
@@ -2595,10 +2329,34 @@ async function deployLocked(run) {
2595
2329
  logger.log(` ✓ Postgres backup schedule created (${backupSchedule})`);
2596
2330
  } else logger.log(" ✓ Using existing postgres backup schedule");
2597
2331
  }
2598
- ctx.emit({
2599
- type: "phase.finished",
2600
- phase: "provision"
2601
- });
2332
+ run.provisioned = {
2333
+ api,
2334
+ endpoint,
2335
+ journal,
2336
+ state,
2337
+ projectId: project.projectId,
2338
+ environmentId,
2339
+ registry,
2340
+ registryId,
2341
+ declaredEnv,
2342
+ changes,
2343
+ applied
2344
+ };
2345
+ }
2346
+ /**
2347
+ * Each app's image built and pushed, its application configured and
2348
+ * deployed, and its domain attached: backends first, each failure stopping
2349
+ * the run; then sites, whose build args are the backends' public URLs.
2350
+ *
2351
+ * Building is here rather than in a `build` phase of its own because an
2352
+ * image is built beside its application — a site's build args are resolved
2353
+ * per app, against the backends released before it.
2354
+ */
2355
+ async function releaseDokploy(run) {
2356
+ const { workspace, stage, imageTag, appsToDeployNames, identity, ctx } = run;
2357
+ const { stageSecrets, sniffedApps, encryptedSecrets } = run.preflight;
2358
+ const { api, journal, state, environmentId, registry, registryId, declaredEnv, changes, applied } = run.provisioned;
2359
+ const project = { projectId: run.provisioned.projectId };
2602
2360
  const backendApps = appsToDeployNames.filter((name) => workspace.apps[name].type === "backend");
2603
2361
  const frontendApps = appsToDeployNames.filter((name) => workspace.apps[name].type === "web");
2604
2362
  const publicUrls = {};
@@ -2634,7 +2392,7 @@ async function deployLocked(run) {
2634
2392
  ctx.emit({
2635
2393
  type: "app.failed",
2636
2394
  app: appName,
2637
- error: eventError(error)
2395
+ error: require_terminal.eventError(error)
2638
2396
  });
2639
2397
  };
2640
2398
  /** An image is pushed: worth keeping even if what follows fails. */
@@ -2659,11 +2417,6 @@ async function deployLocked(run) {
2659
2417
  };
2660
2418
  const frontendUrls = [];
2661
2419
  for (const appName of frontendApps) frontendUrls.push(`https://${hostOf(workspace, appName, stage)}`);
2662
- ctx.signal?.throwIfAborted();
2663
- ctx.emit({
2664
- type: "phase.started",
2665
- phase: "release"
2666
- });
2667
2420
  if (backendApps.length > 0) {
2668
2421
  logger.log("\n📦 PHASE 1: Deploying backend applications...");
2669
2422
  for (const appName of backendApps) {
@@ -2829,15 +2582,17 @@ async function deployLocked(run) {
2829
2582
  logger.log("\n📋 Saving deploy state...");
2830
2583
  await journal.save();
2831
2584
  logger.log(" ✓ State saved");
2832
- ctx.emit({
2833
- type: "phase.finished",
2834
- phase: "release"
2835
- });
2836
- ctx.signal?.throwIfAborted();
2837
- ctx.emit({
2838
- type: "phase.started",
2839
- phase: "verify"
2840
- });
2585
+ run.released = {
2586
+ results,
2587
+ publicUrls,
2588
+ appHostnames
2589
+ };
2590
+ }
2591
+ /** DNS records for each released app, and Dokploy's validation of each domain. */
2592
+ async function verifyDokploy(run) {
2593
+ const { workspace } = run;
2594
+ const { api, endpoint, journal, state } = run.provisioned;
2595
+ const { appHostnames } = run.released;
2841
2596
  const dnsConfig = workspace.deploy.dns;
2842
2597
  if (dnsConfig && appHostnames.size > 0) {
2843
2598
  const dnsResult = await orchestrateDns(appHostnames, dnsConfig, endpoint);
@@ -2857,10 +2612,14 @@ async function deployLocked(run) {
2857
2612
  }
2858
2613
  }
2859
2614
  }
2860
- ctx.emit({
2861
- type: "phase.finished",
2862
- phase: "verify"
2863
- });
2615
+ }
2616
+ /** What the run did, printed as the summary it always ended with. */
2617
+ function dokployResult(run) {
2618
+ if (run.result) return run.result;
2619
+ const { stage, identity, imageTag } = run;
2620
+ const { projectId, environmentId, changes } = run.provisioned;
2621
+ const { results, publicUrls } = run.released;
2622
+ const project = { projectId };
2864
2623
  const successCount = results.filter((r) => r.success).length;
2865
2624
  const failedCount = results.filter((r) => !r.success).length;
2866
2625
  logger.log(`\n${"─".repeat(50)}`);
@@ -2882,7 +2641,7 @@ async function deployLocked(run) {
2882
2641
  identity: identity.key,
2883
2642
  tag: imageTag,
2884
2643
  dryRun: false,
2885
- skipped: run.skipped,
2644
+ skipped: [...run.skipped],
2886
2645
  urls: publicUrls,
2887
2646
  changes
2888
2647
  };
@@ -2983,7 +2742,7 @@ async function dokployApi(workspace, ctx) {
2983
2742
  kind: "dokploy",
2984
2743
  ...configured ? { endpoint: configured } : {}
2985
2744
  }, { signal: ctx.signal });
2986
- if (!creds) throw new MissingCredential("dokploy", configured);
2745
+ if (!creds) throw new require_terminal.MissingCredential("dokploy", configured);
2987
2746
  return {
2988
2747
  api: new require_sniffer.DokployApi({
2989
2748
  baseUrl: creds.endpoint,
@@ -3003,19 +2762,9 @@ function hostOf(workspace, appName, stage) {
3003
2762
  * else: no lock, no state written, no secret generated, no Dokploy resource
3004
2763
  * created or changed, no image built or pushed.
3005
2764
  */
3006
- async function planDeploy(run) {
2765
+ async function planDokploy(run) {
3007
2766
  const { workspace, manifest, stage, imageTag, appsToDeployNames, identity } = run;
3008
2767
  const { ctx } = run;
3009
- await preflight(run);
3010
- ctx.emit({
3011
- type: "phase.finished",
3012
- phase: "validate"
3013
- });
3014
- ctx.signal?.throwIfAborted();
3015
- ctx.emit({
3016
- type: "phase.started",
3017
- phase: "plan"
3018
- });
3019
2768
  logger.log("\n🔎 Dry run: nothing will be created, changed, built or pushed.");
3020
2769
  const changes = [];
3021
2770
  const plan = (change, detail) => {
@@ -3130,11 +2879,7 @@ async function planDeploy(run) {
3130
2879
  }
3131
2880
  const creates = changes.filter((c) => c.action !== "reuse").length;
3132
2881
  logger.log(`\n✅ Dry run complete: ${creates} to create or build, ${changes.length - creates} to reuse.`);
3133
- ctx.emit({
3134
- type: "phase.finished",
3135
- phase: "plan"
3136
- });
3137
- return {
2882
+ run.result = {
3138
2883
  apps,
3139
2884
  projectId: project?.projectId ?? "",
3140
2885
  environmentId: environment?.environmentId ?? "",
@@ -3144,7 +2889,7 @@ async function planDeploy(run) {
3144
2889
  identity: identity.key,
3145
2890
  tag: imageTag,
3146
2891
  dryRun: true,
3147
- skipped: run.skipped,
2892
+ skipped: [...run.skipped],
3148
2893
  urls,
3149
2894
  changes
3150
2895
  };
@@ -3152,161 +2897,18 @@ async function planDeploy(run) {
3152
2897
  /** Why a mobile app is left out of a Dokploy deploy. */
3153
2898
  const MOBILE_SKIP_REASON = "deploys via its framework toolchain";
3154
2899
  //#endregion
3155
- //#region src/deploy/deploy.ts
3156
- /**
3157
- * `deploy()`: a deploy as a library call.
3158
- *
3159
- * `gkm deploy` could only be driven from an interactive terminal: it prompted
3160
- * for what it lacked and exited the process on failure, worked out of
3161
- * `process.cwd()`, and reported progress by printing. Here the caller says
3162
- * where the project is, hands over the credentials and a signal, and gets back
3163
- * a run — events to iterate while it goes, and a structured result at the end.
3164
- * Nothing below this asks a person anything or ends the process; `gkm deploy`
3165
- * is a thin wrapper that does both.
3166
- */
3167
- /**
3168
- * Every event a run emits, kept so that each iteration — however late it
3169
- * starts — sees the run from its first event to its last.
3170
- */
3171
- var EventLog = class {
3172
- events = [];
3173
- closed = false;
3174
- waiting = [];
3175
- push(event) {
3176
- this.events.push(event);
3177
- this.wake();
3178
- }
3179
- close() {
3180
- this.closed = true;
3181
- this.wake();
3182
- }
3183
- wake() {
3184
- const waiting = this.waiting;
3185
- this.waiting = [];
3186
- for (const resume of waiting) resume();
3187
- }
3188
- async *iterate() {
3189
- let next = 0;
3190
- while (true) if (next < this.events.length) yield this.events[next++];
3191
- else if (this.closed) return;
3192
- else await new Promise((resume) => this.waiting.push(resume));
3193
- }
3194
- };
3195
- /** `childOutput` as `spawn` reads it, where it is not the default. */
3196
- const CHILD_STDIO = {
3197
- stderr: [
3198
- "ignore",
3199
- 2,
3200
- 2
3201
- ],
3202
- ignore: "ignore"
3203
- };
3204
- function forward(logger, level, message) {
3205
- if (!logger) return;
3206
- if (level === "info") logger.info(message);
3207
- else if (level === "error" && logger.error) logger.error(message);
3208
- else logger.warn(message);
3209
- }
3210
- /**
3211
- * Deploy a project's stage.
3212
- *
3213
- * ```ts
3214
- * import { deploy } from '@geekmidas/cli/deploy';
3215
- *
3216
- * const run = deploy({ cwd: '/srv/checkouts/shop', stage: 'production' });
3217
- * for await (const event of run) {
3218
- * if (event.type === 'app.deployed') console.log(event.app, event.url);
3219
- * }
3220
- * const result = await run.result;
3221
- * ```
3222
- *
3223
- * The run starts at once; iterating it is optional, and an iteration started
3224
- * late still sees every event from the first.
3225
- */
3226
- function deploy(input) {
3227
- const log = new EventLog();
3228
- const emit = (event) => {
3229
- log.push(event);
3230
- if (event.type === "log") forward(input.logger, event.level, event.message);
3231
- };
3232
- const ctx = {
3233
- emit,
3234
- credentials: input.credentials ?? storedCredentials({ home: input.home ?? require_home.gkmHome() }),
3235
- dryRun: input.dryRun ?? false,
3236
- home: input.home ?? require_home.gkmHome(),
3237
- ...input.signal ? { signal: input.signal } : {},
3238
- ...input.childOutput && input.childOutput !== "inherit" ? { stdio: CHILD_STDIO[input.childOutput] } : {}
3239
- };
3240
- const result = require_discover.withOutput((level, message) => emit({
3241
- type: "log",
3242
- level,
3243
- message
3244
- }), async () => {
3245
- try {
3246
- input.signal?.throwIfAborted();
3247
- const deployed = await runDeploy(() => load(input), {
3248
- stage: input.stage,
3249
- ...input.tag ? { tag: input.tag } : {},
3250
- ...input.apps ? { apps: input.apps } : {}
3251
- }, ctx);
3252
- emit({
3253
- type: "deploy.finished",
3254
- result: deployed
3255
- });
3256
- return deployed;
3257
- } catch (error) {
3258
- emit({
3259
- type: "deploy.failed",
3260
- error: eventError(error)
3261
- });
3262
- throw error;
3263
- } finally {
3264
- log.close();
3265
- }
3266
- });
3267
- result.catch(() => {});
3268
- return {
3269
- result,
3270
- [Symbol.asyncIterator]: () => log.iterate()
3271
- };
3272
- }
3273
- /** The workspace at `input.cwd`, refusing a stage it does not deploy. */
3274
- async function load(input) {
3275
- const { workspace } = await require_config.loadWorkspaceConfig((0, node_path.resolve)(input.cwd));
3276
- require_workspace.assertDeployedStage(workspace.stages, input.stage);
3277
- return workspace;
3278
- }
3279
- //#endregion
3280
2900
  Object.defineProperty(exports, "BackendDeployFailed", {
3281
2901
  enumerable: true,
3282
2902
  get: function() {
3283
2903
  return BackendDeployFailed;
3284
2904
  }
3285
2905
  });
3286
- Object.defineProperty(exports, "DeployProviderUnsupported", {
3287
- enumerable: true,
3288
- get: function() {
3289
- return DeployProviderUnsupported;
3290
- }
3291
- });
3292
- Object.defineProperty(exports, "MissingCredential", {
3293
- enumerable: true,
3294
- get: function() {
3295
- return MissingCredential;
3296
- }
3297
- });
3298
2906
  Object.defineProperty(exports, "MissingEnvVars", {
3299
2907
  enumerable: true,
3300
2908
  get: function() {
3301
2909
  return MissingEnvVars;
3302
2910
  }
3303
2911
  });
3304
- Object.defineProperty(exports, "NoDeployableApps", {
3305
- enumerable: true,
3306
- get: function() {
3307
- return NoDeployableApps;
3308
- }
3309
- });
3310
2912
  Object.defineProperty(exports, "ProjectNotOwned", {
3311
2913
  enumerable: true,
3312
2914
  get: function() {
@@ -3331,35 +2933,41 @@ Object.defineProperty(exports, "RegistryNotFound", {
3331
2933
  return RegistryNotFound;
3332
2934
  }
3333
2935
  });
3334
- Object.defineProperty(exports, "UnknownDeployApps", {
2936
+ Object.defineProperty(exports, "dokployResult", {
2937
+ enumerable: true,
2938
+ get: function() {
2939
+ return dokployResult;
2940
+ }
2941
+ });
2942
+ Object.defineProperty(exports, "planDokploy", {
3335
2943
  enumerable: true,
3336
2944
  get: function() {
3337
- return UnknownDeployApps;
2945
+ return planDokploy;
3338
2946
  }
3339
2947
  });
3340
- Object.defineProperty(exports, "chainCredentials", {
2948
+ Object.defineProperty(exports, "provisionDokploy", {
3341
2949
  enumerable: true,
3342
2950
  get: function() {
3343
- return chainCredentials;
2951
+ return provisionDokploy;
3344
2952
  }
3345
2953
  });
3346
- Object.defineProperty(exports, "deploy", {
2954
+ Object.defineProperty(exports, "releaseDokploy", {
3347
2955
  enumerable: true,
3348
2956
  get: function() {
3349
- return deploy;
2957
+ return releaseDokploy;
3350
2958
  }
3351
2959
  });
3352
- Object.defineProperty(exports, "storedCredentials", {
2960
+ Object.defineProperty(exports, "validateDokploy", {
3353
2961
  enumerable: true,
3354
2962
  get: function() {
3355
- return storedCredentials;
2963
+ return validateDokploy;
3356
2964
  }
3357
2965
  });
3358
- Object.defineProperty(exports, "terminalCredentials", {
2966
+ Object.defineProperty(exports, "verifyDokploy", {
3359
2967
  enumerable: true,
3360
2968
  get: function() {
3361
- return terminalCredentials;
2969
+ return verifyDokploy;
3362
2970
  }
3363
2971
  });
3364
2972
 
3365
- //# sourceMappingURL=deploy-BbJdgQ2b.cjs.map
2973
+ //# sourceMappingURL=deploy-ABBI0lf1.cjs.map