@intentius/chant-lexicon-grafana 0.99.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 (224) hide show
  1. package/README.md +12 -6
  2. package/dist/annotations.d.ts +61 -0
  3. package/dist/annotations.d.ts.map +1 -0
  4. package/dist/api/apply.d.ts +8 -4
  5. package/dist/api/apply.d.ts.map +1 -1
  6. package/dist/api/fake-grafana.d.ts +2 -0
  7. package/dist/api/fake-grafana.d.ts.map +1 -1
  8. package/dist/api/folders.d.ts +53 -17
  9. package/dist/api/folders.d.ts.map +1 -1
  10. package/dist/build.d.ts +26 -5
  11. package/dist/build.d.ts.map +1 -1
  12. package/dist/catalog.d.ts +1 -1
  13. package/dist/catalog.d.ts.map +1 -1
  14. package/dist/codegen/docs.d.ts.map +1 -1
  15. package/dist/codegen/generate.d.ts +7 -1
  16. package/dist/codegen/generate.d.ts.map +1 -1
  17. package/dist/composites/shared.d.ts +4 -3
  18. package/dist/composites/shared.d.ts.map +1 -1
  19. package/dist/dashboard.d.ts +42 -14
  20. package/dist/dashboard.d.ts.map +1 -1
  21. package/dist/datasource-refs.d.ts +9 -5
  22. package/dist/datasource-refs.d.ts.map +1 -1
  23. package/dist/datasource-settings.d.ts +834 -0
  24. package/dist/datasource-settings.d.ts.map +1 -0
  25. package/dist/datasource.d.ts +53 -11
  26. package/dist/datasource.d.ts.map +1 -1
  27. package/dist/deep-observe-hooks.d.ts +1 -1
  28. package/dist/deep-observe-hooks.d.ts.map +1 -1
  29. package/dist/deep-observe.d.ts +9 -4
  30. package/dist/deep-observe.d.ts.map +1 -1
  31. package/dist/describe-resources.d.ts +1 -0
  32. package/dist/describe-resources.d.ts.map +1 -1
  33. package/dist/detect.d.ts +4 -2
  34. package/dist/detect.d.ts.map +1 -1
  35. package/dist/folder.d.ts +68 -0
  36. package/dist/folder.d.ts.map +1 -0
  37. package/dist/import/generator.d.ts.map +1 -1
  38. package/dist/import/mappings.d.ts +12 -6
  39. package/dist/import/mappings.d.ts.map +1 -1
  40. package/dist/import/model.d.ts +7 -0
  41. package/dist/import/model.d.ts.map +1 -1
  42. package/dist/import/normalize.d.ts.map +1 -1
  43. package/dist/import/parser.d.ts +16 -1
  44. package/dist/import/parser.d.ts.map +1 -1
  45. package/dist/import/testdata/fixtures.d.ts +6 -0
  46. package/dist/import/testdata/fixtures.d.ts.map +1 -1
  47. package/dist/import/v2.d.ts +4 -3
  48. package/dist/import/v2.d.ts.map +1 -1
  49. package/dist/index.d.ts +11 -9
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/init-templates.d.ts +27 -0
  52. package/dist/init-templates.d.ts.map +1 -0
  53. package/dist/integrity.json +11 -9
  54. package/dist/lint/audit-catalog.d.ts +1 -1
  55. package/dist/lint/audit-catalog.d.ts.map +1 -1
  56. package/dist/lint/post-synth/graf101.d.ts +1 -1
  57. package/dist/lint/post-synth/graf104.d.ts +2 -2
  58. package/dist/lint/post-synth/graf106.d.ts +2 -2
  59. package/dist/lint/post-synth/graf110.d.ts +8 -0
  60. package/dist/lint/post-synth/graf110.d.ts.map +1 -0
  61. package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -1
  62. package/dist/lint/post-synth/index.d.ts.map +1 -1
  63. package/dist/manifest.json +1 -1
  64. package/dist/meta.json +70 -0
  65. package/dist/okf/index.md +18 -3
  66. package/dist/okf/rules/GRAF101.md +2 -2
  67. package/dist/okf/rules/GRAF104.md +2 -2
  68. package/dist/okf/rules/GRAF106.md +2 -2
  69. package/dist/okf/rules/GRAF110.md +11 -0
  70. package/dist/okf/types/AdhocVariable.md +9 -0
  71. package/dist/okf/types/AzureMonitorQuery.md +9 -0
  72. package/dist/okf/types/BigQueryQuery.md +9 -0
  73. package/dist/okf/types/CloudMonitoringQuery.md +9 -0
  74. package/dist/okf/types/CloudWatchQuery.md +9 -0
  75. package/dist/okf/types/Dashboard.md +1 -1
  76. package/dist/okf/types/Datasource.md +1 -1
  77. package/dist/okf/types/DatasourceProvisioning.md +9 -0
  78. package/dist/okf/types/ElasticsearchQuery.md +9 -0
  79. package/dist/okf/types/ExternalDatasource.md +1 -1
  80. package/dist/okf/types/Folder.md +9 -0
  81. package/dist/okf/types/GroupByVariable.md +9 -0
  82. package/dist/okf/types/MSSQLQuery.md +9 -0
  83. package/dist/okf/types/MySQLQuery.md +9 -0
  84. package/dist/okf/types/PostgresQuery.md +9 -0
  85. package/dist/okf/types/PyroscopeQuery.md +9 -0
  86. package/dist/okf/types/SwitchVariable.md +9 -0
  87. package/dist/op/activities/grafana-apply.d.ts +11 -0
  88. package/dist/op/activities/grafana-apply.d.ts.map +1 -1
  89. package/dist/op/activities/index.d.ts +1 -1
  90. package/dist/op/activities/index.d.ts.map +1 -1
  91. package/dist/ownership.d.ts +11 -0
  92. package/dist/ownership.d.ts.map +1 -1
  93. package/dist/pin.d.ts +1 -1
  94. package/dist/pin.d.ts.map +1 -1
  95. package/dist/plugin.d.ts.map +1 -1
  96. package/dist/promql-check.d.ts.map +1 -1
  97. package/dist/query-models.d.ts +95 -0
  98. package/dist/query-models.d.ts.map +1 -0
  99. package/dist/query.d.ts +107 -10
  100. package/dist/query.d.ts.map +1 -1
  101. package/dist/rules/graf101.ts +2 -2
  102. package/dist/rules/graf104.ts +3 -3
  103. package/dist/rules/graf106.ts +3 -3
  104. package/dist/rules/graf110.ts +17 -0
  105. package/dist/rules/grafana-helpers.ts +13 -3
  106. package/dist/schema/azuremonitor.gen.d.ts +354 -0
  107. package/dist/schema/azuremonitor.gen.d.ts.map +1 -0
  108. package/dist/schema/bigquery.gen.d.ts +93 -0
  109. package/dist/schema/bigquery.gen.d.ts.map +1 -0
  110. package/dist/schema/cloudwatch.gen.d.ts +394 -0
  111. package/dist/schema/cloudwatch.gen.d.ts.map +1 -0
  112. package/dist/schema/elasticsearch.gen.d.ts +444 -0
  113. package/dist/schema/elasticsearch.gen.d.ts.map +1 -0
  114. package/dist/schema/googlecloudmonitoring.gen.d.ts +312 -0
  115. package/dist/schema/googlecloudmonitoring.gen.d.ts.map +1 -0
  116. package/dist/schema/grafanapyroscope.gen.d.ts +60 -0
  117. package/dist/schema/grafanapyroscope.gen.d.ts.map +1 -0
  118. package/dist/schema/index.d.ts +6 -0
  119. package/dist/schema/index.d.ts.map +1 -1
  120. package/dist/schema/table.gen.d.ts +13 -0
  121. package/dist/schema/table.gen.d.ts.map +1 -1
  122. package/dist/schema-validate.d.ts +9 -0
  123. package/dist/schema-validate.d.ts.map +1 -1
  124. package/dist/skill-defs.d.ts.map +1 -1
  125. package/dist/skills/chant-grafana-operations.md +108 -0
  126. package/dist/skills/chant-grafana.md +5 -4
  127. package/dist/spec/schemas.d.ts +9 -7
  128. package/dist/spec/schemas.d.ts.map +1 -1
  129. package/dist/spec/schemas.gen.d.ts +3 -0
  130. package/dist/spec/schemas.gen.d.ts.map +1 -0
  131. package/dist/validate-alerting.d.ts.map +1 -1
  132. package/dist/validate-output.d.ts +15 -2
  133. package/dist/validate-output.d.ts.map +1 -1
  134. package/dist/validate.d.ts.map +1 -1
  135. package/dist/validation.d.ts +14 -0
  136. package/dist/validation.d.ts.map +1 -0
  137. package/dist/variables.d.ts +102 -5
  138. package/dist/variables.d.ts.map +1 -1
  139. package/package.json +2 -2
  140. package/src/annotations.ts +84 -0
  141. package/src/api/apply.test.ts +19 -1
  142. package/src/api/apply.ts +18 -8
  143. package/src/api/fake-grafana.ts +6 -2
  144. package/src/api/folders.ts +106 -32
  145. package/src/build.test.ts +142 -6
  146. package/src/build.ts +126 -24
  147. package/src/catalog.ts +20 -2
  148. package/src/codegen/docs.ts +13 -6
  149. package/src/codegen/generate.ts +27 -1
  150. package/src/composites/shared.ts +3 -2
  151. package/src/dashboard.ts +59 -14
  152. package/src/datasource-refs.ts +30 -6
  153. package/src/datasource-settings.test.ts +106 -0
  154. package/src/datasource-settings.ts +941 -0
  155. package/src/datasource.ts +71 -11
  156. package/src/deep-observe-hooks.ts +16 -1
  157. package/src/deep-observe.test.ts +47 -1
  158. package/src/deep-observe.ts +36 -13
  159. package/src/describe-resources.test.ts +16 -0
  160. package/src/describe-resources.ts +36 -1
  161. package/src/detect.ts +3 -3
  162. package/src/folder.ts +118 -0
  163. package/src/generated/lexicon-grafana.json +70 -0
  164. package/src/import/generated-types.e2e.test.ts +15 -3
  165. package/src/import/generator.ts +2 -1
  166. package/src/import/mappings.ts +98 -26
  167. package/src/import/model.ts +7 -0
  168. package/src/import/normalize.ts +32 -3
  169. package/src/import/parser.test.ts +97 -21
  170. package/src/import/parser.ts +169 -18
  171. package/src/import/roundtrip.test.ts +104 -9
  172. package/src/import/testdata/fixtures.ts +8 -0
  173. package/src/import/v2.ts +4 -3
  174. package/src/index.ts +122 -13
  175. package/src/init-templates.test.ts +74 -0
  176. package/src/init-templates.ts +349 -0
  177. package/src/lint/audit-catalog.ts +9 -1
  178. package/src/lint/post-synth/graf101.ts +2 -2
  179. package/src/lint/post-synth/graf104.ts +3 -3
  180. package/src/lint/post-synth/graf106.ts +3 -3
  181. package/src/lint/post-synth/graf110.ts +17 -0
  182. package/src/lint/post-synth/grafana-helpers.ts +13 -3
  183. package/src/lint/post-synth/index.ts +2 -0
  184. package/src/lint/post-synth/post-synth.test.ts +99 -2
  185. package/src/load-cost.test.ts +35 -0
  186. package/src/op/activities/grafana-apply.e2e.test.ts +14 -5
  187. package/src/op/activities/grafana-apply.test.ts +16 -2
  188. package/src/op/activities/grafana-apply.ts +29 -3
  189. package/src/op/activities/index.ts +1 -1
  190. package/src/ownership.ts +19 -0
  191. package/src/panels.test.ts +3 -1
  192. package/src/pin.ts +12 -0
  193. package/src/plugin.test.ts +9 -2
  194. package/src/plugin.ts +9 -0
  195. package/src/promql-check.ts +5 -1
  196. package/src/query-models.ts +94 -0
  197. package/src/query.test.ts +166 -0
  198. package/src/query.ts +177 -12
  199. package/src/schema/azuremonitor.gen.ts +381 -0
  200. package/src/schema/bigquery.gen.ts +110 -0
  201. package/src/schema/cloudwatch.gen.ts +423 -0
  202. package/src/schema/elasticsearch.gen.ts +508 -0
  203. package/src/schema/googlecloudmonitoring.gen.ts +330 -0
  204. package/src/schema/grafanapyroscope.gen.ts +66 -0
  205. package/src/schema/index.ts +6 -0
  206. package/src/schema/table.gen.ts +14 -0
  207. package/src/schema-validate.ts +58 -7
  208. package/src/skill-defs.ts +17 -0
  209. package/src/skills/chant-grafana-operations.md +108 -0
  210. package/src/skills/chant-grafana.md +5 -4
  211. package/src/spec/overlay/table.overlay.json +19 -0
  212. package/src/spec/schemas/azuremonitor.jsonschema.json +679 -0
  213. package/src/spec/schemas/bigquery.jsonschema.json +290 -0
  214. package/src/spec/schemas/cloudwatch.jsonschema.json +721 -0
  215. package/src/spec/schemas/elasticsearch.jsonschema.json +1695 -0
  216. package/src/spec/schemas/googlecloudmonitoring.jsonschema.json +488 -0
  217. package/src/spec/schemas/grafanapyroscope.jsonschema.json +93 -0
  218. package/src/spec/schemas.gen.ts +40 -0
  219. package/src/spec/schemas.ts +9 -7
  220. package/src/validate-alerting.ts +4 -2
  221. package/src/validate-output.ts +96 -4
  222. package/src/validate.ts +14 -0
  223. package/src/validation.ts +27 -0
  224. package/src/variables.ts +113 -6
