@intentius/chant-lexicon-grafana 0.97.0 → 0.99.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 (451) hide show
  1. package/README.md +15 -5
  2. package/dist/actions/grafana.d.ts +24 -0
  3. package/dist/actions/grafana.d.ts.map +1 -0
  4. package/dist/actions/index.d.ts +2 -0
  5. package/dist/actions/index.d.ts.map +1 -0
  6. package/dist/alerting-build.d.ts +128 -0
  7. package/dist/alerting-build.d.ts.map +1 -0
  8. package/dist/alerting.d.ts +273 -0
  9. package/dist/alerting.d.ts.map +1 -0
  10. package/dist/api/apply.d.ts +156 -0
  11. package/dist/api/apply.d.ts.map +1 -0
  12. package/dist/api/bind.d.ts +32 -0
  13. package/dist/api/bind.d.ts.map +1 -0
  14. package/dist/api/client.d.ts +76 -0
  15. package/dist/api/client.d.ts.map +1 -0
  16. package/dist/api/converge.d.ts +33 -0
  17. package/dist/api/converge.d.ts.map +1 -0
  18. package/dist/api/dashboards.d.ts +102 -0
  19. package/dist/api/dashboards.d.ts.map +1 -0
  20. package/dist/api/datasources.d.ts +26 -0
  21. package/dist/api/datasources.d.ts.map +1 -0
  22. package/dist/api/fake-grafana-writes.d.ts +41 -0
  23. package/dist/api/fake-grafana-writes.d.ts.map +1 -0
  24. package/dist/api/fake-grafana.d.ts +61 -0
  25. package/dist/api/fake-grafana.d.ts.map +1 -0
  26. package/dist/api/folders.d.ts +110 -0
  27. package/dist/api/folders.d.ts.map +1 -0
  28. package/dist/api/library-panels.d.ts +52 -0
  29. package/dist/api/library-panels.d.ts.map +1 -0
  30. package/dist/build.d.ts +30 -2
  31. package/dist/build.d.ts.map +1 -1
  32. package/dist/catalog.d.ts +1 -1
  33. package/dist/catalog.d.ts.map +1 -1
  34. package/dist/codegen/docs.d.ts.map +1 -1
  35. package/dist/codegen/schema-types.d.ts +3 -3
  36. package/dist/codegen/schema-types.d.ts.map +1 -1
  37. package/dist/composites/agent-dashboard.d.ts.map +1 -1
  38. package/dist/composites/catalog.d.ts.map +1 -1
  39. package/dist/composites/index.d.ts +4 -2
  40. package/dist/composites/index.d.ts.map +1 -1
  41. package/dist/composites/red-dashboard.d.ts +21 -2
  42. package/dist/composites/red-dashboard.d.ts.map +1 -1
  43. package/dist/composites/shared.d.ts +7 -0
  44. package/dist/composites/shared.d.ts.map +1 -1
  45. package/dist/composites/slo-alert-rules.d.ts +92 -0
  46. package/dist/composites/slo-alert-rules.d.ts.map +1 -0
  47. package/dist/config.d.ts +111 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/contact-point-secrets.d.ts +17 -0
  50. package/dist/contact-point-secrets.d.ts.map +1 -0
  51. package/dist/dashboard.d.ts +16 -2
  52. package/dist/dashboard.d.ts.map +1 -1
  53. package/dist/datasource-refs.d.ts +95 -0
  54. package/dist/datasource-refs.d.ts.map +1 -0
  55. package/dist/datasource.d.ts +29 -0
  56. package/dist/datasource.d.ts.map +1 -1
  57. package/dist/deep-observe-hooks.d.ts +64 -0
  58. package/dist/deep-observe-hooks.d.ts.map +1 -0
  59. package/dist/deep-observe.d.ts +42 -0
  60. package/dist/deep-observe.d.ts.map +1 -0
  61. package/dist/describe-resources.d.ts +49 -0
  62. package/dist/describe-resources.d.ts.map +1 -0
  63. package/dist/detect.d.ts +28 -1
  64. package/dist/detect.d.ts.map +1 -1
  65. package/dist/export-resources.d.ts +38 -0
  66. package/dist/export-resources.d.ts.map +1 -0
  67. package/dist/import/alerting.d.ts +40 -0
  68. package/dist/import/alerting.d.ts.map +1 -0
  69. package/dist/import/edits.d.ts +47 -0
  70. package/dist/import/edits.d.ts.map +1 -0
  71. package/dist/import/embedded.d.ts +14 -0
  72. package/dist/import/embedded.d.ts.map +1 -0
  73. package/dist/import/generator.d.ts +60 -0
  74. package/dist/import/generator.d.ts.map +1 -0
  75. package/dist/import/live-export.d.ts +108 -0
  76. package/dist/import/live-export.d.ts.map +1 -0
  77. package/dist/import/mappings.d.ts +83 -0
  78. package/dist/import/mappings.d.ts.map +1 -0
  79. package/dist/import/model.d.ts +98 -0
  80. package/dist/import/model.d.ts.map +1 -0
  81. package/dist/import/normalize-alerting.d.ts +26 -0
  82. package/dist/import/normalize-alerting.d.ts.map +1 -0
  83. package/dist/import/normalize.d.ts +74 -0
  84. package/dist/import/normalize.d.ts.map +1 -0
  85. package/dist/import/parser.d.ts +110 -0
  86. package/dist/import/parser.d.ts.map +1 -0
  87. package/dist/import/report.d.ts +26 -0
  88. package/dist/import/report.d.ts.map +1 -0
  89. package/dist/import/testdata/fixtures.d.ts +35 -0
  90. package/dist/import/testdata/fixtures.d.ts.map +1 -0
  91. package/dist/import/v2.d.ts +72 -0
  92. package/dist/import/v2.d.ts.map +1 -0
  93. package/dist/index.d.ts +26 -9
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/integrity.json +18 -10
  96. package/dist/k8s.d.ts +107 -0
  97. package/dist/k8s.d.ts.map +1 -0
  98. package/dist/lint/audit-catalog.d.ts +2 -1
  99. package/dist/lint/audit-catalog.d.ts.map +1 -1
  100. package/dist/lint/post-synth/graf101.d.ts +2 -2
  101. package/dist/lint/post-synth/graf102.d.ts +1 -1
  102. package/dist/lint/post-synth/graf107.d.ts +1 -1
  103. package/dist/lint/post-synth/graf108.d.ts +8 -0
  104. package/dist/lint/post-synth/graf108.d.ts.map +1 -0
  105. package/dist/lint/post-synth/graf109.d.ts +8 -0
  106. package/dist/lint/post-synth/graf109.d.ts.map +1 -0
  107. package/dist/lint/post-synth/graf111.d.ts +8 -0
  108. package/dist/lint/post-synth/graf111.d.ts.map +1 -0
  109. package/dist/lint/post-synth/graf112.d.ts +8 -0
  110. package/dist/lint/post-synth/graf112.d.ts.map +1 -0
  111. package/dist/lint/post-synth/graf113.d.ts +8 -0
  112. package/dist/lint/post-synth/graf113.d.ts.map +1 -0
  113. package/dist/lint/post-synth/graf114.d.ts +8 -0
  114. package/dist/lint/post-synth/graf114.d.ts.map +1 -0
  115. package/dist/lint/post-synth/graf115.d.ts +8 -0
  116. package/dist/lint/post-synth/graf115.d.ts.map +1 -0
  117. package/dist/lint/post-synth/grafana-helpers.d.ts +7 -5
  118. package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -1
  119. package/dist/lint/post-synth/index.d.ts.map +1 -1
  120. package/dist/lint/rules/literal-secret.d.ts +7 -3
  121. package/dist/lint/rules/literal-secret.d.ts.map +1 -1
  122. package/dist/lsp/hover.d.ts.map +1 -1
  123. package/dist/manifest.json +1 -1
  124. package/dist/members.d.ts +27 -0
  125. package/dist/members.d.ts.map +1 -0
  126. package/dist/meta.json +135 -0
  127. package/dist/okf/index.md +36 -2
  128. package/dist/okf/rules/GRAF002.md +3 -2
  129. package/dist/okf/rules/GRAF101.md +3 -2
  130. package/dist/okf/rules/GRAF102.md +1 -0
  131. package/dist/okf/rules/GRAF108.md +11 -0
  132. package/dist/okf/rules/GRAF109.md +15 -0
  133. package/dist/okf/rules/GRAF111.md +11 -0
  134. package/dist/okf/rules/GRAF112.md +16 -0
  135. package/dist/okf/rules/GRAF113.md +16 -0
  136. package/dist/okf/rules/GRAF114.md +11 -0
  137. package/dist/okf/rules/GRAF115.md +11 -0
  138. package/dist/okf/types/AlertListPanel.md +9 -0
  139. package/dist/okf/types/AlertQuery.md +9 -0
  140. package/dist/okf/types/AlertRule.md +9 -0
  141. package/dist/okf/types/AlertRuleGroup.md +9 -0
  142. package/dist/okf/types/BarChartPanel.md +9 -0
  143. package/dist/okf/types/BarGaugePanel.md +9 -0
  144. package/dist/okf/types/CanvasPanel.md +9 -0
  145. package/dist/okf/types/ClassicConditionsExpression.md +9 -0
  146. package/dist/okf/types/ContactPoint.md +14 -0
  147. package/dist/okf/types/Dashboard.md +1 -0
  148. package/dist/okf/types/Datasource.md +3 -2
  149. package/dist/okf/types/ExternalDatasource.md +15 -0
  150. package/dist/okf/types/FlameGraphPanel.md +9 -0
  151. package/dist/okf/types/GeomapPanel.md +9 -0
  152. package/dist/okf/types/HistogramPanel.md +9 -0
  153. package/dist/okf/types/MathExpression.md +9 -0
  154. package/dist/okf/types/MuteTiming.md +13 -0
  155. package/dist/okf/types/NodeGraphPanel.md +9 -0
  156. package/dist/okf/types/NotificationPolicy.md +9 -0
  157. package/dist/okf/types/NotificationTemplate.md +9 -0
  158. package/dist/okf/types/PieChartPanel.md +9 -0
  159. package/dist/okf/types/ReduceExpression.md +9 -0
  160. package/dist/okf/types/ResampleExpression.md +9 -0
  161. package/dist/okf/types/SqlExpression.md +9 -0
  162. package/dist/okf/types/StateTimelinePanel.md +9 -0
  163. package/dist/okf/types/StatusHistoryPanel.md +9 -0
  164. package/dist/okf/types/ThresholdExpression.md +9 -0
  165. package/dist/okf/types/TrendPanel.md +9 -0
  166. package/dist/okf/types/XYChartPanel.md +9 -0
  167. package/dist/op/activities/grafana-apply.d.ts +75 -0
  168. package/dist/op/activities/grafana-apply.d.ts.map +1 -0
  169. package/dist/op/activities/index.d.ts +9 -0
  170. package/dist/op/activities/index.d.ts.map +1 -0
  171. package/dist/op/builders.d.ts +24 -0
  172. package/dist/op/builders.d.ts.map +1 -0
  173. package/dist/ownership.d.ts +67 -0
  174. package/dist/ownership.d.ts.map +1 -0
  175. package/dist/panel-options.d.ts +65 -0
  176. package/dist/panel-options.d.ts.map +1 -0
  177. package/dist/panels.d.ts +46 -9
  178. package/dist/panels.d.ts.map +1 -1
  179. package/dist/pin.d.ts +29 -7
  180. package/dist/pin.d.ts.map +1 -1
  181. package/dist/plugin.d.ts.map +1 -1
  182. package/dist/promql-check.d.ts +51 -0
  183. package/dist/promql-check.d.ts.map +1 -0
  184. package/dist/query.d.ts +9 -8
  185. package/dist/query.d.ts.map +1 -1
  186. package/dist/rules/graf101.ts +3 -3
  187. package/dist/rules/graf102.ts +1 -1
  188. package/dist/rules/graf107.ts +1 -1
  189. package/dist/rules/graf108.ts +17 -0
  190. package/dist/rules/graf109.ts +17 -0
  191. package/dist/rules/graf111.ts +17 -0
  192. package/dist/rules/graf112.ts +17 -0
  193. package/dist/rules/graf113.ts +17 -0
  194. package/dist/rules/graf114.ts +17 -0
  195. package/dist/rules/graf115.ts +17 -0
  196. package/dist/rules/grafana-helpers.ts +15 -8
  197. package/dist/rules/literal-secret.ts +60 -6
  198. package/dist/schema/barchart.gen.d.ts +198 -0
  199. package/dist/schema/barchart.gen.d.ts.map +1 -0
  200. package/dist/schema/bargauge.gen.d.ts +97 -0
  201. package/dist/schema/bargauge.gen.d.ts.map +1 -0
  202. package/dist/schema/canvas.gen.d.ts +152 -0
  203. package/dist/schema/canvas.gen.d.ts.map +1 -0
  204. package/dist/schema/dashboard.gen.d.ts +196 -21
  205. package/dist/schema/dashboard.gen.d.ts.map +1 -1
  206. package/dist/schema/expr.gen.d.ts +606 -0
  207. package/dist/schema/expr.gen.d.ts.map +1 -0
  208. package/dist/schema/gauge.gen.d.ts.map +1 -1
  209. package/dist/schema/geomap.gen.d.ts +100 -0
  210. package/dist/schema/geomap.gen.d.ts.map +1 -0
  211. package/dist/schema/heatmap.gen.d.ts.map +1 -1
  212. package/dist/schema/histogram.gen.d.ts +132 -0
  213. package/dist/schema/histogram.gen.d.ts.map +1 -0
  214. package/dist/schema/index.d.ts +12 -0
  215. package/dist/schema/index.d.ts.map +1 -1
  216. package/dist/schema/logs.gen.d.ts +1 -0
  217. package/dist/schema/logs.gen.d.ts.map +1 -1
  218. package/dist/schema/loki.gen.d.ts.map +1 -1
  219. package/dist/schema/nodegraph.gen.d.ts +49 -0
  220. package/dist/schema/nodegraph.gen.d.ts.map +1 -0
  221. package/dist/schema/piechart.gen.d.ts +127 -0
  222. package/dist/schema/piechart.gen.d.ts.map +1 -0
  223. package/dist/schema/prometheus.gen.d.ts.map +1 -1
  224. package/dist/schema/stat.gen.d.ts.map +1 -1
  225. package/dist/schema/statetimeline.gen.d.ts +124 -0
  226. package/dist/schema/statetimeline.gen.d.ts.map +1 -0
  227. package/dist/schema/statushistory.gen.d.ts +114 -0
  228. package/dist/schema/statushistory.gen.d.ts.map +1 -0
  229. package/dist/schema/table.gen.d.ts +22 -3
  230. package/dist/schema/table.gen.d.ts.map +1 -1
  231. package/dist/schema/tempo.gen.d.ts.map +1 -1
  232. package/dist/schema/text.gen.d.ts.map +1 -1
  233. package/dist/schema/timeseries.gen.d.ts +5 -1
  234. package/dist/schema/timeseries.gen.d.ts.map +1 -1
  235. package/dist/schema/trend.gen.d.ts +180 -0
  236. package/dist/schema/trend.gen.d.ts.map +1 -0
  237. package/dist/schema/xychart.gen.d.ts +145 -0
  238. package/dist/schema/xychart.gen.d.ts.map +1 -0
  239. package/dist/schema-validate.d.ts +30 -4
  240. package/dist/schema-validate.d.ts.map +1 -1
  241. package/dist/serializer.d.ts +11 -3
  242. package/dist/serializer.d.ts.map +1 -1
  243. package/dist/skill-defs.d.ts.map +1 -1
  244. package/dist/skills/chant-grafana-alerting.md +49 -0
  245. package/dist/skills/chant-grafana-provisioning.md +3 -3
  246. package/dist/skills/chant-grafana.md +12 -6
  247. package/dist/spec/fetch-units-cli.d.ts +3 -0
  248. package/dist/spec/fetch-units-cli.d.ts.map +1 -0
  249. package/dist/spec/overlay.d.ts +43 -0
  250. package/dist/spec/overlay.d.ts.map +1 -0
  251. package/dist/spec/schemas.d.ts +13 -7
  252. package/dist/spec/schemas.d.ts.map +1 -1
  253. package/dist/spec/units.d.ts +35 -0
  254. package/dist/spec/units.d.ts.map +1 -0
  255. package/dist/spec/units.gen.d.ts +2 -0
  256. package/dist/spec/units.gen.d.ts.map +1 -0
  257. package/dist/transformations.d.ts +459 -0
  258. package/dist/transformations.d.ts.map +1 -0
  259. package/dist/util.d.ts +6 -0
  260. package/dist/util.d.ts.map +1 -1
  261. package/dist/validate-alerting.d.ts +65 -0
  262. package/dist/validate-alerting.d.ts.map +1 -0
  263. package/dist/validate-output.d.ts +49 -9
  264. package/dist/validate-output.d.ts.map +1 -1
  265. package/dist/validate.d.ts.map +1 -1
  266. package/dist/variables.d.ts +7 -2
  267. package/dist/variables.d.ts.map +1 -1
  268. package/package.json +12 -4
  269. package/src/actions/actions.test.ts +24 -0
  270. package/src/actions/grafana.ts +40 -0
  271. package/src/actions/index.ts +1 -0
  272. package/src/alerting-build.ts +376 -0
  273. package/src/alerting.e2e.test.ts +212 -0
  274. package/src/alerting.test.ts +272 -0
  275. package/src/alerting.ts +435 -0
  276. package/src/api/apply.test.ts +238 -0
  277. package/src/api/apply.ts +384 -0
  278. package/src/api/bind.ts +58 -0
  279. package/src/api/client.ts +148 -0
  280. package/src/api/converge.ts +63 -0
  281. package/src/api/dashboards.ts +247 -0
  282. package/src/api/datasources.ts +33 -0
  283. package/src/api/fake-grafana-writes.ts +201 -0
  284. package/src/api/fake-grafana.ts +186 -0
  285. package/src/api/folders.ts +265 -0
  286. package/src/api/library-panels.ts +101 -0
  287. package/src/build.test.ts +210 -5
  288. package/src/build.ts +180 -43
  289. package/src/catalog.ts +86 -2
  290. package/src/codegen/docs.ts +42 -9
  291. package/src/codegen/schema-types.ts +16 -6
  292. package/src/composites/agent-dashboard.ts +6 -3
  293. package/src/composites/catalog.test.ts +2 -2
  294. package/src/composites/catalog.ts +82 -0
  295. package/src/composites/composites.test.ts +73 -9
  296. package/src/composites/index.ts +4 -2
  297. package/src/composites/queries.e2e.test.ts +374 -0
  298. package/src/composites/red-dashboard.ts +83 -12
  299. package/src/composites/shared.ts +11 -0
  300. package/src/composites/slo-alert-rules.ts +149 -0
  301. package/src/config.test.ts +61 -0
  302. package/src/config.ts +138 -0
  303. package/src/contact-point-secrets.ts +63 -0
  304. package/src/dashboard.ts +16 -2
  305. package/src/datasource-refs.test.ts +56 -0
  306. package/src/datasource-refs.ts +189 -0
  307. package/src/datasource.ts +52 -0
  308. package/src/deep-observe-hooks.ts +252 -0
  309. package/src/deep-observe.test.ts +265 -0
  310. package/src/deep-observe.ts +164 -0
  311. package/src/describe-resources.test.ts +255 -0
  312. package/src/describe-resources.ts +209 -0
  313. package/src/detect.ts +79 -2
  314. package/src/export-resources.test.ts +129 -0
  315. package/src/export-resources.ts +84 -0
  316. package/src/generated/lexicon-grafana.json +135 -0
  317. package/src/import/alerting-roundtrip.test.ts +161 -0
  318. package/src/import/alerting.ts +500 -0
  319. package/src/import/edits.ts +95 -0
  320. package/src/import/embedded.test.ts +45 -0
  321. package/src/import/embedded.ts +47 -0
  322. package/src/import/generated-types.e2e.test.ts +118 -0
  323. package/src/import/generator.test.ts +210 -0
  324. package/src/import/generator.ts +462 -0
  325. package/src/import/live-export.ts +264 -0
  326. package/src/import/mappings.ts +264 -0
  327. package/src/import/model.ts +110 -0
  328. package/src/import/normalize-alerting.ts +101 -0
  329. package/src/import/normalize.test.ts +117 -0
  330. package/src/import/normalize.ts +364 -0
  331. package/src/import/parser.test.ts +440 -0
  332. package/src/import/parser.ts +1236 -0
  333. package/src/import/report.ts +62 -0
  334. package/src/import/roundtrip.test.ts +468 -0
  335. package/src/import/testdata/fixtures.ts +129 -0
  336. package/src/import/v2.test.ts +292 -0
  337. package/src/import/v2.ts +803 -0
  338. package/src/import.e2e.test.ts +31 -84
  339. package/src/import.test.ts +9 -3
  340. package/src/index.ts +190 -5
  341. package/src/k8s.test.ts +98 -0
  342. package/src/k8s.ts +197 -0
  343. package/src/lint/audit-catalog.ts +60 -3
  344. package/src/lint/core-lint.test.ts +43 -0
  345. package/src/lint/post-synth/graf101.ts +3 -3
  346. package/src/lint/post-synth/graf102.ts +1 -1
  347. package/src/lint/post-synth/graf107.ts +1 -1
  348. package/src/lint/post-synth/graf108.ts +17 -0
  349. package/src/lint/post-synth/graf109.ts +17 -0
  350. package/src/lint/post-synth/graf111.ts +17 -0
  351. package/src/lint/post-synth/graf112.ts +17 -0
  352. package/src/lint/post-synth/graf113.ts +17 -0
  353. package/src/lint/post-synth/graf114.ts +17 -0
  354. package/src/lint/post-synth/graf115.ts +17 -0
  355. package/src/lint/post-synth/grafana-helpers.ts +15 -8
  356. package/src/lint/post-synth/index.ts +14 -0
  357. package/src/lint/post-synth/post-synth.test.ts +235 -11
  358. package/src/lint/rules/literal-secret.ts +60 -6
  359. package/src/lint/rules/rules.test.ts +27 -0
  360. package/src/lsp/completions.test.ts +5 -0
  361. package/src/lsp/hover.test.ts +7 -0
  362. package/src/lsp/hover.ts +8 -1
  363. package/src/members.ts +68 -0
  364. package/src/observe.e2e.test.ts +255 -0
  365. package/src/op/activities/grafana-apply.e2e.test.ts +175 -0
  366. package/src/op/activities/grafana-apply.test.ts +229 -0
  367. package/src/op/activities/grafana-apply.ts +171 -0
  368. package/src/op/activities/index.ts +8 -0
  369. package/src/op/builders.test.ts +40 -0
  370. package/src/op/builders.ts +34 -0
  371. package/src/ownership.ts +103 -0
  372. package/src/panel-options.ts +66 -0
  373. package/src/panels.test.ts +51 -0
  374. package/src/panels.ts +148 -10
  375. package/src/pin.ts +57 -6
  376. package/src/plugin.test.ts +5 -2
  377. package/src/plugin.ts +66 -0
  378. package/src/promql-check.test.ts +108 -0
  379. package/src/promql-check.ts +189 -0
  380. package/src/query.ts +13 -8
  381. package/src/schema/barchart.gen.ts +221 -0
  382. package/src/schema/bargauge.gen.ts +111 -0
  383. package/src/schema/canvas.gen.ts +176 -0
  384. package/src/schema/dashboard.gen.ts +206 -22
  385. package/src/schema/expr.gen.ts +618 -0
  386. package/src/schema/gauge.gen.ts +2 -1
  387. package/src/schema/geomap.gen.ts +112 -0
  388. package/src/schema/heatmap.gen.ts +2 -1
  389. package/src/schema/histogram.gen.ts +151 -0
  390. package/src/schema/index.ts +12 -0
  391. package/src/schema/logs.gen.ts +3 -1
  392. package/src/schema/loki.gen.ts +2 -1
  393. package/src/schema/nodegraph.gen.ts +58 -0
  394. package/src/schema/piechart.gen.ts +146 -0
  395. package/src/schema/prometheus.gen.ts +2 -1
  396. package/src/schema/stat.gen.ts +2 -1
  397. package/src/schema/statetimeline.gen.ts +143 -0
  398. package/src/schema/statushistory.gen.ts +132 -0
  399. package/src/schema/table.gen.ts +27 -4
  400. package/src/schema/tempo.gen.ts +2 -1
  401. package/src/schema/text.gen.ts +2 -1
  402. package/src/schema/timeseries.gen.ts +7 -2
  403. package/src/schema/trend.gen.ts +208 -0
  404. package/src/schema/xychart.gen.ts +167 -0
  405. package/src/schema-overlay.test.ts +282 -0
  406. package/src/schema-validate.ts +141 -50
  407. package/src/schema.test.ts +4 -2
  408. package/src/serializer.test.ts +13 -1
  409. package/src/serializer.ts +11 -3
  410. package/src/skill-defs.ts +17 -0
  411. package/src/skills/chant-grafana-alerting.md +49 -0
  412. package/src/skills/chant-grafana-provisioning.md +3 -3
  413. package/src/skills/chant-grafana.md +12 -6
  414. package/src/spec/fetch-cli.ts +3 -3
  415. package/src/spec/fetch-units-cli.ts +37 -0
  416. package/src/spec/overlay/canvas.overlay.json +142 -0
  417. package/src/spec/overlay/dashboard.overlay.json +378 -0
  418. package/src/spec/overlay/expr.overlay.json +14 -0
  419. package/src/spec/overlay/geomap.overlay.json +35 -0
  420. package/src/spec/overlay/logs.overlay.json +14 -0
  421. package/src/spec/overlay/nodegraph.overlay.json +31 -0
  422. package/src/spec/overlay/piechart.overlay.json +17 -0
  423. package/src/spec/overlay/table.overlay.json +84 -0
  424. package/src/spec/overlay/timeseries.overlay.json +21 -0
  425. package/src/spec/overlay/trend.overlay.json +17 -0
  426. package/src/spec/overlay/xychart.overlay.json +16 -0
  427. package/src/spec/overlay.ts +105 -0
  428. package/src/spec/schemas/barchart.jsonschema.json +419 -0
  429. package/src/spec/schemas/bargauge.jsonschema.json +224 -0
  430. package/src/spec/schemas/canvas.jsonschema.json +356 -0
  431. package/src/spec/schemas/dashboardv2.jsonschema.json +3387 -0
  432. package/src/spec/schemas/expr.jsonschema.json +987 -0
  433. package/src/spec/schemas/geomap.jsonschema.json +220 -0
  434. package/src/spec/schemas/histogram.jsonschema.json +308 -0
  435. package/src/spec/schemas/nodegraph.jsonschema.json +77 -0
  436. package/src/spec/schemas/piechart.jsonschema.json +275 -0
  437. package/src/spec/schemas/statetimeline.jsonschema.json +324 -0
  438. package/src/spec/schemas/statushistory.jsonschema.json +292 -0
  439. package/src/spec/schemas/trend.jsonschema.json +449 -0
  440. package/src/spec/schemas/xychart.jsonschema.json +428 -0
  441. package/src/spec/schemas.ts +22 -10
  442. package/src/spec/units.gen.ts +281 -0
  443. package/src/spec/units.ts +77 -0
  444. package/src/transformations.test.ts +65 -0
  445. package/src/transformations.ts +574 -0
  446. package/src/util.ts +8 -0
  447. package/src/validate-alerting.test.ts +255 -0
  448. package/src/validate-alerting.ts +428 -0
  449. package/src/validate-output.ts +332 -101
  450. package/src/validate.ts +14 -0
  451. package/src/variables.ts +7 -2
