@geekmidas/cli 10.0.0-alpha.83 → 10.0.0-alpha.85

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-DFO3aJgs.mjs → LegacyStateStore-CJ2o18nT.mjs} +2 -2
  6. package/dist/{LegacyStateStore-DFO3aJgs.mjs.map → LegacyStateStore-CJ2o18nT.mjs.map} +1 -1
  7. package/dist/{LegacyStateStore-iUWVxrXU.cjs → LegacyStateStore-xGxPwP-m.cjs} +2 -2
  8. package/dist/{LegacyStateStore-iUWVxrXU.cjs.map → LegacyStateStore-xGxPwP-m.cjs.map} +1 -1
  9. package/dist/{LocalStateStore-DIfuh0Z1.mjs → LocalStateStore-ByVjUIvS.mjs} +12 -10
  10. package/dist/LocalStateStore-ByVjUIvS.mjs.map +1 -0
  11. package/dist/{LocalStateStore-BsFHdSeA.cjs → LocalStateStore-CkjFD-4b.cjs} +11 -9
  12. package/dist/LocalStateStore-CkjFD-4b.cjs.map +1 -0
  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-ytvpIiv8.cjs → S3StateStore-iqMezbES.cjs} +2 -2
  18. package/dist/{S3StateStore-ytvpIiv8.cjs.map → S3StateStore-iqMezbES.cjs.map} +1 -1
  19. package/dist/{S3StateStore-DR2f78Dj.mjs → S3StateStore-kpFlGVLE.mjs} +2 -2
  20. package/dist/{S3StateStore-DR2f78Dj.mjs.map → S3StateStore-kpFlGVLE.mjs.map} +1 -1
  21. package/dist/{SSMStateStore-BZ3XL0Mr.mjs → SSMStateStore-Bkz5ztfo.mjs} +2 -2
  22. package/dist/{SSMStateStore-BZ3XL0Mr.mjs.map → SSMStateStore-Bkz5ztfo.mjs.map} +1 -1
  23. package/dist/{SSMStateStore-C1JruCD9.cjs → SSMStateStore-Z2OMVCtq.cjs} +2 -2
  24. package/dist/{SSMStateStore-C1JruCD9.cjs.map → SSMStateStore-Z2OMVCtq.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-Bwddb4KD.cjs → add-CM7RLj89.cjs} +3 -3
  30. package/dist/{add-Bwddb4KD.cjs.map → add-CM7RLj89.cjs.map} +1 -1
  31. package/dist/{add-DkBEZ5_s.mjs → add-jpX7M8RB.mjs} +3 -3
  32. package/dist/{add-DkBEZ5_s.mjs.map → add-jpX7M8RB.mjs.map} +1 -1
  33. package/dist/{bundler-B8TGsunu.mjs → bundler-CaAKsbcN.mjs} +5 -5
  34. package/dist/{bundler-B8TGsunu.mjs.map → bundler-CaAKsbcN.mjs.map} +1 -1
  35. package/dist/{bundler-BkH1kPEX.cjs → bundler-lEBH8ENP.cjs} +5 -5
  36. package/dist/{bundler-BkH1kPEX.cjs.map → bundler-lEBH8ENP.cjs.map} +1 -1
  37. package/dist/{cli-BgDd4cZB.mjs → cli-BV3jzbk0.mjs} +3 -3
  38. package/dist/{cli-BgDd4cZB.mjs.map → cli-BV3jzbk0.mjs.map} +1 -1
  39. package/dist/{cli-DO7DQqCq.cjs → cli-DQCBcNlN.cjs} +3 -3
  40. package/dist/{cli-DO7DQqCq.cjs.map → cli-DQCBcNlN.cjs.map} +1 -1
  41. package/dist/{compose-BPJ9bUKp.mjs → compose-CQK6StuE.mjs} +86 -28
  42. package/dist/compose-CQK6StuE.mjs.map +1 -0
  43. package/dist/{compose-CGyxYe-h.cjs → compose-CSR0yEJm.cjs} +85 -27
  44. package/dist/compose-CSR0yEJm.cjs.map +1 -0
  45. package/dist/{config-DMdzdO5u.d.cts → config-BzIfP8a-.d.cts} +16 -3
  46. package/dist/config-BzIfP8a-.d.cts.map +1 -0
  47. package/dist/{config-BBFiH4qk.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-0XpZDYAr.mjs → deploy-BuU117CA.mjs} +14 -5
  60. package/dist/deploy-BuU117CA.mjs.map +1 -0
  61. package/dist/{deploy-BlZx6J5x.cjs → deploy-Bw2Mm3x3.cjs} +14 -5
  62. package/dist/deploy-Bw2Mm3x3.cjs.map +1 -0
  63. package/dist/{dokploy-rjXmkuwH.cjs → dokploy-C81J1MVK.cjs} +2 -2
  64. package/dist/{dokploy-rjXmkuwH.cjs.map → dokploy-C81J1MVK.cjs.map} +1 -1
  65. package/dist/{dokploy-Crh4uDmP.mjs → dokploy-DWALWk7u.mjs} +2 -2
  66. package/dist/{dokploy-Crh4uDmP.mjs.map → dokploy-DWALWk7u.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-CxTfRx4h.cjs → encryption-B8h8Tna0.cjs} +3 -3
  72. package/dist/{encryption-CxTfRx4h.cjs.map → encryption-B8h8Tna0.cjs.map} +1 -1
  73. package/dist/{encryption-0eo9aY_H.mjs → encryption-DpAum8W7.mjs} +3 -3
  74. package/dist/{encryption-0eo9aY_H.mjs.map → encryption-DpAum8W7.mjs.map} +1 -1
  75. package/dist/{engine-CMzSebbs.cjs → engine-B01fjhLt.cjs} +33 -13
  76. package/dist/engine-B01fjhLt.cjs.map +1 -0
  77. package/dist/{engine-DxWswfXe.mjs → engine-BXCtEhSH.mjs} +33 -13
  78. package/dist/engine-BXCtEhSH.mjs.map +1 -0
  79. package/dist/{github-HOfOpFI_.mjs → github-8B68qrLs.mjs} +3 -3
  80. package/dist/{github-HOfOpFI_.mjs.map → github-8B68qrLs.mjs.map} +1 -1
  81. package/dist/{github-Dukt5cJe.cjs → github-Cis9tYur.cjs} +3 -3
  82. package/dist/{github-Dukt5cJe.cjs.map → github-Cis9tYur.cjs.map} +1 -1
  83. package/dist/{index-Wuqpf316.d.mts → index-D1ODeM9s.d.cts} +2 -2
  84. package/dist/{index-DFrbhRwg.d.cts.map → index-D1ODeM9s.d.cts.map} +1 -1
  85. package/dist/{index-DFrbhRwg.d.cts → index-f77HdqN5.d.mts} +2 -2
  86. package/dist/{index-Wuqpf316.d.mts.map → index-f77HdqN5.d.mts.map} +1 -1
  87. package/dist/index.cjs +173 -70
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.mjs +173 -70
  90. package/dist/index.mjs.map +1 -1
  91. package/dist/{migrate-BgPWVnAZ.cjs → migrate-BBCp5blp.cjs} +3 -3
  92. package/dist/{migrate-BgPWVnAZ.cjs.map → migrate-BBCp5blp.cjs.map} +1 -1
  93. package/dist/{migrate-1dGEzuJ-.mjs → migrate-BeTWLSeC.mjs} +3 -3
  94. package/dist/{migrate-1dGEzuJ-.mjs.map → migrate-BeTWLSeC.mjs.map} +1 -1
  95. package/dist/{migrate-Bemd4tkz.cjs → migrate-CPWn7A51.cjs} +3 -3
  96. package/dist/{migrate-Bemd4tkz.cjs.map → migrate-CPWn7A51.cjs.map} +1 -1
  97. package/dist/{migrate-C14NNbFx.mjs → migrate-sDq7NApJ.mjs} +3 -3
  98. package/dist/{migrate-C14NNbFx.mjs.map → migrate-sDq7NApJ.mjs.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-y1PkSZrF.mjs → resolve-CXbwJ_iu.mjs} +3 -3
  110. package/dist/{resolve-y1PkSZrF.mjs.map → resolve-CXbwJ_iu.mjs.map} +1 -1
  111. package/dist/{resolve-DCTcD823.cjs → resolve-CztIqBOI.cjs} +3 -3
  112. package/dist/{resolve-DCTcD823.cjs.map → resolve-CztIqBOI.cjs.map} +1 -1
  113. package/dist/{rollback-CwVhG_xa.mjs → rollback-ByyFE5lV.mjs} +5 -5
  114. package/dist/{rollback-CwVhG_xa.mjs.map → rollback-ByyFE5lV.mjs.map} +1 -1
  115. package/dist/{rollback-BVQFDjxr.cjs → rollback-CyIJ4xGJ.cjs} +5 -5
  116. package/dist/{rollback-BVQFDjxr.cjs.map → rollback-CyIJ4xGJ.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-BoKQ74Od.mjs → seeds-9C5CkDon.mjs} +1736 -1613
  122. package/dist/seeds-9C5CkDon.mjs.map +1 -0
  123. package/dist/{seeds-Ccju3zGl.cjs → seeds-B_Beuv0o.cjs} +2583 -2418
  124. package/dist/seeds-B_Beuv0o.cjs.map +1 -0
  125. package/dist/{sniffer-DeyYI9Iv.cjs → sniffer-3fA0iExx.cjs} +6 -6
  126. package/dist/{sniffer-DeyYI9Iv.cjs.map → sniffer-3fA0iExx.cjs.map} +1 -1
  127. package/dist/{sniffer-6oYI-MpT.mjs → sniffer-DgBkaLAu.mjs} +6 -6
  128. package/dist/{sniffer-6oYI-MpT.mjs.map → sniffer-DgBkaLAu.mjs.map} +1 -1
  129. package/dist/{stages-CwrYVX9u.cjs → stages-CS1sjcRb.cjs} +2 -2
  130. package/dist/{stages-CwrYVX9u.cjs.map → stages-CS1sjcRb.cjs.map} +1 -1
  131. package/dist/{stages-CHF9RFog.mjs → stages-CSXt7N2b.mjs} +2 -2
  132. package/dist/{stages-CHF9RFog.mjs.map → stages-CSXt7N2b.mjs.map} +1 -1
  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-BzCavjGt.d.mts → types-BZn-8ssD.d.mts} +75 -21
  138. package/dist/types-BZn-8ssD.d.mts.map +1 -0
  139. package/dist/{types-DZtj9jeI.d.cts → types-DiZj6hqp.d.cts} +75 -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 +1 -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 +1 -1
  147. package/dist/{workspace-4i6Jwsoa.cjs → workspace-Bic_R3tz.cjs} +324 -98
  148. package/dist/workspace-Bic_R3tz.cjs.map +1 -0
  149. package/dist/{workspace-DD9mtPy8.mjs → workspace-Drz4jsvy.mjs} +305 -97
  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/LocalStateStore-BsFHdSeA.cjs.map +0 -1
  155. package/dist/LocalStateStore-DIfuh0Z1.mjs.map +0 -1
  156. package/dist/compose-BPJ9bUKp.mjs.map +0 -1
  157. package/dist/compose-CGyxYe-h.cjs.map +0 -1
  158. package/dist/config-BBFiH4qk.d.mts.map +0 -1
  159. package/dist/config-DMdzdO5u.d.cts.map +0 -1
  160. package/dist/deploy-0XpZDYAr.mjs.map +0 -1
  161. package/dist/deploy-BlZx6J5x.cjs.map +0 -1
  162. package/dist/engine-CMzSebbs.cjs.map +0 -1
  163. package/dist/engine-DxWswfXe.mjs.map +0 -1
  164. package/dist/seeds-BoKQ74Od.mjs.map +0 -1
  165. package/dist/seeds-Ccju3zGl.cjs.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-4i6Jwsoa.cjs.map +0 -1
  169. package/dist/workspace-DD9mtPy8.mjs.map +0 -1
