@intentius/chant-lexicon-grafana 0.98.0 → 0.100.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 (532) hide show
  1. package/README.md +24 -8
  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/annotations.d.ts +61 -0
  11. package/dist/annotations.d.ts.map +1 -0
  12. package/dist/api/apply.d.ts +160 -0
  13. package/dist/api/apply.d.ts.map +1 -0
  14. package/dist/api/bind.d.ts +32 -0
  15. package/dist/api/bind.d.ts.map +1 -0
  16. package/dist/api/client.d.ts +76 -0
  17. package/dist/api/client.d.ts.map +1 -0
  18. package/dist/api/converge.d.ts +33 -0
  19. package/dist/api/converge.d.ts.map +1 -0
  20. package/dist/api/dashboards.d.ts +102 -0
  21. package/dist/api/dashboards.d.ts.map +1 -0
  22. package/dist/api/datasources.d.ts +26 -0
  23. package/dist/api/datasources.d.ts.map +1 -0
  24. package/dist/api/fake-grafana-writes.d.ts +41 -0
  25. package/dist/api/fake-grafana-writes.d.ts.map +1 -0
  26. package/dist/api/fake-grafana.d.ts +63 -0
  27. package/dist/api/fake-grafana.d.ts.map +1 -0
  28. package/dist/api/folders.d.ts +146 -0
  29. package/dist/api/folders.d.ts.map +1 -0
  30. package/dist/api/library-panels.d.ts +52 -0
  31. package/dist/api/library-panels.d.ts.map +1 -0
  32. package/dist/build.d.ts +55 -6
  33. package/dist/build.d.ts.map +1 -1
  34. package/dist/catalog.d.ts +1 -1
  35. package/dist/catalog.d.ts.map +1 -1
  36. package/dist/codegen/docs.d.ts.map +1 -1
  37. package/dist/codegen/generate.d.ts +7 -1
  38. package/dist/codegen/generate.d.ts.map +1 -1
  39. package/dist/codegen/schema-types.d.ts +3 -3
  40. package/dist/codegen/schema-types.d.ts.map +1 -1
  41. package/dist/composites/agent-dashboard.d.ts.map +1 -1
  42. package/dist/composites/catalog.d.ts.map +1 -1
  43. package/dist/composites/index.d.ts +4 -2
  44. package/dist/composites/index.d.ts.map +1 -1
  45. package/dist/composites/red-dashboard.d.ts +21 -2
  46. package/dist/composites/red-dashboard.d.ts.map +1 -1
  47. package/dist/composites/shared.d.ts +11 -3
  48. package/dist/composites/shared.d.ts.map +1 -1
  49. package/dist/composites/slo-alert-rules.d.ts +92 -0
  50. package/dist/composites/slo-alert-rules.d.ts.map +1 -0
  51. package/dist/config.d.ts +111 -0
  52. package/dist/config.d.ts.map +1 -0
  53. package/dist/contact-point-secrets.d.ts +17 -0
  54. package/dist/contact-point-secrets.d.ts.map +1 -0
  55. package/dist/dashboard.d.ts +51 -9
  56. package/dist/dashboard.d.ts.map +1 -1
  57. package/dist/datasource-refs.d.ts +99 -0
  58. package/dist/datasource-refs.d.ts.map +1 -0
  59. package/dist/datasource-settings.d.ts +834 -0
  60. package/dist/datasource-settings.d.ts.map +1 -0
  61. package/dist/datasource.d.ts +82 -11
  62. package/dist/datasource.d.ts.map +1 -1
  63. package/dist/deep-observe-hooks.d.ts +64 -0
  64. package/dist/deep-observe-hooks.d.ts.map +1 -0
  65. package/dist/deep-observe.d.ts +47 -0
  66. package/dist/deep-observe.d.ts.map +1 -0
  67. package/dist/describe-resources.d.ts +50 -0
  68. package/dist/describe-resources.d.ts.map +1 -0
  69. package/dist/detect.d.ts +32 -3
  70. package/dist/detect.d.ts.map +1 -1
  71. package/dist/export-resources.d.ts +38 -0
  72. package/dist/export-resources.d.ts.map +1 -0
  73. package/dist/folder.d.ts +68 -0
  74. package/dist/folder.d.ts.map +1 -0
  75. package/dist/import/alerting.d.ts +40 -0
  76. package/dist/import/alerting.d.ts.map +1 -0
  77. package/dist/import/edits.d.ts +47 -0
  78. package/dist/import/edits.d.ts.map +1 -0
  79. package/dist/import/embedded.d.ts +14 -0
  80. package/dist/import/embedded.d.ts.map +1 -0
  81. package/dist/import/generator.d.ts +60 -0
  82. package/dist/import/generator.d.ts.map +1 -0
  83. package/dist/import/live-export.d.ts +108 -0
  84. package/dist/import/live-export.d.ts.map +1 -0
  85. package/dist/import/mappings.d.ts +89 -0
  86. package/dist/import/mappings.d.ts.map +1 -0
  87. package/dist/import/model.d.ts +105 -0
  88. package/dist/import/model.d.ts.map +1 -0
  89. package/dist/import/normalize-alerting.d.ts +26 -0
  90. package/dist/import/normalize-alerting.d.ts.map +1 -0
  91. package/dist/import/normalize.d.ts +74 -0
  92. package/dist/import/normalize.d.ts.map +1 -0
  93. package/dist/import/parser.d.ts +125 -0
  94. package/dist/import/parser.d.ts.map +1 -0
  95. package/dist/import/report.d.ts +26 -0
  96. package/dist/import/report.d.ts.map +1 -0
  97. package/dist/import/testdata/fixtures.d.ts +41 -0
  98. package/dist/import/testdata/fixtures.d.ts.map +1 -0
  99. package/dist/import/v2.d.ts +73 -0
  100. package/dist/import/v2.d.ts.map +1 -0
  101. package/dist/index.d.ts +31 -12
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/init-templates.d.ts +27 -0
  104. package/dist/init-templates.d.ts.map +1 -0
  105. package/dist/integrity.json +22 -12
  106. package/dist/k8s.d.ts +107 -0
  107. package/dist/k8s.d.ts.map +1 -0
  108. package/dist/lint/audit-catalog.d.ts +2 -1
  109. package/dist/lint/audit-catalog.d.ts.map +1 -1
  110. package/dist/lint/post-synth/graf101.d.ts +2 -2
  111. package/dist/lint/post-synth/graf102.d.ts +1 -1
  112. package/dist/lint/post-synth/graf104.d.ts +2 -2
  113. package/dist/lint/post-synth/graf106.d.ts +2 -2
  114. package/dist/lint/post-synth/graf107.d.ts +1 -1
  115. package/dist/lint/post-synth/graf108.d.ts +8 -0
  116. package/dist/lint/post-synth/graf108.d.ts.map +1 -0
  117. package/dist/lint/post-synth/graf109.d.ts +8 -0
  118. package/dist/lint/post-synth/graf109.d.ts.map +1 -0
  119. package/dist/lint/post-synth/graf110.d.ts +8 -0
  120. package/dist/lint/post-synth/graf110.d.ts.map +1 -0
  121. package/dist/lint/post-synth/graf111.d.ts +8 -0
  122. package/dist/lint/post-synth/graf111.d.ts.map +1 -0
  123. package/dist/lint/post-synth/graf112.d.ts +8 -0
  124. package/dist/lint/post-synth/graf112.d.ts.map +1 -0
  125. package/dist/lint/post-synth/graf113.d.ts +8 -0
  126. package/dist/lint/post-synth/graf113.d.ts.map +1 -0
  127. package/dist/lint/post-synth/graf114.d.ts +8 -0
  128. package/dist/lint/post-synth/graf114.d.ts.map +1 -0
  129. package/dist/lint/post-synth/graf115.d.ts +8 -0
  130. package/dist/lint/post-synth/graf115.d.ts.map +1 -0
  131. package/dist/lint/post-synth/grafana-helpers.d.ts +7 -5
  132. package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -1
  133. package/dist/lint/post-synth/index.d.ts.map +1 -1
  134. package/dist/lint/rules/literal-secret.d.ts +7 -3
  135. package/dist/lint/rules/literal-secret.d.ts.map +1 -1
  136. package/dist/lsp/hover.d.ts.map +1 -1
  137. package/dist/manifest.json +1 -1
  138. package/dist/members.d.ts +27 -0
  139. package/dist/members.d.ts.map +1 -0
  140. package/dist/meta.json +205 -0
  141. package/dist/okf/index.md +53 -4
  142. package/dist/okf/rules/GRAF002.md +3 -2
  143. package/dist/okf/rules/GRAF101.md +3 -2
  144. package/dist/okf/rules/GRAF102.md +1 -0
  145. package/dist/okf/rules/GRAF104.md +2 -2
  146. package/dist/okf/rules/GRAF106.md +2 -2
  147. package/dist/okf/rules/GRAF108.md +11 -0
  148. package/dist/okf/rules/GRAF109.md +15 -0
  149. package/dist/okf/rules/GRAF110.md +11 -0
  150. package/dist/okf/rules/GRAF111.md +11 -0
  151. package/dist/okf/rules/GRAF112.md +16 -0
  152. package/dist/okf/rules/GRAF113.md +16 -0
  153. package/dist/okf/rules/GRAF114.md +11 -0
  154. package/dist/okf/rules/GRAF115.md +11 -0
  155. package/dist/okf/types/AdhocVariable.md +9 -0
  156. package/dist/okf/types/AlertListPanel.md +9 -0
  157. package/dist/okf/types/AlertQuery.md +9 -0
  158. package/dist/okf/types/AlertRule.md +9 -0
  159. package/dist/okf/types/AlertRuleGroup.md +9 -0
  160. package/dist/okf/types/AzureMonitorQuery.md +9 -0
  161. package/dist/okf/types/BarChartPanel.md +9 -0
  162. package/dist/okf/types/BarGaugePanel.md +9 -0
  163. package/dist/okf/types/BigQueryQuery.md +9 -0
  164. package/dist/okf/types/CanvasPanel.md +9 -0
  165. package/dist/okf/types/ClassicConditionsExpression.md +9 -0
  166. package/dist/okf/types/CloudMonitoringQuery.md +9 -0
  167. package/dist/okf/types/CloudWatchQuery.md +9 -0
  168. package/dist/okf/types/ContactPoint.md +14 -0
  169. package/dist/okf/types/Dashboard.md +2 -1
  170. package/dist/okf/types/Datasource.md +3 -2
  171. package/dist/okf/types/DatasourceProvisioning.md +9 -0
  172. package/dist/okf/types/ElasticsearchQuery.md +9 -0
  173. package/dist/okf/types/ExternalDatasource.md +15 -0
  174. package/dist/okf/types/FlameGraphPanel.md +9 -0
  175. package/dist/okf/types/Folder.md +9 -0
  176. package/dist/okf/types/GeomapPanel.md +9 -0
  177. package/dist/okf/types/GroupByVariable.md +9 -0
  178. package/dist/okf/types/HistogramPanel.md +9 -0
  179. package/dist/okf/types/MSSQLQuery.md +9 -0
  180. package/dist/okf/types/MathExpression.md +9 -0
  181. package/dist/okf/types/MuteTiming.md +13 -0
  182. package/dist/okf/types/MySQLQuery.md +9 -0
  183. package/dist/okf/types/NodeGraphPanel.md +9 -0
  184. package/dist/okf/types/NotificationPolicy.md +9 -0
  185. package/dist/okf/types/NotificationTemplate.md +9 -0
  186. package/dist/okf/types/PieChartPanel.md +9 -0
  187. package/dist/okf/types/PostgresQuery.md +9 -0
  188. package/dist/okf/types/PyroscopeQuery.md +9 -0
  189. package/dist/okf/types/ReduceExpression.md +9 -0
  190. package/dist/okf/types/ResampleExpression.md +9 -0
  191. package/dist/okf/types/SqlExpression.md +9 -0
  192. package/dist/okf/types/StateTimelinePanel.md +9 -0
  193. package/dist/okf/types/StatusHistoryPanel.md +9 -0
  194. package/dist/okf/types/SwitchVariable.md +9 -0
  195. package/dist/okf/types/ThresholdExpression.md +9 -0
  196. package/dist/okf/types/TrendPanel.md +9 -0
  197. package/dist/okf/types/XYChartPanel.md +9 -0
  198. package/dist/op/activities/grafana-apply.d.ts +86 -0
  199. package/dist/op/activities/grafana-apply.d.ts.map +1 -0
  200. package/dist/op/activities/index.d.ts +9 -0
  201. package/dist/op/activities/index.d.ts.map +1 -0
  202. package/dist/op/builders.d.ts +24 -0
  203. package/dist/op/builders.d.ts.map +1 -0
  204. package/dist/ownership.d.ts +78 -0
  205. package/dist/ownership.d.ts.map +1 -0
  206. package/dist/panel-options.d.ts +65 -0
  207. package/dist/panel-options.d.ts.map +1 -0
  208. package/dist/panels.d.ts +46 -9
  209. package/dist/panels.d.ts.map +1 -1
  210. package/dist/pin.d.ts +29 -7
  211. package/dist/pin.d.ts.map +1 -1
  212. package/dist/plugin.d.ts.map +1 -1
  213. package/dist/promql-check.d.ts +51 -0
  214. package/dist/promql-check.d.ts.map +1 -0
  215. package/dist/query-models.d.ts +95 -0
  216. package/dist/query-models.d.ts.map +1 -0
  217. package/dist/query.d.ts +116 -18
  218. package/dist/query.d.ts.map +1 -1
  219. package/dist/rules/graf101.ts +3 -3
  220. package/dist/rules/graf102.ts +1 -1
  221. package/dist/rules/graf104.ts +3 -3
  222. package/dist/rules/graf106.ts +3 -3
  223. package/dist/rules/graf107.ts +1 -1
  224. package/dist/rules/graf108.ts +17 -0
  225. package/dist/rules/graf109.ts +17 -0
  226. package/dist/rules/graf110.ts +17 -0
  227. package/dist/rules/graf111.ts +17 -0
  228. package/dist/rules/graf112.ts +17 -0
  229. package/dist/rules/graf113.ts +17 -0
  230. package/dist/rules/graf114.ts +17 -0
  231. package/dist/rules/graf115.ts +17 -0
  232. package/dist/rules/grafana-helpers.ts +27 -10
  233. package/dist/rules/literal-secret.ts +60 -6
  234. package/dist/schema/azuremonitor.gen.d.ts +354 -0
  235. package/dist/schema/azuremonitor.gen.d.ts.map +1 -0
  236. package/dist/schema/barchart.gen.d.ts +198 -0
  237. package/dist/schema/barchart.gen.d.ts.map +1 -0
  238. package/dist/schema/bargauge.gen.d.ts +97 -0
  239. package/dist/schema/bargauge.gen.d.ts.map +1 -0
  240. package/dist/schema/bigquery.gen.d.ts +93 -0
  241. package/dist/schema/bigquery.gen.d.ts.map +1 -0
  242. package/dist/schema/canvas.gen.d.ts +152 -0
  243. package/dist/schema/canvas.gen.d.ts.map +1 -0
  244. package/dist/schema/cloudwatch.gen.d.ts +394 -0
  245. package/dist/schema/cloudwatch.gen.d.ts.map +1 -0
  246. package/dist/schema/dashboard.gen.d.ts +196 -21
  247. package/dist/schema/dashboard.gen.d.ts.map +1 -1
  248. package/dist/schema/elasticsearch.gen.d.ts +444 -0
  249. package/dist/schema/elasticsearch.gen.d.ts.map +1 -0
  250. package/dist/schema/expr.gen.d.ts +606 -0
  251. package/dist/schema/expr.gen.d.ts.map +1 -0
  252. package/dist/schema/gauge.gen.d.ts.map +1 -1
  253. package/dist/schema/geomap.gen.d.ts +100 -0
  254. package/dist/schema/geomap.gen.d.ts.map +1 -0
  255. package/dist/schema/googlecloudmonitoring.gen.d.ts +312 -0
  256. package/dist/schema/googlecloudmonitoring.gen.d.ts.map +1 -0
  257. package/dist/schema/grafanapyroscope.gen.d.ts +60 -0
  258. package/dist/schema/grafanapyroscope.gen.d.ts.map +1 -0
  259. package/dist/schema/heatmap.gen.d.ts.map +1 -1
  260. package/dist/schema/histogram.gen.d.ts +132 -0
  261. package/dist/schema/histogram.gen.d.ts.map +1 -0
  262. package/dist/schema/index.d.ts +18 -0
  263. package/dist/schema/index.d.ts.map +1 -1
  264. package/dist/schema/logs.gen.d.ts +1 -0
  265. package/dist/schema/logs.gen.d.ts.map +1 -1
  266. package/dist/schema/loki.gen.d.ts.map +1 -1
  267. package/dist/schema/nodegraph.gen.d.ts +49 -0
  268. package/dist/schema/nodegraph.gen.d.ts.map +1 -0
  269. package/dist/schema/piechart.gen.d.ts +127 -0
  270. package/dist/schema/piechart.gen.d.ts.map +1 -0
  271. package/dist/schema/prometheus.gen.d.ts.map +1 -1
  272. package/dist/schema/stat.gen.d.ts.map +1 -1
  273. package/dist/schema/statetimeline.gen.d.ts +124 -0
  274. package/dist/schema/statetimeline.gen.d.ts.map +1 -0
  275. package/dist/schema/statushistory.gen.d.ts +114 -0
  276. package/dist/schema/statushistory.gen.d.ts.map +1 -0
  277. package/dist/schema/table.gen.d.ts +35 -3
  278. package/dist/schema/table.gen.d.ts.map +1 -1
  279. package/dist/schema/tempo.gen.d.ts.map +1 -1
  280. package/dist/schema/text.gen.d.ts.map +1 -1
  281. package/dist/schema/timeseries.gen.d.ts +5 -1
  282. package/dist/schema/timeseries.gen.d.ts.map +1 -1
  283. package/dist/schema/trend.gen.d.ts +180 -0
  284. package/dist/schema/trend.gen.d.ts.map +1 -0
  285. package/dist/schema/xychart.gen.d.ts +145 -0
  286. package/dist/schema/xychart.gen.d.ts.map +1 -0
  287. package/dist/schema-validate.d.ts +39 -4
  288. package/dist/schema-validate.d.ts.map +1 -1
  289. package/dist/serializer.d.ts +11 -3
  290. package/dist/serializer.d.ts.map +1 -1
  291. package/dist/skill-defs.d.ts.map +1 -1
  292. package/dist/skills/chant-grafana-alerting.md +49 -0
  293. package/dist/skills/chant-grafana-operations.md +108 -0
  294. package/dist/skills/chant-grafana-provisioning.md +3 -3
  295. package/dist/skills/chant-grafana.md +15 -8
  296. package/dist/spec/fetch-units-cli.d.ts +3 -0
  297. package/dist/spec/fetch-units-cli.d.ts.map +1 -0
  298. package/dist/spec/overlay.d.ts +43 -0
  299. package/dist/spec/overlay.d.ts.map +1 -0
  300. package/dist/spec/schemas.d.ts +21 -13
  301. package/dist/spec/schemas.d.ts.map +1 -1
  302. package/dist/spec/schemas.gen.d.ts +3 -0
  303. package/dist/spec/schemas.gen.d.ts.map +1 -0
  304. package/dist/spec/units.d.ts +35 -0
  305. package/dist/spec/units.d.ts.map +1 -0
  306. package/dist/spec/units.gen.d.ts +2 -0
  307. package/dist/spec/units.gen.d.ts.map +1 -0
  308. package/dist/transformations.d.ts +459 -0
  309. package/dist/transformations.d.ts.map +1 -0
  310. package/dist/util.d.ts +6 -0
  311. package/dist/util.d.ts.map +1 -1
  312. package/dist/validate-alerting.d.ts +65 -0
  313. package/dist/validate-alerting.d.ts.map +1 -0
  314. package/dist/validate-output.d.ts +62 -9
  315. package/dist/validate-output.d.ts.map +1 -1
  316. package/dist/validate.d.ts.map +1 -1
  317. package/dist/validation.d.ts +14 -0
  318. package/dist/validation.d.ts.map +1 -0
  319. package/dist/variables.d.ts +109 -7
  320. package/dist/variables.d.ts.map +1 -1
  321. package/package.json +12 -4
  322. package/src/actions/actions.test.ts +24 -0
  323. package/src/actions/grafana.ts +40 -0
  324. package/src/actions/index.ts +1 -0
  325. package/src/alerting-build.ts +376 -0
  326. package/src/alerting.e2e.test.ts +212 -0
  327. package/src/alerting.test.ts +272 -0
  328. package/src/alerting.ts +435 -0
  329. package/src/annotations.ts +84 -0
  330. package/src/api/apply.test.ts +256 -0
  331. package/src/api/apply.ts +394 -0
  332. package/src/api/bind.ts +58 -0
  333. package/src/api/client.ts +148 -0
  334. package/src/api/converge.ts +63 -0
  335. package/src/api/dashboards.ts +247 -0
  336. package/src/api/datasources.ts +33 -0
  337. package/src/api/fake-grafana-writes.ts +201 -0
  338. package/src/api/fake-grafana.ts +190 -0
  339. package/src/api/folders.ts +339 -0
  340. package/src/api/library-panels.ts +101 -0
  341. package/src/build.test.ts +351 -10
  342. package/src/build.ts +294 -55
  343. package/src/catalog.ts +104 -2
  344. package/src/codegen/docs.ts +50 -10
  345. package/src/codegen/generate.ts +27 -1
  346. package/src/codegen/schema-types.ts +16 -6
  347. package/src/composites/agent-dashboard.ts +6 -3
  348. package/src/composites/catalog.test.ts +2 -2
  349. package/src/composites/catalog.ts +82 -0
  350. package/src/composites/composites.test.ts +73 -9
  351. package/src/composites/index.ts +4 -2
  352. package/src/composites/queries.e2e.test.ts +374 -0
  353. package/src/composites/red-dashboard.ts +83 -12
  354. package/src/composites/shared.ts +14 -2
  355. package/src/composites/slo-alert-rules.ts +149 -0
  356. package/src/config.test.ts +61 -0
  357. package/src/config.ts +138 -0
  358. package/src/contact-point-secrets.ts +63 -0
  359. package/src/dashboard.ts +68 -9
  360. package/src/datasource-refs.test.ts +56 -0
  361. package/src/datasource-refs.ts +213 -0
  362. package/src/datasource-settings.test.ts +106 -0
  363. package/src/datasource-settings.ts +941 -0
  364. package/src/datasource.ts +123 -11
  365. package/src/deep-observe-hooks.ts +267 -0
  366. package/src/deep-observe.test.ts +311 -0
  367. package/src/deep-observe.ts +187 -0
  368. package/src/describe-resources.test.ts +271 -0
  369. package/src/describe-resources.ts +244 -0
  370. package/src/detect.ts +82 -5
  371. package/src/export-resources.test.ts +129 -0
  372. package/src/export-resources.ts +84 -0
  373. package/src/folder.ts +118 -0
  374. package/src/generated/lexicon-grafana.json +205 -0
  375. package/src/import/alerting-roundtrip.test.ts +161 -0
  376. package/src/import/alerting.ts +500 -0
  377. package/src/import/edits.ts +95 -0
  378. package/src/import/embedded.test.ts +45 -0
  379. package/src/import/embedded.ts +47 -0
  380. package/src/import/generated-types.e2e.test.ts +130 -0
  381. package/src/import/generator.test.ts +210 -0
  382. package/src/import/generator.ts +463 -0
  383. package/src/import/live-export.ts +264 -0
  384. package/src/import/mappings.ts +336 -0
  385. package/src/import/model.ts +117 -0
  386. package/src/import/normalize-alerting.ts +101 -0
  387. package/src/import/normalize.test.ts +117 -0
  388. package/src/import/normalize.ts +393 -0
  389. package/src/import/parser.test.ts +516 -0
  390. package/src/import/parser.ts +1387 -0
  391. package/src/import/report.ts +62 -0
  392. package/src/import/roundtrip.test.ts +563 -0
  393. package/src/import/testdata/fixtures.ts +137 -0
  394. package/src/import/v2.test.ts +292 -0
  395. package/src/import/v2.ts +804 -0
  396. package/src/import.e2e.test.ts +31 -84
  397. package/src/import.test.ts +9 -3
  398. package/src/index.ts +308 -14
  399. package/src/init-templates.test.ts +74 -0
  400. package/src/init-templates.ts +349 -0
  401. package/src/k8s.test.ts +98 -0
  402. package/src/k8s.ts +197 -0
  403. package/src/lint/audit-catalog.ts +68 -3
  404. package/src/lint/core-lint.test.ts +43 -0
  405. package/src/lint/post-synth/graf101.ts +3 -3
  406. package/src/lint/post-synth/graf102.ts +1 -1
  407. package/src/lint/post-synth/graf104.ts +3 -3
  408. package/src/lint/post-synth/graf106.ts +3 -3
  409. package/src/lint/post-synth/graf107.ts +1 -1
  410. package/src/lint/post-synth/graf108.ts +17 -0
  411. package/src/lint/post-synth/graf109.ts +17 -0
  412. package/src/lint/post-synth/graf110.ts +17 -0
  413. package/src/lint/post-synth/graf111.ts +17 -0
  414. package/src/lint/post-synth/graf112.ts +17 -0
  415. package/src/lint/post-synth/graf113.ts +17 -0
  416. package/src/lint/post-synth/graf114.ts +17 -0
  417. package/src/lint/post-synth/graf115.ts +17 -0
  418. package/src/lint/post-synth/grafana-helpers.ts +27 -10
  419. package/src/lint/post-synth/index.ts +16 -0
  420. package/src/lint/post-synth/post-synth.test.ts +333 -12
  421. package/src/lint/rules/literal-secret.ts +60 -6
  422. package/src/lint/rules/rules.test.ts +27 -0
  423. package/src/load-cost.test.ts +35 -0
  424. package/src/lsp/completions.test.ts +5 -0
  425. package/src/lsp/hover.test.ts +7 -0
  426. package/src/lsp/hover.ts +8 -1
  427. package/src/members.ts +68 -0
  428. package/src/observe.e2e.test.ts +255 -0
  429. package/src/op/activities/grafana-apply.e2e.test.ts +184 -0
  430. package/src/op/activities/grafana-apply.test.ts +243 -0
  431. package/src/op/activities/grafana-apply.ts +197 -0
  432. package/src/op/activities/index.ts +8 -0
  433. package/src/op/builders.test.ts +40 -0
  434. package/src/op/builders.ts +34 -0
  435. package/src/ownership.ts +122 -0
  436. package/src/panel-options.ts +66 -0
  437. package/src/panels.test.ts +53 -0
  438. package/src/panels.ts +148 -10
  439. package/src/pin.ts +69 -6
  440. package/src/plugin.test.ts +12 -2
  441. package/src/plugin.ts +75 -0
  442. package/src/promql-check.test.ts +108 -0
  443. package/src/promql-check.ts +193 -0
  444. package/src/query-models.ts +94 -0
  445. package/src/query.test.ts +166 -0
  446. package/src/query.ts +190 -20
  447. package/src/schema/azuremonitor.gen.ts +381 -0
  448. package/src/schema/barchart.gen.ts +221 -0
  449. package/src/schema/bargauge.gen.ts +111 -0
  450. package/src/schema/bigquery.gen.ts +110 -0
  451. package/src/schema/canvas.gen.ts +176 -0
  452. package/src/schema/cloudwatch.gen.ts +423 -0
  453. package/src/schema/dashboard.gen.ts +206 -22
  454. package/src/schema/elasticsearch.gen.ts +508 -0
  455. package/src/schema/expr.gen.ts +618 -0
  456. package/src/schema/gauge.gen.ts +2 -1
  457. package/src/schema/geomap.gen.ts +112 -0
  458. package/src/schema/googlecloudmonitoring.gen.ts +330 -0
  459. package/src/schema/grafanapyroscope.gen.ts +66 -0
  460. package/src/schema/heatmap.gen.ts +2 -1
  461. package/src/schema/histogram.gen.ts +151 -0
  462. package/src/schema/index.ts +18 -0
  463. package/src/schema/logs.gen.ts +3 -1
  464. package/src/schema/loki.gen.ts +2 -1
  465. package/src/schema/nodegraph.gen.ts +58 -0
  466. package/src/schema/piechart.gen.ts +146 -0
  467. package/src/schema/prometheus.gen.ts +2 -1
  468. package/src/schema/stat.gen.ts +2 -1
  469. package/src/schema/statetimeline.gen.ts +143 -0
  470. package/src/schema/statushistory.gen.ts +132 -0
  471. package/src/schema/table.gen.ts +41 -4
  472. package/src/schema/tempo.gen.ts +2 -1
  473. package/src/schema/text.gen.ts +2 -1
  474. package/src/schema/timeseries.gen.ts +7 -2
  475. package/src/schema/trend.gen.ts +208 -0
  476. package/src/schema/xychart.gen.ts +167 -0
  477. package/src/schema-overlay.test.ts +282 -0
  478. package/src/schema-validate.ts +199 -57
  479. package/src/schema.test.ts +4 -2
  480. package/src/serializer.test.ts +13 -1
  481. package/src/serializer.ts +11 -3
  482. package/src/skill-defs.ts +34 -0
  483. package/src/skills/chant-grafana-alerting.md +49 -0
  484. package/src/skills/chant-grafana-operations.md +108 -0
  485. package/src/skills/chant-grafana-provisioning.md +3 -3
  486. package/src/skills/chant-grafana.md +15 -8
  487. package/src/spec/fetch-cli.ts +3 -3
  488. package/src/spec/fetch-units-cli.ts +37 -0
  489. package/src/spec/overlay/canvas.overlay.json +142 -0
  490. package/src/spec/overlay/dashboard.overlay.json +378 -0
  491. package/src/spec/overlay/expr.overlay.json +14 -0
  492. package/src/spec/overlay/geomap.overlay.json +35 -0
  493. package/src/spec/overlay/logs.overlay.json +14 -0
  494. package/src/spec/overlay/nodegraph.overlay.json +31 -0
  495. package/src/spec/overlay/piechart.overlay.json +17 -0
  496. package/src/spec/overlay/table.overlay.json +103 -0
  497. package/src/spec/overlay/timeseries.overlay.json +21 -0
  498. package/src/spec/overlay/trend.overlay.json +17 -0
  499. package/src/spec/overlay/xychart.overlay.json +16 -0
  500. package/src/spec/overlay.ts +105 -0
  501. package/src/spec/schemas/azuremonitor.jsonschema.json +679 -0
  502. package/src/spec/schemas/barchart.jsonschema.json +419 -0
  503. package/src/spec/schemas/bargauge.jsonschema.json +224 -0
  504. package/src/spec/schemas/bigquery.jsonschema.json +290 -0
  505. package/src/spec/schemas/canvas.jsonschema.json +356 -0
  506. package/src/spec/schemas/cloudwatch.jsonschema.json +721 -0
  507. package/src/spec/schemas/dashboardv2.jsonschema.json +3387 -0
  508. package/src/spec/schemas/elasticsearch.jsonschema.json +1695 -0
  509. package/src/spec/schemas/expr.jsonschema.json +987 -0
  510. package/src/spec/schemas/geomap.jsonschema.json +220 -0
  511. package/src/spec/schemas/googlecloudmonitoring.jsonschema.json +488 -0
  512. package/src/spec/schemas/grafanapyroscope.jsonschema.json +93 -0
  513. package/src/spec/schemas/histogram.jsonschema.json +308 -0
  514. package/src/spec/schemas/nodegraph.jsonschema.json +77 -0
  515. package/src/spec/schemas/piechart.jsonschema.json +275 -0
  516. package/src/spec/schemas/statetimeline.jsonschema.json +324 -0
  517. package/src/spec/schemas/statushistory.jsonschema.json +292 -0
  518. package/src/spec/schemas/trend.jsonschema.json +449 -0
  519. package/src/spec/schemas/xychart.jsonschema.json +428 -0
  520. package/src/spec/schemas.gen.ts +40 -0
  521. package/src/spec/schemas.ts +30 -16
  522. package/src/spec/units.gen.ts +281 -0
  523. package/src/spec/units.ts +77 -0
  524. package/src/transformations.test.ts +65 -0
  525. package/src/transformations.ts +574 -0
  526. package/src/util.ts +8 -0
  527. package/src/validate-alerting.test.ts +255 -0
  528. package/src/validate-alerting.ts +430 -0
  529. package/src/validate-output.ts +427 -104
  530. package/src/validate.ts +28 -0
  531. package/src/validation.ts +27 -0
  532. package/src/variables.ts +120 -8
