@geekmidas/cli 10.0.0-alpha.82 → 10.0.0-alpha.84

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 (169) hide show
  1. package/dist/{EndpointGenerator-DtnIGafh.mjs → EndpointGenerator-CVc6Oi1Y.mjs} +185 -82
  2. package/dist/EndpointGenerator-CVc6Oi1Y.mjs.map +1 -0
  3. package/dist/{EndpointGenerator-cKlnllIu.cjs → EndpointGenerator-CwLjBCFE.cjs} +203 -82
  4. package/dist/EndpointGenerator-CwLjBCFE.cjs.map +1 -0
  5. package/dist/{LegacyStateStore-Ceq7A_75.mjs → LegacyStateStore-CTsUFLNQ.mjs} +2 -2
  6. package/dist/{LegacyStateStore-Ceq7A_75.mjs.map → LegacyStateStore-CTsUFLNQ.mjs.map} +1 -1
  7. package/dist/{LegacyStateStore-Z-EKUGSX.cjs → LegacyStateStore-EDT2TUSe.cjs} +2 -2
  8. package/dist/{LegacyStateStore-Z-EKUGSX.cjs.map → LegacyStateStore-EDT2TUSe.cjs.map} +1 -1
  9. package/dist/{LocalStateStore-Bocb8dmZ.cjs → LocalStateStore-CdpzTvPn.cjs} +2 -2
  10. package/dist/{LocalStateStore-Bocb8dmZ.cjs.map → LocalStateStore-CdpzTvPn.cjs.map} +1 -1
  11. package/dist/{LocalStateStore-C72bwpG2.mjs → LocalStateStore-D1VfxRuK.mjs} +2 -2
  12. package/dist/{LocalStateStore-C72bwpG2.mjs.map → LocalStateStore-D1VfxRuK.mjs.map} +1 -1
  13. package/dist/{OpenApiTsGenerator-CdUM6Hvv.cjs → OpenApiTsGenerator-B--HV-sW.cjs} +2 -2
  14. package/dist/{OpenApiTsGenerator-CdUM6Hvv.cjs.map → OpenApiTsGenerator-B--HV-sW.cjs.map} +1 -1
  15. package/dist/{OpenApiTsGenerator-ByRPMbBN.mjs → OpenApiTsGenerator-CkvsPdgg.mjs} +2 -2
  16. package/dist/{OpenApiTsGenerator-ByRPMbBN.mjs.map → OpenApiTsGenerator-CkvsPdgg.mjs.map} +1 -1
  17. package/dist/{S3StateStore-35YfcdL_.cjs → S3StateStore-BPM74zwv.cjs} +2 -2
  18. package/dist/{S3StateStore-35YfcdL_.cjs.map → S3StateStore-BPM74zwv.cjs.map} +1 -1
  19. package/dist/{S3StateStore-C9upSW5o.mjs → S3StateStore-DVZ1YuGJ.mjs} +2 -2
  20. package/dist/{S3StateStore-C9upSW5o.mjs.map → S3StateStore-DVZ1YuGJ.mjs.map} +1 -1
  21. package/dist/{SSMStateStore-dOmFO6g1.mjs → SSMStateStore-DLvnGyyl.mjs} +2 -2
  22. package/dist/{SSMStateStore-dOmFO6g1.mjs.map → SSMStateStore-DLvnGyyl.mjs.map} +1 -1
  23. package/dist/{SSMStateStore-W-Ps22AQ.cjs → SSMStateStore-qerm5c36.cjs} +2 -2
  24. package/dist/{SSMStateStore-W-Ps22AQ.cjs.map → SSMStateStore-qerm5c36.cjs.map} +1 -1
  25. package/dist/{SubscriberGenerator-DQZeGkDW.mjs → SubscriberGenerator-BPqQf8fB.mjs} +2 -2
  26. package/dist/{SubscriberGenerator-DQZeGkDW.mjs.map → SubscriberGenerator-BPqQf8fB.mjs.map} +1 -1
  27. package/dist/{SubscriberGenerator-CYriX5BV.cjs → SubscriberGenerator-BVn7cQ-2.cjs} +2 -2
  28. package/dist/{SubscriberGenerator-CYriX5BV.cjs.map → SubscriberGenerator-BVn7cQ-2.cjs.map} +1 -1
  29. package/dist/{add-1T3y6E4M.cjs → add-BQ8v1ZII.cjs} +3 -3
  30. package/dist/{add-1T3y6E4M.cjs.map → add-BQ8v1ZII.cjs.map} +1 -1
  31. package/dist/{add-DnYHJOap.mjs → add-DbnzC7Kl.mjs} +3 -3
  32. package/dist/{add-DnYHJOap.mjs.map → add-DbnzC7Kl.mjs.map} +1 -1
  33. package/dist/{bundler-DlKdxCGh.mjs → bundler-D4030Afw.mjs} +5 -5
  34. package/dist/{bundler-DlKdxCGh.mjs.map → bundler-D4030Afw.mjs.map} +1 -1
  35. package/dist/{bundler-YNvLdvlh.cjs → bundler-DjrRffko.cjs} +5 -5
  36. package/dist/{bundler-YNvLdvlh.cjs.map → bundler-DjrRffko.cjs.map} +1 -1
  37. package/dist/{cli-CWee1-wU.cjs → cli-D8YQAYUX.cjs} +3 -3
  38. package/dist/{cli-CWee1-wU.cjs.map → cli-D8YQAYUX.cjs.map} +1 -1
  39. package/dist/{cli-qMszGvDu.mjs → cli-DwTa9d_8.mjs} +3 -3
  40. package/dist/{cli-qMszGvDu.mjs.map → cli-DwTa9d_8.mjs.map} +1 -1
  41. package/dist/{compose-D4sD4Lgr.mjs → compose-C5wz8mf9.mjs} +64 -24
  42. package/dist/compose-C5wz8mf9.mjs.map +1 -0
  43. package/dist/{compose-qnDyPJNp.cjs → compose-DqWh1TaO.cjs} +64 -24
  44. package/dist/compose-DqWh1TaO.cjs.map +1 -0
  45. package/dist/{config-Mr4rcXFC.d.cts → config-BzIfP8a-.d.cts} +16 -3
  46. package/dist/config-BzIfP8a-.d.cts.map +1 -0
  47. package/dist/{config-L_6NivCp.d.mts → config-DhdzmndX.d.mts} +16 -3
  48. package/dist/config-DhdzmndX.d.mts.map +1 -0
  49. package/dist/config.cjs +1 -1
  50. package/dist/config.d.cts +3 -3
  51. package/dist/config.d.mts +3 -3
  52. package/dist/config.mjs +1 -1
  53. package/dist/deploy/public.cjs +6 -6
  54. package/dist/deploy/public.d.cts +3 -3
  55. package/dist/deploy/public.d.cts.map +1 -1
  56. package/dist/deploy/public.d.mts +3 -3
  57. package/dist/deploy/public.d.mts.map +1 -1
  58. package/dist/deploy/public.mjs +6 -6
  59. package/dist/{deploy-C00DAKOt.mjs → deploy-BwIKGxWH.mjs} +14 -5
  60. package/dist/deploy-BwIKGxWH.mjs.map +1 -0
  61. package/dist/{deploy-CXP2fXvK.cjs → deploy-C8sWg81_.cjs} +14 -5
  62. package/dist/deploy-C8sWg81_.cjs.map +1 -0
  63. package/dist/{dokploy-BHcSmghb.cjs → dokploy-BkRxJbfi.cjs} +2 -2
  64. package/dist/{dokploy-BHcSmghb.cjs.map → dokploy-BkRxJbfi.cjs.map} +1 -1
  65. package/dist/{dokploy-B3zoCmJb.mjs → dokploy-ijjms1-h.mjs} +2 -2
  66. package/dist/{dokploy-B3zoCmJb.mjs.map → dokploy-ijjms1-h.mjs.map} +1 -1
  67. package/dist/{drivers-B4RP2B2O.mjs → drivers-DTZzxeIl.mjs} +2 -2
  68. package/dist/{drivers-B4RP2B2O.mjs.map → drivers-DTZzxeIl.mjs.map} +1 -1
  69. package/dist/{drivers-CJx76mcb.cjs → drivers-LYSdQDmd.cjs} +2 -2
  70. package/dist/{drivers-CJx76mcb.cjs.map → drivers-LYSdQDmd.cjs.map} +1 -1
  71. package/dist/{encryption-DPFljXtM.mjs → encryption-BRcBAmjL.mjs} +3 -3
  72. package/dist/{encryption-DPFljXtM.mjs.map → encryption-BRcBAmjL.mjs.map} +1 -1
  73. package/dist/{encryption-DLin89I_.cjs → encryption-g6PzwwfL.cjs} +3 -3
  74. package/dist/{encryption-DLin89I_.cjs.map → encryption-g6PzwwfL.cjs.map} +1 -1
  75. package/dist/{engine-CgzgIg-_.mjs → engine-BP0CZ5fh.mjs} +33 -13
  76. package/dist/engine-BP0CZ5fh.mjs.map +1 -0
  77. package/dist/{engine-BS3iX9Mu.cjs → engine-DLEJsZ3i.cjs} +33 -13
  78. package/dist/engine-DLEJsZ3i.cjs.map +1 -0
  79. package/dist/{github-D8KVmNRg.cjs → github-B8YjwdLK.cjs} +3 -3
  80. package/dist/{github-D8KVmNRg.cjs.map → github-B8YjwdLK.cjs.map} +1 -1
  81. package/dist/{github-DL4zwJsR.mjs → github-Zs-dVJbR.mjs} +3 -3
  82. package/dist/{github-DL4zwJsR.mjs.map → github-Zs-dVJbR.mjs.map} +1 -1
  83. package/dist/{index-C0UmP_lg.d.mts → index-D1ODeM9s.d.cts} +7 -3
  84. package/dist/index-D1ODeM9s.d.cts.map +1 -0
  85. package/dist/{index-DTEPwLml.d.cts → index-f77HdqN5.d.mts} +7 -3
  86. package/dist/index-f77HdqN5.d.mts.map +1 -0
  87. package/dist/index.cjs +553 -134
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.mjs +553 -134
  90. package/dist/index.mjs.map +1 -1
  91. package/dist/{migrate-DIjG8-QR.cjs → migrate-BfZN1S32.cjs} +3 -3
  92. package/dist/{migrate-DIjG8-QR.cjs.map → migrate-BfZN1S32.cjs.map} +1 -1
  93. package/dist/{migrate-CCejlgU0.mjs → migrate-CdXcX0XR.mjs} +3 -3
  94. package/dist/{migrate-CCejlgU0.mjs.map → migrate-CdXcX0XR.mjs.map} +1 -1
  95. package/dist/{migrate-Cd3kcI7o.mjs → migrate-DOMU4uKe.mjs} +3 -3
  96. package/dist/{migrate-Cd3kcI7o.mjs.map → migrate-DOMU4uKe.mjs.map} +1 -1
  97. package/dist/{migrate-BdKhIJgT.cjs → migrate-FoL_mZIz.cjs} +3 -3
  98. package/dist/{migrate-BdKhIJgT.cjs.map → migrate-FoL_mZIz.cjs.map} +1 -1
  99. package/dist/openapi.cjs +3 -3
  100. package/dist/openapi.d.cts +1 -1
  101. package/dist/openapi.d.mts +1 -1
  102. package/dist/openapi.mjs +3 -3
  103. package/dist/{ready-4kx2pAhm.cjs → ready-BpNbORRB.cjs} +5 -5
  104. package/dist/{ready-4kx2pAhm.cjs.map → ready-BpNbORRB.cjs.map} +1 -1
  105. package/dist/{ready-DhZbZtFw.mjs → ready-b6vm0-W-.mjs} +5 -5
  106. package/dist/{ready-DhZbZtFw.mjs.map → ready-b6vm0-W-.mjs.map} +1 -1
  107. package/dist/reconcile/public.d.cts +1 -1
  108. package/dist/reconcile/public.d.mts +1 -1
  109. package/dist/{resolve-ApSUK_HB.cjs → resolve-T2I-5FcT.cjs} +3 -3
  110. package/dist/{resolve-ApSUK_HB.cjs.map → resolve-T2I-5FcT.cjs.map} +1 -1
  111. package/dist/{resolve-DY9TaVeV.mjs → resolve-r7PAs6ng.mjs} +3 -3
  112. package/dist/{resolve-DY9TaVeV.mjs.map → resolve-r7PAs6ng.mjs.map} +1 -1
  113. package/dist/{rollback-DXU6cr7q.mjs → rollback-BSdxnW3X.mjs} +5 -5
  114. package/dist/{rollback-DXU6cr7q.mjs.map → rollback-BSdxnW3X.mjs.map} +1 -1
  115. package/dist/{rollback-CdGhCk1d.cjs → rollback-CPSDjGse.cjs} +5 -5
  116. package/dist/{rollback-CdGhCk1d.cjs.map → rollback-CPSDjGse.cjs.map} +1 -1
  117. package/dist/{runtime-ekxfPNM-.d.mts → runtime-CNu2C2hB.d.mts} +2 -2
  118. package/dist/{runtime-D6A-C6zh.d.cts.map → runtime-CNu2C2hB.d.mts.map} +1 -1
  119. package/dist/{runtime-D6A-C6zh.d.cts → runtime-DMLgL26v.d.cts} +2 -2
  120. package/dist/{runtime-ekxfPNM-.d.mts.map → runtime-DMLgL26v.d.cts.map} +1 -1
  121. package/dist/{seeds-DbyqaXW4.mjs → seeds-BK8caVMm.mjs} +1707 -1612
  122. package/dist/seeds-BK8caVMm.mjs.map +1 -0
  123. package/dist/{seeds-BLzrSwEr.cjs → seeds-DQ0FG57Z.cjs} +2558 -2421
  124. package/dist/seeds-DQ0FG57Z.cjs.map +1 -0
  125. package/dist/{sniffer-ByWtH28i.mjs → sniffer-CqE_KTTp.mjs} +6 -6
  126. package/dist/{sniffer-ByWtH28i.mjs.map → sniffer-CqE_KTTp.mjs.map} +1 -1
  127. package/dist/{sniffer-BjG-1mlD.cjs → sniffer-hSf5mRgV.cjs} +6 -6
  128. package/dist/{sniffer-BjG-1mlD.cjs.map → sniffer-hSf5mRgV.cjs.map} +1 -1
  129. package/dist/stages-CS1sjcRb.cjs +174 -0
  130. package/dist/stages-CS1sjcRb.cjs.map +1 -0
  131. package/dist/stages-CSXt7N2b.mjs +174 -0
  132. package/dist/stages-CSXt7N2b.mjs.map +1 -0
  133. package/dist/target/public.cjs +1 -1
  134. package/dist/target/public.d.cts +2 -2
  135. package/dist/target/public.d.mts +2 -2
  136. package/dist/target/public.mjs +1 -1
  137. package/dist/{types-DZtj9jeI.d.cts → types-BZn-8ssD.d.mts} +75 -22
  138. package/dist/types-BZn-8ssD.d.mts.map +1 -0
  139. package/dist/{types-BzCavjGt.d.mts → types-DiZj6hqp.d.cts} +76 -21
  140. package/dist/types-DiZj6hqp.d.cts.map +1 -0
  141. package/dist/vitest.cjs +1 -1
  142. package/dist/vitest.mjs +1 -1
  143. package/dist/workspace/index.cjs +2 -1
  144. package/dist/workspace/index.d.cts +3 -3
  145. package/dist/workspace/index.d.mts +3 -3
  146. package/dist/workspace/index.mjs +2 -2
  147. package/dist/{workspace-Bp8FEkF-.cjs → workspace-Bic_R3tz.cjs} +345 -99
  148. package/dist/workspace-Bic_R3tz.cjs.map +1 -0
  149. package/dist/{workspace-BBdqmkch.mjs → workspace-Drz4jsvy.mjs} +314 -98
  150. package/dist/workspace-Drz4jsvy.mjs.map +1 -0
  151. package/package.json +15 -15
  152. package/dist/EndpointGenerator-DtnIGafh.mjs.map +0 -1
  153. package/dist/EndpointGenerator-cKlnllIu.cjs.map +0 -1
  154. package/dist/compose-D4sD4Lgr.mjs.map +0 -1
  155. package/dist/compose-qnDyPJNp.cjs.map +0 -1
  156. package/dist/config-L_6NivCp.d.mts.map +0 -1
  157. package/dist/config-Mr4rcXFC.d.cts.map +0 -1
  158. package/dist/deploy-C00DAKOt.mjs.map +0 -1
  159. package/dist/deploy-CXP2fXvK.cjs.map +0 -1
  160. package/dist/engine-BS3iX9Mu.cjs.map +0 -1
  161. package/dist/engine-CgzgIg-_.mjs.map +0 -1
  162. package/dist/index-C0UmP_lg.d.mts.map +0 -1
  163. package/dist/index-DTEPwLml.d.cts.map +0 -1
  164. package/dist/seeds-BLzrSwEr.cjs.map +0 -1
  165. package/dist/seeds-DbyqaXW4.mjs.map +0 -1
  166. package/dist/types-BzCavjGt.d.mts.map +0 -1
  167. package/dist/types-DZtj9jeI.d.cts.map +0 -1
  168. package/dist/workspace-BBdqmkch.mjs.map +0 -1
  169. package/dist/workspace-Bp8FEkF-.cjs.map +0 -1