@@ -37,10 +37,92 @@ function assertKnownSecretsStore(store) {
37
37
  if (typeof provider === "string" && !SECRETS_STORE_PROVIDERS.includes(provider)) throw new UnknownSecretsStoreProvider(provider);
38
38
  }
39
39
  //#endregion
40
+ //#region src/compose/proxy.ts
41
+ /**
42
+ * Which proxy a stage's stack is served by, and with whose certificate —
43
+ * `deploy.compose.proxy` and `deploy.compose.tls`, resolved for one stage.
44
+ *
45
+ * Pure, and kept apart from the stack so the workspace schema can check a
46
+ * config with the same rules — and the same named errors — the stack applies.
47
+ */
48
+ /** A per-stage setting keyed by a stage the workspace does not have. */
49
+ var ComposeStageUnknown = class extends Error {
50
+ setting;
51
+ stage;
52
+ stages;
53
+ constructor(setting, stage, stages) {
54
+ 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.`);
55
+ this.setting = setting;
56
+ this.stage = stage;
57
+ this.stages = stages;
58
+ this.name = "ComposeStageUnknown";
59
+ }
60
+ };
61
+ /**
62
+ * A certificate for the local stage, whose certificates are always Caddy's
63
+ * own CA — the one `gkm trust` installs.
64
+ */
65
+ var ComposeTlsOnLocalStage = class extends Error {
66
+ stage;
67
+ constructor(stage) {
68
+ 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.`);
69
+ this.stage = stage;
70
+ this.name = "ComposeTlsOnLocalStage";
71
+ }
72
+ };
73
+ /** The stage's certificate or key file is not there to read. */
74
+ var ComposeTlsFileMissing = class extends Error {
75
+ stage;
76
+ file;
77
+ constructor(stage, file) {
78
+ 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.`);
79
+ this.stage = stage;
80
+ this.file = file;
81
+ this.name = "ComposeTlsFileMissing";
82
+ }
83
+ };
84
+ /**
85
+ * The proxy a stage's stack is served by. The local stage is always Caddy —
86
+ * its internal CA and `gkm trust` — whatever is configured.
87
+ */
88
+ function proxyFor(config, stage, local) {
89
+ if (local) return "caddy";
90
+ const proxy = config?.proxy;
91
+ if (!proxy) return "caddy";
92
+ if (typeof proxy === "string") return proxy;
93
+ return proxy[stage] ?? "caddy";
94
+ }
95
+ /** A deployed stage's own certificate, its paths absolute, when it sets one. */
96
+ function certificateFor(config, stage, root) {
97
+ const tls = config?.tls?.[stage];
98
+ if (!tls) return void 0;
99
+ const absolute = (file) => isAbsolute(file) ? file : resolve(root, file);
100
+ return {
101
+ certFile: absolute(tls.certFile),
102
+ keyFile: absolute(tls.keyFile)
103
+ };
104
+ }
105
+ /**
106
+ * Throws the named error for the first thing wrong with the per-stage
107
+ * settings: a stage the workspace does not have, or a certificate for the
108
+ * local stage.
109
+ */
110
+ function checkComposeStages(config, stages) {
111
+ const known = [stages.local, ...stages.deployed];
112
+ if (config?.proxy && typeof config.proxy === "object") {
113
+ for (const stage of Object.keys(config.proxy)) if (!known.includes(stage)) throw new ComposeStageUnknown("proxy", stage, known);
114
+ }
115
+ for (const stage of Object.keys(config?.tls ?? {})) {
116
+ if (stage === stages.local) throw new ComposeTlsOnLocalStage(stage);
117
+ if (!known.includes(stage)) throw new ComposeStageUnknown("tls", stage, known);
118
+ }
119
+ }
120
+ //#endregion
40
121
  //#region src/compose/logsConfig.ts
41
122
  /**
42
- * `deploy.compose.logs`, read: whether the stack runs OpenObserve, and how it
43
- * is reached.
123
+ * The self-hosted telemetry provider's options, read: how the stack's
124
+ * OpenObserve is run and reached — `deploy.telemetry.<stage>` with
125
+ * `provider: 'self-hosted'`.
44
126
  *
45
127
  * Kept apart from the stack so the workspace schema can check a config with
46
128
  * the same rules — and the same named errors — the stack applies.
@@ -49,34 +131,42 @@ function assertKnownSecretsStore(store) {
49
131
  const LOGS_PORT = 5080;
50
132
  /** `public` with no address to allow: nobody could reach it. */
51
133
  var LogsAllowEmpty = class extends Error {
52
- constructor() {
53
- 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.");
134
+ stage;
135
+ constructor(stage) {
136
+ 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.`);
137
+ this.stage = stage;
54
138
  this.name = "LogsAllowEmpty";
55
139
  }