@@ -0,0 +1,208 @@
1
+ // Code generated by chant generate from the vendored Grafana schema
2
+ // src/spec/schemas/trend.jsonschema.json (see src/pin.ts) and its correction
3
+ // overlay in src/spec/overlay/ (see src/spec/overlay.ts). DO NOT EDIT.
4
+ /* eslint-disable */
5
+
6
+ /**
7
+ * Identical to timeseries... except it does not have timezone settings
8
+ */
9
+ export interface Options {
10
+ legend: VizLegendOptions;
11
+ tooltip: VizTooltipOptions;
12
+ /**
13
+ * Name of the x field to use (defaults to first number)
14
+ */
15
+ xField?: string;
16
+ }
17
+
18
+ export type FieldConfig = GraphFieldConfig;
19
+
20
+ /**
21
+ * TODO docs
22
+ */
23
+ export interface VizLegendOptions {
24
+ displayMode: LegendDisplayMode;
25
+ placement: LegendPlacement;
26
+ showLegend: boolean;
27
+ asTable?: boolean;
28
+ isVisible?: boolean;
29
+ sortBy?: string;
30
+ sortDesc?: boolean;
31
+ width?: number;
32
+ calcs: string[];
33
+ }
34
+
35
+ /**
36
+ * TODO docs
37
+ */
38
+ export interface VizTooltipOptions {
39
+ mode: TooltipDisplayMode;
40
+ sort: SortOrder;
41
+ maxWidth?: number;
42
+ maxHeight?: number;
43
+ hideZeros?: boolean;
44
+ }
45
+
46
+ /**
47
+ * TODO docs
48
+ */
49
+ export interface GraphFieldConfig {
50
+ drawStyle?: GraphDrawStyle;
51
+ gradientMode?: GraphGradientMode;
52
+ thresholdsStyle?: GraphThresholdsStyleConfig;
53
+ transform?: GraphTransform;
54
+ lineColor?: string;
55
+ lineWidth?: number;
56
+ lineInterpolation?: LineInterpolation;
57
+ lineStyle?: LineStyle;
58
+ fillColor?: string;
59
+ fillOpacity?: number;
60
+ showPoints?: VisibilityMode;
61
+ pointSize?: number;
62
+ pointColor?: string;
63
+ axisPlacement?: AxisPlacement;
64
+ axisColorMode?: AxisColorMode;
65
+ axisLabel?: string;
66
+ axisWidth?: number;
67
+ axisSoftMin?: number;
68
+ axisSoftMax?: number;
69
+ axisGridShow?: boolean;
70
+ scaleDistribution?: ScaleDistributionConfig;
71
+ axisCenteredZero?: boolean;
72
+ barAlignment?: BarAlignment;
73
+ barWidthFactor?: number;
74
+ stacking?: StackingConfig;
75
+ hideFrom?: HideSeriesConfig;
76
+ insertNulls?: boolean | number;
77
+ /**
78
+ * Indicate if null values should be treated as gaps or connected.
79
+ * When the value is a number, it represents the maximum delta in the
80
+ * X axis that should be considered connected. For timeseries, this is milliseconds
81
+ */
82
+ spanNulls?: boolean | number;
83
+ fillBelowTo?: string;
84
+ pointSymbol?: string;
85
+ axisBorderShow?: boolean;
86
+ barMaxWidth?: number;
87
+ /**
88
+ * Show point values on the graph.
89
+ */
90
+ showValues?: boolean;
91
+ }
92
+
93
+ /**
94
+ * TODO docs
95
+ * Note: "hidden" needs to remain as an option for plugins compatibility
96
+ */
97
+ export type LegendDisplayMode = "list" | "table" | "hidden";
98
+
99
+ /**
100
+ * TODO docs
101
+ */
102
+ export type LegendPlacement = "bottom" | "right";
103
+
104
+ /**
105
+ * TODO docs
106
+ */
107
+ export type TooltipDisplayMode = "single" | "multi" | "none";
108
+
109
+ /**
110
+ * TODO docs
111
+ */
112
+ export type SortOrder = "asc" | "desc" | "none";
113
+
114
+ /**
115
+ * TODO docs
116
+ */
117
+ export type GraphDrawStyle = "line" | "bars" | "points";
118
+
119
+ /**
120
+ * TODO docs
121
+ */
122
+ export type GraphGradientMode = "none" | "opacity" | "hue" | "scheme";
123
+
124
+ /**
125
+ * TODO docs
126
+ */
127
+ export interface GraphThresholdsStyleConfig {
128
+ mode: GraphThresholdsStyleMode;
129
+ }
130
+
131
+ /**
132
+ * TODO docs
133
+ */
134
+ export type GraphTransform = "constant" | "negative-Y";
135
+
136
+ /**
137
+ * TODO docs
138
+ */
139
+ export type LineInterpolation = "linear" | "smooth" | "stepBefore" | "stepAfter";
140
+
141
+ /**
142
+ * TODO docs
143
+ */
144
+ export interface LineStyle {
145
+ fill?: "solid" | "dash" | "dot" | "square";
146
+ dash?: number[];
147
+ }
148
+
149
+ /**
150
+ * TODO docs
151
+ */
152
+ export type VisibilityMode = "auto" | "never" | "always";
153
+
154
+ /**
155
+ * TODO docs
156
+ */
157
+ export type AxisPlacement = "auto" | "top" | "right" | "bottom" | "left" | "hidden";
158
+
159
+ /**
160
+ * TODO docs
161
+ */
162
+ export type AxisColorMode = "text" | "series";
163
+
164
+ /**
165
+ * TODO docs
166
+ */
167
+ export interface ScaleDistributionConfig {
168
+ type: ScaleDistribution;
169
+ log?: number;
170
+ linearThreshold?: number;
171
+ }
172
+
173
+ /**
174
+ * TODO docs
175
+ */
176
+ export type BarAlignment = -1 | 0 | 1;
177
+
178
+ /**
179
+ * TODO docs
180
+ */
181
+ export interface StackingConfig {
182
+ mode?: StackingMode;
183
+ group?: string;
184
+ }
185
+
186
+ /**
187
+ * TODO docs
188
+ */
189
+ export interface HideSeriesConfig {
190
+ tooltip: boolean;
191
+ legend: boolean;
192
+ viz: boolean;
193
+ }
194
+
195
+ /**
196
+ * TODO docs
197
+ */
198
+ export type GraphThresholdsStyleMode = "off" | "line" | "dashed" | "area" | "line+area" | "dashed+area" | "series";
199
+
200
+ /**
201
+ * TODO docs
202
+ */
203
+ export type ScaleDistribution = "linear" | "log" | "ordinal" | "symlog";
204
+
205
+ /**
206
+ * TODO docs
207
+ */
208
+ export type StackingMode = "none" | "normal" | "percent";
@@ -0,0 +1,167 @@
1
+ // Code generated by chant generate from the vendored Grafana schema
2
+ // src/spec/schemas/xychart.jsonschema.json (see src/pin.ts) and its correction
3
+ // overlay in src/spec/overlay/ (see src/spec/overlay.ts). DO NOT EDIT.
4
+ /* eslint-disable */
5
+
6
+ export type PointShape = "circle" | "square";
7
+
8
+ export type SeriesMapping = "auto" | "manual";
9
+
10
+ export type XYShowMode = "points" | "lines" | "points+lines";
11
+
12
+ /**
13
+ * NOTE: (copied from dashboard_kind.cue, since not exported)
14
+ * Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.
15
+ * It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.
16
+ */
17
+ export interface MatcherConfig {
18
+ /**
19
+ * The matcher id. This is used to find the matcher implementation from registry.
20
+ */
21
+ id: string;
22
+ /**
23
+ * The matcher options. This is specific to the matcher implementation: a field name for byName, a frame index for byIndex.
24
+ */
25
+ options?: unknown;
26
+ }
27
+
28
+ export interface FieldConfig {
29
+ show?: XYShowMode;
30
+ pointSize?: {
31
+ fixed?: number;
32
+ min?: number;
33
+ max?: number;
34
+ };
35
+ pointShape?: PointShape;
36
+ pointStrokeWidth?: number;
37
+ fillOpacity?: number;
38
+ lineWidth?: number;
39
+ hideFrom?: HideSeriesConfig;
40
+ axisPlacement?: AxisPlacement;
41
+ axisColorMode?: AxisColorMode;
42
+ axisLabel?: string;
43
+ axisWidth?: number;
44
+ axisSoftMin?: number;
45
+ axisSoftMax?: number;
46
+ axisGridShow?: boolean;
47
+ scaleDistribution?: ScaleDistributionConfig;
48
+ axisCenteredZero?: boolean;
49
+ lineStyle?: LineStyle;
50
+ axisBorderShow?: boolean;
51
+ }
52
+
53
+ export interface XYSeriesConfig {
54
+ name?: {
55
+ fixed?: string;
56
+ };
57
+ frame?: {
58
+ matcher: MatcherConfig;
59
+ };
60
+ x?: {
61
+ matcher: MatcherConfig;
62
+ };
63
+ y?: {
64
+ matcher: MatcherConfig;
65
+ };
66
+ color?: {
67
+ matcher: MatcherConfig;
68
+ };
69
+ size?: {
70
+ matcher: MatcherConfig;
71
+ };
72
+ }
73
+
74
+ export interface Options {
75
+ mapping: SeriesMapping;
76
+ legend: VizLegendOptions;
77
+ tooltip: VizTooltipOptions;
78
+ series: XYSeriesConfig[];
79
+ }
80
+
81
+ /**
82
+ * TODO docs
83
+ */
84
+ export interface HideSeriesConfig {
85
+ tooltip: boolean;
86
+ legend: boolean;
87
+ viz: boolean;
88
+ }
89
+
90
+ /**
91
+ * TODO docs
92
+ */
93
+ export type AxisPlacement = "auto" | "top" | "right" | "bottom" | "left" | "hidden";
94
+
95
+ /**
96
+ * TODO docs
97
+ */
98
+ export type AxisColorMode = "text" | "series";
99
+
100
+ /**
101
+ * TODO docs
102
+ */
103
+ export interface ScaleDistributionConfig {
104
+ type: ScaleDistribution;
105
+ log?: number;
106
+ linearThreshold?: number;
107
+ }
108
+
109
+ /**
110
+ * TODO docs
111
+ */
112
+ export interface LineStyle {
113
+ fill?: "solid" | "dash" | "dot" | "square";
114
+ dash?: number[];
115
+ }
116
+
117
+ /**
118
+ * TODO docs
119
+ */
120
+ export interface VizLegendOptions {
121
+ displayMode: LegendDisplayMode;
122
+ placement: LegendPlacement;
123
+ showLegend: boolean;
124
+ asTable?: boolean;
125
+ isVisible?: boolean;
126
+ sortBy?: string;
127
+ sortDesc?: boolean;
128
+ width?: number;
129
+ calcs: string[];
130
+ }
131
+
132
+ /**
133
+ * TODO docs
134
+ */
135
+ export interface VizTooltipOptions {
136
+ mode: TooltipDisplayMode;
137
+ sort: SortOrder;
138
+ maxWidth?: number;
139
+ maxHeight?: number;
140
+ hideZeros?: boolean;
141
+ }
142
+
143
+ /**
144
+ * TODO docs
145
+ */
146
+ export type ScaleDistribution = "linear" | "log" | "ordinal" | "symlog";
147
+
148
+ /**
149
+ * TODO docs
150
+ * Note: "hidden" needs to remain as an option for plugins compatibility
151
+ */
152
+ export type LegendDisplayMode = "list" | "table" | "hidden";
153
+
154
+ /**
155
+ * TODO docs
156
+ */
157
+ export type LegendPlacement = "bottom" | "right";
158
+
159
+ /**
160
+ * TODO docs
161
+ */
162
+ export type TooltipDisplayMode = "single" | "multi" | "none";
163
+
164
+ /**
165
+ * TODO docs
166
+ */
167
+ export type SortOrder = "asc" | "desc" | "none";
@@ -0,0 +1,282 @@
1
+ /**
2
+ * The correction overlay (chant #2939, #2971): real Grafana 12.4 and 13.x
3
+ * exports pass GRAF107, the reproductions from the issues type and build,
4
+ * unknown keys are warnings, genuine type violations stay errors, and the
5
+ * library panels an external export embeds in `__elements` are checked.
6
+ */
7
+ import { describe, expect, test } from "vitest";
8
+ import { readdirSync, readFileSync } from "fs";
9
+ import { dirname, join } from "path";
10
+ import { fileURLToPath } from "url";
11
+ import { SCHEMA_NAMES } from "./pin";
12
+ import { applyOverlay, loadOverlay, type SchemaOverlay } from "./spec/overlay";
13
+ import { loadSchema, loadVendoredSchema } from "./spec/schemas";
14
+ import { validateDashboardSchema } from "./schema-validate";
15
+ import { checkSchema } from "./validate-output";
16
+ import { renderDashboard } from "./build";
17
+ import { Dashboard } from "./dashboard";
18
+ import { TablePanel, TimeSeriesPanel } from "./panels";
19
+ import { PromQuery } from "./query";
20
+ import { Datasource } from "./datasource";
21
+
22
+ const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
23
+ const exportsDir = join(pkgDir, "test", "fixtures", "exports");
24
+
25
+ type Json = Record<string, unknown>;
26
+
27
+ function readJson(path: string): Json {
28
+ return JSON.parse(readFileSync(path, "utf-8")) as Json;
29
+ }
30
+
31
+ const versions = readdirSync(exportsDir).filter((d) => d.startsWith("grafana-"));
32
+ const classicExports = versions.flatMap((v) =>
33
+ readdirSync(join(exportsDir, v))
34
+ // The v1 and v2 resources (#2947) are API reads, not classic exports.
35
+ .filter((f) => f.endsWith(".json") && !f.includes("-resource"))
36
+ .map((f) => [`${v}/${f}`, join(exportsDir, v, f)] as const),
37
+ );
38
+
39
+ describe("the overlay files", () => {
40
+ test("every patch cites its Grafana source and says why", () => {
41
+ for (const name of SCHEMA_NAMES) {
42
+ const overlay = loadOverlay(name);
43
+ if (!overlay) continue;
44
+ expect(overlay.grafana).toMatch(/^v\d+\.\d+\.\d+$/);
45
+ for (const p of overlay.patches) {
46
+ expect({ path: p.path, source: p.source }).toEqual({ path: p.path, source: expect.stringMatching(/\.(cue|ts|go):\d+/) });
47
+ expect(p.why.length).toBeGreaterThan(0);
48
+ }
49
+ }
50
+ });
51
+
52
+ test("the schemas with an overlay are patched; the vendored bytes are not", () => {
53
+ expect(SCHEMA_NAMES.filter((n) => loadOverlay(n))).toEqual(["dashboard", "timeseries", "table", "logs", "piechart", "nodegraph", "xychart", "trend", "canvas", "geomap", "expr"]);
54
+ const vendored = loadVendoredSchema("dashboard").definitions as Record<string, Json>;
55
+ const patched = loadSchema("dashboard").definitions as Record<string, Json>;
56
+ expect((vendored.MatcherConfig.properties as Json).scope).toBeUndefined();
57
+ expect((patched.MatcherConfig.properties as Json).scope).toEqual(expect.objectContaining({ $ref: "#/definitions/MatcherScope" }));
58
+ });
59
+
60
+ test("applying refuses a patch the vendored schema already carries, or a path it lacks", () => {
61
+ const base = { definitions: { A: { properties: { x: { type: "string" } } } } };
62
+ const overlay = (patches: SchemaOverlay["patches"]): SchemaOverlay => ({ schema: "dashboard", grafana: "v13.2.2", patches });
63
+ const cite = { source: "kinds/dashboard/dashboard_kind.cue:1", why: "test" };
64
+ expect(() => applyOverlay(base, overlay([{ op: "add", path: "/definitions/A/properties/x", value: {}, ...cite }]))).toThrow(/already present/);
65
+ expect(() => applyOverlay(base, overlay([{ op: "replace", path: "/definitions/A/properties/y", value: {}, ...cite }]))).toThrow(/not present/);
66
+ expect(() => applyOverlay(base, overlay([{ op: "remove", path: "/definitions/B/properties", ...cite }]))).toThrow(/no parent/);
67
+ const out = applyOverlay(base, overlay([{ op: "add", path: "/definitions/A/properties/y", value: { type: "number" }, ...cite }]));
68
+ expect(out).toEqual({ definitions: { A: { properties: { x: { type: "string" }, y: { type: "number" } } } } });
69
+ expect(base.definitions.A.properties).toEqual({ x: { type: "string" } });
70
+ });
71
+ });
72
+
73
+ describe("real Grafana exports", () => {
74
+ test("the corpus covers Grafana 12.4 and 13.2, plain and shared externally", () => {
75
+ expect(versions).toEqual(["grafana-12.4.11", "grafana-13.2.2"]);
76
+ expect(classicExports.map(([name]) => name)).toEqual(
77
+ expect.arrayContaining([
78
+ "grafana-12.4.11/checkout.external.json",
79
+ "grafana-13.2.2/slo.external.json",
80
+ "grafana-13.2.2/checkout.json",
81
+ "grafana-13.2.2/cells.external.json",
82
+ ]),
83
+ );
84
+ });
85
+
86
+ test.each(classicExports)("%s passes GRAF107 with no errors or warnings", (name, path) => {
87
+ const json = readJson(path);
88
+ expect({ name, problems: validateDashboardSchema(json) }).toEqual({ name, problems: [] });
89
+ expect(checkSchema({ dashboards: [{ source: name, json }], datasources: [] })).toEqual([]);
90
+ });
91
+
92
+ test("the external exports carry the metadata the overlay allows", () => {
93
+ const json = readJson(join(exportsDir, "grafana-13.2.2", "slo.external.json"));
94
+ expect(Object.keys(json)).toEqual(expect.arrayContaining(["__inputs", "__requires", "__elements"]));
95
+ expect(Object.keys(json.__elements as Json)).toEqual(["chant-fx-burn"]);
96
+ });
97
+ });
98
+
99
+ describe("enum values newer than the pin", () => {
100
+ const cells = readJson(join(exportsDir, "grafana-13.2.2", "cells.external.json"));
101
+ const panels = (cells.panels as Json[]).filter((p) => !p.libraryPanel);
102
+ const custom = (p: Json) => ((p.fieldConfig as Json).defaults as Json).custom as Json;
103
+ const colorMode = (p: Json) => (((p.fieldConfig as Json).defaults as Json).color as Json).mode;
104
+
105
+ test("the 13.2 cells export uses them, in panels and in its library panel", () => {
106
+ expect(panels.map((p) => (custom(p)?.cellOptions as Json | undefined)?.type).filter(Boolean)).toEqual(["pill", "markdown", "geo"]);
107
+ expect(panels.map(colorMode)).toEqual([
108
+ "continuous-viridis",
109
+ "continuous-magma",
110
+ "continuous-plasma",
111
+ "continuous-inferno",
112
+ ]);
113
+ expect(custom(panels[3]).lineStyle).toEqual({ fill: "accessible" });
114
+ const model = ((cells.__elements as Json)["chant-fx-owners"] as Json).model as Json;
115
+ expect([(custom(model).cellOptions as Json).type, colorMode(model)]).toEqual(["markdown", "continuous-cividis"]);
116
+ });
117
+
118
+ test("the vendored schemas reject them; the overlay accepts them", () => {
119
+ const enumOf = (schema: Json, def: string) => ((schema.definitions as Json)[def] as Json).enum as string[];
120
+ const fill = (schema: Json) => ((((schema.definitions as Json).LineStyle as Json).properties as Json).fill as Json).enum as string[];
121
+ for (const [name, def, value] of [
122
+ ["dashboard", "FieldColorModeId", "continuous-viridis"],
123
+ ["table", "TableCellDisplayMode", "pill"],
124
+ ["table", "TableCellDisplayMode", "markdown"],
125
+ ["table", "TableCellDisplayMode", "geo"],
126
+ ] as const) {
127
+ expect(enumOf(loadVendoredSchema(name), def)).not.toContain(value);
128
+ expect(enumOf(loadSchema(name), def)).toContain(value);
129
+ }
130
+ for (const name of ["timeseries", "table"] as const) {
131
+ expect(fill(loadVendoredSchema(name))).not.toContain("accessible");
132
+ expect(fill(loadSchema(name))).toContain("accessible");
133
+ }
134
+ });
135
+
136
+ test("an unknown enum value is still an error", () => {
137
+ const bad = structuredClone(cells);
138
+ custom((bad.panels as Json[])[0]).cellOptions = { type: "hologram" };
139
+ const problems = validateDashboardSchema(bad);
140
+ expect(problems.map((p) => [p.severity, p.path])).toContainEqual(["error", "/panels/0/fieldConfig/defaults/custom/cellOptions/type"]);
141
+ });
142
+ });
143
+
144
+ describe("library panels in __elements", () => {
145
+ const external = () => readJson(join(exportsDir, "grafana-13.2.2", "slo.external.json"));
146
+ const burn = (json: Json) => ((json.__elements as Json)["chant-fx-burn"] as Json).model as Json;
147
+
148
+ test("a bad library panel model is reported at its path", () => {
149
+ const json = external();
150
+ const model = burn(json);
151
+ ((model.options as Json).legend as Json).displayMode = "sideways";
152
+ (model.targets as Json[])[0].format = "csv";
153
+ model.transparent = "yes";
154
+ model.fancyNewField = true;
155
+ const problems = validateDashboardSchema(json).map((p) => `${p.severity} ${p.path}: ${p.message}`);
156
+ expect(problems).toEqual(
157
+ expect.arrayContaining([
158
+ expect.stringMatching(/^error \/__elements\/chant-fx-burn\/model\/options\/legend\/displayMode: must be equal to one of the allowed values/),
159
+ expect.stringMatching(/^error \/__elements\/chant-fx-burn\/model\/targets\/0\/format: must be equal to one of the allowed values/),
160
+ "error /__elements/chant-fx-burn/model/transparent: must be boolean",
161
+ 'warning /__elements/chant-fx-burn/model: unknown key "fancyNewField" (not in the pinned schema)',
162
+ ]),
163
+ );
164
+ expect(problems).toHaveLength(4);
165
+ const issues = checkSchema({ dashboards: [{ source: "slo.external.json", json }], datasources: [] });
166
+ expect(issues.filter((i) => i.code === "GRAF107" && i.severity === "error")).toHaveLength(3);
167
+ });
168
+
169
+ test("a model with neither a type nor a library panel reference is an error", () => {
170
+ const json = external();
171
+ delete burn(json).type;
172
+ expect(validateDashboardSchema(json).map((p) => [p.severity, p.path, p.message])).toEqual([
173
+ ["error", "/__elements/chant-fx-burn/model", "must have required property 'type'"],
174
+ ["error", "/__elements/chant-fx-burn/model", "must have required property 'libraryPanel'"],
175
+ ]);
176
+ });
177
+
178
+ test("the element itself is checked by the envelope, and a uid with a slash is escaped in the path", () => {
179
+ const json = external();
180
+ const el = (json.__elements as Json)["chant-fx-burn"] as Json;
181
+ json.__elements = { "team/burn": { ...el, uid: "team/burn", name: 7, model: { ...(el.model as Json), title: 9 } } };
182
+ expect(validateDashboardSchema(json).map((p) => `${p.path}: ${p.message}`)).toEqual([
183
+ "/__elements/team~1burn/name: must be string",
184
+ "/__elements/team~1burn/model/title: must be string",
185
+ ]);
186
+ });
187
+
188
+ test("an element of another kind is not read as a panel", () => {
189
+ const json = external();
190
+ const el = (json.__elements as Json)["chant-fx-burn"] as Json;
191
+ json.__elements = { "chant-fx-burn": { ...el, kind: 2, model: { type: 7 } } };
192
+ expect(validateDashboardSchema(json)).toEqual([]);
193
+ });
194
+ });
195
+
196
+ describe("the issue's reproductions", () => {
197
+ const prometheus = new Datasource({ name: "Prometheus", type: "prometheus" });
198
+ const rate = new PromQuery({ expr: "sum(rate(http_requests_total[5m]))" });
199
+
200
+ test("a byName matcher with a string option and a data link with only title and url type, build and pass", () => {
201
+ const panel = new TimeSeriesPanel({
202
+ title: "Requests",
203
+ datasource: prometheus,
204
+ targets: [rate],
205
+ fieldConfig: {
206
+ defaults: { links: [{ title: "Runbook", url: "https://example.com/runbook" }] },
207
+ overrides: [
208
+ { matcher: { id: "byName", options: "requests" }, properties: [{ id: "unit", value: "reqps" }] },
209
+ { matcher: { id: "byType", options: "number", scope: "series" }, properties: [{ id: "decimals", value: 1 }] },
210
+ ],
211
+ },
212
+ links: [{ title: "Traces", url: "https://example.com/traces", targetBlank: true }],
213
+ });
214
+ const json = renderDashboard(new Dashboard({ title: "Repro", uid: "repro", panels: [panel] })) as unknown as Json;
215
+ expect(validateDashboardSchema(json)).toEqual([]);
216
+ });
217
+
218
+ test("a table cellOptions matching several variants is accepted", () => {
219
+ const panel = new TablePanel({ title: "T", fieldConfig: { defaults: { custom: { cellOptions: { type: "auto" } } } } });
220
+ const json = renderDashboard(new Dashboard({ title: "Table", uid: "table", panels: [panel] })) as unknown as Json;
221
+ expect(validateDashboardSchema(json)).toEqual([]);
222
+ });
223
+ });
224
+
225
+ describe("errors and warnings", () => {
226
+ function dashboard(extra: Json = {}, panel: Json = {}): Json {
227
+ return {
228
+ uid: "d",
229
+ title: "D",
230
+ schemaVersion: 42,
231
+ panels: [{ type: "timeseries", id: 1, gridPos: { x: 0, y: 0, w: 12, h: 8 }, fieldConfig: { defaults: {}, overrides: [] }, ...panel }],
232
+ ...extra,
233
+ };
234
+ }
235
+
236
+ test("a key the pin does not know is a warning, wherever it is", () => {
237
+ const problems = validateDashboardSchema(
238
+ dashboard({ fancyNewField: true }, { fieldConfig: { defaults: { custom: { brandNewOption: 1 } }, overrides: [] } }),
239
+ );
240
+ expect(problems).toEqual([
241
+ { path: "/", message: 'unknown key "fancyNewField" (not in the pinned schema)', severity: "warning" },
242
+ { path: "/panels/0/fieldConfig/defaults/custom", message: 'unknown key "brandNewOption" (not in the pinned schema)', severity: "warning" },
243
+ ]);
244
+ });
245
+
246
+ test("a genuine type violation stays an error", () => {
247
+ const problems = validateDashboardSchema(
248
+ dashboard(
249
+ { templating: { list: [{ type: "query", name: "q", query: 5 }] } },
250
+ { fieldConfig: { defaults: {}, overrides: [{ matcher: { id: 7, scope: "everything" }, properties: [] }] }, links: [{ url: "x" }] },
251
+ ),
252
+ );
253
+ expect(problems.filter((p) => p.severity === "error").map((p) => `${p.path}: ${p.message}`)).toEqual(
254
+ expect.arrayContaining([
255
+ "/templating/list/0/query: must be string",
256
+ "/templating/list/0/query: must be object",
257
+ "/panels/0/links/0: must have required property 'title'",
258
+ "/panels/0/fieldConfig/overrides/0/matcher/id: must be string",
259
+ expect.stringMatching(/^\/panels\/0\/fieldConfig\/overrides\/0\/matcher\/scope: must be equal to one of the allowed values/),
260
+ ]),
261
+ );
262
+ expect(problems.every((p) => p.severity === "error")).toBe(true);
263
+ });
264
+
265
+ test("a panel with neither a type nor a library panel is an error; a library panel reference is fine", () => {
266
+ const bare = validateDashboardSchema({ uid: "d", title: "D", schemaVersion: 42, panels: [{ id: 1, gridPos: { x: 0, y: 0, w: 6, h: 6 } }] });
267
+ expect(bare.map((p) => [p.severity, p.message])).toEqual([
268
+ ["error", "must have required property 'type'"],
269
+ ["error", "must have required property 'libraryPanel'"],
270
+ ]);
271
+ const lib = { id: 1, gridPos: { x: 0, y: 0, w: 6, h: 6 }, libraryPanel: { uid: "u", name: "n" } };
272
+ expect(validateDashboardSchema({ uid: "d", title: "D", schemaVersion: 42, panels: [lib] })).toEqual([]);
273
+ });
274
+
275
+ test("GRAF107 carries the severity through", () => {
276
+ const issues = checkSchema({ dashboards: [{ json: dashboard({ fancyNewField: true, graphTooltip: 7 }) }], datasources: [] });
277
+ expect(issues.map((i) => [i.code, i.severity])).toEqual([
278
+ ["GRAF107", "error"],
279
+ ["GRAF107", "warning"],
280
+ ]);
281
+ });
282
+ });