@@ -0,0 +1,174 @@
1
+ const require_workspace = require("./workspace-Bic_R3tz.cjs");
2
+ const require_config = require("./config.cjs");
3
+ let node_fs_promises = require("node:fs/promises");
4
+ //#region src/stages/plan.ts
5
+ /**
6
+ * Which stages a workflow run builds and deploys, from the event that started
7
+ * it and the project's `stages`.
8
+ *
9
+ * The rules live here, in tested code, rather than in a workflow's YAML or in
10
+ * the action that runs `gkm stages --github-output`: a project's deploy
11
+ * workflow names no stage, and what it does for each event is decided by the
12
+ * CLI the project installed.
13
+ *
14
+ * | event | build | deploy |
15
+ * | ------------------- | ------------------ | ------------------------------- |
16
+ * | `push` | every deployed | deployed, less the protected |
17
+ * | `release` | none | the protected |
18
+ * | `workflow_dispatch` | none | the one stage named |
19
+ * | anything else | none | none |
20
+ *
21
+ * A push builds every deployed stage, protected ones included, so a release
22
+ * deploys images built from the very commit its tag names; a release and a
23
+ * manual run deploy what a push already built.
24
+ */
25
+ function planStages(stages, input) {
26
+ const kept = stages.protected ?? [];
27
+ switch (input.event) {
28
+ case "push": return {
29
+ build: [...stages.deployed],
30
+ deploy: stages.deployed.filter((stage) => !kept.includes(stage))
31
+ };
32
+ case "release": return {
33
+ build: [],
34
+ deploy: [...kept]
35
+ };
36
+ case "workflow_dispatch": {
37
+ const stage = input.stage?.trim();
38
+ if (!stage) throw new DispatchNamesNoStage(stages.deployed);
39
+ if (!stages.deployed.includes(stage)) throw new require_workspace.UndeclaredStage(stage, stages.deployed);
40
+ return {
41
+ build: [],
42
+ deploy: [stage]
43
+ };
44
+ }
45
+ default: return {
46
+ build: [],
47
+ deploy: []
48
+ };
49
+ }
50
+ }
51
+ /**
52
+ * A manual run with no stage. Refused rather than read as "nothing to do", so
53
+ * a run started with the field left empty fails where it can be seen.
54
+ */
55
+ var DispatchNamesNoStage = class extends Error {
56
+ deployed;
57
+ constructor(deployed) {
58
+ super(`A manual run deploys one stage, and none was given. Run the workflow again with stage set to one of: ${deployed.join(", ") || "nothing yet — gkm.config.ts deploys to no stage"}.`);
59
+ this.deployed = deployed;
60
+ this.name = "DispatchNamesNoStage";
61
+ }
62
+ };
63
+ //#endregion
64
+ //#region src/stages/index.ts
65
+ /**
66
+ * `gkm stages` — the workspace's stages, as gkm.config.ts declares them.
67
+ *
68
+ * ```bash
69
+ * gkm stages # a table
70
+ * gkm stages --json # {"local":"dev","deployed":["prod"],"protected":["prod"]}
71
+ * gkm stages --github-output # a workflow run's build and deploy matrices
72
+ * ```
73
+ *
74
+ * The config is read by the normal loader (and sandbox), so a workflow never
75
+ * parses TypeScript to learn which stages exist. `--github-output` is what the
76
+ * `geekmidas/toolbox/actions/stages` action runs: it writes the stages, and
77
+ * which of them this run builds and deploys, to `$GITHUB_OUTPUT`.
78
+ */
79
+ function stagesJson(stages) {
80
+ return {
81
+ local: stages.local,
82
+ deployed: [...stages.deployed],
83
+ protected: [...stages.protected ?? []]
84
+ };
85
+ }
86
+ /**
87
+ * The region of the workspace's AWS secrets store — `ssm` or
88
+ * `secrets-manager` — or `''` when its deployed stages keep their secrets
89
+ * anywhere else. A job assumes the stage's AWS role only when this is set.
90
+ */
91
+ function awsSecretsRegion(workspace) {
92
+ const store = workspace.secrets?.store;
93
+ if (typeof store !== "object" || store === null) return "";
94
+ if (store.provider === "ssm" || store.provider === "secrets-manager") return store.region;
95
+ return "";
96
+ }
97
+ /**
98
+ * Every output the stages action sets, each a string `fromJSON()` reads, for
99
+ * one workflow run.
100
+ */
101
+ function githubOutputs(workspace, input) {
102
+ const stages = stagesJson(workspace.stages);
103
+ const plan = planStages(workspace.stages, input);
104
+ return {
105
+ local: JSON.stringify(stages.local),
106
+ deployed: JSON.stringify(stages.deployed),
107
+ protected: JSON.stringify(stages.protected),
108
+ build: JSON.stringify(plan.build),
109
+ deploy: JSON.stringify(plan.deploy),
110
+ "has-build": String(plan.build.length > 0),
111
+ "has-deploy": String(plan.deploy.length > 0),
112
+ "aws-region": awsSecretsRegion(workspace)
113
+ };
114
+ }
115
+ /** `name=value` lines, as `$GITHUB_OUTPUT` takes single-line values. */
116
+ function formatGithubOutputs(outputs) {
117
+ return Object.entries(outputs).map(([name, value]) => `${name}=${value}\n`).join("");
118
+ }
119
+ /** A message as a workflow command's data: GitHub reads `%`, CR and LF escaped. */
120
+ function workflowCommandData(message) {
121
+ return message.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
122
+ }
123
+ function table(stages) {
124
+ const rows = [
125
+ ["STAGE", "KIND"],
126
+ [stages.local, "local"],
127
+ ...stages.deployed.map((name) => [name, stages.protected.includes(name) ? "deployed, protected" : "deployed"])
128
+ ];
129
+ const width = Math.max(...rows.map(([name]) => name.length));
130
+ return rows.map(([name, kind]) => `${name.padEnd(width)} ${kind}`).join("\n");
131
+ }
132
+ async function stagesCommand(options, deps = {}) {
133
+ const env = deps.env ?? process.env;
134
+ const log = deps.log ?? ((line) => console.log(line));
135
+ if (!options.githubOutput) {
136
+ const stages = stagesJson((await require_config.loadWorkspaceSettings(deps.cwd)).stages);
137
+ log(options.json ? JSON.stringify(stages) : table(stages));
138
+ return;
139
+ }
140
+ try {
141
+ const file = env.GITHUB_OUTPUT;
142
+ if (!file) throw new GithubOutputNotSet();
143
+ const workspace = await require_config.loadWorkspaceSettings(deps.cwd);
144
+ const event = options.event || env.GITHUB_EVENT_NAME;
145
+ if (!event) throw new GithubEventNotSet();
146
+ const outputs = githubOutputs(workspace, {
147
+ event,
148
+ ...options.stage ? { stage: options.stage } : {}
149
+ });
150
+ await (0, node_fs_promises.appendFile)(file, formatGithubOutputs(outputs));
151
+ log(`${event}: build ${outputs.build}, deploy ${outputs.deploy}`);
152
+ } catch (error) {
153
+ log(`::error title=gkm stages::${workflowCommandData(error instanceof Error ? error.message : String(error))}`);
154
+ throw error;
155
+ }
156
+ }
157
+ /** `--github-output` outside a GitHub Actions step, which sets the file. */
158
+ var GithubOutputNotSet = class extends Error {
159
+ constructor() {
160
+ super("gkm stages --github-output writes to the file GITHUB_OUTPUT names, and it is not set. Run it in a GitHub Actions step, or set GITHUB_OUTPUT to a file to write to.");
161
+ this.name = "GithubOutputNotSet";
162
+ }
163
+ };
164
+ /** No `--event`, and no `GITHUB_EVENT_NAME` to take it from. */
165
+ var GithubEventNotSet = class extends Error {
166
+ constructor() {
167
+ super("gkm stages --github-output plans for an event, and none was given. Pass --event (push, release, workflow_dispatch), or run it in a GitHub Actions step, which sets GITHUB_EVENT_NAME.");
168
+ this.name = "GithubEventNotSet";
169
+ }
170
+ };
171
+ //#endregion
172
+ exports.stagesCommand = stagesCommand;
173
+
174
+ //# sourceMappingURL=stages-CS1sjcRb.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stages-CS1sjcRb.cjs","names":["UndeclaredStage","loadWorkspaceSettings","appendFile"],"sources":["../src/stages/plan.ts","../src/stages/index.ts"],"sourcesContent":["/**\n * Which stages a workflow run builds and deploys, from the event that started\n * it and the project's `stages`.\n *\n * The rules live here, in tested code, rather than in a workflow's YAML or in\n * the action that runs `gkm stages --github-output`: a project's deploy\n * workflow names no stage, and what it does for each event is decided by the\n * CLI the project installed.\n *\n * | event | build | deploy |\n * | ------------------- | ------------------ | ------------------------------- |\n * | `push` | every deployed | deployed, less the protected |\n * | `release` | none | the protected |\n * | `workflow_dispatch` | none | the one stage named |\n * | anything else | none | none |\n *\n * A push builds every deployed stage, protected ones included, so a release\n * deploys images built from the very commit its tag names; a release and a\n * manual run deploy what a push already built.\n */\n\nimport { UndeclaredStage } from '../workspace/stages.js';\nimport type { StagesConfig } from '../workspace/types.js';\n\nexport interface StagePlan {\n\t/** The stages whose images this run builds and pushes. */\n\tbuild: string[];\n\t/** The stages this run deploys. */\n\tdeploy: string[];\n}\n\nexport interface PlanInput {\n\t/** The GitHub event name: `push`, `release`, `workflow_dispatch`, … */\n\tevent: string;\n\t/** The stage a `workflow_dispatch` names. */\n\tstage?: string;\n}\n\nexport function planStages(stages: StagesConfig, input: PlanInput): StagePlan {\n\tconst kept = stages.protected ?? [];\n\n\tswitch (input.event) {\n\t\tcase 'push':\n\t\t\treturn {\n\t\t\t\tbuild: [...stages.deployed],\n\t\t\t\tdeploy: stages.deployed.filter((stage) => !kept.includes(stage)),\n\t\t\t};\n\t\tcase 'release':\n\t\t\treturn { build: [], deploy: [...kept] };\n\t\tcase 'workflow_dispatch': {\n\t\t\tconst stage = input.stage?.trim();\n\t\t\tif (!stage) throw new DispatchNamesNoStage(stages.deployed);\n\t\t\tif (!stages.deployed.includes(stage)) {\n\t\t\t\tthrow new UndeclaredStage(stage, stages.deployed);\n\t\t\t}\n\t\t\treturn { build: [], deploy: [stage] };\n\t\t}\n\t\tdefault:\n\t\t\treturn { build: [], deploy: [] };\n\t}\n}\n\n/**\n * A manual run with no stage. Refused rather than read as \"nothing to do\", so\n * a run started with the field left empty fails where it can be seen.\n */\nexport class DispatchNamesNoStage extends Error {\n\tconstructor(readonly deployed: readonly string[]) {\n\t\tsuper(\n\t\t\t`A manual run deploys one stage, and none was given. Run the workflow again with stage set to one of: ${deployed.join(', ') || 'nothing yet — gkm.config.ts deploys to no stage'}.`,\n\t\t);\n\t\tthis.name = 'DispatchNamesNoStage';\n\t}\n}\n","/**\n * `gkm stages` — the workspace's stages, as gkm.config.ts declares them.\n *\n * ```bash\n * gkm stages # a table\n * gkm stages --json # {\"local\":\"dev\",\"deployed\":[\"prod\"],\"protected\":[\"prod\"]}\n * gkm stages --github-output # a workflow run's build and deploy matrices\n * ```\n *\n * The config is read by the normal loader (and sandbox), so a workflow never\n * parses TypeScript to learn which stages exist. `--github-output` is what the\n * `geekmidas/toolbox/actions/stages` action runs: it writes the stages, and\n * which of them this run builds and deploys, to `$GITHUB_OUTPUT`.\n */\n\nimport { appendFile } from 'node:fs/promises';\nimport { loadWorkspaceSettings } from '../config.js';\nimport type { NormalizedWorkspace, StagesConfig } from '../workspace/types.js';\nimport { planStages } from './plan.js';\n\nexport { DispatchNamesNoStage, type PlanInput, planStages } from './plan.js';\n\nexport interface StagesOptions {\n\t/** Print the stages as JSON. */\n\tjson?: boolean;\n\t/** Write the outputs a deploy workflow reads to `$GITHUB_OUTPUT`. */\n\tgithubOutput?: boolean;\n\t/** The event to plan for; defaults to `GITHUB_EVENT_NAME`. */\n\tevent?: string;\n\t/** The stage a `workflow_dispatch` names. */\n\tstage?: string;\n}\n\nexport interface StagesDeps {\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n\t/** Where lines go; stdout by default. */\n\tlog?: (line: string) => void;\n}\n\n/** The stages, as `gkm stages --json` prints them. */\nexport interface StagesJson {\n\tlocal: string;\n\tdeployed: string[];\n\tprotected: string[];\n}\n\nexport function stagesJson(stages: StagesConfig): StagesJson {\n\treturn {\n\t\tlocal: stages.local,\n\t\tdeployed: [...stages.deployed],\n\t\tprotected: [...(stages.protected ?? [])],\n\t};\n}\n\n/**\n * The region of the workspace's AWS secrets store — `ssm` or\n * `secrets-manager` — or `''` when its deployed stages keep their secrets\n * anywhere else. A job assumes the stage's AWS role only when this is set.\n */\nexport function awsSecretsRegion(workspace: NormalizedWorkspace): string {\n\tconst store = workspace.secrets?.store;\n\tif (typeof store !== 'object' || store === null) return '';\n\tif (store.provider === 'ssm' || store.provider === 'secrets-manager') {\n\t\treturn store.region;\n\t}\n\treturn '';\n}\n\n/**\n * Every output the stages action sets, each a string `fromJSON()` reads, for\n * one workflow run.\n */\nexport function githubOutputs(\n\tworkspace: NormalizedWorkspace,\n\tinput: { event: string; stage?: string },\n): Record<string, string> {\n\tconst stages = stagesJson(workspace.stages);\n\tconst plan = planStages(workspace.stages, input);\n\n\treturn {\n\t\tlocal: JSON.stringify(stages.local),\n\t\tdeployed: JSON.stringify(stages.deployed),\n\t\tprotected: JSON.stringify(stages.protected),\n\t\tbuild: JSON.stringify(plan.build),\n\t\tdeploy: JSON.stringify(plan.deploy),\n\t\t// A matrix over an empty list is an error on GitHub, so a job over one\n\t\t// is skipped on these instead.\n\t\t'has-build': String(plan.build.length > 0),\n\t\t'has-deploy': String(plan.deploy.length > 0),\n\t\t'aws-region': awsSecretsRegion(workspace),\n\t};\n}\n\n/** `name=value` lines, as `$GITHUB_OUTPUT` takes single-line values. */\nexport function formatGithubOutputs(outputs: Record<string, string>): string {\n\treturn Object.entries(outputs)\n\t\t.map(([name, value]) => `${name}=${value}\\n`)\n\t\t.join('');\n}\n\n/** A message as a workflow command's data: GitHub reads `%`, CR and LF escaped. */\nfunction workflowCommandData(message: string): string {\n\treturn message\n\t\t.replaceAll('%', '%25')\n\t\t.replaceAll('\\r', '%0D')\n\t\t.replaceAll('\\n', '%0A');\n}\n\nfunction table(stages: StagesJson): string {\n\tconst rows: [string, string][] = [\n\t\t['STAGE', 'KIND'],\n\t\t[stages.local, 'local'],\n\t\t...stages.deployed.map((name): [string, string] => [\n\t\t\tname,\n\t\t\tstages.protected.includes(name) ? 'deployed, protected' : 'deployed',\n\t\t]),\n\t];\n\tconst width = Math.max(...rows.map(([name]) => name.length));\n\treturn rows\n\t\t.map(([name, kind]) => `${name.padEnd(width)} ${kind}`)\n\t\t.join('\\n');\n}\n\nexport async function stagesCommand(\n\toptions: StagesOptions,\n\tdeps: StagesDeps = {},\n): Promise<void> {\n\tconst env = deps.env ?? process.env;\n\tconst log = deps.log ?? ((line: string) => console.log(line));\n\n\tif (!options.githubOutput) {\n\t\tconst workspace = await loadWorkspaceSettings(deps.cwd);\n\t\tconst stages = stagesJson(workspace.stages);\n\t\tlog(options.json ? JSON.stringify(stages) : table(stages));\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst file = env.GITHUB_OUTPUT;\n\t\tif (!file) throw new GithubOutputNotSet();\n\n\t\tconst workspace = await loadWorkspaceSettings(deps.cwd);\n\t\tconst event = options.event || env.GITHUB_EVENT_NAME;\n\t\tif (!event) throw new GithubEventNotSet();\n\n\t\tconst outputs = githubOutputs(workspace, {\n\t\t\tevent,\n\t\t\t...(options.stage ? { stage: options.stage } : {}),\n\t\t});\n\t\tawait appendFile(file, formatGithubOutputs(outputs));\n\n\t\tlog(`${event}: build ${outputs.build}, deploy ${outputs.deploy}`);\n\t} catch (error) {\n\t\t// Annotated on the run, where whoever started it looks first.\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tlog(`::error title=gkm stages::${workflowCommandData(message)}`);\n\t\tthrow error;\n\t}\n}\n\n/** `--github-output` outside a GitHub Actions step, which sets the file. */\nexport class GithubOutputNotSet extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'gkm stages --github-output writes to the file GITHUB_OUTPUT names, and it is not set. Run it in a GitHub Actions step, or set GITHUB_OUTPUT to a file to write to.',\n\t\t);\n\t\tthis.name = 'GithubOutputNotSet';\n\t}\n}\n\n/** No `--event`, and no `GITHUB_EVENT_NAME` to take it from. */\nexport class GithubEventNotSet extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'gkm stages --github-output plans for an event, and none was given. Pass --event (push, release, workflow_dispatch), or run it in a GitHub Actions step, which sets GITHUB_EVENT_NAME.',\n\t\t);\n\t\tthis.name = 'GithubEventNotSet';\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,174 @@
1
+ import { A as UndeclaredStage } from "./workspace-Drz4jsvy.mjs";
2
+ import { loadWorkspaceSettings } from "./config.mjs";
3
+ import { appendFile } from "node:fs/promises";
4
+ //#region src/stages/plan.ts
5
+ /**
6
+ * Which stages a workflow run builds and deploys, from the event that started
7
+ * it and the project's `stages`.
8
+ *
9
+ * The rules live here, in tested code, rather than in a workflow's YAML or in
10
+ * the action that runs `gkm stages --github-output`: a project's deploy
11
+ * workflow names no stage, and what it does for each event is decided by the
12
+ * CLI the project installed.
13
+ *
14
+ * | event | build | deploy |
15
+ * | ------------------- | ------------------ | ------------------------------- |
16
+ * | `push` | every deployed | deployed, less the protected |
17
+ * | `release` | none | the protected |
18
+ * | `workflow_dispatch` | none | the one stage named |
19
+ * | anything else | none | none |
20
+ *
21
+ * A push builds every deployed stage, protected ones included, so a release
22
+ * deploys images built from the very commit its tag names; a release and a
23
+ * manual run deploy what a push already built.
24
+ */
25
+ function planStages(stages, input) {
26
+ const kept = stages.protected ?? [];
27
+ switch (input.event) {
28
+ case "push": return {
29
+ build: [...stages.deployed],
30
+ deploy: stages.deployed.filter((stage) => !kept.includes(stage))
31
+ };
32
+ case "release": return {
33
+ build: [],
34
+ deploy: [...kept]
35
+ };
36
+ case "workflow_dispatch": {
37
+ const stage = input.stage?.trim();
38
+ if (!stage) throw new DispatchNamesNoStage(stages.deployed);
39
+ if (!stages.deployed.includes(stage)) throw new UndeclaredStage(stage, stages.deployed);
40
+ return {
41
+ build: [],
42
+ deploy: [stage]
43
+ };
44
+ }
45
+ default: return {
46
+ build: [],
47
+ deploy: []
48
+ };
49
+ }
50
+ }
51
+ /**
52
+ * A manual run with no stage. Refused rather than read as "nothing to do", so
53
+ * a run started with the field left empty fails where it can be seen.
54
+ */
55
+ var DispatchNamesNoStage = class extends Error {
56
+ deployed;
57
+ constructor(deployed) {
58
+ super(`A manual run deploys one stage, and none was given. Run the workflow again with stage set to one of: ${deployed.join(", ") || "nothing yet — gkm.config.ts deploys to no stage"}.`);
59
+ this.deployed = deployed;
60
+ this.name = "DispatchNamesNoStage";
61
+ }
62
+ };
63
+ //#endregion
64
+ //#region src/stages/index.ts
65
+ /**
66
+ * `gkm stages` — the workspace's stages, as gkm.config.ts declares them.
67
+ *
68
+ * ```bash
69
+ * gkm stages # a table
70
+ * gkm stages --json # {"local":"dev","deployed":["prod"],"protected":["prod"]}
71
+ * gkm stages --github-output # a workflow run's build and deploy matrices
72
+ * ```
73
+ *
74
+ * The config is read by the normal loader (and sandbox), so a workflow never
75
+ * parses TypeScript to learn which stages exist. `--github-output` is what the
76
+ * `geekmidas/toolbox/actions/stages` action runs: it writes the stages, and
77
+ * which of them this run builds and deploys, to `$GITHUB_OUTPUT`.
78
+ */
79
+ function stagesJson(stages) {
80
+ return {
81
+ local: stages.local,
82
+ deployed: [...stages.deployed],
83
+ protected: [...stages.protected ?? []]
84
+ };
85
+ }
86
+ /**
87
+ * The region of the workspace's AWS secrets store — `ssm` or
88
+ * `secrets-manager` — or `''` when its deployed stages keep their secrets
89
+ * anywhere else. A job assumes the stage's AWS role only when this is set.
90
+ */
91
+ function awsSecretsRegion(workspace) {
92
+ const store = workspace.secrets?.store;
93
+ if (typeof store !== "object" || store === null) return "";
94
+ if (store.provider === "ssm" || store.provider === "secrets-manager") return store.region;
95
+ return "";
96
+ }
97
+ /**
98
+ * Every output the stages action sets, each a string `fromJSON()` reads, for
99
+ * one workflow run.
100
+ */
101
+ function githubOutputs(workspace, input) {
102
+ const stages = stagesJson(workspace.stages);
103
+ const plan = planStages(workspace.stages, input);
104
+ return {
105
+ local: JSON.stringify(stages.local),
106
+ deployed: JSON.stringify(stages.deployed),
107
+ protected: JSON.stringify(stages.protected),
108
+ build: JSON.stringify(plan.build),
109
+ deploy: JSON.stringify(plan.deploy),
110
+ "has-build": String(plan.build.length > 0),
111
+ "has-deploy": String(plan.deploy.length > 0),
112
+ "aws-region": awsSecretsRegion(workspace)
113
+ };
114
+ }
115
+ /** `name=value` lines, as `$GITHUB_OUTPUT` takes single-line values. */
116
+ function formatGithubOutputs(outputs) {
117
+ return Object.entries(outputs).map(([name, value]) => `${name}=${value}\n`).join("");
118
+ }
119
+ /** A message as a workflow command's data: GitHub reads `%`, CR and LF escaped. */
120
+ function workflowCommandData(message) {
121
+ return message.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
122
+ }
123
+ function table(stages) {
124
+ const rows = [
125
+ ["STAGE", "KIND"],
126
+ [stages.local, "local"],
127
+ ...stages.deployed.map((name) => [name, stages.protected.includes(name) ? "deployed, protected" : "deployed"])
128
+ ];
129
+ const width = Math.max(...rows.map(([name]) => name.length));
130
+ return rows.map(([name, kind]) => `${name.padEnd(width)} ${kind}`).join("\n");
131
+ }
132
+ async function stagesCommand(options, deps = {}) {
133
+ const env = deps.env ?? process.env;
134
+ const log = deps.log ?? ((line) => console.log(line));
135
+ if (!options.githubOutput) {
136
+ const stages = stagesJson((await loadWorkspaceSettings(deps.cwd)).stages);
137
+ log(options.json ? JSON.stringify(stages) : table(stages));
138
+ return;
139
+ }
140
+ try {
141
+ const file = env.GITHUB_OUTPUT;
142
+ if (!file) throw new GithubOutputNotSet();
143
+ const workspace = await loadWorkspaceSettings(deps.cwd);
144
+ const event = options.event || env.GITHUB_EVENT_NAME;
145
+ if (!event) throw new GithubEventNotSet();
146
+ const outputs = githubOutputs(workspace, {
147
+ event,
148
+ ...options.stage ? { stage: options.stage } : {}
149
+ });
150
+ await appendFile(file, formatGithubOutputs(outputs));
151
+ log(`${event}: build ${outputs.build}, deploy ${outputs.deploy}`);
152
+ } catch (error) {
153
+ log(`::error title=gkm stages::${workflowCommandData(error instanceof Error ? error.message : String(error))}`);
154
+ throw error;
155
+ }
156
+ }
157
+ /** `--github-output` outside a GitHub Actions step, which sets the file. */
158
+ var GithubOutputNotSet = class extends Error {
159
+ constructor() {
160
+ super("gkm stages --github-output writes to the file GITHUB_OUTPUT names, and it is not set. Run it in a GitHub Actions step, or set GITHUB_OUTPUT to a file to write to.");
161
+ this.name = "GithubOutputNotSet";
162
+ }
163
+ };
164
+ /** No `--event`, and no `GITHUB_EVENT_NAME` to take it from. */
165
+ var GithubEventNotSet = class extends Error {
166
+ constructor() {
167
+ super("gkm stages --github-output plans for an event, and none was given. Pass --event (push, release, workflow_dispatch), or run it in a GitHub Actions step, which sets GITHUB_EVENT_NAME.");
168
+ this.name = "GithubEventNotSet";
169
+ }
170
+ };
171
+ //#endregion
172
+ export { stagesCommand };
173
+
174
+ //# sourceMappingURL=stages-CSXt7N2b.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stages-CSXt7N2b.mjs","names":[],"sources":["../src/stages/plan.ts","../src/stages/index.ts"],"sourcesContent":["/**\n * Which stages a workflow run builds and deploys, from the event that started\n * it and the project's `stages`.\n *\n * The rules live here, in tested code, rather than in a workflow's YAML or in\n * the action that runs `gkm stages --github-output`: a project's deploy\n * workflow names no stage, and what it does for each event is decided by the\n * CLI the project installed.\n *\n * | event | build | deploy |\n * | ------------------- | ------------------ | ------------------------------- |\n * | `push` | every deployed | deployed, less the protected |\n * | `release` | none | the protected |\n * | `workflow_dispatch` | none | the one stage named |\n * | anything else | none | none |\n *\n * A push builds every deployed stage, protected ones included, so a release\n * deploys images built from the very commit its tag names; a release and a\n * manual run deploy what a push already built.\n */\n\nimport { UndeclaredStage } from '../workspace/stages.js';\nimport type { StagesConfig } from '../workspace/types.js';\n\nexport interface StagePlan {\n\t/** The stages whose images this run builds and pushes. */\n\tbuild: string[];\n\t/** The stages this run deploys. */\n\tdeploy: string[];\n}\n\nexport interface PlanInput {\n\t/** The GitHub event name: `push`, `release`, `workflow_dispatch`, … */\n\tevent: string;\n\t/** The stage a `workflow_dispatch` names. */\n\tstage?: string;\n}\n\nexport function planStages(stages: StagesConfig, input: PlanInput): StagePlan {\n\tconst kept = stages.protected ?? [];\n\n\tswitch (input.event) {\n\t\tcase 'push':\n\t\t\treturn {\n\t\t\t\tbuild: [...stages.deployed],\n\t\t\t\tdeploy: stages.deployed.filter((stage) => !kept.includes(stage)),\n\t\t\t};\n\t\tcase 'release':\n\t\t\treturn { build: [], deploy: [...kept] };\n\t\tcase 'workflow_dispatch': {\n\t\t\tconst stage = input.stage?.trim();\n\t\t\tif (!stage) throw new DispatchNamesNoStage(stages.deployed);\n\t\t\tif (!stages.deployed.includes(stage)) {\n\t\t\t\tthrow new UndeclaredStage(stage, stages.deployed);\n\t\t\t}\n\t\t\treturn { build: [], deploy: [stage] };\n\t\t}\n\t\tdefault:\n\t\t\treturn { build: [], deploy: [] };\n\t}\n}\n\n/**\n * A manual run with no stage. Refused rather than read as \"nothing to do\", so\n * a run started with the field left empty fails where it can be seen.\n */\nexport class DispatchNamesNoStage extends Error {\n\tconstructor(readonly deployed: readonly string[]) {\n\t\tsuper(\n\t\t\t`A manual run deploys one stage, and none was given. Run the workflow again with stage set to one of: ${deployed.join(', ') || 'nothing yet — gkm.config.ts deploys to no stage'}.`,\n\t\t);\n\t\tthis.name = 'DispatchNamesNoStage';\n\t}\n}\n","/**\n * `gkm stages` — the workspace's stages, as gkm.config.ts declares them.\n *\n * ```bash\n * gkm stages # a table\n * gkm stages --json # {\"local\":\"dev\",\"deployed\":[\"prod\"],\"protected\":[\"prod\"]}\n * gkm stages --github-output # a workflow run's build and deploy matrices\n * ```\n *\n * The config is read by the normal loader (and sandbox), so a workflow never\n * parses TypeScript to learn which stages exist. `--github-output` is what the\n * `geekmidas/toolbox/actions/stages` action runs: it writes the stages, and\n * which of them this run builds and deploys, to `$GITHUB_OUTPUT`.\n */\n\nimport { appendFile } from 'node:fs/promises';\nimport { loadWorkspaceSettings } from '../config.js';\nimport type { NormalizedWorkspace, StagesConfig } from '../workspace/types.js';\nimport { planStages } from './plan.js';\n\nexport { DispatchNamesNoStage, type PlanInput, planStages } from './plan.js';\n\nexport interface StagesOptions {\n\t/** Print the stages as JSON. */\n\tjson?: boolean;\n\t/** Write the outputs a deploy workflow reads to `$GITHUB_OUTPUT`. */\n\tgithubOutput?: boolean;\n\t/** The event to plan for; defaults to `GITHUB_EVENT_NAME`. */\n\tevent?: string;\n\t/** The stage a `workflow_dispatch` names. */\n\tstage?: string;\n}\n\nexport interface StagesDeps {\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n\t/** Where lines go; stdout by default. */\n\tlog?: (line: string) => void;\n}\n\n/** The stages, as `gkm stages --json` prints them. */\nexport interface StagesJson {\n\tlocal: string;\n\tdeployed: string[];\n\tprotected: string[];\n}\n\nexport function stagesJson(stages: StagesConfig): StagesJson {\n\treturn {\n\t\tlocal: stages.local,\n\t\tdeployed: [...stages.deployed],\n\t\tprotected: [...(stages.protected ?? [])],\n\t};\n}\n\n/**\n * The region of the workspace's AWS secrets store — `ssm` or\n * `secrets-manager` — or `''` when its deployed stages keep their secrets\n * anywhere else. A job assumes the stage's AWS role only when this is set.\n */\nexport function awsSecretsRegion(workspace: NormalizedWorkspace): string {\n\tconst store = workspace.secrets?.store;\n\tif (typeof store !== 'object' || store === null) return '';\n\tif (store.provider === 'ssm' || store.provider === 'secrets-manager') {\n\t\treturn store.region;\n\t}\n\treturn '';\n}\n\n/**\n * Every output the stages action sets, each a string `fromJSON()` reads, for\n * one workflow run.\n */\nexport function githubOutputs(\n\tworkspace: NormalizedWorkspace,\n\tinput: { event: string; stage?: string },\n): Record<string, string> {\n\tconst stages = stagesJson(workspace.stages);\n\tconst plan = planStages(workspace.stages, input);\n\n\treturn {\n\t\tlocal: JSON.stringify(stages.local),\n\t\tdeployed: JSON.stringify(stages.deployed),\n\t\tprotected: JSON.stringify(stages.protected),\n\t\tbuild: JSON.stringify(plan.build),\n\t\tdeploy: JSON.stringify(plan.deploy),\n\t\t// A matrix over an empty list is an error on GitHub, so a job over one\n\t\t// is skipped on these instead.\n\t\t'has-build': String(plan.build.length > 0),\n\t\t'has-deploy': String(plan.deploy.length > 0),\n\t\t'aws-region': awsSecretsRegion(workspace),\n\t};\n}\n\n/** `name=value` lines, as `$GITHUB_OUTPUT` takes single-line values. */\nexport function formatGithubOutputs(outputs: Record<string, string>): string {\n\treturn Object.entries(outputs)\n\t\t.map(([name, value]) => `${name}=${value}\\n`)\n\t\t.join('');\n}\n\n/** A message as a workflow command's data: GitHub reads `%`, CR and LF escaped. */\nfunction workflowCommandData(message: string): string {\n\treturn message\n\t\t.replaceAll('%', '%25')\n\t\t.replaceAll('\\r', '%0D')\n\t\t.replaceAll('\\n', '%0A');\n}\n\nfunction table(stages: StagesJson): string {\n\tconst rows: [string, string][] = [\n\t\t['STAGE', 'KIND'],\n\t\t[stages.local, 'local'],\n\t\t...stages.deployed.map((name): [string, string] => [\n\t\t\tname,\n\t\t\tstages.protected.includes(name) ? 'deployed, protected' : 'deployed',\n\t\t]),\n\t];\n\tconst width = Math.max(...rows.map(([name]) => name.length));\n\treturn rows\n\t\t.map(([name, kind]) => `${name.padEnd(width)} ${kind}`)\n\t\t.join('\\n');\n}\n\nexport async function stagesCommand(\n\toptions: StagesOptions,\n\tdeps: StagesDeps = {},\n): Promise<void> {\n\tconst env = deps.env ?? process.env;\n\tconst log = deps.log ?? ((line: string) => console.log(line));\n\n\tif (!options.githubOutput) {\n\t\tconst workspace = await loadWorkspaceSettings(deps.cwd);\n\t\tconst stages = stagesJson(workspace.stages);\n\t\tlog(options.json ? JSON.stringify(stages) : table(stages));\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst file = env.GITHUB_OUTPUT;\n\t\tif (!file) throw new GithubOutputNotSet();\n\n\t\tconst workspace = await loadWorkspaceSettings(deps.cwd);\n\t\tconst event = options.event || env.GITHUB_EVENT_NAME;\n\t\tif (!event) throw new GithubEventNotSet();\n\n\t\tconst outputs = githubOutputs(workspace, {\n\t\t\tevent,\n\t\t\t...(options.stage ? { stage: options.stage } : {}),\n\t\t});\n\t\tawait appendFile(file, formatGithubOutputs(outputs));\n\n\t\tlog(`${event}: build ${outputs.build}, deploy ${outputs.deploy}`);\n\t} catch (error) {\n\t\t// Annotated on the run, where whoever started it looks first.\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tlog(`::error title=gkm stages::${workflowCommandData(message)}`);\n\t\tthrow error;\n\t}\n}\n\n/** `--github-output` outside a GitHub Actions step, which sets the file. */\nexport class GithubOutputNotSet extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'gkm stages --github-output writes to the file GITHUB_OUTPUT names, and it is not set. Run it in a GitHub Actions step, or set GITHUB_OUTPUT to a file to write to.',\n\t\t);\n\t\tthis.name = 'GithubOutputNotSet';\n\t}\n}\n\n/** No `--event`, and no `GITHUB_EVENT_NAME` to take it from. */\nexport class GithubEventNotSet extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'gkm stages --github-output plans for an event, and none was given. Pass --event (push, release, workflow_dispatch), or run it in a GitHub Actions step, which sets GITHUB_EVENT_NAME.',\n\t\t);\n\t\tthis.name = 'GithubEventNotSet';\n\t}\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_define = require("../define-DzRz8FgH.cjs");
3
- const require_resolve = require("../resolve-ApSUK_HB.cjs");
3
+ const require_resolve = require("../resolve-T2I-5FcT.cjs");
4
4
  const require_provider = require("../provider-C9_-45d5.cjs");