56
140
  };
57
141
  /** An `allow` entry that is not an IP address or a CIDR range. */
58
142
  var LogsAllowEntryInvalid = class extends Error {
143
+ stage;
59
144
  entry;
60
- constructor(entry) {
61
- 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'.`);
145
+ constructor(stage, entry) {
146
+ 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'.`);
147
+ this.stage = stage;
62
148
  this.entry = entry;
63
149
  this.name = "LogsAllowEntryInvalid";
64
150
  }
65
151
  };
66
152
  /** A retention OpenObserve would refuse to start with. */
67
153
  var LogsRetentionInvalid = class extends Error {
154
+ stage;
68
155
  retentionDays;
69
- constructor(retentionDays) {
70
- 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.`);
156
+ constructor(stage, retentionDays) {
157
+ 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.`);
158
+ this.stage = stage;
71
159
  this.retentionDays = retentionDays;
72
160
  this.name = "LogsRetentionInvalid";
73
161
  }
74
162
  };
75
163
  /** A port that is not one. */
76
164
  var LogsPortInvalid = class extends Error {
165
+ stage;
77
166
  port;
78
- constructor(port) {
79
- super(`deploy.compose.logs.port is ${String(port)}; set it to a number between 1 and 65535, or leave it out for ${LOGS_PORT}.`);
167
+ constructor(stage, port) {
168
+ super(`deploy.telemetry.${stage}.port is ${String(port)}; set it to a number between 1 and 65535, or leave it out for ${LOGS_PORT}.`);
169
+ this.stage = stage;
80
170
  this.port = port;
81
171
  this.name = "LogsPortInvalid";
82
172
  }
@@ -92,20 +182,18 @@ function isAddressOrRange(entry) {
92
182
  return Number(prefix) <= (family === 4 ? 32 : 128);
93
183
  }
94
184
  /**
95
- * `deploy.compose.logs` with its defaults, or undefined when it is off.
96
- * Throws the named error for the first thing wrong with it.
185
+ * The self-hosted provider's options with their defaults — `{}` for all of
186
+ * them. Throws the named error for the first thing wrong with them.
97
187
  */
98
- function resolveLogs(logs) {
99
- if (!logs) return void 0;
100
- const config = logs === true ? {} : logs;
188
+ function resolveSelfHosted(config, stage) {
101
189
  const port = config.port ?? 5080;
102
- if (!Number.isInteger(port) || port < 1 || port > 65535) throw new LogsPortInvalid(config.port);
190
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new LogsPortInvalid(stage, config.port);
103
191
  const retentionDays = config.retentionDays ?? 30;
104
- if (!Number.isInteger(retentionDays) || retentionDays < 3) throw new LogsRetentionInvalid(config.retentionDays);
192
+ if (!Number.isInteger(retentionDays) || retentionDays < 3) throw new LogsRetentionInvalid(stage, config.retentionDays);
105
193
  if (config.public) {
106
194
  const allow = config.public.allow ?? [];
107
- if (allow.length === 0) throw new LogsAllowEmpty();
108
- for (const entry of allow) if (!isAddressOrRange(entry)) throw new LogsAllowEntryInvalid(entry);
195
+ if (allow.length === 0) throw new LogsAllowEmpty(stage);
196
+ for (const entry of allow) if (!isAddressOrRange(entry)) throw new LogsAllowEntryInvalid(stage, entry);
109
197
  return {
110
198
  port,
111
199
  retentionDays,
@@ -118,85 +206,189 @@ function resolveLogs(logs) {
118
206
  };
119
207
  }
120
208
  //#endregion
121
- //#region src/compose/proxy.ts
209
+ //#region src/telemetry/config.ts
122
210
  /**
123
- * Which proxy a stage's stack is served by, and with whose certificate —
124
- * `deploy.compose.proxy` and `deploy.compose.tls`, resolved for one stage.
211
+ * `deploy.telemetry`, read: where one stage's telemetry goes, and how much.
125
212
  *
126
- * Pure, and kept apart from the stack so the workspace schema can check a
127
- * config with the same rules — and the same named errors — the stack applies.
213
+ * The application says what it emits (the `Telemetry` construct). This says
214
+ * where it is sent, per stage, and is the only place that does:
215
+ *
216
+ * - **self-hosted** — the target runs OpenObserve beside the apps (#189's
217
+ * stack service). A server target that can run it uses it when a stage
218
+ * names nothing.
219
+ * - **otlp** — any OTLP/HTTP endpoint, with its headers.
220
+ * - **false** — nothing is sent.
221
+ *
222
+ * Vendor presets (a known endpoint and header shape, with the stage secret
223
+ * `TELEMETRY_CREDENTIALS`) are one more entry in {@link PROVIDERS}: a
224
+ * resolver from the stage's config to a {@link ResolvedTelemetry}, which
225
+ * every target already consumes through {@link telemetryEnv}.
226
+ *
227
+ * The local stage ignores all of it: `gkm dev` and `gkm compose` on it run
228
+ * OpenObserve and keep every trace.
128
229
  */
129
- /** A per-stage setting keyed by a stage the workspace does not have. */
130
- var ComposeStageUnknown = class extends Error {
131
- setting;
230
+ /** A deployed stage uses telemetry and its target cannot choose for it. */
231
+ var TelemetryProviderRequired = class extends Error {
132
232
  stage;
133
- stages;
134
- constructor(setting, stage, stages) {
135
- 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.`);
136
- this.setting = setting;
233
+ target;
234
+ constructor(stage, target) {
235
+ 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.`);
137
236
  this.stage = stage;
138
- this.stages = stages;
139
- this.name = "ComposeStageUnknown";
237
+ this.target = target;
238
+ this.name = "TelemetryProviderRequired";
140
239
  }
141
240
  };
142
- /**
143
- * A certificate for the local stage, whose certificates are always Caddy's
144
- * own CA — the one `gkm trust` installs.
145
- */
146
- var ComposeTlsOnLocalStage = class extends Error {
241
+ /** A stage asks for the self-hosted provider on a target that cannot run it. */
242
+ var SelfHostedTelemetryUnavailable = class extends Error {
147
243
  stage;
148
- constructor(stage) {
149
- 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.`);
244
+ target;
245
+ constructor(stage, target) {
246
+ 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://…' } } }.`);
150
247
  this.stage = stage;
151
- this.name = "ComposeTlsOnLocalStage";
248
+ this.target = target;
249
+ this.name = "SelfHostedTelemetryUnavailable";
152
250
  }
153
251
  };
154
- /** The stage's certificate or key file is not there to read. */
155
- var ComposeTlsFileMissing = class extends Error {
252
+ /** A sample rate that is not a fraction. */
253
+ var TelemetrySampleRateInvalid = class extends Error {
156
254
  stage;
157
- file;
158
- constructor(stage, file) {
159
- 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.`);
255
+ sampleRate;
256
+ constructor(stage, sampleRate) {
257
+ 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.`);
160
258
  this.stage = stage;
161
- this.file = file;
162
- this.name = "ComposeTlsFileMissing";
259
+ this.sampleRate = sampleRate;
260
+ this.name = "TelemetrySampleRateInvalid";
261
+ }
262
+ };
263
+ /** An OTLP endpoint that is not an http(s) URL. */
264
+ var TelemetryEndpointInvalid = class extends Error {
265
+ stage;
266
+ endpoint;
267
+ constructor(stage, endpoint) {
268
+ 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.`);
269
+ this.stage = stage;
270
+ this.endpoint = endpoint;
271
+ this.name = "TelemetryEndpointInvalid";
163
272
  }
164
273
  };
274
+ /** The sample rate a stage keeps, checked. */
275
+ function sampleRateOf(stage, sampleRate) {
276
+ const rate = sampleRate ?? 1;
277
+ if (!Number.isFinite(rate) || rate < 0 || rate > 1) throw new TelemetrySampleRateInvalid(stage, sampleRate);
278
+ return rate;
279
+ }
165
280
  /**
166
- * The proxy a stage's stack is served by. The local stage is always Caddy —
167
- * its internal CA and `gkm trust` — whatever is configured.
281
+ * Each provider's resolver: a stage's config to what the targets consume.
282
+ * A vendor preset is one more entry here.
168
283
  */
169
- function proxyFor(config, stage, local) {
170
- if (local) return "caddy";
171
- const proxy = config?.proxy;
172
- if (!proxy) return "caddy";
173
- if (typeof proxy === "string") return proxy;
174
- return proxy[stage] ?? "caddy";
284
+ const PROVIDERS = {
285
+ "self-hosted": (config, stage) => {
286
+ const { provider: _, sampleRate, ...options } = config;
287
+ return {
288
+ provider: "self-hosted",
289
+ selfHosted: resolveSelfHosted(options, stage),
290
+ sampleRate: sampleRateOf(stage, sampleRate)
291
+ };
292
+ },
293
+ otlp: (config, stage) => {
294
+ if (typeof config.endpoint !== "string" || !isHttpUrl(config.endpoint)) throw new TelemetryEndpointInvalid(stage, config.endpoint);
295
+ return {
296
+ provider: "otlp",
297
+ endpoint: config.endpoint.replace(/\/+$/, ""),
298
+ headers: { ...config.headers },
299
+ sampleRate: sampleRateOf(stage, config.sampleRate)
300
+ };
301
+ }
302
+ };
303
+ function isHttpUrl(value) {
304
+ try {
305
+ const url = new URL(value);
306
+ return url.protocol === "http:" || url.protocol === "https:";
307
+ } catch {
308
+ return false;
309
+ }
175
310
  }
176
- /** A deployed stage's own certificate, its paths absolute, when it sets one. */
177
- function certificateFor(config, stage, root) {
178
- const tls = config?.tls?.[stage];
179
- if (!tls) return void 0;
180
- const absolute = (file) => isAbsolute(file) ? file : resolve(root, file);
181
- return {
182
- certFile: absolute(tls.certFile),
183
- keyFile: absolute(tls.keyFile)
311
+ /**
312
+ * One stage's entry, checked on its own — what the workspace schema runs, so
313
+ * a bad config fails to load with the words a deploy would fail with.
314
+ */
315
+ function checkStageTelemetry(stage, config) {
316
+ if (config === false) return void 0;
317
+ const entry = config === "self-hosted" ? { provider: "self-hosted" } : config;
318
+ const resolve = PROVIDERS[entry.provider];
319
+ return resolve(entry, stage);
320
+ }
321
+ /**
322
+ * Where a stage's telemetry goes, or undefined when nothing is sent — no
323
+ * process uses a `Telemetry` node, or the stage opted out with `false`.
324
+ *
325
+ * The local stage always runs the self-hosted provider with its defaults and
326
+ * keeps every trace, whatever `deploy.telemetry` says. A deployed stage that
327
+ * names nothing gets the self-hosted provider where its target runs one, and
328
+ * {@link TelemetryProviderRequired} where it cannot — AWS has none.
329
+ */
330
+ function resolveStageTelemetry(input) {
331
+ const { stage } = input;
332
+ if (!input.used) return void 0;
333
+ if (input.local) return {
334
+ provider: "self-hosted",
335
+ selfHosted: resolveSelfHosted({}, stage),
336
+ sampleRate: 1
184
337
  };
338
+ const config = input.telemetry?.[stage];
339
+ if (config === void 0) {
340
+ if (input.runtime === "server" && input.selfHosted) return checkStageTelemetry(stage, "self-hosted");
341
+ throw new TelemetryProviderRequired(stage, input.target);
342
+ }
343
+ const resolved = checkStageTelemetry(stage, config);
344
+ if (resolved?.provider === "self-hosted" && !input.selfHosted) throw new SelfHostedTelemetryUnavailable(stage, input.target);
345
+ return resolved;
185
346
  }
347
+ /** The sampler every process with the edge runs, per the stage's rate. */
348
+ const TRACES_SAMPLER = "parentbased_traceidratio";
186
349
  /**
187
- * Throws the named error for the first thing wrong with the per-stage
188
- * settings: a stage the workspace does not have, or a certificate for the
189
- * local stage.
350
+ * `OTEL_EXPORTER_OTLP_HEADERS` for a set of headers: `key=value` pairs,
351
+ * comma-separated, each value percent-encoded — the W3C baggage format the
352
+ * SDK parses.
190
353
  */
191
- function checkComposeStages(config, stages) {
192
- const known = [stages.local, ...stages.deployed];
193
- if (config?.proxy && typeof config.proxy === "object") {
194
- for (const stage of Object.keys(config.proxy)) if (!known.includes(stage)) throw new ComposeStageUnknown("proxy", stage, known);
195
- }
196
- for (const stage of Object.keys(config?.tls ?? {})) {
197
- if (stage === stages.local) throw new ComposeTlsOnLocalStage(stage);
198
- if (!known.includes(stage)) throw new ComposeStageUnknown("tls", stage, known);
199
- }
354
+ function otlpHeaderString(headers) {
355
+ return Object.entries(headers).map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join(",");
356
+ }
357
+ /**
358
+ * The `OTEL_*` values a stage resolves for its `Telemetry` node, before any
359
+ * one process is named: where to export, how to sign, and how much to keep.
360
+ * `OTEL_SERVICE_NAME` is each process's own — see `scopeTelemetryEnv`.
361
+ */
362
+ function telemetryEnv(destination, sampleRate) {
363
+ return {
364
+ OTEL_EXPORTER_OTLP_ENDPOINT: destination.endpoint,
365
+ ...destination.headers ? { OTEL_EXPORTER_OTLP_HEADERS: destination.headers } : {},
366
+ OTEL_TRACES_SAMPLER: TRACES_SAMPLER,
367
+ OTEL_TRACES_SAMPLER_ARG: String(sampleRate)
368
+ };
369
+ }
370
+ /** What an `otlp` stage resolves, for every process with the edge. */
371
+ function otlpTelemetryEnv(resolved) {
372
+ const headers = otlpHeaderString(resolved.headers);
373
+ return telemetryEnv({
374
+ endpoint: resolved.endpoint,
375
+ ...headers ? { headers } : {}
376
+ }, resolved.sampleRate);
377
+ }
378
+ /**
379
+ * The sample rate a stage's browsers trace page views at — a public value,
380
+ * the same rate its servers sample at — or undefined when the stage sends no
381
+ * telemetry. The local stage keeps every trace.
382
+ *
383
+ * Lenient where `resolveStageTelemetry` is strict: a site's client is built
384
+ * before, and apart from, the deploy that refuses a stage with no provider.
385
+ */
386
+ function stageSampleRate(telemetry, stage, local) {
387
+ if (local) return 1;
388
+ const config = telemetry?.[stage];
389
+ if (config === false) return void 0;
390
+ if (config === void 0 || config === "self-hosted") return 1;
391
+ return sampleRateOf(stage, config.sampleRate);
200
392
  }
201
393
  //#endregion
202
394
  //#region src/workspace/stages.ts
@@ -581,31 +773,46 @@ const BackupsConfigSchema = object({
581
773
  /** Number of backups to retain (default: 30) */
582
774
  retention: number().optional()
583
775
  });
584
- /**
585
- * `deploy.compose` — what the compose target runs beside the apps. The rules
586
- * past the shape are `resolveLogs`'s, so the schema and the stack refuse the
587
- * same configs with the same words.
588
- */
776
+ /** `deploy.compose` — what the compose target runs beside the apps. */
589
777
  const ComposeWorkspaceConfigSchema = object({
590
- logs: union([boolean(), object({
591
- port: number().optional(),
592
- retentionDays: number().optional(),
593
- public: object({ allow: array(string()) }).optional()
594
- })]).superRefine((logs, ctx) => {
595
- try {
596
- resolveLogs(logs);
597
- } catch (error) {
598
- ctx.addIssue({
599
- code: "custom",
600
- message: error instanceof Error ? error.message : String(error)
601
- });
602
- }
603
- }).optional(),
604
778
  proxy: union([_enum(["caddy", "traefik"]), record(string(), _enum(["caddy", "traefik"]))]).optional(),
605
779
  tls: record(string(), object({
606
780
  certFile: string().min(1),
607
781
  keyFile: string().min(1)
608
782
  }).strict()).optional()
783
+ }).strict();
784
+ const TelemetrySampleRate = number().optional();
785
+ /**
786
+ * `deploy.telemetry` — where each stage's telemetry goes. The rules past the
787
+ * shape are `checkStageTelemetry`'s, so the schema and a deploy refuse the
788
+ * same configs with the same words.
789
+ */
790
+ const TelemetryConfigSchema = record(string(), union([
791
+ literal(false),
792
+ literal("self-hosted"),
793
+ object({
794
+ provider: literal("self-hosted"),
795
+ port: number().optional(),
796
+ retentionDays: number().optional(),
797
+ public: object({ allow: array(string()) }).optional(),
798
+ sampleRate: TelemetrySampleRate
799
+ }).strict(),
800
+ object({
801
+ provider: literal("otlp"),
802
+ endpoint: string(),
803
+ headers: record(string(), string()).optional(),
804
+ sampleRate: TelemetrySampleRate
805
+ }).strict()
806
+ ])).superRefine((telemetry, ctx) => {
807
+ for (const [stage, config] of Object.entries(telemetry)) try {
808
+ checkStageTelemetry(stage, config);
809
+ } catch (error) {
810
+ ctx.addIssue({
811
+ code: "custom",
812
+ message: error instanceof Error ? error.message : String(error),
813
+ path: [stage]
814
+ });
815
+ }
609
816
  });
610
817
  /**
611
818
  * Deploy configuration schema.
@@ -627,6 +834,7 @@ const DeployConfigSchema = object({
627
834
  registry: string().min(1).optional(),
628
835
  dokploy: DokployWorkspaceConfigSchema.optional(),
629
836
  compose: ComposeWorkspaceConfigSchema.optional(),
837
+ telemetry: TelemetryConfigSchema.optional(),
630
838
  dns: DnsConfigWithLegacySchema.optional(),
631
839
  backups: BackupsConfigSchema.optional()
632
840
  });
@@ -1297,6 +1505,6 @@ function getEndpointForStage(dokployConfig, stage) {
1297
1505
  return dokployConfig.endpoint;
1298
1506
  }
1299
1507
  //#endregion
1300
- export { UndeclaredStage as A, UnknownSecretsStoreProvider as B, getDeployTargetError as C, validateWorkspaceConfig as D, safeValidateWorkspaceConfig as E, certificateFor as F, proxyFor as I, LOGS_PORT as L, deployedProblems as M, stageProblems as N, InvalidStages as O, ComposeTlsFileMissing as P, resolveLogs as R, formatValidationErrors as S, isPhase2DeployTarget as T, stripPublicPrefix as _, assertNoMovedDeployKeys as a, SUPPORTED_DEPLOY_TARGETS as b, getAppBuildOrder as c, normalizeWorkspace as d, processConfig as f, getPublicEnvPrefix as g, PUBLIC_ENV_PREFIXES as h, appConstructGlobs as i, assertDeployedStage as j, TEST_STAGE as k, getAppGkmConfig as l, wrapSingleAppAsWorkspace as m, InvalidWorkspaceConfig as n, constructPatterns as o, workspaceConstructGlobs as p, allConstructGlobs as r, defineWorkspace as s, DokployRegistryMoved as t, getEndpointForStage as u, isWorkspaceConfig as v, isDeployTargetSupported as w, WorkspaceConfigSchema as x, PHASE_2_DEPLOY_TARGETS as y, SECRETS_STORE_PROVIDERS as z };
1508
+ export { UndeclaredStage as A, certificateFor as B, getDeployTargetError as C, validateWorkspaceConfig as D, safeValidateWorkspaceConfig as E, resolveStageTelemetry as F, SECRETS_STORE_PROVIDERS as H, stageSampleRate as I, telemetryEnv as L, deployedProblems as M, stageProblems as N, InvalidStages as O, otlpTelemetryEnv as P, LOGS_PORT as R, formatValidationErrors as S, isPhase2DeployTarget as T, UnknownSecretsStoreProvider as U, proxyFor as V, stripPublicPrefix as _, assertNoMovedDeployKeys as a, SUPPORTED_DEPLOY_TARGETS as b, getAppBuildOrder as c, normalizeWorkspace as d, processConfig as f, getPublicEnvPrefix as g, PUBLIC_ENV_PREFIXES as h, appConstructGlobs as i, assertDeployedStage as j, TEST_STAGE as k, getAppGkmConfig as l, wrapSingleAppAsWorkspace as m, InvalidWorkspaceConfig as n, constructPatterns as o, workspaceConstructGlobs as p, allConstructGlobs as r, defineWorkspace as s, DokployRegistryMoved as t, getEndpointForStage as u, isWorkspaceConfig as v, isDeployTargetSupported as w, WorkspaceConfigSchema as x, PHASE_2_DEPLOY_TARGETS as y, ComposeTlsFileMissing as z };
1301
1509
 
1302
- //# sourceMappingURL=workspace-DD9mtPy8.mjs.map
1510
+ //# sourceMappingURL=workspace-Drz4jsvy.mjs.map