@miragon/pulse-analytics-client 0.0.0-bootstrap.0 → 0.21.0

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 (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -3
  3. package/dist/index.d.ts +12 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +14 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/metric-names.d.ts +43 -0
  8. package/dist/metric-names.d.ts.map +1 -0
  9. package/dist/metric-names.js +53 -0
  10. package/dist/metric-names.js.map +1 -0
  11. package/dist/metrics-contract-labels.test.d.ts +2 -0
  12. package/dist/metrics-contract-labels.test.d.ts.map +1 -0
  13. package/dist/metrics-contract-labels.test.js +169 -0
  14. package/dist/metrics-contract-labels.test.js.map +1 -0
  15. package/dist/metrics-contract.test.d.ts +2 -0
  16. package/dist/metrics-contract.test.d.ts.map +1 -0
  17. package/dist/metrics-contract.test.js +247 -0
  18. package/dist/metrics-contract.test.js.map +1 -0
  19. package/dist/prometheus-client.test.d.ts +2 -0
  20. package/dist/prometheus-client.test.d.ts.map +1 -0
  21. package/dist/prometheus-client.test.js +265 -0
  22. package/dist/prometheus-client.test.js.map +1 -0
  23. package/dist/prometheus.d.ts +100 -0
  24. package/dist/prometheus.d.ts.map +1 -0
  25. package/dist/prometheus.js +295 -0
  26. package/dist/prometheus.js.map +1 -0
  27. package/dist/prometheus.test.d.ts +2 -0
  28. package/dist/prometheus.test.d.ts.map +1 -0
  29. package/dist/prometheus.test.js +54 -0
  30. package/dist/prometheus.test.js.map +1 -0
  31. package/dist/promql-labels.test-support.d.ts +53 -0
  32. package/dist/promql-labels.test-support.d.ts.map +1 -0
  33. package/dist/promql-labels.test-support.js +237 -0
  34. package/dist/promql-labels.test-support.js.map +1 -0
  35. package/dist/promql-labels.test.d.ts +2 -0
  36. package/dist/promql-labels.test.d.ts.map +1 -0
  37. package/dist/promql-labels.test.js +190 -0
  38. package/dist/promql-labels.test.js.map +1 -0
  39. package/dist/promql-parse.test-support.d.ts +57 -0
  40. package/dist/promql-parse.test-support.d.ts.map +1 -0
  41. package/dist/promql-parse.test-support.js +284 -0
  42. package/dist/promql-parse.test-support.js.map +1 -0
  43. package/dist/promql-reading-rules.test-support.d.ts +29 -0
  44. package/dist/promql-reading-rules.test-support.d.ts.map +1 -0
  45. package/dist/promql-reading-rules.test-support.js +79 -0
  46. package/dist/promql-reading-rules.test-support.js.map +1 -0
  47. package/dist/promql-reading-rules.test.d.ts +2 -0
  48. package/dist/promql-reading-rules.test.d.ts.map +1 -0
  49. package/dist/promql-reading-rules.test.js +61 -0
  50. package/dist/promql-reading-rules.test.js.map +1 -0
  51. package/dist/promql-sources.test-support.d.ts +29 -0
  52. package/dist/promql-sources.test-support.d.ts.map +1 -0
  53. package/dist/promql-sources.test-support.js +112 -0
  54. package/dist/promql-sources.test-support.js.map +1 -0
  55. package/dist/promql-sources.test.d.ts +2 -0
  56. package/dist/promql-sources.test.d.ts.map +1 -0
  57. package/dist/promql-sources.test.js +93 -0
  58. package/dist/promql-sources.test.js.map +1 -0
  59. package/dist/queries/as-of.test.d.ts +2 -0
  60. package/dist/queries/as-of.test.d.ts.map +1 -0
  61. package/dist/queries/as-of.test.js +80 -0
  62. package/dist/queries/as-of.test.js.map +1 -0
  63. package/dist/queries/cluster-compare.d.ts +62 -0
  64. package/dist/queries/cluster-compare.d.ts.map +1 -0
  65. package/dist/queries/cluster-compare.js +70 -0
  66. package/dist/queries/cluster-compare.js.map +1 -0
  67. package/dist/queries/cluster-compare.test.d.ts +2 -0
  68. package/dist/queries/cluster-compare.test.d.ts.map +1 -0
  69. package/dist/queries/cluster-compare.test.js +81 -0
  70. package/dist/queries/cluster-compare.test.js.map +1 -0
  71. package/dist/queries/dashboard.d.ts +60 -0
  72. package/dist/queries/dashboard.d.ts.map +1 -0
  73. package/dist/queries/dashboard.js +292 -0
  74. package/dist/queries/dashboard.js.map +1 -0
  75. package/dist/queries/dashboard.test.d.ts +2 -0
  76. package/dist/queries/dashboard.test.d.ts.map +1 -0
  77. package/dist/queries/dashboard.test.js +423 -0
  78. package/dist/queries/dashboard.test.js.map +1 -0
  79. package/dist/queries/element.d.ts +68 -0
  80. package/dist/queries/element.d.ts.map +1 -0
  81. package/dist/queries/element.js +98 -0
  82. package/dist/queries/element.js.map +1 -0
  83. package/dist/queries/element.test.d.ts +2 -0
  84. package/dist/queries/element.test.d.ts.map +1 -0
  85. package/dist/queries/element.test.js +105 -0
  86. package/dist/queries/element.test.js.map +1 -0
  87. package/dist/queries/engine-compare.d.ts +52 -0
  88. package/dist/queries/engine-compare.d.ts.map +1 -0
  89. package/dist/queries/engine-compare.js +57 -0
  90. package/dist/queries/engine-compare.js.map +1 -0
  91. package/dist/queries/engine-compare.test.d.ts +2 -0
  92. package/dist/queries/engine-compare.test.d.ts.map +1 -0
  93. package/dist/queries/engine-compare.test.js +159 -0
  94. package/dist/queries/engine-compare.test.js.map +1 -0
  95. package/dist/queries/engine-landscape.d.ts +92 -0
  96. package/dist/queries/engine-landscape.d.ts.map +1 -0
  97. package/dist/queries/engine-landscape.js +183 -0
  98. package/dist/queries/engine-landscape.js.map +1 -0
  99. package/dist/queries/engine-landscape.test.d.ts +2 -0
  100. package/dist/queries/engine-landscape.test.d.ts.map +1 -0
  101. package/dist/queries/engine-landscape.test.js +171 -0
  102. package/dist/queries/engine-landscape.test.js.map +1 -0
  103. package/dist/queries/failures.d.ts +33 -0
  104. package/dist/queries/failures.d.ts.map +1 -0
  105. package/dist/queries/failures.js +31 -0
  106. package/dist/queries/failures.js.map +1 -0
  107. package/dist/queries/health.d.ts +77 -0
  108. package/dist/queries/health.d.ts.map +1 -0
  109. package/dist/queries/health.js +126 -0
  110. package/dist/queries/health.js.map +1 -0
  111. package/dist/queries/health.test.d.ts +2 -0
  112. package/dist/queries/health.test.d.ts.map +1 -0
  113. package/dist/queries/health.test.js +187 -0
  114. package/dist/queries/health.test.js.map +1 -0
  115. package/dist/queries/helpers.d.ts +184 -0
  116. package/dist/queries/helpers.d.ts.map +1 -0
  117. package/dist/queries/helpers.js +219 -0
  118. package/dist/queries/helpers.js.map +1 -0
  119. package/dist/queries/helpers.test.d.ts +2 -0
  120. package/dist/queries/helpers.test.d.ts.map +1 -0
  121. package/dist/queries/helpers.test.js +53 -0
  122. package/dist/queries/helpers.test.js.map +1 -0
  123. package/dist/queries/index.d.ts +19 -0
  124. package/dist/queries/index.d.ts.map +1 -0
  125. package/dist/queries/index.js +10 -0
  126. package/dist/queries/index.js.map +1 -0
  127. package/dist/queries/performance.d.ts +103 -0
  128. package/dist/queries/performance.d.ts.map +1 -0
  129. package/dist/queries/performance.js +173 -0
  130. package/dist/queries/performance.js.map +1 -0
  131. package/dist/queries/performance.test.d.ts +2 -0
  132. package/dist/queries/performance.test.d.ts.map +1 -0
  133. package/dist/queries/performance.test.js +265 -0
  134. package/dist/queries/performance.test.js.map +1 -0
  135. package/dist/queries/version-compare.d.ts +41 -0
  136. package/dist/queries/version-compare.d.ts.map +1 -0
  137. package/dist/queries/version-compare.js +44 -0
  138. package/dist/queries/version-compare.js.map +1 -0
  139. package/dist/queries/version-compare.test.d.ts +2 -0
  140. package/dist/queries/version-compare.test.d.ts.map +1 -0
  141. package/dist/queries/version-compare.test.js +162 -0
  142. package/dist/queries/version-compare.test.js.map +1 -0
  143. package/dist/queries/windows.d.ts +40 -0
  144. package/dist/queries/windows.d.ts.map +1 -0
  145. package/dist/queries/windows.js +56 -0
  146. package/dist/queries/windows.js.map +1 -0
  147. package/dist/query-honesty.test.d.ts +2 -0
  148. package/dist/query-honesty.test.d.ts.map +1 -0
  149. package/dist/query-honesty.test.js +294 -0
  150. package/dist/query-honesty.test.js.map +1 -0
  151. package/dist/query-scenarios.test-support.d.ts +49 -0
  152. package/dist/query-scenarios.test-support.d.ts.map +1 -0
  153. package/dist/query-scenarios.test-support.js +146 -0
  154. package/dist/query-scenarios.test-support.js.map +1 -0
  155. package/dist/schemas/cluster-compare.d.ts +11 -0
  156. package/dist/schemas/cluster-compare.d.ts.map +1 -0
  157. package/dist/schemas/cluster-compare.js +35 -0
  158. package/dist/schemas/cluster-compare.js.map +1 -0
  159. package/dist/schemas/engine-compare.d.ts +10 -0
  160. package/dist/schemas/engine-compare.d.ts.map +1 -0
  161. package/dist/schemas/engine-compare.js +27 -0
  162. package/dist/schemas/engine-compare.js.map +1 -0
  163. package/dist/schemas/engine-landscape.d.ts +5 -0
  164. package/dist/schemas/engine-landscape.d.ts.map +1 -0
  165. package/dist/schemas/engine-landscape.js +8 -0
  166. package/dist/schemas/engine-landscape.js.map +1 -0
  167. package/dist/schemas/failures.d.ts +8 -0
  168. package/dist/schemas/failures.d.ts.map +1 -0
  169. package/dist/schemas/failures.js +9 -0
  170. package/dist/schemas/failures.js.map +1 -0
  171. package/dist/schemas/health.d.ts +5 -0
  172. package/dist/schemas/health.d.ts.map +1 -0
  173. package/dist/schemas/health.js +6 -0
  174. package/dist/schemas/health.js.map +1 -0
  175. package/dist/schemas/index.d.ts +10 -0
  176. package/dist/schemas/index.d.ts.map +1 -0
  177. package/dist/schemas/index.js +10 -0
  178. package/dist/schemas/index.js.map +1 -0
  179. package/dist/schemas/path.d.ts +15 -0
  180. package/dist/schemas/path.d.ts.map +1 -0
  181. package/dist/schemas/path.js +21 -0
  182. package/dist/schemas/path.js.map +1 -0
  183. package/dist/schemas/performance.d.ts +23 -0
  184. package/dist/schemas/performance.d.ts.map +1 -0
  185. package/dist/schemas/performance.js +21 -0
  186. package/dist/schemas/performance.js.map +1 -0
  187. package/dist/schemas/shared.d.ts +34 -0
  188. package/dist/schemas/shared.d.ts.map +1 -0
  189. package/dist/schemas/shared.js +34 -0
  190. package/dist/schemas/shared.js.map +1 -0
  191. package/dist/schemas/version-compare.d.ts +10 -0
  192. package/dist/schemas/version-compare.d.ts.map +1 -0
  193. package/dist/schemas/version-compare.js +25 -0
  194. package/dist/schemas/version-compare.js.map +1 -0
  195. package/dist/widgets.d.ts +138 -0
  196. package/dist/widgets.d.ts.map +1 -0
  197. package/dist/widgets.js +2 -0
  198. package/dist/widgets.js.map +1 -0
  199. package/metrics-contract.json +174 -0
  200. package/package.json +72 -5
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Test support for the metrics-contract guards — never imported by runtime
3
+ * code. Resolves every selector of a parsed PromQL expression
4
+ * (`promql-parse.test-support.ts`) to its contract series and asserts that
5
+ * each label the expression names — in a matcher, a `by`/`without` grouping, an
6
+ * `on`/`ignoring` vector match or a `group_left`/`group_right` include list —
7
+ * is a label that operand can carry.
8
+ *
9
+ * Label availability propagates the way PromQL evaluates: a selector carries
10
+ * its series' declared labels (`le` added on `_bucket`), `increase()` keeps
11
+ * them, `sum by (a)` narrows to `a`, `histogram_quantile` consumes `le`, a
12
+ * one-to-one `on (a)` match keeps `a`. So `sum by (a)(sum by (b)(x))` fails
13
+ * even when `a` is declared on `x`. Unknown functions and series are reported
14
+ * as violations instead of passing silently.
15
+ */
16
+ import { parsePromql, } from "./promql-parse.test-support.js";
17
+ /**
18
+ * Catalogue over the contract: counters/gauges by `promName`, histograms as
19
+ * their `_sum`/`_count`/`_bucket` series (`_bucket` adds `le`). The bare
20
+ * histogram name is deliberately absent — classic histograms expose no such
21
+ * series, so a query on it reads nothing. `extra` adds non-contract series
22
+ * (Prometheus' own `ALERTS`, `up`, …) with their documented labels.
23
+ */
24
+ export function contractCatalog(metrics, extra = {}) {
25
+ const series = new Map(Object.entries(extra));
26
+ for (const m of metrics) {
27
+ const info = { labels: m.labels, knownValues: m.knownValues };
28
+ if (m.type !== "histogram") {
29
+ series.set(m.promName, info);
30
+ continue;
31
+ }
32
+ series.set(`${m.promName}_sum`, info);
33
+ series.set(`${m.promName}_count`, info);
34
+ series.set(`${m.promName}_bucket`, { ...info, labels: [...m.labels, "le"] });
35
+ }
36
+ return (name) => series.get(name);
37
+ }
38
+ const vector = (labels, series) => ({
39
+ kind: "vector",
40
+ labels: new Set(labels),
41
+ series,
42
+ });
43
+ const isVector = (s) => s.kind === "vector";
44
+ /** Functions whose result keeps the label set of their (first) vector argument. */
45
+ const LABEL_PRESERVING = new Set([
46
+ "abs ceil changes clamp clamp_max clamp_min delta deriv exp floor idelta increase irate ln",
47
+ "log10 log2 predict_linear rate resets round sgn sort sort_desc sqrt timestamp",
48
+ "avg_over_time count_over_time last_over_time max_over_time min_over_time present_over_time",
49
+ "quantile_over_time stddev_over_time stdvar_over_time sum_over_time",
50
+ ]
51
+ .join(" ")
52
+ .split(" "));
53
+ /** Aggregators that return a subset of their input series, labels intact. */
54
+ const SAMPLE_SELECTING = new Set(["topk", "bottomk", "limitk", "limit_ratio"]);
55
+ const isWildcard = (alt) => alt === ".*" || alt === ".+" || alt.startsWith("$");
56
+ class LabelChecker {
57
+ catalog;
58
+ violations = [];
59
+ series = new Set();
60
+ checkedLabels = 0;
61
+ constructor(catalog) {
62
+ this.catalog = catalog;
63
+ }
64
+ fail(message) {
65
+ this.violations.push(message);
66
+ }
67
+ requireLabel(scope, label, context) {
68
+ this.checkedLabels++;
69
+ if (scope.labels.has(label))
70
+ return;
71
+ this.fail(`${context}: "${label}" is not a label of ${describeSeries(scope)} ` +
72
+ `(available: ${[...scope.labels].sort().join(", ") || "none"})`);
73
+ }
74
+ eval(node) {
75
+ switch (node.type) {
76
+ case "number":
77
+ return { kind: "scalar" };
78
+ case "string":
79
+ return { kind: "string", value: node.value };
80
+ case "selector":
81
+ return this.evalSelector(node);
82
+ case "call":
83
+ return this.evalCall(node);
84
+ case "aggregate":
85
+ return this.evalAggregate(node);
86
+ case "binary":
87
+ return this.evalBinary(node);
88
+ }
89
+ }
90
+ evalSelector(node) {
91
+ if (!node.name) {
92
+ this.fail("selector without a metric name — not supported");
93
+ return vector([], []);
94
+ }
95
+ this.series.add(node.name);
96
+ const info = this.catalog(node.name);
97
+ if (!info) {
98
+ this.fail(`"${node.name}" is neither a contract series nor an allowlisted one`);
99
+ return vector([], [node.name]);
100
+ }
101
+ const scope = vector(info.labels, [node.name]);
102
+ for (const m of node.matchers) {
103
+ if (m.label === "__name__")
104
+ continue;
105
+ this.requireLabel(scope, m.label, `selector ${node.name}{${m.label}${m.op}"${m.value}"}`);
106
+ this.checkKnownValues(node.name, info, m);
107
+ }
108
+ return scope;
109
+ }
110
+ /** A hardcoded value of a label with documented `knownValues` must be one of them. */
111
+ checkKnownValues(series, info, m) {
112
+ const known = info.knownValues?.[m.label];
113
+ if (!known)
114
+ return;
115
+ const values = m.op === "=~" || m.op === "!~" ? m.value.split("|") : [m.value];
116
+ for (const value of values.filter((v) => !isWildcard(v))) {
117
+ if (known.includes(value))
118
+ continue;
119
+ this.fail(`selector ${series}{${m.label}${m.op}"${m.value}"}: "${value}" is not a knownValue ` +
120
+ `of ${m.label} (${known.join(", ")})`);
121
+ }
122
+ }
123
+ evalCall(node) {
124
+ const args = node.args.map((a) => this.eval(a));
125
+ const firstVector = args.find(isVector);
126
+ if (node.func === "histogram_quantile")
127
+ return this.evalHistogramQuantile(args[1]);
128
+ if (LABEL_PRESERVING.has(node.func) && firstVector)
129
+ return firstVector;
130
+ if (node.func === "vector")
131
+ return vector([], []);
132
+ this.fail(`unsupported function ${node.func}() — extend promql-labels.test-support.ts`);
133
+ return firstVector ?? { kind: "scalar" };
134
+ }
135
+ evalHistogramQuantile(arg) {
136
+ if (!arg || !isVector(arg)) {
137
+ this.fail("histogram_quantile() needs a bucket vector as its second argument");
138
+ return vector([], []);
139
+ }
140
+ this.requireLabel(arg, "le", "histogram_quantile()");
141
+ return vector([...arg.labels].filter((l) => l !== "le"), arg.series);
142
+ }
143
+ evalAggregate(node) {
144
+ const param = node.param ? this.eval(node.param) : undefined;
145
+ const inner = this.eval(node.expr);
146
+ if (!isVector(inner)) {
147
+ this.fail(`${node.op}() over a non-vector expression`);
148
+ return vector([], []);
149
+ }
150
+ const g = node.grouping;
151
+ for (const label of g?.labels ?? []) {
152
+ this.requireLabel(inner, label, `${node.op} ${g?.mode} (${label})`);
153
+ }
154
+ const labels = aggregateLabels(node.op, inner, g);
155
+ if (node.op === "count_values" && param?.kind === "string")
156
+ labels.add(param.value);
157
+ return vector(labels, inner.series);
158
+ }
159
+ evalBinary(node) {
160
+ const lhs = this.eval(node.lhs);
161
+ const rhs = this.eval(node.rhs);
162
+ if (!isVector(lhs) || !isVector(rhs)) {
163
+ if (node.matching)
164
+ this.fail(`vector matching on "${node.op}" with a scalar operand`);
165
+ if (isVector(lhs))
166
+ return lhs;
167
+ return isVector(rhs) ? rhs : { kind: "scalar" };
168
+ }
169
+ const m = node.matching;
170
+ if (m)
171
+ this.checkMatching(node.op, m, lhs, rhs);
172
+ return vector(binaryLabels(node.op, m, lhs, rhs), [...lhs.series, ...rhs.series]);
173
+ }
174
+ checkMatching(op, m, lhs, rhs) {
175
+ for (const label of m.labels) {
176
+ if (m.mode === "on") {
177
+ // Matching on a label one side lacks pairs everything with "" — a bug.
178
+ this.requireLabel(lhs, label, `${op} on (${label}), left side`);
179
+ this.requireLabel(rhs, label, `${op} on (${label}), right side`);
180
+ continue;
181
+ }
182
+ this.checkedLabels++;
183
+ if (!lhs.labels.has(label) && !rhs.labels.has(label)) {
184
+ this.fail(`${op} ignoring (${label}): "${label}" is a label of neither ` +
185
+ `${describeSeries(lhs)} nor ${describeSeries(rhs)}`);
186
+ }
187
+ }
188
+ // group_x(include) copies labels from the "one" side.
189
+ const one = m.group === "group_left" ? rhs : lhs;
190
+ for (const label of m.include)
191
+ this.requireLabel(one, label, `${op} ${m.group} (${label})`);
192
+ }
193
+ }
194
+ function describeSeries(scope) {
195
+ const names = [...new Set(scope.series)];
196
+ return names.length ? names.join(" / ") : "the expression";
197
+ }
198
+ function aggregateLabels(op, inner, g) {
199
+ if (SAMPLE_SELECTING.has(op))
200
+ return new Set(inner.labels);
201
+ if (!g)
202
+ return new Set();
203
+ if (g.mode === "by")
204
+ return new Set(g.labels.filter((l) => inner.labels.has(l)));
205
+ return new Set([...inner.labels].filter((l) => !g.labels.includes(l)));
206
+ }
207
+ /** Result labels of a vector/vector operation (Prometheus' `resultMetric`). */
208
+ function binaryLabels(op, m, lhs, rhs) {
209
+ if (op === "or")
210
+ return new Set([...lhs.labels, ...rhs.labels]);
211
+ if (op === "and" || op === "unless")
212
+ return new Set(lhs.labels);
213
+ if (m?.group === "group_left")
214
+ return new Set([...lhs.labels, ...m.include]);
215
+ if (m?.group === "group_right")
216
+ return new Set([...rhs.labels, ...m.include]);
217
+ if (m?.mode === "on")
218
+ return new Set([...lhs.labels].filter((l) => m.labels.includes(l)));
219
+ if (m?.mode === "ignoring")
220
+ return new Set([...lhs.labels].filter((l) => !m.labels.includes(l)));
221
+ return new Set(lhs.labels);
222
+ }
223
+ /**
224
+ * Parse `query` and check every label it names against `catalog`. Throws on a
225
+ * syntax outside the supported subset; everything else lands in `violations`.
226
+ */
227
+ export function checkQueryLabels(query, catalog) {
228
+ const checker = new LabelChecker(catalog);
229
+ const result = checker.eval(parsePromql(query));
230
+ return {
231
+ violations: checker.violations,
232
+ series: [...checker.series],
233
+ checkedLabels: checker.checkedLabels,
234
+ resultLabels: isVector(result) ? [...result.labels].sort() : undefined,
235
+ };
236
+ }
237
+ //# sourceMappingURL=promql-labels.test-support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promql-labels.test-support.js","sourceRoot":"","sources":["../src/promql-labels.test-support.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=promql-labels.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promql-labels.test.d.ts","sourceRoot":"","sources":["../src/promql-labels.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,190 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { checkQueryLabels, contractCatalog } from "./promql-labels.test-support.js";
3
+ import { parsePromql } from "./promql-parse.test-support.js";
4
+ /**
5
+ * The checker behind the selector-label contract guard
6
+ * (`metrics-contract-labels.test.ts`). These cases pin down that each
7
+ * violation class is actually caught — a checker that silently accepts
8
+ * everything would let the guard pass vacuously.
9
+ */
10
+ const catalog = contractCatalog([
11
+ {
12
+ promName: "inc_total",
13
+ type: "counter",
14
+ labels: ["process_definition_key", "activity_id", "engine_id"],
15
+ },
16
+ {
17
+ promName: "ended_total",
18
+ type: "counter",
19
+ labels: ["process_definition_key", "process_definition_version", "engine_id", "state"],
20
+ knownValues: { state: ["COMPLETED", "EXTERNALLY_TERMINATED"] },
21
+ },
22
+ {
23
+ promName: "dur_seconds",
24
+ type: "histogram",
25
+ labels: ["process_definition_key", "engine_id"],
26
+ },
27
+ { promName: "backlog", type: "gauge", labels: ["engine_id"] },
28
+ ], { ALERTS: { labels: ["alertname", "alertstate", "engine_id"] } });
29
+ const check = (query) => checkQueryLabels(query, catalog);
30
+ const violations = (query) => check(query).violations;
31
+ describe("checkQueryLabels — accepted shapes", () => {
32
+ it.each([
33
+ 'sum(increase(inc_total{process_definition_key="k",engine_id=~"a|b"}[7d]))',
34
+ "sum by (activity_id)(increase(inc_total[86400s] @ 1700000000))",
35
+ 'histogram_quantile(0.95, sum by (le)(increase(dur_seconds_bucket{engine_id="a"}[7d])))',
36
+ "sum(increase(dur_seconds_sum[7d])) / sum(increase(dur_seconds_count[7d]))",
37
+ 'sum(increase(ended_total{state="COMPLETED"}[7d]))',
38
+ "sum by (engine_id) (rate(ended_total[15m])) == 0 and sum by (engine_id) (backlog) > 0",
39
+ 'ALERTS{alertstate="firing",engine_id="a"}',
40
+ "count by (engine_id)(inc_total)",
41
+ 'sum by (engine_id) (rate(inc_total{engine_id=~"$engine_id"}[$__rate_interval]))',
42
+ "sum(rate(inc_total[5m])) * 60",
43
+ "-sum(inc_total offset 1h)",
44
+ "topk(3, sum by (activity_id)(inc_total))",
45
+ "inc_total / on (engine_id) group_left (process_definition_version) ended_total",
46
+ ])("%s", (query) => {
47
+ expect(violations(query)).toEqual([]);
48
+ });
49
+ it("counts every label reference it verifies", () => {
50
+ const result = check('sum by (activity_id)(inc_total{engine_id="a",activity_id="x"})');
51
+ expect(result.checkedLabels).toBe(3);
52
+ expect(result.series).toEqual(["inc_total"]);
53
+ expect(result.resultLabels).toEqual(["activity_id"]);
54
+ });
55
+ });
56
+ describe("checkQueryLabels — violations", () => {
57
+ it("flags a matcher label the series does not declare (the version-compare bug)", () => {
58
+ const [v, ...rest] = violations('sum(increase(inc_total{process_definition_key="k",process_definition_version="2"}[7d]))');
59
+ expect(rest).toEqual([]);
60
+ expect(v).toContain('"process_definition_version" is not a label of inc_total');
61
+ });
62
+ it("flags a by-label the aggregated series does not declare", () => {
63
+ expect(violations("sum by (state)(increase(inc_total[7d]))")).toEqual([
64
+ expect.stringContaining('sum by (state): "state" is not a label of inc_total'),
65
+ ]);
66
+ });
67
+ it("tracks label narrowing through nested aggregations", () => {
68
+ expect(violations("sum by (activity_id)(sum by (process_definition_key)(inc_total))")).toEqual([
69
+ expect.stringContaining('"activity_id" is not a label of inc_total'),
70
+ ]);
71
+ });
72
+ it("flags without-labels the operand does not carry", () => {
73
+ expect(violations("sum without (state)(inc_total)")).toHaveLength(1);
74
+ expect(check("sum without (activity_id)(inc_total)").resultLabels).toEqual([
75
+ "engine_id",
76
+ "process_definition_key",
77
+ ]);
78
+ });
79
+ it("flags unknown series, including a bare histogram name", () => {
80
+ expect(violations("sum(nope_total)")).toEqual([
81
+ expect.stringContaining('"nope_total" is neither a contract series'),
82
+ ]);
83
+ expect(violations("sum(dur_seconds)")).toHaveLength(1);
84
+ });
85
+ it("requires le for histogram_quantile and consumes it", () => {
86
+ expect(violations("histogram_quantile(0.5, sum by (engine_id)(dur_seconds_bucket))")).toEqual([
87
+ expect.stringContaining('histogram_quantile(): "le" is not a label'),
88
+ ]);
89
+ expect(check("histogram_quantile(0.5, dur_seconds_bucket)").resultLabels).toEqual([
90
+ "engine_id",
91
+ "process_definition_key",
92
+ ]);
93
+ expect(violations("histogram_quantile(0.5)")).toHaveLength(1);
94
+ });
95
+ it("checks on/ignoring/group_left/group_right label lists against both operands", () => {
96
+ expect(violations("inc_total / on (activity_id) backlog")).toEqual([
97
+ expect.stringContaining("on (activity_id), right side"),
98
+ ]);
99
+ expect(violations("inc_total / ignoring (state) backlog")).toEqual([
100
+ expect.stringContaining('"state" is a label of neither inc_total nor backlog'),
101
+ ]);
102
+ expect(violations("inc_total * on (engine_id) group_left (state) backlog")).toEqual([
103
+ expect.stringContaining('group_left (state): "state" is not a label of backlog'),
104
+ ]);
105
+ expect(violations("backlog * on (engine_id) group_right (state) inc_total")).toEqual([
106
+ expect.stringContaining('group_right (state): "state" is not a label of backlog'),
107
+ ]);
108
+ expect(violations("inc_total + on (engine_id) 1")).toHaveLength(1);
109
+ });
110
+ it("flags hardcoded values outside the documented knownValues", () => {
111
+ expect(violations('ended_total{state="DONE"}')).toEqual([
112
+ expect.stringContaining('"DONE" is not a knownValue of state'),
113
+ ]);
114
+ expect(violations('ended_total{state=~"COMPLETED|DONE|.*"}')).toHaveLength(1);
115
+ });
116
+ it("reports unsupported functions and name-less selectors instead of passing them", () => {
117
+ expect(violations('label_replace(inc_total, "x", "$1", "activity_id", "(.*)")')).toEqual([
118
+ expect.stringContaining("unsupported function label_replace()"),
119
+ ]);
120
+ expect(violations('{engine_id="a"}')).toEqual([
121
+ expect.stringContaining("selector without a metric name"),
122
+ ]);
123
+ expect(violations('{__name__="backlog",engine_id="a"}')).toEqual([]);
124
+ expect(violations("sum(1)")).toEqual([expect.stringContaining("non-vector")]);
125
+ });
126
+ });
127
+ describe("checkQueryLabels — result labels", () => {
128
+ it.each([
129
+ ["inc_total or backlog", ["activity_id", "engine_id", "process_definition_key"]],
130
+ ["backlog unless inc_total", ["engine_id"]],
131
+ ["inc_total / on (engine_id) backlog", ["engine_id"]],
132
+ ["inc_total / ignoring (activity_id) inc_total", ["engine_id", "process_definition_key"]],
133
+ [
134
+ "backlog * on (engine_id) group_right inc_total",
135
+ ["activity_id", "engine_id", "process_definition_key"],
136
+ ],
137
+ ['count_values("value", backlog)', ["value"]],
138
+ ["vector(1)", []],
139
+ ["2 * backlog", ["engine_id"]],
140
+ ])("%s → %j", (query, labels) => {
141
+ expect(check(query).resultLabels).toEqual(labels);
142
+ });
143
+ it("has no result labels for a scalar expression", () => {
144
+ expect(check("1 + 2").resultLabels).toBeUndefined();
145
+ });
146
+ });
147
+ describe("parsePromql", () => {
148
+ it("folds parentheses, unary signs and range/offset/@ postfixes into the operand", () => {
149
+ expect(parsePromql("(-inc_total[5m] offset 1h @ start())")).toEqual({
150
+ type: "selector",
151
+ name: "inc_total",
152
+ matchers: [],
153
+ });
154
+ // Grafana interpolates its interval variables as durations, offsets included.
155
+ expect(parsePromql("inc_total[1h] @ 1700000000 offset $__range")).toEqual({
156
+ type: "selector",
157
+ name: "inc_total",
158
+ matchers: [],
159
+ });
160
+ });
161
+ it("parses grouping after the aggregation body and binds ^ right-associatively", () => {
162
+ expect(parsePromql("sum(inc_total) by (engine_id)")).toMatchObject({
163
+ type: "aggregate",
164
+ grouping: { mode: "by", labels: ["engine_id"] },
165
+ });
166
+ expect(parsePromql("1 ^ 2 ^ 3")).toMatchObject({ rhs: { type: "binary", op: "^" } });
167
+ expect(parsePromql("1 - 2 * 3")).toMatchObject({ op: "-", rhs: { op: "*" } });
168
+ });
169
+ it("unescapes label values", () => {
170
+ expect(parsePromql('x{a="q\\"uote",b=`raw\\`}')).toMatchObject({
171
+ matchers: [
172
+ { label: "a", value: 'q"uote' },
173
+ { label: "b", value: "raw\\" },
174
+ ],
175
+ });
176
+ });
177
+ it.each([
178
+ "sum(inc_total",
179
+ "inc_total{engine_id}",
180
+ 'inc_total{engine_id=="a"}',
181
+ "inc_total @ now",
182
+ "sum by engine_id (inc_total)",
183
+ "sum()",
184
+ "inc_total )",
185
+ "inc_total # comment",
186
+ ])("rejects %s", (query) => {
187
+ expect(() => parsePromql(query)).toThrow(/PromQL:/);
188
+ });
189
+ });
190
+ //# sourceMappingURL=promql-labels.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promql-labels.test.js","sourceRoot":"","sources":["../src/promql-labels.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAE5D;;;;;GAKG;AAEH,MAAM,OAAO,GAAG,eAAe,CAC7B;IACE;QACE,QAAQ,EAAE,WAAW;QACrB,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,CAAC,wBAAwB,EAAE,aAAa,EAAE,WAAW,CAAC;KAC/D;IACD;QACE,QAAQ,EAAE,aAAa;QACvB,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,CAAC,wBAAwB,EAAE,4BAA4B,EAAE,WAAW,EAAE,OAAO,CAAC;QACtF,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE;KAC/D;IACD;QACE,QAAQ,EAAE,aAAa;QACvB,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,CAAC,wBAAwB,EAAE,WAAW,CAAC;KAChD;IACD,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE;CAC9D,EACD,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,EAAE,CACjE,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACjE,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,CAAA;AAE7D,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,IAAI,CAAC;QACN,2EAA2E;QAC3E,gEAAgE;QAChE,wFAAwF;QACxF,2EAA2E;QAC3E,mDAAmD;QACnD,uFAAuF;QACvF,2CAA2C;QAC3C,iCAAiC;QACjC,iFAAiF;QACjF,+BAA+B;QAC/B,2BAA2B;QAC3B,0CAA0C;QAC1C,gFAAgF;KACjF,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QACjB,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,KAAK,CAAC,gEAAgE,CAAC,CAAA;QACtF,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAA;QAC5C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,UAAU,CAC7B,yFAAyF,CAC1F,CAAA;QACD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACxB,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,0DAA0D,CAAC,CAAA;IACjF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,UAAU,CAAC,yCAAyC,CAAC,CAAC,CAAC,OAAO,CAAC;YACpE,MAAM,CAAC,gBAAgB,CAAC,qDAAqD,CAAC;SAC/E,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,UAAU,CAAC,kEAAkE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7F,MAAM,CAAC,gBAAgB,CAAC,2CAA2C,CAAC;SACrE,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,UAAU,CAAC,gCAAgC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QACpE,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;YACzE,WAAW;YACX,wBAAwB;SACzB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5C,MAAM,CAAC,gBAAgB,CAAC,2CAA2C,CAAC;SACrE,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,UAAU,CAAC,iEAAiE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5F,MAAM,CAAC,gBAAgB,CAAC,2CAA2C,CAAC;SACrE,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;YAChF,WAAW;YACX,wBAAwB;SACzB,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,CAAC,UAAU,CAAC,sCAAsC,CAAC,CAAC,CAAC,OAAO,CAAC;YACjE,MAAM,CAAC,gBAAgB,CAAC,8BAA8B,CAAC;SACxD,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,sCAAsC,CAAC,CAAC,CAAC,OAAO,CAAC;YACjE,MAAM,CAAC,gBAAgB,CAAC,qDAAqD,CAAC;SAC/E,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,uDAAuD,CAAC,CAAC,CAAC,OAAO,CAAC;YAClF,MAAM,CAAC,gBAAgB,CAAC,uDAAuD,CAAC;SACjF,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,wDAAwD,CAAC,CAAC,CAAC,OAAO,CAAC;YACnF,MAAM,CAAC,gBAAgB,CAAC,wDAAwD,CAAC;SAClF,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,qCAAqC,CAAC;SAC/D,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,yCAAyC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC/E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,CAAC,UAAU,CAAC,4DAA4D,CAAC,CAAC,CAAC,OAAO,CAAC;YACvF,MAAM,CAAC,gBAAgB,CAAC,sCAAsC,CAAC;SAChE,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5C,MAAM,CAAC,gBAAgB,CAAC,gCAAgC,CAAC;SAC1D,CAAC,CAAA;QACF,MAAM,CAAC,UAAU,CAAC,oCAAoC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC/E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,sBAAsB,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,wBAAwB,CAAC,CAAC;QAChF,CAAC,0BAA0B,EAAE,CAAC,WAAW,CAAC,CAAC;QAC3C,CAAC,oCAAoC,EAAE,CAAC,WAAW,CAAC,CAAC;QACrD,CAAC,8CAA8C,EAAE,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;QACzF;YACE,gDAAgD;YAChD,CAAC,aAAa,EAAE,WAAW,EAAE,wBAAwB,CAAC;SACvD;QACD,CAAC,gCAAgC,EAAE,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC,WAAW,EAAE,EAAE,CAAC;QACjB,CAAC,aAAa,EAAE,CAAC,WAAW,CAAC,CAAC;KAC/B,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,aAAa,EAAE,CAAA;IACrD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,CAAC,WAAW,CAAC,sCAAsC,CAAC,CAAC,CAAC,OAAO,CAAC;YAClE,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,EAAE;SACb,CAAC,CAAA;QACF,8EAA8E;QAC9E,MAAM,CAAC,WAAW,CAAC,4CAA4C,CAAC,CAAC,CAAC,OAAO,CAAC;YACxE,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,EAAE;SACb,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,MAAM,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAC,CAAC,aAAa,CAAC;YACjE,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE;SAChD,CAAC,CAAA;QACF,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QACpF,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;IAC/E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC,CAAC,aAAa,CAAC;YAC7D,QAAQ,EAAE;gBACR,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAC/B,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;aAC/B;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,IAAI,CAAC;QACN,eAAe;QACf,sBAAsB;QACtB,2BAA2B;QAC3B,iBAAiB;QACjB,8BAA8B;QAC9B,OAAO;QACP,aAAa;QACb,qBAAqB;KACtB,CAAC,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Test support for the metrics-contract guards — never imported by runtime
3
+ * code. A parser for the PromQL subset the analytics consumers write (TS
4
+ * queries, alert rules, Grafana dashboards) into the small AST the label
5
+ * checker (`promql-labels.test-support.ts`) walks.
6
+ *
7
+ * Anything outside the supported subset throws instead of parsing to
8
+ * something approximate — extend the parser when a new query shape needs it.
9
+ */
10
+ export interface Matcher {
11
+ label: string;
12
+ op: "=" | "!=" | "=~" | "!~";
13
+ value: string;
14
+ }
15
+ export interface Grouping {
16
+ mode: "by" | "without";
17
+ labels: string[];
18
+ }
19
+ export interface VectorMatching {
20
+ mode?: "on" | "ignoring";
21
+ labels: string[];
22
+ group?: "group_left" | "group_right";
23
+ include: string[];
24
+ }
25
+ /**
26
+ * Parsed expression. Parentheses, unary signs and the range / `offset` / `@`
27
+ * postfixes are folded into their operand — none of them changes the label set.
28
+ */
29
+ export type PromNode = {
30
+ type: "number";
31
+ } | {
32
+ type: "string";
33
+ value: string;
34
+ } | {
35
+ type: "selector";
36
+ name: string | undefined;
37
+ matchers: Matcher[];
38
+ } | {
39
+ type: "call";
40
+ func: string;
41
+ args: PromNode[];
42
+ } | {
43
+ type: "aggregate";
44
+ op: string;
45
+ grouping?: Grouping;
46
+ param?: PromNode;
47
+ expr: PromNode;
48
+ } | {
49
+ type: "binary";
50
+ op: string;
51
+ lhs: PromNode;
52
+ rhs: PromNode;
53
+ matching?: VectorMatching;
54
+ };
55
+ /** Parse one PromQL expression; throws on anything outside the supported subset. */
56
+ export declare function parsePromql(src: string): PromNode;
57
+ //# sourceMappingURL=promql-parse.test-support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promql-parse.test-support.d.ts","sourceRoot":"","sources":["../src/promql-parse.test-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+DH,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;IACtB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,IAAI,GAAG,UAAU,CAAA;IACxB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,CAAC,EAAE,YAAY,GAAG,aAAa,CAAA;IACpC,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACxF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,CAAA;AA8O3F,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAEjD"}