@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
@@ -36,10 +36,92 @@ function assertKnownSecretsStore(store) {
36
36
  if (typeof provider === "string" && !SECRETS_STORE_PROVIDERS.includes(provider)) throw new UnknownSecretsStoreProvider(provider);
37
37
  }
38
38
  //#endregion
39
+ //#region src/compose/proxy.ts
40
+ /**
41
+ * Which proxy a stage's stack is served by, and with whose certificate —
42
+ * `deploy.compose.proxy` and `deploy.compose.tls`, resolved for one stage.
43
+ *
44
+ * Pure, and kept apart from the stack so the workspace schema can check a
45
+ * config with the same rules — and the same named errors — the stack applies.
46
+ */
47
+ /** A per-stage setting keyed by a stage the workspace does not have. */
48
+ var ComposeStageUnknown = class extends Error {
49
+ setting;
50
+ stage;
51
+ stages;
52
+ constructor(setting, stage, stages) {
53
+ super(`deploy.compose.${setting} names the stage '${stage}', which is not one of this workspace's (${stages.join(", ")}). Use a stage from stages.local or stages.deployed.`);
54
+ this.setting = setting;
55
+ this.stage = stage;
56
+ this.stages = stages;
57
+ this.name = "ComposeStageUnknown";
58
+ }
59
+ };
60
+ /**
61
+ * A certificate for the local stage, whose certificates are always Caddy's
62
+ * own CA — the one `gkm trust` installs.
63
+ */
64
+ var ComposeTlsOnLocalStage = class extends Error {
65
+ stage;
66
+ constructor(stage) {
67
+ super(`deploy.compose.tls sets a certificate for '${stage}', the local stage, whose certificates always come from Caddy's local CA (\`gkm trust\` installs it). Remove it, or set it for a deployed stage.`);
68
+ this.stage = stage;
69
+ this.name = "ComposeTlsOnLocalStage";
70
+ }
71
+ };
72
+ /** The stage's certificate or key file is not there to read. */
73
+ var ComposeTlsFileMissing = class extends Error {
74
+ stage;
75
+ file;
76
+ constructor(stage, file) {
77
+ super(`deploy.compose.tls for '${stage}' names ${file}, and there is no file there. Point certFile and keyFile at the PEM certificate (with its chain) and key — relative to the workspace root, or absolute.`);
78
+ this.stage = stage;
79
+ this.file = file;
80
+ this.name = "ComposeTlsFileMissing";
81
+ }
82
+ };
83
+ /**
84
+ * The proxy a stage's stack is served by. The local stage is always Caddy —
85
+ * its internal CA and `gkm trust` — whatever is configured.
86
+ */
87
+ function proxyFor(config, stage, local) {
88
+ if (local) return "caddy";
89
+ const proxy = config?.proxy;
90
+ if (!proxy) return "caddy";
91
+ if (typeof proxy === "string") return proxy;
92
+ return proxy[stage] ?? "caddy";
93
+ }
94
+ /** A deployed stage's own certificate, its paths absolute, when it sets one. */
95
+ function certificateFor(config, stage, root) {
96
+ const tls = config?.tls?.[stage];
97
+ if (!tls) return void 0;
98
+ const absolute = (file) => (0, node_path.isAbsolute)(file) ? file : (0, node_path.resolve)(root, file);
99
+ return {
100
+ certFile: absolute(tls.certFile),
101
+ keyFile: absolute(tls.keyFile)
102
+ };
103
+ }
104
+ /**
105
+ * Throws the named error for the first thing wrong with the per-stage
106
+ * settings: a stage the workspace does not have, or a certificate for the
107
+ * local stage.
108
+ */
109
+ function checkComposeStages(config, stages) {
110
+ const known = [stages.local, ...stages.deployed];
111
+ if (config?.proxy && typeof config.proxy === "object") {
112
+ for (const stage of Object.keys(config.proxy)) if (!known.includes(stage)) throw new ComposeStageUnknown("proxy", stage, known);
113
+ }
114
+ for (const stage of Object.keys(config?.tls ?? {})) {
115
+ if (stage === stages.local) throw new ComposeTlsOnLocalStage(stage);
116
+ if (!known.includes(stage)) throw new ComposeStageUnknown("tls", stage, known);
117
+ }
118
+ }
119
+ //#endregion
39
120
  //#region src/compose/logsConfig.ts
