@intentius/chant-lexicon-grafana 0.96.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 (259) hide show
  1. package/README.md +50 -0
  2. package/dist/build.d.ts +116 -0
  3. package/dist/build.d.ts.map +1 -0
  4. package/dist/catalog.d.ts +26 -0
  5. package/dist/catalog.d.ts.map +1 -0
  6. package/dist/codegen/docs-cli.d.ts +3 -0
  7. package/dist/codegen/docs-cli.d.ts.map +1 -0
  8. package/dist/codegen/docs.d.ts +8 -0
  9. package/dist/codegen/docs.d.ts.map +1 -0
  10. package/dist/codegen/generate-cli.d.ts +3 -0
  11. package/dist/codegen/generate-cli.d.ts.map +1 -0
  12. package/dist/codegen/generate.d.ts +21 -0
  13. package/dist/codegen/generate.d.ts.map +1 -0
  14. package/dist/codegen/package.d.ts +7 -0
  15. package/dist/codegen/package.d.ts.map +1 -0
  16. package/dist/codegen/schema-types.d.ts +41 -0
  17. package/dist/codegen/schema-types.d.ts.map +1 -0
  18. package/dist/composites/agent-dashboard.d.ts +70 -0
  19. package/dist/composites/agent-dashboard.d.ts.map +1 -0
  20. package/dist/composites/catalog.d.ts +3 -0
  21. package/dist/composites/catalog.d.ts.map +1 -0
  22. package/dist/composites/index.d.ts +12 -0
  23. package/dist/composites/index.d.ts.map +1 -0
  24. package/dist/composites/red-dashboard.d.ts +58 -0
  25. package/dist/composites/red-dashboard.d.ts.map +1 -0
  26. package/dist/composites/shared.d.ts +68 -0
  27. package/dist/composites/shared.d.ts.map +1 -0
  28. package/dist/composites/slo-dashboard.d.ts +62 -0
  29. package/dist/composites/slo-dashboard.d.ts.map +1 -0
  30. package/dist/dashboard.d.ts +84 -0
  31. package/dist/dashboard.d.ts.map +1 -0
  32. package/dist/datasource.d.ts +67 -0
  33. package/dist/datasource.d.ts.map +1 -0
  34. package/dist/detect.d.ts +20 -0
  35. package/dist/detect.d.ts.map +1 -0
  36. package/dist/index.d.ts +17 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/integrity.json +22 -0
  39. package/dist/lint/audit-catalog.d.ts +13 -0
  40. package/dist/lint/audit-catalog.d.ts.map +1 -0
  41. package/dist/lint/post-synth/graf101.d.ts +8 -0
  42. package/dist/lint/post-synth/graf101.d.ts.map +1 -0
  43. package/dist/lint/post-synth/graf102.d.ts +8 -0
  44. package/dist/lint/post-synth/graf102.d.ts.map +1 -0
  45. package/dist/lint/post-synth/graf103.d.ts +8 -0
  46. package/dist/lint/post-synth/graf103.d.ts.map +1 -0
  47. package/dist/lint/post-synth/graf104.d.ts +8 -0
  48. package/dist/lint/post-synth/graf104.d.ts.map +1 -0
  49. package/dist/lint/post-synth/graf105.d.ts +8 -0
  50. package/dist/lint/post-synth/graf105.d.ts.map +1 -0
  51. package/dist/lint/post-synth/graf106.d.ts +8 -0
  52. package/dist/lint/post-synth/graf106.d.ts.map +1 -0
  53. package/dist/lint/post-synth/graf107.d.ts +8 -0
  54. package/dist/lint/post-synth/graf107.d.ts.map +1 -0
  55. package/dist/lint/post-synth/grafana-helpers.d.ts +16 -0
  56. package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -0
  57. package/dist/lint/post-synth/index.d.ts +3 -0
  58. package/dist/lint/post-synth/index.d.ts.map +1 -0
  59. package/dist/lint/rules/grafana-ast.d.ts +21 -0
  60. package/dist/lint/rules/grafana-ast.d.ts.map +1 -0
  61. package/dist/lint/rules/index.d.ts +6 -0
  62. package/dist/lint/rules/index.d.ts.map +1 -0
  63. package/dist/lint/rules/literal-secret.d.ts +12 -0
  64. package/dist/lint/rules/literal-secret.d.ts.map +1 -0
  65. package/dist/lint/rules/uid-syntax.d.ts +12 -0
  66. package/dist/lint/rules/uid-syntax.d.ts.map +1 -0
  67. package/dist/lsp/completions.d.ts +4 -0
  68. package/dist/lsp/completions.d.ts.map +1 -0
  69. package/dist/lsp/hover.d.ts +4 -0
  70. package/dist/lsp/hover.d.ts.map +1 -0
  71. package/dist/manifest.json +8 -0
  72. package/dist/meta.json +107 -0
  73. package/dist/okf/index.md +39 -0
  74. package/dist/okf/rules/GRAF001.md +16 -0
  75. package/dist/okf/rules/GRAF002.md +15 -0
  76. package/dist/okf/rules/GRAF101.md +15 -0
  77. package/dist/okf/rules/GRAF102.md +15 -0
  78. package/dist/okf/rules/GRAF103.md +11 -0
  79. package/dist/okf/rules/GRAF104.md +15 -0
  80. package/dist/okf/rules/GRAF105.md +11 -0
  81. package/dist/okf/rules/GRAF106.md +11 -0
  82. package/dist/okf/rules/GRAF107.md +11 -0
  83. package/dist/okf/types/ConstantVariable.md +9 -0
  84. package/dist/okf/types/CustomVariable.md +9 -0
  85. package/dist/okf/types/Dashboard.md +14 -0
  86. package/dist/okf/types/DashboardProvider.md +9 -0
  87. package/dist/okf/types/Datasource.md +16 -0
  88. package/dist/okf/types/DatasourceVariable.md +9 -0
  89. package/dist/okf/types/GaugePanel.md +9 -0
  90. package/dist/okf/types/HeatmapPanel.md +9 -0
  91. package/dist/okf/types/IntervalVariable.md +9 -0
  92. package/dist/okf/types/LogsPanel.md +9 -0
  93. package/dist/okf/types/LokiQuery.md +9 -0
  94. package/dist/okf/types/PromQuery.md +9 -0
  95. package/dist/okf/types/QueryVariable.md +9 -0
  96. package/dist/okf/types/Row.md +9 -0
  97. package/dist/okf/types/StatPanel.md +9 -0
  98. package/dist/okf/types/TablePanel.md +9 -0
  99. package/dist/okf/types/TempoQuery.md +9 -0
  100. package/dist/okf/types/TextPanel.md +9 -0
  101. package/dist/okf/types/TextboxVariable.md +9 -0
  102. package/dist/okf/types/TimeSeriesPanel.md +9 -0
  103. package/dist/okf/types/TracesPanel.md +9 -0
  104. package/dist/package-cli.d.ts +3 -0
  105. package/dist/package-cli.d.ts.map +1 -0
  106. package/dist/panels.d.ts +138 -0
  107. package/dist/panels.d.ts.map +1 -0
  108. package/dist/pin.d.ts +32 -0
  109. package/dist/pin.d.ts.map +1 -0
  110. package/dist/plugin.d.ts +12 -0
  111. package/dist/plugin.d.ts.map +1 -0
  112. package/dist/query.d.ts +81 -0
  113. package/dist/query.d.ts.map +1 -0
  114. package/dist/rules/graf101.ts +17 -0
  115. package/dist/rules/graf102.ts +17 -0
  116. package/dist/rules/graf103.ts +17 -0
  117. package/dist/rules/graf104.ts +17 -0
  118. package/dist/rules/graf105.ts +17 -0
  119. package/dist/rules/graf106.ts +17 -0
  120. package/dist/rules/graf107.ts +17 -0
  121. package/dist/rules/grafana-ast.ts +70 -0
  122. package/dist/rules/grafana-helpers.ts +68 -0
  123. package/dist/rules/literal-secret.ts +48 -0
  124. package/dist/rules/uid-syntax.ts +56 -0
  125. package/dist/schema/dashboard.gen.d.ts +1231 -0
  126. package/dist/schema/dashboard.gen.d.ts.map +1 -0
  127. package/dist/schema/gauge.gen.d.ts +57 -0
  128. package/dist/schema/gauge.gen.d.ts.map +1 -0
  129. package/dist/schema/heatmap.gen.d.ts +295 -0
  130. package/dist/schema/heatmap.gen.d.ts.map +1 -0
  131. package/dist/schema/index.d.ts +18 -0
  132. package/dist/schema/index.d.ts.map +1 -0
  133. package/dist/schema/logs.gen.d.ts +29 -0
  134. package/dist/schema/logs.gen.d.ts.map +1 -0
  135. package/dist/schema/loki.gen.d.ts +69 -0
  136. package/dist/schema/loki.gen.d.ts.map +1 -0
  137. package/dist/schema/prometheus.gen.d.ts +169 -0
  138. package/dist/schema/prometheus.gen.d.ts.map +1 -0
  139. package/dist/schema/stat.gen.d.ts +75 -0
  140. package/dist/schema/stat.gen.d.ts.map +1 -0
  141. package/dist/schema/table.gen.d.ts +295 -0
  142. package/dist/schema/table.gen.d.ts.map +1 -0
  143. package/dist/schema/tempo.gen.d.ts +136 -0
  144. package/dist/schema/tempo.gen.d.ts.map +1 -0
  145. package/dist/schema/text.gen.d.ts +16 -0
  146. package/dist/schema/text.gen.d.ts.map +1 -0
  147. package/dist/schema/timeseries.gen.d.ts +179 -0
  148. package/dist/schema/timeseries.gen.d.ts.map +1 -0
  149. package/dist/schema-validate.d.ts +20 -0
  150. package/dist/schema-validate.d.ts.map +1 -0
  151. package/dist/serializer.d.ts +22 -0
  152. package/dist/serializer.d.ts.map +1 -0
  153. package/dist/skill-defs.d.ts +3 -0
  154. package/dist/skill-defs.d.ts.map +1 -0
  155. package/dist/skills/chant-grafana-provisioning.md +42 -0
  156. package/dist/skills/chant-grafana.md +93 -0
  157. package/dist/spec/fetch-cli.d.ts +3 -0
  158. package/dist/spec/fetch-cli.d.ts.map +1 -0
  159. package/dist/spec/schemas.d.ts +25 -0
  160. package/dist/spec/schemas.d.ts.map +1 -0
  161. package/dist/types/index.d.ts +3 -0
  162. package/dist/util.d.ts +17 -0
  163. package/dist/util.d.ts.map +1 -0
  164. package/dist/validate-cli.d.ts +3 -0
  165. package/dist/validate-cli.d.ts.map +1 -0
  166. package/dist/validate-output.d.ts +42 -0
  167. package/dist/validate-output.d.ts.map +1 -0
  168. package/dist/validate.d.ts +12 -0
  169. package/dist/validate.d.ts.map +1 -0
  170. package/dist/variables.d.ts +100 -0
  171. package/dist/variables.d.ts.map +1 -0
  172. package/package.json +79 -0
  173. package/src/build.test.ts +210 -0
  174. package/src/build.ts +573 -0
  175. package/src/catalog.ts +116 -0
  176. package/src/codegen/docs-cli.ts +4 -0
  177. package/src/codegen/docs.ts +97 -0
  178. package/src/codegen/generate-cli.ts +8 -0
  179. package/src/codegen/generate.ts +83 -0
  180. package/src/codegen/package.ts +41 -0
  181. package/src/codegen/schema-types.ts +173 -0
  182. package/src/composites/agent-dashboard.ts +235 -0
  183. package/src/composites/catalog.test.ts +37 -0
  184. package/src/composites/catalog.ts +223 -0
  185. package/src/composites/composites.test.ts +314 -0
  186. package/src/composites/index.ts +12 -0
  187. package/src/composites/red-dashboard.ts +159 -0
  188. package/src/composites/shared.ts +94 -0
  189. package/src/composites/slo-dashboard.ts +177 -0
  190. package/src/dashboard.ts +123 -0
  191. package/src/datasource.ts +93 -0
  192. package/src/detect.ts +30 -0
  193. package/src/generated/lexicon-grafana.json +107 -0
  194. package/src/import.e2e.test.ts +147 -0
  195. package/src/import.test.ts +45 -0
  196. package/src/index.ts +178 -0
  197. package/src/lint/audit-catalog.ts +87 -0
  198. package/src/lint/post-synth/graf101.ts +17 -0
  199. package/src/lint/post-synth/graf102.ts +17 -0
  200. package/src/lint/post-synth/graf103.ts +17 -0
  201. package/src/lint/post-synth/graf104.ts +17 -0
  202. package/src/lint/post-synth/graf105.ts +17 -0
  203. package/src/lint/post-synth/graf106.ts +17 -0
  204. package/src/lint/post-synth/graf107.ts +17 -0
  205. package/src/lint/post-synth/grafana-helpers.ts +68 -0
  206. package/src/lint/post-synth/index.ts +19 -0
  207. package/src/lint/post-synth/post-synth.test.ts +231 -0
  208. package/src/lint/rules/grafana-ast.ts +70 -0
  209. package/src/lint/rules/index.ts +9 -0
  210. package/src/lint/rules/literal-secret.ts +48 -0
  211. package/src/lint/rules/rules.test.ts +70 -0
  212. package/src/lint/rules/uid-syntax.ts +56 -0
  213. package/src/lsp/completions.test.ts +31 -0
  214. package/src/lsp/completions.ts +15 -0
  215. package/src/lsp/hover.test.ts +25 -0
  216. package/src/lsp/hover.ts +28 -0
  217. package/src/package-cli.ts +17 -0
  218. package/src/panels.ts +275 -0
  219. package/src/pin.ts +68 -0
  220. package/src/plugin.test.ts +50 -0
  221. package/src/plugin.ts +116 -0
  222. package/src/query.ts +160 -0
  223. package/src/schema/dashboard.gen.ts +1289 -0
  224. package/src/schema/gauge.gen.ts +64 -0
  225. package/src/schema/heatmap.gen.ts +321 -0
  226. package/src/schema/index.ts +17 -0
  227. package/src/schema/logs.gen.ts +34 -0
  228. package/src/schema/loki.gen.ts +77 -0
  229. package/src/schema/prometheus.gen.ts +181 -0
  230. package/src/schema/stat.gen.ts +86 -0
  231. package/src/schema/table.gen.ts +334 -0
  232. package/src/schema/tempo.gen.ts +146 -0
  233. package/src/schema/text.gen.ts +22 -0
  234. package/src/schema/timeseries.gen.ts +208 -0
  235. package/src/schema-validate.ts +143 -0
  236. package/src/schema.test.ts +76 -0
  237. package/src/serializer.test.ts +170 -0
  238. package/src/serializer.ts +37 -0
  239. package/src/skill-defs.ts +31 -0
  240. package/src/skills/chant-grafana-provisioning.md +42 -0
  241. package/src/skills/chant-grafana.md +93 -0
  242. package/src/spec/fetch-cli.ts +27 -0
  243. package/src/spec/schemas/dashboard.jsonschema.json +1901 -0
  244. package/src/spec/schemas/gauge.jsonschema.json +114 -0
  245. package/src/spec/schemas/heatmap.jsonschema.json +480 -0
  246. package/src/spec/schemas/logs.jsonschema.json +94 -0
  247. package/src/spec/schemas/loki.jsonschema.json +118 -0
  248. package/src/spec/schemas/prometheus.jsonschema.json +276 -0
  249. package/src/spec/schemas/stat.jsonschema.json +163 -0
  250. package/src/spec/schemas/table.jsonschema.json +751 -0
  251. package/src/spec/schemas/tempo.jsonschema.json +225 -0
  252. package/src/spec/schemas/text.jsonschema.json +72 -0
  253. package/src/spec/schemas/timeseries.jsonschema.json +471 -0
  254. package/src/spec/schemas.ts +56 -0
  255. package/src/util.ts +43 -0
  256. package/src/validate-cli.ts +7 -0
  257. package/src/validate-output.ts +380 -0
  258. package/src/validate.ts +108 -0
  259. package/src/variables.ts +161 -0
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Dashboard variables (Grafana's "templating"): query, custom, interval,
3
+ * datasource, constant and textbox.
4
+ *
5
+ * A variable is declared on its own and listed in a dashboard's
6
+ * `variables`. Queries reference it as `$name` or `${name}` in their
7
+ * expression; GRAF103 checks every such reference names a declared
8
+ * variable. A `DatasourceVariable` can stand in for a datasource on a panel
9
+ * or query, and the reference becomes `${name}`.
10
+ */
11
+ import type { Declarable } from "@intentius/chant/declarable";
12
+ import type { DatasourceEntity, DatasourceRef } from "./datasource.js";
13
+ import type { VariableOption } from "./schema/dashboard.gen.js";
14
+ export type VariableKind = "query" | "custom" | "interval" | "datasource" | "constant" | "textbox";
15
+ /** Where the variable shows: with its label, without it, or not at all. */
16
+ export type VariableHide = "label" | "valueOnly" | "hidden";
17
+ interface CommonVariableProps {
18
+ /** The name queries use, `$name`. Letters, digits and `_`. */
19
+ name: string;
20
+ label?: string;
21
+ description?: string;
22
+ hide?: VariableHide;
23
+ /** Keep the value out of the URL. */
24
+ skipUrlSync?: boolean;
25
+ /** The value selected when the dashboard loads. */
26
+ current?: VariableOption;
27
+ }
28
+ interface MultiValueProps {
29
+ multi?: boolean;
30
+ includeAll?: boolean;
31
+ /** What `All` expands to, e.g. `.*` for a regex matcher. */
32
+ allValue?: string;
33
+ }
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>;
36
+ export interface QueryVariableProps extends CommonVariableProps, MultiValueProps {
37
+ datasource: VariableDatasource;
38
+ /** The datasource's variable query, e.g. `label_values(up, job)` for Prometheus. */
39
+ query: string;
40
+ regex?: string;
41
+ /** When to re-run the query. Defaults to on dashboard load. */
42
+ refresh?: "never" | "onLoad" | "onTimeRangeChange";
43
+ /** Grafana's `VariableSort` (0 disabled, 1 alphabetical asc, 2 desc, 3 numerical asc, …). */
44
+ sort?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
45
+ }
46
+ export interface CustomVariableProps extends CommonVariableProps, MultiValueProps {
47
+ values: string[];
48
+ }
49
+ export interface IntervalVariableProps extends CommonVariableProps {
50
+ /** e.g. `["1m", "5m", "1h"]`. */
51
+ values: string[];
52
+ auto?: boolean;
53
+ autoCount?: number;
54
+ autoMin?: string;
55
+ }
56
+ export interface DatasourceVariableProps<T extends string = string> extends CommonVariableProps, MultiValueProps {
57
+ /** The datasource plugin id to choose among, e.g. `prometheus`. */
58
+ pluginType: T;
59
+ /** Only datasources whose name matches. */
60
+ regex?: string;
61
+ }
62
+ export interface ConstantVariableProps extends Omit<CommonVariableProps, "hide"> {
63
+ value: string;
64
+ }
65
+ export interface TextboxVariableProps extends CommonVariableProps {
66
+ value?: string;
67
+ }
68
+ export interface VariableEntity<P = CommonVariableProps> extends Declarable {
69
+ readonly props: P;
70
+ readonly variableKind: VariableKind;
71
+ /** The variable name, `$name` in queries. */
72
+ readonly variableName: string;
73
+ }
74
+ export interface DatasourceVariableEntity<T extends string = string> extends VariableEntity<DatasourceVariableProps<T>> {
75
+ readonly variableKind: "datasource";
76
+ readonly pluginType: T;
77
+ }
78
+ export declare const VARIABLE_TYPE_PREFIX = "Grafana::Variable::";
79
+ /** A variable whose values come from a datasource query. */
80
+ export declare const QueryVariable: new (props: QueryVariableProps) => VariableEntity<QueryVariableProps>;
81
+ /** A variable with a fixed list of values. */
82
+ export declare const CustomVariable: new (props: CustomVariableProps) => VariableEntity<CustomVariableProps>;
83
+ /** A time interval to choose, used as `$name` in range selectors. */
84
+ export declare const IntervalVariable: new (props: IntervalVariableProps) => VariableEntity<IntervalVariableProps>;
85
+ /** A choice of datasource of one plugin type. Usable wherever a datasource is. */
86
+ export declare const DatasourceVariable: {
87
+ new <T extends string>(props: DatasourceVariableProps<T>): DatasourceVariableEntity<T>;
88
+ };
89
+ /** A hidden, fixed value. */
90
+ export declare const ConstantVariable: new (props: ConstantVariableProps) => VariableEntity<ConstantVariableProps>;
91
+ /** A free-text box. */
92
+ export declare const TextboxVariable: new (props: TextboxVariableProps) => VariableEntity<TextboxVariableProps>;
93
+ export declare function isVariableEntity(value: unknown): value is VariableEntity;
94
+ export declare function isDatasourceVariable(value: unknown): value is DatasourceVariableEntity;
95
+ /** Variable names Grafana defines itself; queries may use them without declaring anything. */
96
+ export declare function isBuiltinVariable(name: string): boolean;
97
+ /** A valid variable name: what `$name` can match. */
98
+ export declare const VARIABLE_NAME: RegExp;
99
+ export {};
100
+ //# sourceMappingURL=variables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@intentius/chant-lexicon-grafana",
3
+ "version": "0.96.0",
4
+ "description": "Grafana lexicon for chant — typed dashboards, panels, queries and datasources, serialized to dashboard JSON and Grafana provisioning files",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://intentius.io/chant",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/INTENTIUS/chant.git",
10
+ "directory": "lexicons/grafana"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/INTENTIUS/chant/issues"
14
+ },
15
+ "keywords": [
16
+ "infrastructure-as-code",
17
+ "iac",
18
+ "typescript",
19
+ "grafana",
20
+ "dashboards",
21
+ "observability",
22
+ "prometheus",
23
+ "tempo",
24
+ "loki",
25
+ "chant"
26
+ ],
27
+ "type": "module",
28
+ "files": [
29
+ "src/",
30
+ "dist/"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "exports": {
36
+ ".": {
37
+ "development": "./src/index.ts",
38
+ "types": "./dist/index.d.ts",
39
+ "default": "./src/index.ts"
40
+ },
41
+ "./*": {
42
+ "development": "./src/*.ts",
43
+ "types": "./dist/*.d.ts",
44
+ "default": "./src/*.ts"
45
+ },
46
+ "./lint/post-synth": {
47
+ "development": "./src/lint/post-synth/index.ts",
48
+ "types": "./dist/lint/post-synth/index.d.ts",
49
+ "default": "./src/lint/post-synth/index.ts"
50
+ },
51
+ "./manifest": "./dist/manifest.json",
52
+ "./meta": "./dist/meta.json",
53
+ "./types": "./dist/types/index.d.ts"
54
+ },
55
+ "scripts": {
56
+ "generate": "tsx src/codegen/generate-cli.ts",
57
+ "bundle": "tsx src/package-cli.ts",
58
+ "validate": "tsx src/validate-cli.ts",
59
+ "docs": "tsx src/codegen/docs-cli.ts",
60
+ "prepack": "npm run generate && npm run bundle && npm run validate && npm run build",
61
+ "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
62
+ },
63
+ "dependencies": {
64
+ "@intentius/chant-lexicon-otel": "*",
65
+ "@intentius/chant-lexicon-prometheus": "*",
66
+ "ajv": "^8.20.0",
67
+ "js-yaml": "^4.3.1"
68
+ },
69
+ "devDependencies": {
70
+ "@intentius/chant": "*",
71
+ "@types/js-yaml": "^4.0.9",
72
+ "tsc-alias": "^1.8.17",
73
+ "typescript": "^5.9.3"
74
+ },
75
+ "peerDependencies": {
76
+ "@intentius/chant": "^0.96.0",
77
+ "typescript": "^5.9.3"
78
+ }
79
+ }
@@ -0,0 +1,210 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { Datasource } from "./datasource";
3
+ import { Dashboard } from "./dashboard";
4
+ import { Row, StatPanel, TextPanel, TimeSeriesPanel, TablePanel, definePanel } from "./panels";
5
+ import { PromQuery, TempoQuery, LokiQuery, defineQuery } from "./query";
6
+ import {
7
+ CustomVariable,
8
+ ConstantVariable,
9
+ DatasourceVariable,
10
+ IntervalVariable,
11
+ QueryVariable,
12
+ TextboxVariable,
13
+ } from "./variables";
14
+ import { panelsJson, renderDashboard, variableModel, dashboardJson, grafanaFiles, type PanelJson } from "./build";
15
+
16
+ /** The panels array, read as plain panels (the tests below build no rows unless they say so). */
17
+ function panelsOnly(items: Parameters<typeof panelsJson>[0]): PanelJson[] {
18
+ return panelsJson(items) as PanelJson[];
19
+ }
20
+ import { validateDashboardSchema } from "./schema-validate";
21
+
22
+ const prometheus = new Datasource({ name: "Prometheus", type: "prometheus" });
23
+ const tempo = new Datasource({ name: "Tempo", type: "tempo" });
24
+
25
+ describe("layout", () => {
26
+ test("panels flow left to right and wrap at 24 columns", () => {
27
+ const stats = [1, 2, 3, 4, 5].map((i) => new StatPanel({ title: `s${i}` }));
28
+ const panels = panelsJson(stats);
29
+ expect(panels.map((p) => p.gridPos)).toEqual([
30
+ { h: 4, w: 6, x: 0, y: 0 },
31
+ { h: 4, w: 6, x: 6, y: 0 },
32
+ { h: 4, w: 6, x: 12, y: 0 },
33
+ { h: 4, w: 6, x: 18, y: 0 },
34
+ { h: 4, w: 6, x: 0, y: 4 },
35
+ ]);
36
+ });
37
+
38
+ test("a new line starts below the tallest panel of the line before", () => {
39
+ const panels = panelsJson([new StatPanel(), new TimeSeriesPanel(), new StatPanel(), new TextPanel()]);
40
+ expect(panels.map((p) => p.gridPos)).toEqual([
41
+ { h: 4, w: 6, x: 0, y: 0 },
42
+ { h: 8, w: 12, x: 6, y: 0 },
43
+ { h: 4, w: 6, x: 18, y: 0 },
44
+ { h: 3, w: 24, x: 0, y: 8 },
45
+ ]);
46
+ });
47
+
48
+ test("an explicit position is kept, and w/h without x/y only resize", () => {
49
+ const panels = panelsJson([
50
+ new StatPanel({ gridPos: { x: 12, y: 20, w: 12, h: 2 } }),
51
+ new StatPanel({ gridPos: { w: 24 } }),
52
+ ]);
53
+ expect(panels.map((p) => p.gridPos)).toEqual([
54
+ { h: 2, w: 12, x: 12, y: 20 },
55
+ { h: 4, w: 24, x: 0, y: 0 },
56
+ ]);
57
+ });
58
+
59
+ test("rows start below everything and their panels follow; a collapsed row nests them", () => {
60
+ const panels = panelsJson([
61
+ new TimeSeriesPanel({ title: "top" }),
62
+ new Row({ title: "open", panels: [new StatPanel({ title: "a" }), new StatPanel({ title: "b" })] }),
63
+ new Row({ title: "shut", collapsed: true, panels: [new TablePanel({ title: "c" })] }),
64
+ new StatPanel({ title: "after" }),
65
+ ]);
66
+ expect(panels.map((p) => [p.type, p.title, p.gridPos, p.id])).toEqual([
67
+ ["timeseries", "top", { h: 8, w: 12, x: 0, y: 0 }, 1],
68
+ ["row", "open", { h: 1, w: 24, x: 0, y: 8 }, 2],
69
+ ["stat", "a", { h: 4, w: 6, x: 0, y: 9 }, 3],
70
+ ["stat", "b", { h: 4, w: 6, x: 6, y: 9 }, 4],
71
+ ["row", "shut", { h: 1, w: 24, x: 0, y: 13 }, 5],
72
+ ["stat", "after", { h: 4, w: 6, x: 0, y: 14 }, 7],
73
+ ]);
74
+ const shut = panels[4] as unknown as { collapsed: boolean; panels: Array<{ title: string; id: number; gridPos: unknown }> };
75
+ expect(shut.collapsed).toBe(true);
76
+ expect(shut.panels.map((p) => [p.title, p.id, p.gridPos])).toEqual([["c", 6, { h: 8, w: 12, x: 0, y: 14 }]]);
77
+ expect((panels[1] as unknown as { panels: unknown[] }).panels).toEqual([]);
78
+ });
79
+
80
+ test("auto ids skip ids set explicitly", () => {
81
+ const panels = panelsJson([new StatPanel(), new StatPanel({ id: 1 }), new StatPanel()]);
82
+ expect(panels.map((p) => p.id)).toEqual([2, 1, 3]);
83
+ });
84
+ });
85
+
86
+ describe("datasources and targets", () => {
87
+ test("refIds default to A, B, C; an explicit refId is kept", () => {
88
+ const [panel] = panelsOnly([
89
+ new TimeSeriesPanel({ datasource: prometheus, targets: [new PromQuery({ expr: "a" }), new PromQuery({ expr: "b", refId: "errors" }), new PromQuery({ expr: "c" })] }),
90
+ ]);
91
+ expect(panel.targets!.map((t) => (t as { refId: string }).refId)).toEqual(["A", "errors", "C"]);
92
+ });
93
+
94
+ test("queries on different datasources make the panel Mixed", () => {
95
+ const [panel] = panelsOnly([
96
+ new TablePanel({ targets: [new PromQuery({ expr: "up", datasource: prometheus }), new TempoQuery({ query: "{}", datasource: tempo })] }),
97
+ ]);
98
+ expect(panel.datasource).toEqual({ type: "datasource", uid: "-- Mixed --" });
99
+ expect(panel.targets!.map((t) => (t as { datasource: unknown }).datasource)).toEqual([
100
+ { type: "prometheus", uid: "prometheus" },
101
+ { type: "tempo", uid: "tempo" },
102
+ ]);
103
+ });
104
+
105
+ test("a panel takes its queries' shared datasource, and a row passes its own down", () => {
106
+ const [shared] = panelsOnly([new StatPanel({ targets: [new PromQuery({ expr: "up", datasource: prometheus })] })]);
107
+ expect(shared.datasource).toEqual({ type: "prometheus", uid: "prometheus" });
108
+ const [, child] = panelsOnly([new Row({ title: "r", datasource: prometheus, panels: [new StatPanel({ targets: [new PromQuery({ expr: "up" })] })] })]);
109
+ expect((child.targets![0] as { datasource: unknown }).datasource).toEqual({ type: "prometheus", uid: "prometheus" });
110
+ });
111
+
112
+ test("a datasource variable is referenced as ${name}; a plain ref passes through", () => {
113
+ const ds = new DatasourceVariable({ name: "ds", pluginType: "prometheus" });
114
+ const [a, b] = panelsOnly([
115
+ new StatPanel({ datasource: ds, targets: [new PromQuery({ expr: "up" })] }),
116
+ new StatPanel({ datasource: { type: "prometheus", uid: "mimir" }, targets: [new PromQuery({ expr: "up" })] }),
117
+ ]);
118
+ expect(a.datasource).toEqual({ type: "prometheus", uid: "${ds}" });
119
+ expect(b.datasource).toEqual({ type: "prometheus", uid: "mimir" });
120
+ });
121
+
122
+ test("Tempo queries get the fields the schema requires", () => {
123
+ const [panel] = panelsOnly([new TablePanel({ datasource: tempo, targets: [new TempoQuery({ query: "{ status = error }" })] })]);
124
+ expect(panel.targets![0]).toEqual({ datasource: { type: "tempo", uid: "tempo" }, refId: "A", filters: [], queryType: "traceql", query: "{ status = error }" });
125
+ });
126
+
127
+ test("Loki queries carry their expression as expr", () => {
128
+ const loki = new Datasource({ name: "Loki", type: "loki" });
129
+ const [panel] = panelsOnly([new TablePanel({ datasource: loki, targets: [new LokiQuery({ expr: '{app="x"}', maxLines: 100 })] })]);
130
+ expect(panel.targets![0]).toMatchObject({ expr: '{app="x"}', maxLines: 100 });
131
+ });
132
+ });
133
+
134
+ describe("variables", () => {
135
+ test("each kind renders to a VariableModel", () => {
136
+ expect(variableModel(new QueryVariable({ name: "svc", datasource: prometheus, query: "label_values(up, job)", multi: true }))).toEqual({
137
+ type: "query",
138
+ name: "svc",
139
+ datasource: { type: "prometheus", uid: "prometheus" },
140
+ query: "label_values(up, job)",
141
+ definition: "label_values(up, job)",
142
+ refresh: 1,
143
+ multi: true,
144
+ options: [],
145
+ });
146
+ expect(variableModel(new CustomVariable({ name: "env", values: ["prod", "a,b"] }))).toMatchObject({
147
+ type: "custom",
148
+ query: "prod,a\\,b",
149
+ current: { text: "prod", value: "prod" },
150
+ options: [
151
+ { selected: true, text: "prod", value: "prod" },
152
+ { selected: false, text: "a,b", value: "a,b" },
153
+ ],
154
+ });
155
+ expect(variableModel(new IntervalVariable({ name: "step", values: ["1m", "5m"] }))).toMatchObject({ type: "interval", query: "1m,5m", auto: false, refresh: 2 });
156
+ expect(variableModel(new DatasourceVariable({ name: "ds", pluginType: "loki", hide: "valueOnly" }))).toMatchObject({ type: "datasource", query: "loki", hide: 1 });
157
+ expect(variableModel(new ConstantVariable({ name: "cluster", value: "prod-1" }))).toMatchObject({ type: "constant", query: "prod-1", hide: 2 });
158
+ expect(variableModel(new TextboxVariable({ name: "q" }))).toMatchObject({ type: "textbox", query: "" });
159
+ });
160
+
161
+ test("a dashboard with every variable kind matches the dashboard schema", () => {
162
+ const dash = new Dashboard({
163
+ title: "Vars",
164
+ variables: [
165
+ new QueryVariable({ name: "svc", datasource: prometheus, query: "label_values(up, job)" }),
166
+ new CustomVariable({ name: "env", values: ["prod", "dev"] }),
167
+ new IntervalVariable({ name: "step", values: ["1m"] }),
168
+ new DatasourceVariable({ name: "ds", pluginType: "prometheus" }),
169
+ new ConstantVariable({ name: "cluster", value: "x" }),
170
+ new TextboxVariable({ name: "q", value: "y" }),
171
+ ],
172
+ });
173
+ expect(validateDashboardSchema(renderDashboard(dash) as unknown as Record<string, unknown>)).toEqual([]);
174
+ });
175
+ });
176
+
177
+ describe("extension points", () => {
178
+ test("definePanel and defineQuery produce classes that render and lay out like built-ins", () => {
179
+ const PieChartPanel = definePanel<{ pieType?: "pie" | "donut" }>()({ type: "piechart", className: "PieChartPanel", defaultSize: { w: 8, h: 8 } });
180
+ const ElasticQuery = defineQuery<{ query: string; refId?: string }>()({ datasourceType: "elasticsearch", className: "ElasticQuery" });
181
+ const es = new Datasource({ name: "Logs ES", type: "elasticsearch" });
182
+ const json = renderDashboard(
183
+ new Dashboard({ title: "Custom", panels: [new PieChartPanel({ options: { pieType: "donut" }, datasource: es, targets: [new ElasticQuery({ query: "*" })] })] }),
184
+ );
185
+ expect(json.panels![0]).toMatchObject({
186
+ type: "piechart",
187
+ gridPos: { w: 8, h: 8, x: 0, y: 0 },
188
+ options: { pieType: "donut" },
189
+ datasource: { type: "elasticsearch", uid: "logs-es" },
190
+ targets: [{ refId: "A", query: "*" }],
191
+ });
192
+ expect(validateDashboardSchema(json as unknown as Record<string, unknown>)).toEqual([]);
193
+ });
194
+
195
+ test("redefining a built-in panel or query type throws", () => {
196
+ expect(() => definePanel()({ type: "stat", className: "MyStat", defaultSize: { w: 1, h: 1 } })).toThrow(/built in/);
197
+ expect(() => defineQuery()({ datasourceType: "prometheus", className: "MyProm" })).toThrow(/built in/);
198
+ expect(() => definePanel()({ type: "row", className: "R", defaultSize: { w: 1, h: 1 } })).toThrow(/Row/);
199
+ });
200
+
201
+ test("dashboardJson and grafanaFiles render without a build", () => {
202
+ const dash = new Dashboard({ title: "Plain", uid: "plain" });
203
+ expect(JSON.parse(dashboardJson(dash)).uid).toBe("plain");
204
+ expect(Object.keys(grafanaFiles([dash, prometheus])).sort()).toEqual([
205
+ "dashboards/plain.json",
206
+ "provisioning/dashboards/chant.yaml",
207
+ "provisioning/datasources/chant.yaml",
208
+ ]);
209
+ });
210
+ });