@@ -1 +1 @@
1
- {"version":3,"file":"validate-output.d.ts","sourceRoot":"","sources":["../src/validate-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAOrD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEjH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC;AA2CD,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAIzD;AAoCD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CA0DvE;AAID,wBAAgB,cAAc,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAkClE;AAaD,wBAAgB,eAAe,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAyBnE;AAsBD,wBAAgB,SAAS,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAiC7D;AAID,wBAAgB,aAAa,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CA2BjE;AAID,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAa/D;AAYD,kCAAkC;AAClC,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAErF;AAED,oDAAoD;AACpD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAEzE"}
1
+ {"version":3,"file":"validate-output.d.ts","sourceRoot":"","sources":["../src/validate-output.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,mCAAmC,CAAC;AASvF,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEvF,0DAA0D;AAC1D,eAAO,MAAM,cAAc,UAsB1B,CAAC;AAIF,wBAAsB,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CA2DxD"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,mCAAmC,CAAC;AASvF,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEvF,0DAA0D;AAC1D,eAAO,MAAM,cAAc,UAoC1B,CAAC;AAIF,wBAAsB,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CA2DxD"}
@@ -9,7 +9,7 @@
9
9
  * or query, and the reference becomes `${name}`.
10
10
  */
11
11
  import type { Declarable } from "@intentius/chant/declarable";
12
- import type { DatasourceEntity, DatasourceRef } from "./datasource.js";
12
+ import type { DatasourceEntity, DatasourceRef, ExternalDatasourceEntity } from "./datasource.js";
13
13
  import type { VariableOption } from "./schema/dashboard.gen.js";
14
14
  export type VariableKind = "query" | "custom" | "interval" | "datasource" | "constant" | "textbox";
15
15
  /** Where the variable shows: with its label, without it, or not at all. */
@@ -32,7 +32,7 @@ interface MultiValueProps {
32
32
  allValue?: string;
33
33
  }
34
34
  /** A variable anything can hold before its datasource is known: its own datasource ref or a datasource variable. */
35
- export type VariableDatasource = DatasourceEntity<any> | DatasourceRef | DatasourceVariableEntity<any>;
35
+ export type VariableDatasource = DatasourceEntity<any> | ExternalDatasourceEntity<any> | DatasourceRef | DatasourceVariableEntity<any>;
36
36
  export interface QueryVariableProps extends CommonVariableProps, MultiValueProps {
37
37
  datasource: VariableDatasource;
38
38
  /** The datasource's variable query, e.g. `label_values(up, job)` for Prometheus. */
@@ -44,6 +44,11 @@ export interface QueryVariableProps extends CommonVariableProps, MultiValueProps
44
44
  sort?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
45
45
  }
46
46
  export interface CustomVariableProps extends CommonVariableProps, MultiValueProps {
47
+ /**
48
+ * The values, in Grafana's syntax: `"Production : prod"` shows
49
+ * `Production` and sets `prod`. A comma is part of the value (written as
50
+ * `\,`, and one already escaped is kept).
51
+ */
47
52
  values: string[];
48
53
  }
49
54
  export interface IntervalVariableProps extends CommonVariableProps {
@@ -1 +1 @@
1
- {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-grafana",
3
- "version": "0.97.0",
3
+ "version": "0.99.0",
4
4
  "description": "Grafana lexicon for chant — typed dashboards, panels, queries and datasources, serialized to dashboard JSON and Grafana provisioning files",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -43,6 +43,11 @@
43
43
  "types": "./dist/*.d.ts",
44
44
  "default": "./src/*.ts"
45
45
  },
46
+ "./op/activities": {
47
+ "development": "./src/op/activities/index.ts",
48
+ "types": "./dist/op/activities/index.d.ts",
49
+ "default": "./src/op/activities/index.ts"
50
+ },
46
51
  "./lint/post-synth": {
47
52
  "development": "./src/lint/post-synth/index.ts",
48
53
  "types": "./dist/lint/post-synth/index.d.ts",
@@ -61,6 +66,7 @@
61
66
  "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
62
67
  },
63
68
  "dependencies": {
69
+ "@intentius/chant-lexicon-k8s": "*",
64
70
  "@intentius/chant-lexicon-otel": "*",
65
71
  "@intentius/chant-lexicon-prometheus": "*",
66
72
  "ajv": "^8.20.0",
@@ -70,10 +76,12 @@
70
76
  "@intentius/chant": "*",
71
77
  "@types/js-yaml": "^4.0.9",
72
78
  "tsc-alias": "^1.8.17",
73
- "typescript": "^5.9.3"
79
+ "typescript": "^5.9.3",
80
+ "zod": "^4.3.6"
74
81
  },
75
82
  "peerDependencies": {
76
- "@intentius/chant": "^0.97.0",
77
- "typescript": "^5.9.3"
83
+ "@intentius/chant": "^0.99.0",
84
+ "typescript": "^5.9.3",
85
+ "zod": "^4.3.6"
78
86
  }
79
87
  }
@@ -0,0 +1,24 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { GrafanaActions, grafanaActionsFor } from "./grafana";
3
+
4
+ describe("GrafanaActions", () => {
5
+ test("every action is a Grafana RBAC action name (<resource>:<verb>), with no duplicate in a group", () => {
6
+ for (const actions of Object.values(GrafanaActions)) {
7
+ for (const a of actions) expect(a).toMatch(/^[a-z]+(\.[a-z]+)*:[a-z]+$/);
8
+ expect(new Set(actions).size).toBe(actions.length);
9
+ }
10
+ });
11
+
12
+ test("apply and prune together cover every call the applier makes", () => {
13
+ expect(grafanaActionsFor("Apply", "Prune")).toEqual(
14
+ expect.arrayContaining(["dashboards:create", "dashboards:write", "dashboards:delete", "folders:create", "folders:delete", "library.panels:create", "library.panels:write"]),
15
+ );
16
+ expect(grafanaActionsFor("Prune")).not.toContain("library.panels:delete");
17
+ });
18
+
19
+ test("levels are merged without duplicates", () => {
20
+ const merged = grafanaActionsFor("Observe", "Apply");
21
+ expect(new Set(merged).size).toBe(merged.length);
22
+ expect(merged[0]).toBe("dashboards:read");
23
+ });
24
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The Grafana RBAC actions chant's live paths call, for a custom role on the
3
+ * service account whose token a `grafana.profiles.<env>` entry names. The
4
+ * basic Editor role covers all of them; these are for a narrower role.
5
+ *
6
+ * - `Observe`: `chant lifecycle diff --live` and `chant import --from`
7
+ * (#2946), which read dashboards, folders and datasources.
8
+ * - `Apply`: the API applier (#2948), which also reads what it writes to
9
+ * compare, and writes folders, library panels and dashboards.
10
+ * - `Prune`: the applier with `prune`, which deletes dashboards and folders
11
+ * (never library panels or datasources).
12
+ *
13
+ * Grant them on `folders:*` and `dashboards:*` scopes, or on the folders
14
+ * chant writes to.
15
+ */
16
+ export const GrafanaActions = {
17
+ Observe: ["dashboards:read", "folders:read", "datasources:read"],
18
+ Apply: [
19
+ "dashboards:read",
20
+ "dashboards:create",
21
+ "dashboards:write",
22
+ "folders:read",
23
+ "folders:create",
24
+ "folders:write",
25
+ "library.panels:read",
26
+ "library.panels:create",
27
+ "library.panels:write",
28
+ ],
29
+ Prune: ["dashboards:read", "dashboards:delete", "folders:read", "folders:delete"],
30
+ } as const;
31
+
32
+ export type GrafanaAccessLevel = keyof typeof GrafanaActions;
33
+
34
+ // A Map-backed lookup, so evaluable code avoids computed element access (EVL003).
35
+ const GRAFANA_ACTIONS = new Map<GrafanaAccessLevel, readonly string[]>(Object.entries(GrafanaActions) as [GrafanaAccessLevel, readonly string[]][]);
36
+
37
+ /** The actions for one or more access levels, deduplicated, in first-seen order. */
38
+ export function grafanaActionsFor(...levels: GrafanaAccessLevel[]): string[] {
39
+ return [...new Set(levels.flatMap((l) => GRAFANA_ACTIONS.get(l) ?? []))];
40
+ }
@@ -0,0 +1 @@
1
+ export { GrafanaActions, grafanaActionsFor, type GrafanaAccessLevel } from "./grafana";
@@ -0,0 +1,376 @@
1
+ /**
2
+ * From alerting entities to Grafana's alerting provisioning file,
3
+ * `provisioning/alerting/chant.yaml`.
4
+ *
5
+ * The file is what Grafana's file provisioner reads
6
+ * (`pkg/services/provisioning/alerting`, the same at v12.4.11 and v13.2.2)
7
+ * and what `GET /api/v1/provisioning/*\/export` writes: `apiVersion: 1`
8
+ * and the lists `groups`, `contactPoints`, `policies`, `muteTimes` and
9
+ * `templates`. Mount `provisioning/` at `/etc/grafana/provisioning`, as for
10
+ * datasources and dashboards.
11
+ *
12
+ * Plain functions, so a test or another lexicon can render the same file
13
+ * with `alertingYaml()` without a build.
14
+ */
15
+
16
+ import { dump } from "js-yaml";
17
+ import type { Declarable } from "@intentius/chant/declarable";
18
+ import { durationMs, isValidDuration } from "@intentius/chant-lexicon-prometheus/duration";
19
+ import {
20
+ EXPRESSION_DATASOURCE_UID,
21
+ isAlertQueryEntity,
22
+ isAlertRuleGroupEntity,
23
+ isContactPointEntity,
24
+ isExpressionEntity,
25
+ isMuteTimingEntity,
26
+ isNotificationPolicyEntity,
27
+ isNotificationTemplateEntity,
28
+ type AlertDuration,
29
+ type AlertRuleData,
30
+ type AlertRuleEntity,
31
+ type AlertRuleGroupEntity,
32
+ type ContactPointEntity,
33
+ type MuteTimingEntity,
34
+ type NotificationPolicyEntity,
35
+ type NotificationTemplateEntity,
36
+ type PolicyRoute,
37
+ type RelativeTimeRange,
38
+ } from "./alerting";
39
+ import { isDashboardEntity } from "./dashboard";
40
+ import { isQueryEntity, type QueryEntity } from "./query";
41
+ import { isDatasourceVariable } from "./variables";
42
+ import { compact, slugUid } from "./util";
43
+ // build.ts imports this module too; only functions cross the cycle, and only at call time.
44
+ import { datasourceRef, targetJson } from "./build";
45
+
46
+ /** Where the alerting provisioning file goes, relative to the build output directory. */
47
+ export const ALERTING_FILE = "provisioning/alerting/chant.yaml";
48
+
49
+ /** The time range a query reads when neither it nor its rule sets one: the last 10 minutes, Grafana's editor default. */
50
+ export const DEFAULT_RELATIVE_TIME_RANGE = { from: 600, to: 0 } as const;
51
+
52
+ /** A rule group's evaluation interval when it sets none. */
53
+ export const DEFAULT_GROUP_INTERVAL = "1m";
54
+
55
+ type Json = Record<string, unknown>;
56
+
57
+ /** One entry of a rule's `data` in the file. */
58
+ export interface ProvisionedAlertQuery {
59
+ refId: string;
60
+ queryType?: string;
61
+ relativeTimeRange?: { from: number; to: number };
62
+ datasourceUid: string;
63
+ model: Json;
64
+ }
65
+
66
+ export interface ProvisionedAlertRule {
67
+ uid: string;
68
+ title: string;
69
+ condition?: string;
70
+ data: ProvisionedAlertQuery[];
71
+ dashboardUid?: string;
72
+ panelId?: number;
73
+ noDataState?: string;
74
+ execErrState?: string;
75
+ for?: string;
76
+ keepFiringFor?: string;
77
+ missing_series_evals_to_resolve?: number;
78
+ annotations?: Record<string, string>;
79
+ labels?: Record<string, string>;
80
+ isPaused?: boolean;
81
+ notification_settings?: Json;
82
+ record?: Json;
83
+ }
84
+
85
+ export interface ProvisionedRuleGroup {
86
+ orgId?: number;
87
+ name: string;
88
+ folder: string;
89
+ interval: string;
90
+ rules: ProvisionedAlertRule[];
91
+ }
92
+
93
+ export interface ProvisionedContactPoint {
94
+ orgId?: number;
95
+ name: string;
96
+ receivers: Array<{ uid: string; type: string; settings: Json; disableResolveMessage?: boolean }>;
97
+ }
98
+
99
+ export interface ProvisionedMuteTiming {
100
+ orgId?: number;
101
+ name: string;
102
+ time_intervals: Json[];
103
+ }
104
+
105
+ export interface ProvisionedTemplate {
106
+ orgId?: number;
107
+ name: string;
108
+ template: string;
109
+ }
110
+
111
+ /** The alerting provisioning file, parsed. */
112
+ export interface AlertingFile {
113
+ apiVersion: 1;
114
+ groups?: ProvisionedRuleGroup[];
115
+ contactPoints?: ProvisionedContactPoint[];
116
+ policies?: Json[];
117
+ muteTimes?: ProvisionedMuteTiming[];
118
+ templates?: ProvisionedTemplate[];
119
+ }
120
+
121
+ /** The keys an alerting provisioning file can hold, from `AlertingFileV1`. */
122
+ export const ALERTING_FILE_KEYS = [
123
+ "apiVersion",
124
+ "groups",
125
+ "deleteRules",
126
+ "contactPoints",
127
+ "deleteContactPoints",
128
+ "policies",
129
+ "resetPolicies",
130
+ "muteTimes",
131
+ "deleteMuteTimes",
132
+ "templates",
133
+ "deleteTemplates",
134
+ ] as const;
135
+
136
+ // ── Durations ───────────────────────────────────────────────────
137
+
138
+ /** A duration as whole seconds: a number is taken as seconds, a string as a Prometheus duration. */
139
+ export function durationSeconds(value: AlertDuration, what: string): number {
140
+ if (typeof value === "number") {
141
+ if (!Number.isInteger(value) || value < 0) throw new Error(`grafana: ${what} must be a whole number of seconds, got ${value}`);
142
+ return value;
143
+ }
144
+ if (!isValidDuration(value)) throw new Error(`grafana: ${what} "${value}" is not a duration like 10m or 1h`);
145
+ return Math.floor(durationMs(value)! / 1000);
146
+ }
147
+
148
+ function timeRange(range: RelativeTimeRange, what: string): { from: number; to: number } {
149
+ return { from: durationSeconds(range.from, `${what} from`), to: durationSeconds(range.to ?? 0, `${what} to`) };
150
+ }
151
+
152
+ // ── References ──────────────────────────────────────────────────
153
+
154
+ function receiverName(receiver: ContactPointEntity | string): string {
155
+ return typeof receiver === "string" ? receiver : receiver.props.name;
156
+ }
157
+
158
+ function timingNames(list: Array<MuteTimingEntity | string> | undefined): string[] | undefined {
159
+ return list?.map((t) => (typeof t === "string" ? t : t.props.name));
160
+ }
161
+
162
+ // ── Rules ───────────────────────────────────────────────────────
163
+
164
+ const REF_IDS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
165
+ function refIdAt(i: number): string {
166
+ return i < REF_IDS.length ? REF_IDS[i] : `${REF_IDS[Math.floor(i / REF_IDS.length) - 1]}${REF_IDS[i % REF_IDS.length]}`;
167
+ }
168
+
169
+ /** The uid a query's datasource resolves to, and its type when known. */
170
+ function datasourceOf(input: unknown, where: string): { uid: string; type?: string } {
171
+ if (input === undefined || input === null) throw new Error(`grafana: ${where} has no datasource; an alert query must name one`);
172
+ if (typeof input === "string") return { uid: input };
173
+ if (isDatasourceVariable(input)) {
174
+ throw new Error(`grafana: ${where} uses a DatasourceVariable; alert rules are evaluated without dashboard variables, so name the datasource itself`);
175
+ }
176
+ const ref = datasourceRef(input as Parameters<typeof datasourceRef>[0])!;
177
+ return { uid: ref.uid!, ...(ref.type ? { type: ref.type } : {}) };
178
+ }
179
+
180
+ function typedQueryModel(query: QueryEntity, refId: string, where: string): { uid: string; model: Json } {
181
+ const ds = datasourceOf((query.props as Json).datasource, where);
182
+ const model = targetJson(query, 0, ds.type ? { type: ds.type, uid: ds.uid } : undefined);
183
+ return { uid: ds.uid, model: { ...model, refId } };
184
+ }
185
+
186
+ /** One entry of `data`, as the file holds it. */
187
+ export function alertQueryJson(item: AlertRuleData, index: number, ruleRange: RelativeTimeRange | undefined, rule: string): ProvisionedAlertQuery {
188
+ const where = `alert rule "${rule}" data[${index}]`;
189
+ const fallbackRange = ruleRange ? timeRange(ruleRange, `${where} relativeTimeRange`) : { ...DEFAULT_RELATIVE_TIME_RANGE };
190
+ if (isExpressionEntity(item)) {
191
+ const { refId: ownRefId, relativeTimeRange, ...rest } = item.props as Json & { refId?: string; relativeTimeRange?: RelativeTimeRange };
192
+ const refId = ownRefId ?? refIdAt(index);
193
+ return compact({
194
+ refId,
195
+ relativeTimeRange: relativeTimeRange ? timeRange(relativeTimeRange, `${where} relativeTimeRange`) : undefined,
196
+ datasourceUid: EXPRESSION_DATASOURCE_UID,
197
+ model: { datasource: { type: EXPRESSION_DATASOURCE_UID, uid: EXPRESSION_DATASOURCE_UID }, refId, type: item.expressionKind, ...rest },
198
+ });
199
+ }
200
+ if (isAlertQueryEntity(item)) {
201
+ const p = item.props;
202
+ const refId = p.refId ?? refIdAt(index);
203
+ const range = p.relativeTimeRange ? timeRange(p.relativeTimeRange, `${where} relativeTimeRange`) : fallbackRange;
204
+ let uid: string;
205
+ let model: Json;
206
+ if (p.query) {
207
+ const typed = typedQueryModel(p.query, refId, where);
208
+ const own = p.datasource !== undefined ? datasourceOf(p.datasource, where) : undefined;
209
+ uid = own?.uid ?? typed.uid;
210
+ model = { ...typed.model, ...(p.model ?? {}) };
211
+ } else {
212
+ uid = datasourceOf(p.datasource, where).uid;
213
+ model = p.model ?? {};
214
+ }
215
+ return compact({ refId, queryType: p.queryType, relativeTimeRange: range, datasourceUid: uid, model });
216
+ }
217
+ if (isQueryEntity(item)) {
218
+ const refId = ((item.props as Json).refId as string | undefined) ?? refIdAt(index);
219
+ const typed = typedQueryModel(item, refId, where);
220
+ return { refId, relativeTimeRange: fallbackRange, datasourceUid: typed.uid, model: typed.model };
221
+ }
222
+ throw new Error(`grafana: ${where} must be a query (PromQuery, AlertQuery, ...) or an expression (ReduceExpression, ...)`);
223
+ }
224
+
225
+ /** One rule as the file holds it. */
226
+ export function alertRuleJson(rule: AlertRuleEntity): ProvisionedAlertRule {
227
+ const p = rule.props;
228
+ const data = (p.data ?? []).map((d, i) => alertQueryJson(d, i, p.relativeTimeRange, p.title));
229
+ const condition = p.condition ?? (p.record ? undefined : data[data.length - 1]?.refId);
230
+ const dashboardUid = p.dashboardUid === undefined ? undefined : isDashboardEntity(p.dashboardUid) ? (p.dashboardUid.props.uid ?? slugUid(p.dashboardUid.props.title)) : p.dashboardUid;
231
+ const ns = p.notification_settings;
232
+ return compact({
233
+ uid: p.uid ?? slugUid(p.title),
234
+ title: p.title,
235
+ condition,
236
+ data,
237
+ dashboardUid,
238
+ panelId: p.panelId,
239
+ noDataState: p.noDataState,
240
+ execErrState: p.execErrState,
241
+ for: p.for,
242
+ keepFiringFor: p.keepFiringFor,
243
+ missing_series_evals_to_resolve: p.missing_series_evals_to_resolve,
244
+ annotations: p.annotations,
245
+ labels: p.labels,
246
+ isPaused: p.isPaused,
247
+ notification_settings: ns
248
+ ? {
249
+ receiver: receiverName(ns.receiver),
250
+ group_by: ns.group_by,
251
+ group_wait: ns.group_wait,
252
+ group_interval: ns.group_interval,
253
+ repeat_interval: ns.repeat_interval,
254
+ mute_time_intervals: timingNames(ns.mute_time_intervals),
255
+ active_time_intervals: timingNames(ns.active_time_intervals),
256
+ }
257
+ : undefined,
258
+ record: p.record ? { ...p.record } : undefined,
259
+ });
260
+ }
261
+
262
+ /** One rule group as the file holds it. */
263
+ export function ruleGroupJson(group: AlertRuleGroupEntity): ProvisionedRuleGroup {
264
+ const p = group.props;
265
+ return compact({
266
+ orgId: p.orgId,
267
+ name: p.name,
268
+ folder: p.folder,
269
+ interval: p.interval ?? DEFAULT_GROUP_INTERVAL,
270
+ rules: (p.rules ?? []).map(alertRuleJson),
271
+ });
272
+ }
273
+
274
+ // ── Notifications ───────────────────────────────────────────────
275
+
276
+ /** One contact point as the file holds it. A receiver without a uid gets one from the name and the integration type. */
277
+ export function contactPointJson(cp: ContactPointEntity): ProvisionedContactPoint {
278
+ const p = cp.props;
279
+ const taken = new Set<string>();
280
+ const receivers = (p.receivers ?? []).map((r) => {
281
+ let uid = r.uid ?? slugUid(`${p.name} ${r.type}`);
282
+ if (r.uid === undefined) for (let n = 2; taken.has(uid); n++) uid = slugUid(`${p.name} ${r.type} ${n}`);
283
+ taken.add(uid);
284
+ return compact({ uid, type: r.type, settings: r.settings ?? {}, disableResolveMessage: r.disableResolveMessage });
285
+ });
286
+ return compact({ orgId: p.orgId, name: p.name, receivers });
287
+ }
288
+
289
+ function routeJson(route: PolicyRoute): Json {
290
+ return compact({
291
+ receiver: route.receiver === undefined ? undefined : receiverName(route.receiver),
292
+ group_by: route.group_by,
293
+ object_matchers: route.object_matchers?.map((m) => [...m]),
294
+ matchers: route.matchers,
295
+ match: route.match,
296
+ match_re: route.match_re,
297
+ continue: route.continue,
298
+ group_wait: route.group_wait,
299
+ group_interval: route.group_interval,
300
+ repeat_interval: route.repeat_interval,
301
+ mute_time_intervals: timingNames(route.mute_time_intervals),
302
+ active_time_intervals: timingNames(route.active_time_intervals),
303
+ routes: route.routes?.map(routeJson),
304
+ });
305
+ }
306
+
307
+ /** One organisation's policy tree as the file holds it. */
308
+ export function notificationPolicyJson(policy: NotificationPolicyEntity): Json {
309
+ const p = policy.props;
310
+ return compact({
311
+ orgId: p.orgId,
312
+ receiver: receiverName(p.receiver),
313
+ group_by: p.group_by,
314
+ group_wait: p.group_wait,
315
+ group_interval: p.group_interval,
316
+ repeat_interval: p.repeat_interval,
317
+ mute_time_intervals: timingNames(p.mute_time_intervals),
318
+ active_time_intervals: timingNames(p.active_time_intervals),
319
+ routes: p.routes?.map(routeJson),
320
+ });
321
+ }
322
+
323
+ export function muteTimingJson(t: MuteTimingEntity): ProvisionedMuteTiming {
324
+ return compact({ orgId: t.props.orgId, name: t.props.name, time_intervals: (t.props.time_intervals ?? []) as unknown as Json[] });
325
+ }
326
+
327
+ export function notificationTemplateJson(t: NotificationTemplateEntity): ProvisionedTemplate {
328
+ return compact({ orgId: t.props.orgId, name: t.props.name, template: t.props.template });
329
+ }
330
+
331
+ // ── The file ────────────────────────────────────────────────────
332
+
333
+ /** The alerting provisioning file as YAML text. */
334
+ export function alertingYaml(file: AlertingFile): string {
335
+ return `# Grafana alerting provisioning, generated by chant.\n${dump(file, { lineWidth: -1, noRefs: true, quotingType: '"' })}`;
336
+ }
337
+
338
+ /** Summary of the alerting a build provisions, for the build index. */
339
+ export interface AlertingIndex {
340
+ ruleGroups: Array<{ name: string; folder: string; rules: number }>;
341
+ contactPoints: string[];
342
+ policies: number;
343
+ muteTimings: string[];
344
+ templates: string[];
345
+ }
346
+
347
+ /** The alerting provisioning file for the alerting entities among these, or undefined when there are none. */
348
+ export function buildAlerting(entities: Iterable<Declarable>): { file: AlertingFile; index: AlertingIndex } | undefined {
349
+ const all = [...entities];
350
+ const byName = <T extends { name: string }>(a: T, b: T) => a.name.localeCompare(b.name);
351
+ const groups = all
352
+ .filter(isAlertRuleGroupEntity)
353
+ .map(ruleGroupJson)
354
+ .sort((a, b) => a.folder.localeCompare(b.folder) || a.name.localeCompare(b.name));
355
+ const contactPoints = all.filter(isContactPointEntity).map(contactPointJson).sort(byName);
356
+ const policies = all.filter(isNotificationPolicyEntity).map(notificationPolicyJson);
357
+ const muteTimes = all.filter(isMuteTimingEntity).map(muteTimingJson).sort(byName);
358
+ const templates = all.filter(isNotificationTemplateEntity).map(notificationTemplateJson).sort(byName);
359
+ if (groups.length + contactPoints.length + policies.length + muteTimes.length + templates.length === 0) return undefined;
360
+ const file: AlertingFile = compact({
361
+ apiVersion: 1 as const,
362
+ groups: groups.length > 0 ? groups : undefined,
363
+ contactPoints: contactPoints.length > 0 ? contactPoints : undefined,
364
+ policies: policies.length > 0 ? policies : undefined,
365
+ muteTimes: muteTimes.length > 0 ? muteTimes : undefined,
366
+ templates: templates.length > 0 ? templates : undefined,
367
+ });
368
+ const index: AlertingIndex = {
369
+ ruleGroups: groups.map((g) => ({ name: g.name, folder: g.folder, rules: g.rules.length })),
370
+ contactPoints: contactPoints.map((c) => c.name),
371
+ policies: policies.length,
372
+ muteTimings: muteTimes.map((m) => m.name),
373
+ templates: templates.map((t) => t.name),
374
+ };
375
+ return { file, index };
376
+ }