40
121
  /**
41
- * `deploy.compose.logs`, read: whether the stack runs OpenObserve, and how it
42
- * is reached.
122
+ * The self-hosted telemetry provider's options, read: how the stack's
123
+ * OpenObserve is run and reached — `deploy.telemetry.<stage>` with
124
+ * `provider: 'self-hosted'`.
43
125
  *
44
126
  * Kept apart from the stack so the workspace schema can check a config with
45
127
  * the same rules — and the same named errors — the stack applies.
@@ -48,34 +130,42 @@ function assertKnownSecretsStore(store) {
48
130
  const LOGS_PORT = 5080;
49
131
  /** `public` with no address to allow: nobody could reach it. */
50
132
  var LogsAllowEmpty = class extends Error {
51
- constructor() {
52
- super("deploy.compose.logs.public.allow is empty, so the logs site would answer every request with 403. List the addresses that may reach it (public: { allow: ['203.0.113.7', '10.0.0.0/8'] }), or remove public and reach it through an SSH tunnel.");
133
+ stage;
134
+ constructor(stage) {
135
+ super(`deploy.telemetry.${stage}.public.allow is empty, so the logs site would answer every request with 403. List the addresses that may reach it (public: { allow: ['203.0.113.7', '10.0.0.0/8'] }), or remove public and reach it through an SSH tunnel.`);
136
+ this.stage = stage;
53
137
  this.name = "LogsAllowEmpty";
54
138
  }
55
139
  };
56
140
  /** An `allow` entry that is not an IP address or a CIDR range. */
57
141
  var LogsAllowEntryInvalid = class extends Error {
142
+ stage;
58
143
  entry;
59
- constructor(entry) {
60
- super(`deploy.compose.logs.public.allow has '${entry}', which is not an IP address or a CIDR range. Write one like '203.0.113.7', '10.0.0.0/8' or '2001:db8::/32'.`);
144
+ constructor(stage, entry) {
145
+ super(`deploy.telemetry.${stage}.public.allow has '${entry}', which is not an IP address or a CIDR range. Write one like '203.0.113.7', '10.0.0.0/8' or '2001:db8::/32'.`);
146
+ this.stage = stage;
61
147
  this.entry = entry;
62
148
  this.name = "LogsAllowEntryInvalid";
63
149
  }
64
150
  };
65
151
  /** A retention OpenObserve would refuse to start with. */
66
152
  var LogsRetentionInvalid = class extends Error {
153
+ stage;
67
154
  retentionDays;
68
- constructor(retentionDays) {
69
- super(`deploy.compose.logs.retentionDays is ${String(retentionDays)}; it must be a whole number of days, at least 3 — OpenObserve refuses to start with fewer. Leave it out for 30.`);
155
+ constructor(stage, retentionDays) {
156
+ super(`deploy.telemetry.${stage}.retentionDays is ${String(retentionDays)}; it must be a whole number of days, at least 3 — OpenObserve refuses to start with fewer. Leave it out for 30.`);
157
+ this.stage = stage;
70
158
  this.retentionDays = retentionDays;
71
159
  this.name = "LogsRetentionInvalid";
72
160
  }
73
161
  };
74
162
  /** A port that is not one. */
75
163
  var LogsPortInvalid = class extends Error {
164
+ stage;
76
165
  port;
77
- constructor(port) {
78
- super(`deploy.compose.logs.port is ${String(port)}; set it to a number between 1 and 65535, or leave it out for ${LOGS_PORT}.`);
166
+ constructor(stage, port) {
167
+ super(`deploy.telemetry.${stage}.port is ${String(port)}; set it to a number between 1 and 65535, or leave it out for ${LOGS_PORT}.`);
168
+ this.stage = stage;
79
169
  this.port = port;
80
170
  this.name = "LogsPortInvalid";
81
171
  }
@@ -91,20 +181,18 @@ function isAddressOrRange(entry) {
91
181
  return Number(prefix) <= (family === 4 ? 32 : 128);
92
182
  }
93
183
  /**
94
- * `deploy.compose.logs` with its defaults, or undefined when it is off.
95
- * Throws the named error for the first thing wrong with it.
184
+ * The self-hosted provider's options with their defaults — `{}` for all of
185
+ * them. Throws the named error for the first thing wrong with them.
96
186
  */
97
- function resolveLogs(logs) {
98
- if (!logs) return void 0;
99
- const config = logs === true ? {} : logs;
187
+ function resolveSelfHosted(config, stage) {
100
188
  const port = config.port ?? 5080;
101
- if (!Number.isInteger(port) || port < 1 || port > 65535) throw new LogsPortInvalid(config.port);
189
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new LogsPortInvalid(stage, config.port);
102
190
  const retentionDays = config.retentionDays ?? 30;
103
- if (!Number.isInteger(retentionDays) || retentionDays < 3) throw new LogsRetentionInvalid(config.retentionDays);
191
+ if (!Number.isInteger(retentionDays) || retentionDays < 3) throw new LogsRetentionInvalid(stage, config.retentionDays);
104
192
  if (config.public) {
105
193
  const allow = config.public.allow ?? [];
106
- if (allow.length === 0) throw new LogsAllowEmpty();
107
- for (const entry of allow) if (!isAddressOrRange(entry)) throw new LogsAllowEntryInvalid(entry);
194
+ if (allow.length === 0) throw new LogsAllowEmpty(stage);
195
+ for (const entry of allow) if (!isAddressOrRange(entry)) throw new LogsAllowEntryInvalid(stage, entry);
108
196
  return {
109
197
  port,
110
198
  retentionDays,
@@ -117,85 +205,189 @@ function resolveLogs(logs) {
117
205
  };
118
206
  }
119
207
  //#endregion
120
- //#region src/compose/proxy.ts
208
+ //#region src/telemetry/config.ts
121
209
  /**
122
- * Which proxy a stage's stack is served by, and with whose certificate —
123
- * `deploy.compose.proxy` and `deploy.compose.tls`, resolved for one stage.
210
+ * `deploy.telemetry`, read: where one stage's telemetry goes, and how much.
124
211
  *
125
- * Pure, and kept apart from the stack so the workspace schema can check a
126
- * config with the same rules — and the same named errors — the stack applies.
212
+ * The application says what it emits (the `Telemetry` construct). This says
213
+ * where it is sent, per stage, and is the only place that does:
214
+ *
215
+ * - **self-hosted** — the target runs OpenObserve beside the apps (#189's
216
+ * stack service). A server target that can run it uses it when a stage
217
+ * names nothing.
218
+ * - **otlp** — any OTLP/HTTP endpoint, with its headers.
219
+ * - **false** — nothing is sent.
220
+ *
221
+ * Vendor presets (a known endpoint and header shape, with the stage secret
222
+ * `TELEMETRY_CREDENTIALS`) are one more entry in {@link PROVIDERS}: a
223
+ * resolver from the stage's config to a {@link ResolvedTelemetry}, which
224
+ * every target already consumes through {@link telemetryEnv}.
225
+ *
226
+ * The local stage ignores all of it: `gkm dev` and `gkm compose` on it run
227
+ * OpenObserve and keep every trace.
127
228
  */
128
- /** A per-stage setting keyed by a stage the workspace does not have. */
129
- var ComposeStageUnknown = class extends Error {
130
- setting;
229
+ /** A deployed stage uses telemetry and its target cannot choose for it. */
230
+ var TelemetryProviderRequired = class extends Error {
131
231
  stage;
132
- stages;
133
- constructor(setting, stage, stages) {
134
- super(`deploy.compose.${setting} names the stage '${stage}', which is not one of this workspace's (${stages.join(", ")}). Use a stage from stages.local or stages.deployed.`);
135
- this.setting = setting;
232
+ target;
233
+ constructor(stage, target) {
234
+ super(`The stage '${stage}' deploys through ${target}, which cannot run telemetry itself, and a process uses a Telemetry construct. Say where it goes in gkm.config.ts: deploy: { telemetry: { ${stage}: { provider: 'otlp', endpoint: 'https://…' } } } — or deploy: { telemetry: { ${stage}: false } } to send nothing.`);
136
235
  this.stage = stage;
137
- this.stages = stages;
138
- this.name = "ComposeStageUnknown";
236
+ this.target = target;
237
+ this.name = "TelemetryProviderRequired";
139
238
  }
140
239
  };
141
- /**
142
- * A certificate for the local stage, whose certificates are always Caddy's
143
- * own CA — the one `gkm trust` installs.
144
- */
145
- var ComposeTlsOnLocalStage = class extends Error {
240
+ /** A stage asks for the self-hosted provider on a target that cannot run it. */
241
+ var SelfHostedTelemetryUnavailable = class extends Error {
146
242
  stage;
147
- constructor(stage) {
148
- super(`deploy.compose.tls sets a certificate for '${stage}', the local stage, whose certificates always come from Caddy's local CA (\`gkm trust\` installs it). Remove it, or set it for a deployed stage.`);
243
+ target;
244
+ constructor(stage, target) {
245
+ super(`deploy.telemetry.${stage} is 'self-hosted', and ${target} does not run OpenObserve beside the apps — the compose target does. Deploy '${stage}' through compose, or send its telemetry elsewhere: deploy: { telemetry: { ${stage}: { provider: 'otlp', endpoint: 'https://…' } } }.`);
149
246
  this.stage = stage;
150
- this.name = "ComposeTlsOnLocalStage";
247
+ this.target = target;
248
+ this.name = "SelfHostedTelemetryUnavailable";
151
249
  }
152
250
  };
153
- /** The stage's certificate or key file is not there to read. */
154
- var ComposeTlsFileMissing = class extends Error {
251
+ /** A sample rate that is not a fraction. */
252
+ var TelemetrySampleRateInvalid = class extends Error {
155
253
  stage;
156
- file;
157
- constructor(stage, file) {
158
- super(`deploy.compose.tls for '${stage}' names ${file}, and there is no file there. Point certFile and keyFile at the PEM certificate (with its chain) and key — relative to the workspace root, or absolute.`);
254
+ sampleRate;
255
+ constructor(stage, sampleRate) {
256
+ super(`deploy.telemetry.${stage}.sampleRate is ${String(sampleRate)}; set it to a number from 0 to 1 — the fraction of traces kept — or leave it out to keep every one.`);
159
257
  this.stage = stage;
160
- this.file = file;
161
- this.name = "ComposeTlsFileMissing";
258
+ this.sampleRate = sampleRate;
259
+ this.name = "TelemetrySampleRateInvalid";
260
+ }
261
+ };
262
+ /** An OTLP endpoint that is not an http(s) URL. */
263
+ var TelemetryEndpointInvalid = class extends Error {
264
+ stage;
265
+ endpoint;
266
+ constructor(stage, endpoint) {
267
+ super(`deploy.telemetry.${stage}.endpoint is ${JSON.stringify(endpoint)}; set it to the collector's OTLP/HTTP base URL, like 'https://otlp.example.com' — /v1/traces and /v1/logs are added to it.`);
268
+ this.stage = stage;
269
+ this.endpoint = endpoint;
270
+ this.name = "TelemetryEndpointInvalid";
162
271
  }
163
272
  };
273
+ /** The sample rate a stage keeps, checked. */
274
+ function sampleRateOf(stage, sampleRate) {
275
+ const rate = sampleRate ?? 1;
276
+ if (!Number.isFinite(rate) || rate < 0 || rate > 1) throw new TelemetrySampleRateInvalid(stage, sampleRate);
277
+ return rate;
278
+ }
164
279
  /**
165
- * The proxy a stage's stack is served by. The local stage is always Caddy —
166
- * its internal CA and `gkm trust` — whatever is configured.
280
+ * Each provider's resolver: a stage's config to what the targets consume.
281
+ * A vendor preset is one more entry here.
167
282
  */
168
- function proxyFor(config, stage, local) {
169
- if (local) return "caddy";
170
- const proxy = config?.proxy;
171
- if (!proxy) return "caddy";
172
- if (typeof proxy === "string") return proxy;
173
- return proxy[stage] ?? "caddy";
283
+ const PROVIDERS = {
284
+ "self-hosted": (config, stage) => {
285
+ const { provider: _, sampleRate, ...options } = config;
286
+ return {
287
+ provider: "self-hosted",
288
+ selfHosted: resolveSelfHosted(options, stage),
289
+ sampleRate: sampleRateOf(stage, sampleRate)
290
+ };
291
+ },
292
+ otlp: (config, stage) => {
293
+ if (typeof config.endpoint !== "string" || !isHttpUrl(config.endpoint)) throw new TelemetryEndpointInvalid(stage, config.endpoint);
294
+ return {
295
+ provider: "otlp",
296
+ endpoint: config.endpoint.replace(/\/+$/, ""),
297
+ headers: { ...config.headers },
298
+ sampleRate: sampleRateOf(stage, config.sampleRate)
299
+ };
300
+ }
301
+ };
302
+ function isHttpUrl(value) {
303
+ try {
304
+ const url = new URL(value);
305
+ return url.protocol === "http:" || url.protocol === "https:";
306
+ } catch {
307
+ return false;
308
+ }
174
309
  }
175
- /** A deployed stage's own certificate, its paths absolute, when it sets one. */
176
- function certificateFor(config, stage, root) {
177
- const tls = config?.tls?.[stage];
178
- if (!tls) return void 0;
179
- const absolute = (file) => (0, node_path.isAbsolute)(file) ? file : (0, node_path.resolve)(root, file);
180
- return {
181
- certFile: absolute(tls.certFile),
182
- keyFile: absolute(tls.keyFile)
310
+ /**
311
+ * One stage's entry, checked on its own — what the workspace schema runs, so
312
+ * a bad config fails to load with the words a deploy would fail with.
313
+ */
314
+ function checkStageTelemetry(stage, config) {
315
+ if (config === false) return void 0;
316
+ const entry = config === "self-hosted" ? { provider: "self-hosted" } : config;
317
+ const resolve = PROVIDERS[entry.provider];
318
+ return resolve(entry, stage);
319
+ }
320
+ /**
321
+ * Where a stage's telemetry goes, or undefined when nothing is sent — no
322
+ * process uses a `Telemetry` node, or the stage opted out with `false`.
323
+ *
324
+ * The local stage always runs the self-hosted provider with its defaults and
325
+ * keeps every trace, whatever `deploy.telemetry` says. A deployed stage that
326
+ * names nothing gets the self-hosted provider where its target runs one, and
327
+ * {@link TelemetryProviderRequired} where it cannot — AWS has none.
328
+ */
329
+ function resolveStageTelemetry(input) {
330
+ const { stage } = input;
331
+ if (!input.used) return void 0;
332
+ if (input.local) return {
333
+ provider: "self-hosted",
334
+ selfHosted: resolveSelfHosted({}, stage),
335
+ sampleRate: 1
183
336
  };
337
+ const config = input.telemetry?.[stage];
338
+ if (config === void 0) {
339
+ if (input.runtime === "server" && input.selfHosted) return checkStageTelemetry(stage, "self-hosted");
340
+ throw new TelemetryProviderRequired(stage, input.target);
341
+ }
342
+ const resolved = checkStageTelemetry(stage, config);
343
+ if (resolved?.provider === "self-hosted" && !input.selfHosted) throw new SelfHostedTelemetryUnavailable(stage, input.target);
344
+ return resolved;
184
345
  }
346
+ /** The sampler every process with the edge runs, per the stage's rate. */
347
+ const TRACES_SAMPLER = "parentbased_traceidratio";
185
348
  /**
186
- * Throws the named error for the first thing wrong with the per-stage
187
- * settings: a stage the workspace does not have, or a certificate for the
188
- * local stage.
349
+ * `OTEL_EXPORTER_OTLP_HEADERS` for a set of headers: `key=value` pairs,
350
+ * comma-separated, each value percent-encoded — the W3C baggage format the
351
+ * SDK parses.
189
352
  */
190
- function checkComposeStages(config, stages) {
191
- const known = [stages.local, ...stages.deployed];
192
- if (config?.proxy && typeof config.proxy === "object") {
193
- for (const stage of Object.keys(config.proxy)) if (!known.includes(stage)) throw new ComposeStageUnknown("proxy", stage, known);
194
- }
195
- for (const stage of Object.keys(config?.tls ?? {})) {
196
- if (stage === stages.local) throw new ComposeTlsOnLocalStage(stage);
197
- if (!known.includes(stage)) throw new ComposeStageUnknown("tls", stage, known);
198
- }
353
+ function otlpHeaderString(headers) {
354
+ return Object.entries(headers).map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join(",");
355
+ }
356
+ /**
357
+ * The `OTEL_*` values a stage resolves for its `Telemetry` node, before any
358
+ * one process is named: where to export, how to sign, and how much to keep.
359
+ * `OTEL_SERVICE_NAME` is each process's own — see `scopeTelemetryEnv`.
360
+ */
361
+ function telemetryEnv(destination, sampleRate) {
362
+ return {
363
+ OTEL_EXPORTER_OTLP_ENDPOINT: destination.endpoint,
364
+ ...destination.headers ? { OTEL_EXPORTER_OTLP_HEADERS: destination.headers } : {},
365
+ OTEL_TRACES_SAMPLER: TRACES_SAMPLER,
366
+ OTEL_TRACES_SAMPLER_ARG: String(sampleRate)
367
+ };
368
+ }
369
+ /** What an `otlp` stage resolves, for every process with the edge. */
370
+ function otlpTelemetryEnv(resolved) {
371
+ const headers = otlpHeaderString(resolved.headers);
372
+ return telemetryEnv({
373
+ endpoint: resolved.endpoint,
374
+ ...headers ? { headers } : {}
375
+ }, resolved.sampleRate);
376
+ }
377
+ /**
378
+ * The sample rate a stage's browsers trace page views at — a public value,
379
+ * the same rate its servers sample at — or undefined when the stage sends no
380
+ * telemetry. The local stage keeps every trace.
381
+ *
382
+ * Lenient where `resolveStageTelemetry` is strict: a site's client is built
383
+ * before, and apart from, the deploy that refuses a stage with no provider.
384
+ */
385
+ function stageSampleRate(telemetry, stage, local) {
386
+ if (local) return 1;
387
+ const config = telemetry?.[stage];
388
+ if (config === false) return void 0;
389
+ if (config === void 0 || config === "self-hosted") return 1;
390
+ return sampleRateOf(stage, config.sampleRate);
199
391
  }
200
392
  //#endregion
201
393
  //#region src/workspace/stages.ts
@@ -580,31 +772,46 @@ const BackupsConfigSchema = require_schemas.object({
580
772
  /** Number of backups to retain (default: 30) */
581
773
  retention: require_schemas.number().optional()
582
774
  });
583
- /**
584
- * `deploy.compose` — what the compose target runs beside the apps. The rules
585
- * past the shape are `resolveLogs`'s, so the schema and the stack refuse the
586
- * same configs with the same words.
587
- */
775
+ /** `deploy.compose` — what the compose target runs beside the apps. */
588
776
  const ComposeWorkspaceConfigSchema = require_schemas.object({
589
- logs: require_schemas.union([require_schemas.boolean(), require_schemas.object({
590
- port: require_schemas.number().optional(),
591
- retentionDays: require_schemas.number().optional(),
592
- public: require_schemas.object({ allow: require_schemas.array(require_schemas.string()) }).optional()
593
- })]).superRefine((logs, ctx) => {
594
- try {
595
- resolveLogs(logs);
596
- } catch (error) {
597
- ctx.addIssue({
598
- code: "custom",
599
- message: error instanceof Error ? error.message : String(error)
600
- });
601
- }
602
- }).optional(),
603
777
  proxy: require_schemas.union([require_schemas._enum(["caddy", "traefik"]), require_schemas.record(require_schemas.string(), require_schemas._enum(["caddy", "traefik"]))]).optional(),
604
778
  tls: require_schemas.record(require_schemas.string(), require_schemas.object({
605
779
  certFile: require_schemas.string().min(1),
606
780
  keyFile: require_schemas.string().min(1)
607
781
  }).strict()).optional()
782
+ }).strict();
783
+ const TelemetrySampleRate = require_schemas.number().optional();
784
+ /**
785
+ * `deploy.telemetry` — where each stage's telemetry goes. The rules past the
786
+ * shape are `checkStageTelemetry`'s, so the schema and a deploy refuse the
787
+ * same configs with the same words.
788
+ */
789
+ const TelemetryConfigSchema = require_schemas.record(require_schemas.string(), require_schemas.union([
790
+ require_schemas.literal(false),
791
+ require_schemas.literal("self-hosted"),
792
+ require_schemas.object({
793
+ provider: require_schemas.literal("self-hosted"),
794
+ port: require_schemas.number().optional(),
795
+ retentionDays: require_schemas.number().optional(),
796
+ public: require_schemas.object({ allow: require_schemas.array(require_schemas.string()) }).optional(),
797
+ sampleRate: TelemetrySampleRate
798
+ }).strict(),
799
+ require_schemas.object({
800
+ provider: require_schemas.literal("otlp"),
801
+ endpoint: require_schemas.string(),
802
+ headers: require_schemas.record(require_schemas.string(), require_schemas.string()).optional(),
803
+ sampleRate: TelemetrySampleRate
804
+ }).strict()
805
+ ])).superRefine((telemetry, ctx) => {
806
+ for (const [stage, config] of Object.entries(telemetry)) try {
807
+ checkStageTelemetry(stage, config);
808
+ } catch (error) {
809
+ ctx.addIssue({
810
+ code: "custom",
811
+ message: error instanceof Error ? error.message : String(error),
812
+ path: [stage]
813
+ });
814
+ }
608
815
  });
609
816
  /**
610
817
  * Deploy configuration schema.
@@ -626,6 +833,7 @@ const DeployConfigSchema = require_schemas.object({
626
833
  registry: require_schemas.string().min(1).optional(),
627
834
  dokploy: DokployWorkspaceConfigSchema.optional(),
628
835
  compose: ComposeWorkspaceConfigSchema.optional(),
836
+ telemetry: TelemetryConfigSchema.optional(),
629
837
  dns: DnsConfigWithLegacySchema.optional(),
630
838
  backups: BackupsConfigSchema.optional()
631
839
  });
@@ -1162,8 +1370,9 @@ function processConfig(config, cwd) {
1162
1370
  assertNoMovedDeployKeys(config.deploy);
1163
1371
  if (isWorkspaceConfig(config)) {
1164
1372
  assertKnownSecretsStore(config.secrets?.store);
1373
+ if (config.stages === void 0) throw new InvalidStages(stageProblems(void 0));
1165
1374
  const result = safeValidateWorkspaceConfig(config);
1166
- if (!result.success && result.error) throw new Error(formatValidationErrors(result.error));
1375
+ if (!result.success && result.error) throw new InvalidWorkspaceConfig(formatValidationErrors(result.error));
1167
1376
  return {
1168
1377
  type: "workspace",
1169
1378
  raw: config,
@@ -1176,6 +1385,13 @@ function processConfig(config, cwd) {
1176
1385
  workspace: wrapSingleAppAsWorkspace(config, cwd)
1177
1386
  };
1178
1387
  }
1388
+ /** A workspace config the schema refuses; the message lists every issue. */
1389
+ var InvalidWorkspaceConfig = class extends Error {
1390
+ constructor(message) {
1391
+ super(message);
1392
+ this.name = "InvalidWorkspaceConfig";
1393
+ }
1394
+ };
1179
1395
  /**
1180
1396
  * The workspace's own constructs globs, absolute.
1181
1397
  *
@@ -1306,6 +1522,12 @@ Object.defineProperty(exports, "InvalidStages", {
1306
1522
  return InvalidStages;
1307
1523
  }
1308
1524
  });
1525
+ Object.defineProperty(exports, "InvalidWorkspaceConfig", {
1526
+ enumerable: true,
1527
+ get: function() {
1528
+ return InvalidWorkspaceConfig;
1529
+ }
1530
+ });
1309
1531
  Object.defineProperty(exports, "LOGS_PORT", {
1310
1532
  enumerable: true,
1311
1533
  get: function() {
@@ -1342,6 +1564,12 @@ Object.defineProperty(exports, "TEST_STAGE", {
1342
1564
  return TEST_STAGE;
1343
1565
  }
1344
1566
  });
1567
+ Object.defineProperty(exports, "UndeclaredStage", {
1568
+ enumerable: true,
1569
+ get: function() {
1570
+ return UndeclaredStage;
1571
+ }
1572
+ });
1345
1573
  Object.defineProperty(exports, "UnknownSecretsStoreProvider", {
1346
1574
  enumerable: true,
1347
1575
  get: function() {
@@ -1462,6 +1690,12 @@ Object.defineProperty(exports, "normalizeWorkspace", {
1462
1690
  return normalizeWorkspace;
1463
1691
  }
1464
1692
  });
1693
+ Object.defineProperty(exports, "otlpTelemetryEnv", {
1694
+ enumerable: true,
1695
+ get: function() {
1696
+ return otlpTelemetryEnv;
1697
+ }
1698
+ });
1465
1699
  Object.defineProperty(exports, "processConfig", {
1466
1700
  enumerable: true,
1467
1701
  get: function() {
@@ -1474,10 +1708,10 @@ Object.defineProperty(exports, "proxyFor", {
1474
1708
  return proxyFor;
1475
1709
  }
1476
1710
  });
1477
- Object.defineProperty(exports, "resolveLogs", {
1711
+ Object.defineProperty(exports, "resolveStageTelemetry", {
1478
1712
  enumerable: true,
1479
1713
  get: function() {
1480
- return resolveLogs;
1714
+ return resolveStageTelemetry;
1481
1715
  }
1482
1716
  });
1483
1717
  Object.defineProperty(exports, "safeValidateWorkspaceConfig", {
@@ -1492,12 +1726,24 @@ Object.defineProperty(exports, "stageProblems", {
1492
1726
  return stageProblems;
1493
1727
  }
1494
1728
  });
1729
+ Object.defineProperty(exports, "stageSampleRate", {
1730
+ enumerable: true,
1731
+ get: function() {
1732
+ return stageSampleRate;
1733
+ }
1734
+ });
1495
1735
  Object.defineProperty(exports, "stripPublicPrefix", {
1496
1736
  enumerable: true,
1497
1737
  get: function() {
1498
1738
  return stripPublicPrefix;
1499
1739
  }
1500
1740
  });
1741
+ Object.defineProperty(exports, "telemetryEnv", {
1742
+ enumerable: true,
1743
+ get: function() {
1744
+ return telemetryEnv;
1745
+ }
1746
+ });
1501
1747
  Object.defineProperty(exports, "validateWorkspaceConfig", {
1502
1748
  enumerable: true,
1503
1749
  get: function() {
@@ -1517,4 +1763,4 @@ Object.defineProperty(exports, "wrapSingleAppAsWorkspace", {
1517
1763
  }
1518
1764
  });
1519
1765
 
1520
- //# sourceMappingURL=workspace-Bp8FEkF-.cjs.map
1766
+ //# sourceMappingURL=workspace-Bic_R3tz.cjs.map