@@ -2,14 +2,15 @@
2
2
  * Read the vendored Grafana schemas (`src/spec/schemas/*.jsonschema.json`), check
3
3
  * them against the digests in `GRAFANA_SCHEMA_PIN`, and apply the correction
4
4
  * overlay (`src/spec/overlay/`, see `./overlay.ts`) on top.
5
+ *
6
+ * This is the source side, for `npm run generate`, the lexicon's own
7
+ * validate step, the importer's tests and the fetch scripts: it reads files
8
+ * next to this module. Nothing a build or lint runs imports it. Validation
9
+ * reads the generated `./schemas.gen.ts`, which generate writes from
10
+ * {@link loadSchema}.
5
11
  */
6
12
  import { type SchemaName, type VendoredSchemaName } from "../pin.js";
7
- /**
8
- * Where the vendored files live: beside this module, under `src/`, so they
9
- * ship with the source the package runs from and GRAF107 can read them.
10
- * A function, not a module-scope constant, so edge bundles that import the
11
- * lexicon never evaluate a filesystem path at load.
12
- */
13
+ /** Where the vendored files live: beside this module, under `src/`. */
13
14
  export declare function schemasDir(): string;
14
15
  export declare function schemaPath(name: VendoredSchemaName): string;
15
16
  export declare function sha256(text: string | Buffer): string;