5
5
  exports.DeployTargetNotYetSupported = require_define.DeployTargetNotYetSupported;
6
6
  exports.InvalidTargetOptions = require_resolve.InvalidTargetOptions;
@@ -1,5 +1,5 @@
1
- import { $ as TargetOptionsSchema, G as DeploySecrets, H as DeployFailure, J as DeployTargetEntry, K as DeployTarget, Ot as StageSecrets, Q as TargetOptionsIssue, Tt as StateStore, U as DeployPhaseContext, V as AnyDeployTarget, W as DeployRuntime, X as TargetEvent, Y as DeployTargetLogger, Z as TargetOptions, _t as CredentialKinds, at as ResourceVia, et as DeployEvent, gt as CredentialKind, ht as Credential, it as ResourceChange, kt as DeployIdentity, mt as AwsCredential, nt as DeployEventType, ot as AppDeployResult, q as DeployTargetCapabilities, rt as DeployPhase, st as DeployResult, tt as DeployEventError, vt as CredentialProvider, yt as CredentialRequest } from "../types-DZtj9jeI.cjs";
2
- import { a as TargetRuntimeMismatch, c as DeployTargetNotYetSupported, i as TargetPackageInvalid, l as UnknownDeployTarget, n as InvalidTargetOptions, o as ProviderRemoved, r as TargetEntryInvalid, s as TargetPackageNotFound, t as TargetRuntimeUndeclared } from "../runtime-D6A-C6zh.cjs";
1
+ import { $ as TargetOptions, At as StageSecrets, Dt as StateStore, G as DeployPhaseContext, J as DeployTarget, K as DeployRuntime, Q as TargetEvent, U as AnyDeployTarget, W as DeployFailure, X as DeployTargetEntry, Y as DeployTargetCapabilities, Z as DeployTargetLogger, _t as Credential, at as DeployPhase, bt as CredentialProvider, ct as AppDeployResult, et as TargetOptionsIssue, gt as AwsCredential, it as DeployEventType, jt as DeployIdentity, lt as DeployResult, nt as DeployEvent, ot as ResourceChange, q as DeploySecrets, rt as DeployEventError, st as ResourceVia, tt as TargetOptionsSchema, vt as CredentialKind, xt as CredentialRequest, yt as CredentialKinds } from "../types-DiZj6hqp.cjs";
2
+ import { a as TargetRuntimeMismatch, c as DeployTargetNotYetSupported, i as TargetPackageInvalid, l as UnknownDeployTarget, n as InvalidTargetOptions, o as ProviderRemoved, r as TargetEntryInvalid, s as TargetPackageNotFound, t as TargetRuntimeUndeclared } from "../runtime-DMLgL26v.cjs";
3
3
  //#region src/target/define.d.ts
4
4
  /**
5
5
  * A deploy target, typed from what it is written with: the options from its
@@ -1,5 +1,5 @@
1
- import { $ as TargetOptionsSchema, G as DeploySecrets, H as DeployFailure, J as DeployTargetEntry, K as DeployTarget, Ot as StageSecrets, Q as TargetOptionsIssue, Tt as StateStore, U as DeployPhaseContext, V as AnyDeployTarget, W as DeployRuntime, X as TargetEvent, Y as DeployTargetLogger, Z as TargetOptions, _t as CredentialKinds, at as ResourceVia, et as DeployEvent, gt as CredentialKind, ht as Credential, it as ResourceChange, kt as DeployIdentity, mt as AwsCredential, nt as DeployEventType, ot as AppDeployResult, q as DeployTargetCapabilities, rt as DeployPhase, st as DeployResult, tt as DeployEventError, vt as CredentialProvider, yt as CredentialRequest } from "../types-BzCavjGt.mjs";
2
- import { a as TargetRuntimeMismatch, c as DeployTargetNotYetSupported, i as TargetPackageInvalid, l as UnknownDeployTarget, n as InvalidTargetOptions, o as ProviderRemoved, r as TargetEntryInvalid, s as TargetPackageNotFound, t as TargetRuntimeUndeclared } from "../runtime-ekxfPNM-.mjs";
1
+ import { $ as TargetOptions, At as StageSecrets, Dt as StateStore, G as DeployPhaseContext, J as DeployTarget, K as DeployRuntime, Q as TargetEvent, U as AnyDeployTarget, W as DeployFailure, X as DeployTargetEntry, Y as DeployTargetCapabilities, Z as DeployTargetLogger, _t as Credential, at as DeployPhase, bt as CredentialProvider, ct as AppDeployResult, et as TargetOptionsIssue, gt as AwsCredential, it as DeployEventType, jt as DeployIdentity, lt as DeployResult, nt as DeployEvent, ot as ResourceChange, q as DeploySecrets, rt as DeployEventError, st as ResourceVia, tt as TargetOptionsSchema, vt as CredentialKind, xt as CredentialRequest, yt as CredentialKinds } from "../types-BZn-8ssD.mjs";
2
+ import { a as TargetRuntimeMismatch, c as DeployTargetNotYetSupported, i as TargetPackageInvalid, l as UnknownDeployTarget, n as InvalidTargetOptions, o as ProviderRemoved, r as TargetEntryInvalid, s as TargetPackageNotFound, t as TargetRuntimeUndeclared } from "../runtime-CNu2C2hB.mjs";
3
3
  //#region src/target/define.d.ts
4
4
  /**
5
5
  * A deploy target, typed from what it is written with: the options from its
@@ -1,4 +1,4 @@
1
1
  import { a as UnknownDeployTarget, i as DeployTargetNotYetSupported, n as isDeployTarget, t as defineTarget } from "../define-DR8xGYfL.mjs";
2
- import { i as TargetRuntimeMismatch, l as TargetPackageNotFound, n as TargetEntryInvalid, r as TargetPackageInvalid, s as TargetRuntimeUndeclared, t as InvalidTargetOptions } from "../resolve-DY9TaVeV.mjs";
2
+ import { i as TargetRuntimeMismatch, l as TargetPackageNotFound, n as TargetEntryInvalid, r as TargetPackageInvalid, s as TargetRuntimeUndeclared, t as InvalidTargetOptions } from "../resolve-r7PAs6ng.mjs";
3
3
  import { t as ProviderRemoved } from "../provider-q4lsYzYG.mjs";
4
4
  export { DeployTargetNotYetSupported, InvalidTargetOptions, ProviderRemoved, TargetEntryInvalid, TargetPackageInvalid, TargetPackageNotFound, TargetRuntimeMismatch, TargetRuntimeUndeclared, UnknownDeployTarget, defineTarget, isDeployTarget };
@@ -1,5 +1,4 @@
1
1
  import { ConstructManifest } from "@geekmidas/manifest";
2
- //#endregion
3
2
  //#region src/deploy/identity.d.ts
4
3
  /**
5
4
  * Who a deploy is, on a target it shares with other workspaces.
@@ -911,6 +910,13 @@ interface DeployTargetCapabilities {
911
910
  * stage with `UndeclaredStage`.
912
911
  */