@@ -19,7 +20,8 @@ export declare function readSchemaText(name: VendoredSchemaName): string;
19
20
  export declare function loadVendoredSchema(name: VendoredSchemaName): Record<string, unknown>;
20
21
  /**
21
22
  * One schema as the lexicon uses it: the vendored file with its overlay
22
- * applied (cached per process). Types, GRAF107 and validation all read this.
23
+ * applied (cached per process). Generate writes the types and
24
+ * `./schemas.gen.ts` from this, so GRAF107 sees the same schema.
23
25
  */
24
26
  export declare function loadSchema(name: SchemaName): Record<string, unknown>;
25
27
  /** Vendored files whose digest does not match the pin, with what was found. */
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/spec/schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAA6C,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAG7G;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAE3D;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEpD;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAE/D;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEpF;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASpE;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQxG"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/spec/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAA6C,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAG7G,uEAAuE;AACvE,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAE3D;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEpD;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAE/D;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEpF;AAID;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASpE;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQxG"}
@@ -0,0 +1,3 @@
1
+ import type { SchemaName } from "../pin.js";
2
+ export declare const SCHEMA_JSON: Readonly<Record<SchemaName, string>>;
3
+ //# sourceMappingURL=schemas.gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.gen.d.ts","sourceRoot":"","sources":["../../src/spec/schemas.gen.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CA8B5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate-alerting.d.ts","sourceRoot":"","sources":["../src/validate-alerting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAKzD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpC,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAAsC,CAAC;AAe9F,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,IAAI,CAAC;IACZ,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,QAAQ,EAAE,CAUnE;AAYD,sCAAsC;AACtC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,CAwBtD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CA0C9E;AAaD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,aAAa,EAAE,CA6C/H;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAajK;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,aAAa,EAAE,CAO1H;AAqBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CAiEnF;AAaD,wGAAwG;AACxG,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAIxC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CA2EnF"}
1
+ {"version":3,"file":"validate-alerting.d.ts","sourceRoot":"","sources":["../src/validate-alerting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAKzD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpC,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAAsC,CAAC;AAe9F,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,IAAI,CAAC;IACZ,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,QAAQ,EAAE,CAUnE;AAYD,sCAAsC;AACtC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,CAwBtD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CA4C9E;AAaD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,aAAa,EAAE,CA6C/H;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAajK;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,aAAa,EAAE,CAO1H;AAqBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CAiEnF;AAaD,wGAAwG;AACxG,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAIxC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CA2EnF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The checks behind GRAF101-GRAF109, GRAF111-GRAF114 and GRAF115, as plain
2
+ * The checks behind GRAF101-GRAF110, GRAF111-GRAF114 and GRAF115, as plain
3
3
  * functions over built Grafana output: dashboard JSON documents, provisioned
4
4
  * datasources, dashboard providers and alerting provisioning files (the
5
5
  * alerting checks are in `validate-alerting.ts`). The
@@ -16,7 +16,7 @@
16
16
  import type { ExternalDatasourceRecord, ProvisionedDatasource } from "./build.js";
17
17
  import { variableReferences, type KnownDatasource } from "./datasource-refs.js";
18
18
  import { type AlertingDoc } from "./validate-alerting.js";
19
- export type GrafanaIssueCode = "GRAF101" | "GRAF102" | "GRAF103" | "GRAF104" | "GRAF105" | "GRAF106" | "GRAF107" | "GRAF108" | "GRAF109" | "GRAF111" | "GRAF112" | "GRAF113" | "GRAF114" | "GRAF115";
19
+ export type GrafanaIssueCode = "GRAF101" | "GRAF102" | "GRAF103" | "GRAF104" | "GRAF105" | "GRAF106" | "GRAF107" | "GRAF108" | "GRAF109" | "GRAF110" | "GRAF111" | "GRAF112" | "GRAF113" | "GRAF114" | "GRAF115";
20
20
  export interface GrafanaIssue {
21
21
  code: GrafanaIssueCode;
22
22
  severity: "error" | "warning";
@@ -39,6 +39,18 @@ export interface GrafanaArtifacts {
39
39
  providers?: Array<Record<string, unknown>>;
40
40
  /** Alerting provisioning files (rule groups, contact points, policies, mute timings, templates). */
41
41
  alerting?: AlertingDoc[];
42
+ /** The folders the build resolved (its index's `folders`): each level of each dashboard's folder path, and every `Folder`. */
43
+ folders?: Array<{
44
+ uid: string;
45
+ title: string;
46
+ path?: string;
47
+ parentUid?: string;
48
+ }>;
49
+ /** `deleteDatasources` entries of datasource provisioning files. */
50
+ deleteDatasources?: Array<{
51
+ name: string;
52
+ orgId?: number;
53
+ }>;
42
54
  }
43
55
  export type { AlertingDoc };
44
56
  export { variableReferences };
@@ -63,6 +75,7 @@ export declare function checkSchema(a: GrafanaArtifacts): GrafanaIssue[];
63
75
  * not parsed.
64
76
  */
65
77
  export declare function checkPromqlSyntax(a: GrafanaArtifacts): GrafanaIssue[];
78
+ export declare function checkRepeats(a: GrafanaArtifacts): GrafanaIssue[];
66
79
  /** Every unit a panel sets, with where: field defaults, `unit` overrides, heatmap axes and cells, and a legacy graph panel's y-axes. */
67
80
  export declare function panelUnits(panel: Json): Array<{
68
81
  where: string;
@@ -1 +1 @@
1
- {"version":3,"file":"validate-output.d.ts","sourceRoot":"","sources":["../src/validate-output.ts"],"names":[],"mappings":"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"}
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,UAoC1B,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,UAkD1B,CAAC;AAIF,wBAAsB,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CA2DxD"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@intentius/chant-lexicon-grafana/validation`: the GRAF101-GRAF115 checks
3
+ * as plain functions over built Grafana output, and the schema validation
4
+ * behind GRAF107, for code that checks dashboards without a build.
5
+ *
6
+ * These are not on the package root, so importing the lexicon to declare
7
+ * dashboards does not load them. `chant build` and `chant lint` run the same
8
+ * checks through the plugin's post-synth checks. ajv is loaded the first time
9
+ * a schema is checked, and the schemas come from a generated module rather
10
+ * than files, so this works bundled.
11
+ */
12
+ export { validateGrafanaOutput, issuesFor, knownDatasourcesOf, type GrafanaIssue, type GrafanaIssueCode, type GrafanaArtifacts, type DashboardDoc, } from "./validate-output.js";
13
+ export { validateDashboardSchema, validateExpressionSchema, schemaValidationUnavailable, type SchemaProblem, } from "./schema-validate.js";
14
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Dashboard variables (Grafana's "templating"): query, custom, interval,
3
- * datasource, constant and textbox.
3
+ * datasource, constant, textbox, ad hoc filters, group by and switch.
4
4
  *
5
5
  * A variable is declared on its own and listed in a dashboard's
6
6
  * `variables`. Queries reference it as `$name` or `${name}` in their
@@ -10,8 +10,10 @@
10
10
  */
11
11
  import type { Declarable } from "@intentius/chant/declarable";
12
12
  import type { DatasourceEntity, DatasourceRef, ExternalDatasourceEntity } from "./datasource.js";
13
- import type { VariableOption } from "./schema/dashboard.gen.js";
14
- export type VariableKind = "query" | "custom" | "interval" | "datasource" | "constant" | "textbox";
13
+ import type { AdHocFilter, VariableOption } from "./schema/dashboard.gen.js";
14
+ export type VariableKind = "query" | "custom" | "interval" | "datasource" | "constant" | "textbox" | "adhoc" | "groupby" | "switch";
15
+ /** The kinds Grafana can repeat a panel or row over: the ones that hold a list of values (`MultiValueVariable` in @grafana/scenes). */
16
+ export declare const MULTI_VALUE_KINDS: ReadonlySet<string>;
15
17
  /** Where the variable shows: with its label, without it, or not at all. */
16
18
  export type VariableHide = "label" | "valueOnly" | "hidden";
17
19
  interface CommonVariableProps {
@@ -33,10 +35,47 @@ interface MultiValueProps {
33
35
  }
34
36
  /** A variable anything can hold before its datasource is known: its own datasource ref or a datasource variable. */
35
37
  export type VariableDatasource = DatasourceEntity<any> | ExternalDatasourceEntity<any> | DatasourceRef | DatasourceVariableEntity<any>;
38
+ /**
39
+ * A variable query in the object form a datasource's variable editor
40
+ * writes. Grafana passes it to the datasource as it is, so any key the
41
+ * datasource reads may be here.
42
+ */
43
+ export interface VariableQueryObject {
44
+ /** The query text, when the datasource has one (Prometheus, Loki, and most others). */
45
+ query?: string;
46
+ /** The editor's id for the query; Grafana writes e.g. `PrometheusVariableQueryEditor-VariableQuery`. */
47
+ refId?: string;
48
+ [key: string]: unknown;
49
+ }
50
+ /**
51
+ * A Prometheus variable query as Grafana's Prometheus variable editor
52
+ * writes it. `query` is the text Grafana runs (`label_values(up, job)`);
53
+ * the other fields let the editor show the query in its form again.
54
+ */
55
+ export interface PrometheusVariableQuery extends VariableQueryObject {
56
+ query: string;
57
+ /** The editor's query type: 0 label names, 1 label values, 2 metrics, 3 query result, 4 series query, 5 classic query. */
58
+ qryType?: 0 | 1 | 2 | 3 | 4 | 5;
59
+ label?: string;
60
+ metric?: string;
61
+ seriesQuery?: string;
62
+ varQueryResult?: string;
63
+ labelFilters?: Array<{
64
+ label: string;
65
+ op: string;
66
+ value: string;
67
+ }>;
68
+ }
36
69
  export interface QueryVariableProps extends CommonVariableProps, MultiValueProps {
37
70
  datasource: VariableDatasource;
38
- /** The datasource's variable query, e.g. `label_values(up, job)` for Prometheus. */
39
- query: string;
71
+ /**
72
+ * The datasource's variable query: a string (`label_values(up, job)` for
73
+ * Prometheus), or the object the datasource's variable editor writes
74
+ * (`{ query: "label_values(up, job)", qryType: 1 }`).
75
+ */
76
+ query: string | VariableQueryObject;
77
+ /** The text Grafana shows for the query in the variable list. Defaults to the query string. */
78
+ definition?: string;
40
79
  regex?: string;
41
80
  /** When to re-run the query. Defaults to on dashboard load. */
42
81
  refresh?: "never" | "onLoad" | "onTimeRangeChange";
@@ -70,6 +109,49 @@ export interface ConstantVariableProps extends Omit<CommonVariableProps, "hide">
70
109
  export interface TextboxVariableProps extends CommonVariableProps {
71
110
  value?: string;
72
111
  }
112
+ /** One ad hoc filter: `key operator value`, e.g. `{ key: "namespace", operator: "=", value: "shop" }`. */
113
+ export type AdhocFilter = AdHocFilter;
114
+ /** A key an ad hoc or group by variable offers, in place of asking the datasource. */
115
+ export interface VariableKeyOption {
116
+ text: string;
117
+ value?: string | number;
118
+ [key: string]: unknown;
119
+ }
120
+ export interface AdhocVariableProps extends CommonVariableProps {
121
+ /** The datasource whose queries get the filters, and which is asked for keys and values. */
122
+ datasource: VariableDatasource;
123
+ /** The filters applied when the dashboard loads. */
124
+ filters?: AdhocFilter[];
125
+ /** Filters that narrow the key and value lookups, not shown or applied to queries. */
126
+ baseFilters?: AdhocFilter[];
127
+ /** A fixed set of keys to offer instead of the datasource's. */
128
+ defaultKeys?: VariableKeyOption[];
129
+ /** Whether a key or value not in the list can be typed in. Grafana's default is true. */
130
+ allowCustomValue?: boolean;
131
+ /** Offer the group-by operator in the filter box (Grafana 13, behind the `dashboardUnifiedDrilldownControls` feature toggle). */
132
+ enableGroupBy?: boolean;
133
+ }
134
+ export interface GroupByVariableProps extends CommonVariableProps {
135
+ /** The datasource whose queries are grouped, and which is asked for the keys. */
136
+ datasource: VariableDatasource;
137
+ /** A fixed set of keys to offer instead of the datasource's: a key, or `{ text, value }`. */
138
+ options?: Array<string | {
139
+ text: string;
140
+ value: string;
141
+ }>;
142
+ /** The keys selected when the dashboard loads with none in the URL. */
143
+ defaultValue?: string[] | VariableOption;
144
+ /** Whether a key not in the list can be typed in. Grafana's default is true. */
145
+ allowCustomValue?: boolean;
146
+ }
147
+ export interface SwitchVariableProps extends Omit<CommonVariableProps, "current"> {
148
+ /** Whether the switch is on when the dashboard loads. Defaults to off. */
149
+ enabled?: boolean;
150
+ /** The value `$name` has when the switch is on. Defaults to `"true"`. */
151
+ enabledValue?: string;
152
+ /** The value `$name` has when the switch is off. Defaults to `"false"`. */
153
+ disabledValue?: string;
154
+ }
73
155
  export interface VariableEntity<P = CommonVariableProps> extends Declarable {
74
156
  readonly props: P;
75
157
  readonly variableKind: VariableKind;
@@ -95,6 +177,21 @@ export declare const DatasourceVariable: {
95
177
  export declare const ConstantVariable: new (props: ConstantVariableProps) => VariableEntity<ConstantVariableProps>;
96
178
  /** A free-text box. */
97
179
  export declare const TextboxVariable: new (props: TextboxVariableProps) => VariableEntity<TextboxVariableProps>;
180
+ /**
181
+ * Ad hoc filters: `key operator value` filters Grafana adds to every query
182
+ * sent to the variable's datasource (Prometheus, Loki, Elasticsearch,
183
+ * InfluxDB and others whose plugin supports them). Referenced by no query.
184
+ */
185
+ export declare const AdhocVariable: new (props: AdhocVariableProps) => VariableEntity<AdhocVariableProps>;
186
+ /**
187
+ * Group by: a choice of label keys Grafana adds as a grouping to every query
188
+ * sent to the variable's datasource. In Grafana 12.4 and 13.x it is
189
+ * experimental: with the `groupByVariable` feature toggle off, Grafana
190
+ * drops it when the dashboard loads.
191
+ */
192
+ export declare const GroupByVariable: new (props: GroupByVariableProps) => VariableEntity<GroupByVariableProps>;
193
+ /** An on/off switch, `$name` being `enabledValue` or `disabledValue`. New in Grafana 12.3. */
194
+ export declare const SwitchVariable: new (props: SwitchVariableProps) => VariableEntity<SwitchVariableProps>;
98
195
  export declare function isVariableEntity(value: unknown): value is VariableEntity;
99
196
  export declare function isDatasourceVariable(value: unknown): value is DatasourceVariableEntity;
100
197
  /** Variable names Grafana defines itself; queries may use them without declaring anything. */
@@ -1 +1 @@
1
- {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAC9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAEnG,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE5D,UAAU,mBAAmB;IAC3B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,qCAAqC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mDAAmD;IACnD,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,oHAAoH;AAEpH,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,wBAAwB,CAAC,GAAG,CAAC,GAAG,aAAa,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;AAEvI,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB,EAAE,eAAe;IAC9E,UAAU,EAAE,kBAAkB,CAAC;IAC/B,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,mBAAmB,CAAC;IACnD,6FAA6F;IAC7F,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB,EAAE,eAAe;IAC/E;;;;OAIG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,iCAAiC;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,mBAAmB,EAAE,eAAe;IAC9G,mEAAmE;IACnE,UAAU,EAAE,CAAC,CAAC;IACd,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC;IAC9E,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,mBAAmB,CAAE,SAAQ,UAAU;IACzE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,6CAA6C;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,cAAc,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;IACrH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;CACxB;AAED,eAAO,MAAM,oBAAoB,wBAAwB,CAAC;AAgB1D,4DAA4D;AAC5D,eAAO,MAAM,aAAa,EAA6E,KACrG,KAAK,EAAE,kBAAkB,KACtB,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAExC,8CAA8C;AAC9C,eAAO,MAAM,cAAc,EAAgF,KACzG,KAAK,EAAE,mBAAmB,KACvB,cAAc,CAAC,mBAAmB,CAAC,CAAC;AAEzC,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,EAAsF,KACjH,KAAK,EAAE,qBAAqB,KACzB,cAAc,CAAC,qBAAqB,CAAC,CAAC;AAE3C,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,EAA4F;IACzH,KAAK,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAC;CACxF,CAAC;AAEF,6BAA6B;AAC7B,eAAO,MAAM,gBAAgB,EAAsF,KACjH,KAAK,EAAE,qBAAqB,KACzB,cAAc,CAAC,qBAAqB,CAAC,CAAC;AAE3C,uBAAuB;AACvB,eAAO,MAAM,eAAe,EAAmF,KAC7G,KAAK,EAAE,oBAAoB,KACxB,cAAc,CAAC,oBAAoB,CAAC,CAAC;AAE1C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAQxE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAEtF;AAED,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,qDAAqD;AACrD,eAAO,MAAM,aAAa,QAA6B,CAAC"}
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.99.0",
3
+ "version": "0.100.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",
@@ -80,7 +80,7 @@
80
80
  "zod": "^4.3.6"
81
81
  },
82
82
  "peerDependencies": {
83
- "@intentius/chant": "^0.99.0",
83
+ "@intentius/chant": "^0.100.0",
84
84
  "typescript": "^5.9.3",
85
85
  "zod": "^4.3.6"
86
86
  }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Dashboard annotations: the queries in a dashboard's `annotations.list`
3
+ * whose events Grafana draws on time series panels (deploy markers,
4
+ * incidents, alert state changes).
5
+ *
6
+ * An annotation is plain data on `Dashboard.annotations`, typed from
7
+ * Grafana's `AnnotationQuery`, except that its `datasource` takes the same
8
+ * values a panel's does (a `Datasource`, an `ExternalDatasource`, a
9
+ * `DatasourceVariable` or a `{ type, uid }` ref) and its `target` may be a
10
+ * query entity (`new PromQuery({ expr })`). What a datasource plugin keeps
11
+ * beside the common keys (Prometheus's legacy `expr`, `step`,
12
+ * `titleFormat`) is written as given.
13
+ *
14
+ * Grafana adds its built-in "Annotations & Alerts" query (`builtIn: 1`, the
15
+ * `-- Grafana --` datasource) to any dashboard without one, so a dashboard
16
+ * leaves it out unless it changes it (hides the toggle, turns it off).
17
+ */
18
+
19
+ import type { AnnotationEventFieldMapping, AnnotationPanelFilter, AnnotationQuery, AnnotationQueryPlacement, DataSourceRef } from "./schema/dashboard.gen";
20
+ import { isQueryEntity, type DatasourceInput, type QueryEntity } from "./query";
21
+ import { compact } from "./util";
22
+
23
+ /** One annotation query on a dashboard. */
24
+ export interface AnnotationInput {
25
+ /** The name shown on its toggle, unique on the dashboard. */
26
+ name: string;
27
+ /** Where its events come from. Leave it out for Grafana's default datasource. */
28
+ datasource?: DatasourceInput;
29
+ /** Whether it runs when the dashboard loads. Defaults to true. */
30
+ enable?: boolean;
31
+ /** Hide its toggle in the dashboard's controls. */
32
+ hide?: boolean;
33
+ /** The colour of its markers. Defaults to `red`, as Grafana's editor does. */
34
+ iconColor?: string;
35
+ /** Only draw its events on these panels, or on every panel but these. */
36
+ filter?: AnnotationPanelFilter;
37
+ /** The query, in the datasource plugin's own shape, or a query entity of that plugin. */
38
+ target?: Record<string, unknown> | QueryEntity;
39
+ /** For the `-- Grafana --` datasource: `dashboard` or `tags`. */
40
+ type?: string;
41
+ /** 1 for Grafana's own "Annotations & Alerts" query. */
42
+ builtIn?: number;
43
+ placement?: AnnotationQueryPlacement;
44
+ /** Prometheus's legacy query fields, kept beside `target` by dashboards saved before Grafana 10. */
45
+ expr?: string;
46
+ textFormat?: string;
47
+ titleFormat?: string;
48
+ tagKeys?: string;
49
+ step?: string;
50
+ useValueForTime?: boolean;
51
+ /** How the fields of the query's result become an event's time, text and tags. */
52
+ mappings?: Record<string, AnnotationEventFieldMapping>;
53
+ /** Anything else a datasource plugin reads from its annotation query. */
54
+ [key: string]: unknown;
55
+ }
56
+
57
+ /** The refId Grafana gives an annotation query's target. */
58
+ export const ANNOTATION_REF_ID = "Anno";
59
+
60
+ /**
61
+ * One annotation as the entry Grafana stores in `annotations.list`.
62
+ * `datasourceRef` resolves the datasource the same way a panel's is (it is
63
+ * build.ts's, passed in so this module needs nothing from the build).
64
+ */
65
+ export function annotationJson(input: AnnotationInput, datasourceRef: (d: DatasourceInput | undefined) => DataSourceRef | undefined): AnnotationQuery {
66
+ const { name, datasource, enable, iconColor, target, ...rest } = input;
67
+ let ds = datasourceRef(datasource);
68
+ let targetJson: Record<string, unknown> | undefined;
69
+ if (isQueryEntity(target)) {
70
+ const { datasource: queryDs, ...model } = target.props as Record<string, unknown> & { datasource?: DatasourceInput };
71
+ ds ??= datasourceRef(queryDs);
72
+ targetJson = compact({ refId: ANNOTATION_REF_ID, ...(target.queryDefinition.defaults ?? {}), ...model });
73
+ } else {
74
+ targetJson = target;
75
+ }
76
+ return compact({
77
+ ...(ds ? { datasource: ds } : {}),
78
+ enable: enable ?? true,
79
+ iconColor: iconColor ?? "red",
80
+ name,
81
+ ...rest,
82
+ ...(targetJson !== undefined ? { target: targetJson } : {}),
83
+ }) as AnnotationQuery;
84
+ }
@@ -31,13 +31,31 @@ describe("planFromDashboards", () => {
31
31
  { json: dashboard("b", { __elements: { burn: LIB } }), folder: "Team A" },
32
32
  { json: dashboard("c") },
33
33
  ]);
34
- expect(plan.folders).toEqual([{ uid: "team-a", title: "Team A" }]);
34
+ expect(plan.folders).toEqual([{ uid: "team-a", title: "Team A", path: "Team A" }]);
35
35
  expect(plan.libraryPanels).toEqual([{ uid: "burn", name: "Shared burn", model: LIB.model, folderUid: "team-a" }]);
36
36
  expect(plan.dashboards.map((d) => [d.uid, d.folderUid])).toEqual([["a", "team-a"], ["b", "team-a"], ["c", undefined]]);
37
37
  expect(Object.keys(plan.dashboards[0].json)).not.toEqual(expect.arrayContaining(["__elements"]));
38
38
  expect(planRefs(plan).map((r) => `${r.kind}/${r.name}`)).toEqual(["Folder/team-a", "LibraryPanel/burn", "Dashboard/a", "Dashboard/b", "Dashboard/c"]);
39
39
  });
40
40
 
41
+ test("a nested path is a folder per level, parents first; the build's folders pin uids (#2953)", () => {
42
+ const plan = planFromDashboards(
43
+ [
44
+ { json: dashboard("a"), folder: "Platform/Kubernetes" },
45
+ { json: dashboard("b"), folder: "Platform/Kubernetes/Nodes", folderUid: "nodes" },
46
+ ],
47
+ [{ uid: "plat", title: "Platform", path: "Platform" }, { uid: "empty", title: "Empty", path: "Empty" }],
48
+ );
49
+ expect(plan.folders).toEqual([
50
+ { uid: "empty", title: "Empty", path: "Empty" },
51
+ { uid: "plat", title: "Platform", path: "Platform" },
52
+ { uid: "platform-kubernetes", title: "Kubernetes", parentUid: "plat", path: "Platform/Kubernetes" },
53
+ { uid: "nodes", title: "Nodes", parentUid: "platform-kubernetes", path: "Platform/Kubernetes/Nodes" },
54
+ ]);
55
+ expect(plan.dashboards.map((d) => [d.uid, d.folderUid])).toEqual([["a", "platform-kubernetes"], ["b", "nodes"]]);
56
+ expect(() => planFromDashboards([{ json: dashboard("a"), folder: "X", folderUid: "one" }], [{ uid: "two", title: "X", path: "X" }])).toThrow(/declared with the uids/);
57
+ });
58
+
41
59
  test("a library variable in __elements is reported unsupported, not dropped", () => {
42
60
  const plan = planFromDashboards([{ json: dashboard("a", { __elements: { v: { uid: "v", name: "v", kind: 2, model: {} } } }) }]);
43
61
  expect(plan.unsupported).toEqual([expect.objectContaining({ kind: "LibraryElement", name: "v" })]);
package/src/api/apply.ts CHANGED
@@ -51,8 +51,8 @@ import {
51
51
  ensureFolder,
52
52
  folderApi,
53
53
  folderContentCount,
54
- foldersForDashboards,
55
54
  listFolders,
55
+ resolveFolders,
56
56
  send,
57
57
  type FolderPlan,
58
58
  } from "./folders";
@@ -92,10 +92,11 @@ export interface GrafanaApplyPlan {
92
92
  readonly unsupported: Array<{ kind: string; name: string; detail: string }>;
93
93
  }
94
94
 
95
- /** A dashboard as the build hands it over: its JSON and the folder title it names. */
95
+ /** A dashboard as the build hands it over: its JSON, the folder path it names, and that folder's uid when the build resolved it. */
96
96
  export interface BuiltDashboardInput {
97
97
  readonly json: Json;
98
98
  readonly folder?: string;
99
+ readonly folderUid?: string;
99
100
  }
100
101
 
101
102
  function sameJson(a: unknown, b: unknown): boolean {
@@ -103,14 +104,23 @@ function sameJson(a: unknown, b: unknown): boolean {
103
104
  }
104
105
 
105
106
  /**
106
- * Turn built dashboards into an apply plan: the folders they name, the
107
+ * Turn built dashboards into an apply plan: the folders they name (each
108
+ * level of a path, with its parent) and the build's own `folders` (its
109
+ * index lists every one, `Folder`s holding no dashboard included), the
107
110
  * library panels their `__elements` carry, and the dashboards themselves.
108
111
  * Throws on a plan no apply could satisfy: a dashboard with no uid, two
109
- * dashboards with one uid, or one library panel uid with two models.
112
+ * dashboards with one uid, two folders with one uid, or one library panel
113
+ * uid with two models.
110
114
  */
111
- export function planFromDashboards(dashboards: readonly BuiltDashboardInput[]): GrafanaApplyPlan {
112
- const folders = foldersForDashboards(dashboards);
113
- const folderUid = new Map(folders.map((f) => [f.title, f.uid]));
115
+ export function planFromDashboards(dashboards: readonly BuiltDashboardInput[], declaredFolders: readonly FolderPlan[] = []): GrafanaApplyPlan {
116
+ const resolved = resolveFolders({
117
+ declared: [
118
+ ...declaredFolders.flatMap((f) => (f.path ? [{ uid: f.uid, path: f.path }] : [])),
119
+ ...dashboards.flatMap((d) => (d.folder && d.folderUid ? [{ uid: d.folderUid, path: d.folder }] : [])),
120
+ ],
121
+ paths: dashboards.map((d) => d.folder),
122
+ });
123
+ const folders = resolved.folders;
114
124
  const libraryPanels = new Map<string, LibraryPanelPlan>();
115
125
  const unsupported: GrafanaApplyPlan["unsupported"] = [];
116
126
  const out: DashboardPlan[] = [];
@@ -120,7 +130,7 @@ export function planFromDashboards(dashboards: readonly BuiltDashboardInput[]):
120
130
  if (typeof uid !== "string" || uid === "") throw new Error(`grafana apply: dashboard "${String(d.json.title ?? "?")}" has no uid`);
121
131
  if (seen.has(uid)) throw new Error(`grafana apply: two dashboards have the uid "${uid}"`);
122
132
  seen.add(uid);
123
- const inFolder = d.folder ? folderUid.get(d.folder) : undefined;
133
+ const inFolder = d.folderUid ?? resolved.uidOf(d.folder);
124
134
  const { panels, skipped } = libraryPanelsOf(d.json, inFolder);
125
135
  for (const p of panels) {
126
136
  const prior = libraryPanels.get(p.uid);
@@ -35,6 +35,8 @@ export interface FakeGrafanaState {
35
35
  dashboards: Record<string, FakeDashboard>;
36
36
  datasources?: Record<string, Json>;
37
37
  folders?: Record<string, string>;
38
+ /** A folder's parent uid, by folder uid, for nested folders. */
39
+ folderParents?: Record<string, string>;
38
40
  /** Answer every request with this status (a refused token: 401). */
39
41
  status?: number;
40
42
  namespace?: string;
@@ -147,8 +149,10 @@ export function fakeGrafana(state: FakeGrafanaState, calls: string[] = []): Graf
147
149
  }
148
150
  const folder = /^\/api\/folders\/([^/]+)$/.exec(route);
149
151
  if (folder) {
150
- const title = state.folders?.[decodeURIComponent(folder[1])];
151
- return title ? ok({ uid: folder[1], title }) : notFound;
152
+ const uid = decodeURIComponent(folder[1]);
153
+ const title = state.folders?.[uid];
154
+ const parentUid = state.folderParents?.[uid];
155
+ return title ? ok({ uid, title, ...(parentUid ? { parentUid } : {}) }) : notFound;
152
156
  }
153
157
  if (route === "/api/datasources") return ok(Object.values(state.datasources ?? {}).map(({ secureJsonFields: _s, ...rest }) => rest));
154
158
  const ds = /^\/api\/datasources\/uid\/([^/]+)$/.exec(route);