913
912
  localStage?: boolean;
913
+ /**
914
+ * Whether it runs telemetry's self-hosted provider — OpenObserve beside
915
+ * the apps — for a stage whose `deploy.telemetry` asks for it, or names
916
+ * nothing. Absent, a stage that uses a `Telemetry` construct names a
917
+ * provider of its own (`otlp`) or opts out with `false`.
918
+ */
919
+ selfHostedTelemetry?: boolean;
914
920
  }
915
921
  /** A failed validation of a target's options, issue by issue. */
916
922
  interface TargetOptionsIssue {
@@ -5831,13 +5837,6 @@ declare const WorkspaceConfigSchema: ZodObject<{
5831
5837
  }, $strip>>;
5832
5838
  }, $strip>>;
5833
5839
  compose: ZodOptional<ZodObject<{
5834
- logs: ZodOptional<ZodUnion<readonly [ZodBoolean, ZodObject<{
5835
- port: ZodOptional<ZodNumber>;
5836
- retentionDays: ZodOptional<ZodNumber>;
5837
- public: ZodOptional<ZodObject<{
5838
- allow: ZodArray<ZodString>;
5839
- }, $strip>>;
5840
- }, $strip>]>>;
5841
5840
  proxy: ZodOptional<ZodUnion<readonly [ZodEnum<{
5842
5841
  caddy: "caddy";
5843
5842
  traefik: "traefik";
@@ -5849,7 +5848,21 @@ declare const WorkspaceConfigSchema: ZodObject<{
5849
5848
  certFile: ZodString;
5850
5849
  keyFile: ZodString;
5851
5850
  }, $strict>>>;
5852
- }, $strip>>;
5851
+ }, $strict>>;
5852
+ telemetry: ZodOptional<ZodRecord<ZodString, ZodUnion<readonly [ZodLiteral<false>, ZodLiteral<"self-hosted">, ZodObject<{
5853
+ provider: ZodLiteral<"self-hosted">;
5854
+ port: ZodOptional<ZodNumber>;
5855
+ retentionDays: ZodOptional<ZodNumber>;
5856
+ public: ZodOptional<ZodObject<{
5857
+ allow: ZodArray<ZodString>;
5858
+ }, $strip>>;
5859
+ sampleRate: ZodOptional<ZodNumber>;
5860
+ }, $strict>, ZodObject<{
5861
+ provider: ZodLiteral<"otlp">;
5862
+ endpoint: ZodString;
5863
+ headers: ZodOptional<ZodRecord<ZodString, ZodString>>;
5864
+ sampleRate: ZodOptional<ZodNumber>;
5865
+ }, $strict>]>>>;
5853
5866
  dns: ZodOptional<ZodUnion<readonly [ZodRecord<ZodString, ZodUnion<readonly [ZodDiscriminatedUnion<[ZodObject<{
5854
5867
  provider: ZodLiteral<"hostinger">;
5855
5868
  ttl: ZodOptional<ZodNumber>;
@@ -6313,17 +6326,10 @@ interface DokployVerifyConfig {
6313
6326
  *
6314
6327
  * @example
6315
6328
  * ```ts
6316
- * deploy: { compose: { logs: true } }
6317
- * deploy: { compose: { logs: { port: 5081, retentionDays: 14 } } }
6318
- * deploy: { compose: { logs: { public: { allow: ['203.0.113.7', '10.0.0.0/8'] } } } }
6329
+ * deploy: { compose: { proxy: 'traefik' } }
6319
6330
  * ```
6320
6331
  */
6321
6332
  interface ComposeWorkspaceConfig {
6322
- /**
6323
- * Run OpenObserve in the stack and send every backend's logs and traces
6324
- * to it. `true` for the defaults.
6325
- */
6326
- logs?: boolean | ComposeLogsConfig;
6327
6333
  /**
6328
6334
  * What serves a deployed stage's stack: `'caddy'` (the default) — the
6329
6335
  * stack's own Caddy on 80/443 — or `'traefik'`, the server's shared
@@ -6355,8 +6361,42 @@ interface ComposeTlsConfig {
6355
6361
  certFile: string;
6356
6362
  keyFile: string;
6357
6363
  }
6358
- /** How the stack's OpenObserve is run and reached — `deploy.compose.logs`. */
6359
- interface ComposeLogsConfig {
6364
+ /**
6365
+ * Where one stage's telemetry goes, and how much of it — `deploy.telemetry`,
6366
+ * by stage.
6367
+ *
6368
+ * What is emitted is the application's (the `Telemetry` construct); where it
6369
+ * goes is this. A server target runs the self-hosted provider when a stage
6370
+ * names nothing; AWS has none, so a deployed AWS stage that uses telemetry
6371
+ * names a provider. `false` sends nothing. The local stage ignores this: `gkm
6372
+ * dev` and `gkm compose` on it always run OpenObserve, at 100%.
6373
+ *
6374
+ * @example
6375
+ * ```ts
6376
+ * telemetry: {
6377
+ * staging: 'self-hosted',
6378
+ * production: { provider: 'self-hosted', retentionDays: 14, sampleRate: 0.1 },
6379
+ * preview: { provider: 'otlp', endpoint: 'https://otlp.example.com', sampleRate: 0.5 },
6380
+ * scratch: false,
6381
+ * }
6382
+ * ```
6383
+ */
6384
+ type StageTelemetryConfig = 'self-hosted' | SelfHostedTelemetryConfig | OtlpTelemetryConfig | false;
6385
+ /** Shared by every provider. */
6386
+ interface TelemetryProviderConfig {
6387
+ /**
6388
+ * The fraction of traces kept, decided where a trace starts and followed
6389
+ * by every service it reaches (`parentbased_traceidratio`). Logs are not
6390
+ * sampled. 0 to 1; default 1.
6391
+ */
6392
+ sampleRate?: number;
6393
+ }
6394
+ /**
6395
+ * The target runs the collector and its UI: OpenObserve, in a compose stack,
6396
+ * reached through an SSH tunnel by default.
6397
+ */
6398
+ interface SelfHostedTelemetryConfig extends TelemetryProviderConfig {
6399
+ provider: 'self-hosted';
6360
6400
  /**
6361
6401
  * The port it is published on, on 127.0.0.1 only — reached from another
6362
6402
  * machine through an SSH tunnel. Default 5080.
@@ -6368,7 +6408,7 @@ interface ComposeLogsConfig {
6368
6408
  */
6369
6409
  retentionDays?: number;
6370
6410
  /**
6371
- * Serve it on `logs.<stage domain>` through the stack's Caddy, to these
6411
+ * Serve it on `logs.<stage domain>` through the stack's proxy, to these
6372
6412
  * addresses only (IPs or CIDRs), instead of on a loopback port. Every
6373
6413
  * other address is answered 403.
6374
6414
  */
@@ -6376,6 +6416,14 @@ interface ComposeLogsConfig {
6376
6416
  allow: string[];
6377
6417
  };
6378
6418
  }
6419
+ /** Any OTLP/HTTP endpoint — a collector, a vendor's ingest. */
6420
+ interface OtlpTelemetryConfig extends TelemetryProviderConfig {
6421
+ provider: 'otlp';
6422
+ /** The OTLP/HTTP base URL; `/v1/traces` and `/v1/logs` are added to it. */
6423
+ endpoint: string;
6424
+ /** Headers sent with every export — `{ 'x-team': 'shop' }`. */
6425
+ headers?: Record<string, string>;
6426
+ }
6379
6427
  /**
6380
6428
  * Deployment configuration for the workspace.
6381
6429
  *
@@ -6451,6 +6499,11 @@ interface DeployConfig {
6451
6499
  dokploy?: DokployWorkspaceConfig;
6452
6500
  /** What the `compose` target runs beside the apps — see {@link ComposeWorkspaceConfig}. */
6453
6501
  compose?: ComposeWorkspaceConfig;
6502
+ /**
6503
+ * Where each deployed stage's telemetry goes — see
6504
+ * {@link StageTelemetryConfig}.
6505
+ */
6506
+ telemetry?: Record<string, StageTelemetryConfig>;
6454
6507
  /** DNS configuration for automatic record creation */
6455
6508
  dns?: DnsConfig;
6456
6509
  /** Backup destination configuration for database services */
@@ -7393,5 +7446,5 @@ interface GkmConfig {
7393
7446
  deploy?: DeployConfig;
7394
7447
  }
7395
7448
  //#endregion
7396
- export { TargetOptionsSchema as $, FrontendFramework as A, deployIdentity as At, validateWorkspaceConfig as B, SecretsConfig as C, storedCredentials as Ct, isWorkspaceConfig as D, ReleasedImage as Dt, WorkspaceInput as E, StateVersionConflict as Et, formatValidationErrors as F, DeploySecrets as G, DeployFailure as H, getDeployTargetError as I, DeployTargetEntry as J, DeployTarget as K, isDeployTargetSupported as L, PHASE_2_DEPLOY_TARGETS as M, SUPPORTED_DEPLOY_TARGETS as N, BackendFramework as O, StageSecrets as Ot, WorkspaceConfigSchema as P, TargetOptionsIssue as Q, isPhase2DeployTarget as R, NormalizedWorkspace as S, chainCredentials as St, WorkspaceConfig as T, StateStore as Tt, DeployPhaseContext as U, AnyDeployTarget as V, DeployRuntime as W, TargetEvent as X, DeployTargetLogger as Y, TargetOptions as Z, InferAppNames as _, CredentialKinds as _t, Routes as a, ResourceVia as at, ModelsConfig as b, MissingCredential as bt, AppInput as c, DEV_SERVICES as ct, ComposeWorkspaceConfig as d, ExternalServicesNotConfigured as dt, DeployEvent as et, ConstrainedApps as f, MissingServiceKey as ft, DokployWorkspaceConfig as g, CredentialKind as gt, DevConfig as h, Credential as ht, OpenApiConfig as i, ResourceChange as it, MobileFramework as j, Framework as k, DeployIdentity as kt, AppsRecord as l, DevService as lt, DeployTargetName as m, AwsCredential as mt, EmailBackend as n, DeployEventType as nt, AppConfig as o, AppDeployResult as ot, DeployConfig as p, UnknownDevService as pt, DeployTargetCapabilities as q, GkmConfig as r, DeployPhase as rt, AppConfigInput as s, DeployResult as st, CacheBackend as t, DeployEventError as tt, ComposeLogsConfig as u, DevServicesNeedServerTarget as ut, InferredWorkspaceConfig as v, CredentialProvider as vt, SharedConfig as w, StateLocked as wt, NormalizedAppConfig as x, StoredCredentialsOptions as xt, LoadedConfig as y, CredentialRequest as yt, safeValidateWorkspaceConfig as z };
7397
- //# sourceMappingURL=types-DZtj9jeI.d.cts.map
7449
+ export { TargetOptions as $, BackendFramework as A, StageSecrets as At, isPhase2DeployTarget as B, SecretsConfig as C, StoredCredentialsOptions as Ct, WorkspaceConfig as D, StateStore as Dt, StageTelemetryConfig as E, StateLocked as Et, SUPPORTED_DEPLOY_TARGETS as F, DeployPhaseContext as G, validateWorkspaceConfig as H, WorkspaceConfigSchema as I, DeployTarget as J, DeployRuntime as K, formatValidationErrors as L, FrontendFramework as M, deployIdentity as Mt, MobileFramework as N, WorkspaceInput as O, StateVersionConflict as Ot, PHASE_2_DEPLOY_TARGETS as P, TargetEvent as Q, getDeployTargetError as R, OtlpTelemetryConfig as S, MissingCredential as St, SharedConfig as T, storedCredentials as Tt, AnyDeployTarget as U, safeValidateWorkspaceConfig as V, DeployFailure as W, DeployTargetEntry as X, DeployTargetCapabilities as Y, DeployTargetLogger as Z, InferredWorkspaceConfig as _, Credential as _t, Routes as a, DeployPhase as at, NormalizedAppConfig as b, CredentialProvider as bt, AppInput as c, AppDeployResult as ct, ConstrainedApps as d, DevService as dt, TargetOptionsIssue as et, DeployConfig as f, DevServicesNeedServerTarget as ft, InferAppNames as g, AwsCredential as gt, DokployWorkspaceConfig as h, UnknownDevService as ht, OpenApiConfig as i, DeployEventType as it, Framework as j, DeployIdentity as jt, isWorkspaceConfig as k, ReleasedImage as kt, AppsRecord as l, DeployResult as lt, DevConfig as m, MissingServiceKey as mt, EmailBackend as n, DeployEvent as nt, AppConfig as o, ResourceChange as ot, DeployTargetName as p, ExternalServicesNotConfigured as pt, DeploySecrets as q, GkmConfig as r, DeployEventError as rt, AppConfigInput as s, ResourceVia as st, CacheBackend as t, TargetOptionsSchema as tt, ComposeWorkspaceConfig as u, DEV_SERVICES as ut, LoadedConfig as v, CredentialKind as vt, SelfHostedTelemetryConfig as w, chainCredentials as wt, NormalizedWorkspace as x, CredentialRequest as xt, ModelsConfig as y, CredentialKinds as yt, isDeployTargetSupported as z };
7450
+ //# sourceMappingURL=types-BZn-8ssD.d.mts.map