@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.
- package/README.md +24 -8
- package/dist/actions/grafana.d.ts +24 -0
- package/dist/actions/grafana.d.ts.map +1 -0
- package/dist/actions/index.d.ts +2 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/alerting-build.d.ts +128 -0
- package/dist/alerting-build.d.ts.map +1 -0
- package/dist/alerting.d.ts +273 -0
- package/dist/alerting.d.ts.map +1 -0
- package/dist/annotations.d.ts +61 -0
- package/dist/annotations.d.ts.map +1 -0
- package/dist/api/apply.d.ts +160 -0
- package/dist/api/apply.d.ts.map +1 -0
- package/dist/api/bind.d.ts +32 -0
- package/dist/api/bind.d.ts.map +1 -0
- package/dist/api/client.d.ts +76 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/converge.d.ts +33 -0
- package/dist/api/converge.d.ts.map +1 -0
- package/dist/api/dashboards.d.ts +102 -0
- package/dist/api/dashboards.d.ts.map +1 -0
- package/dist/api/datasources.d.ts +26 -0
- package/dist/api/datasources.d.ts.map +1 -0
- package/dist/api/fake-grafana-writes.d.ts +41 -0
- package/dist/api/fake-grafana-writes.d.ts.map +1 -0
- package/dist/api/fake-grafana.d.ts +63 -0
- package/dist/api/fake-grafana.d.ts.map +1 -0
- package/dist/api/folders.d.ts +146 -0
- package/dist/api/folders.d.ts.map +1 -0
- package/dist/api/library-panels.d.ts +52 -0
- package/dist/api/library-panels.d.ts.map +1 -0
- package/dist/build.d.ts +55 -6
- package/dist/build.d.ts.map +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/generate.d.ts +7 -1
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/schema-types.d.ts +3 -3
- package/dist/codegen/schema-types.d.ts.map +1 -1
- package/dist/composites/agent-dashboard.d.ts.map +1 -1
- package/dist/composites/catalog.d.ts.map +1 -1
- package/dist/composites/index.d.ts +4 -2
- package/dist/composites/index.d.ts.map +1 -1
- package/dist/composites/red-dashboard.d.ts +21 -2
- package/dist/composites/red-dashboard.d.ts.map +1 -1
- package/dist/composites/shared.d.ts +11 -3
- package/dist/composites/shared.d.ts.map +1 -1
- package/dist/composites/slo-alert-rules.d.ts +92 -0
- package/dist/composites/slo-alert-rules.d.ts.map +1 -0
- package/dist/config.d.ts +111 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/contact-point-secrets.d.ts +17 -0
- package/dist/contact-point-secrets.d.ts.map +1 -0
- package/dist/dashboard.d.ts +51 -9
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/datasource-refs.d.ts +99 -0
- package/dist/datasource-refs.d.ts.map +1 -0
- package/dist/datasource-settings.d.ts +834 -0
- package/dist/datasource-settings.d.ts.map +1 -0
- package/dist/datasource.d.ts +82 -11
- package/dist/datasource.d.ts.map +1 -1
- package/dist/deep-observe-hooks.d.ts +64 -0
- package/dist/deep-observe-hooks.d.ts.map +1 -0
- package/dist/deep-observe.d.ts +47 -0
- package/dist/deep-observe.d.ts.map +1 -0
- package/dist/describe-resources.d.ts +50 -0
- package/dist/describe-resources.d.ts.map +1 -0
- package/dist/detect.d.ts +32 -3
- package/dist/detect.d.ts.map +1 -1
- package/dist/export-resources.d.ts +38 -0
- package/dist/export-resources.d.ts.map +1 -0
- package/dist/folder.d.ts +68 -0
- package/dist/folder.d.ts.map +1 -0
- package/dist/import/alerting.d.ts +40 -0
- package/dist/import/alerting.d.ts.map +1 -0
- package/dist/import/edits.d.ts +47 -0
- package/dist/import/edits.d.ts.map +1 -0
- package/dist/import/embedded.d.ts +14 -0
- package/dist/import/embedded.d.ts.map +1 -0
- package/dist/import/generator.d.ts +60 -0
- package/dist/import/generator.d.ts.map +1 -0
- package/dist/import/live-export.d.ts +108 -0
- package/dist/import/live-export.d.ts.map +1 -0
- package/dist/import/mappings.d.ts +89 -0
- package/dist/import/mappings.d.ts.map +1 -0
- package/dist/import/model.d.ts +105 -0
- package/dist/import/model.d.ts.map +1 -0
- package/dist/import/normalize-alerting.d.ts +26 -0
- package/dist/import/normalize-alerting.d.ts.map +1 -0
- package/dist/import/normalize.d.ts +74 -0
- package/dist/import/normalize.d.ts.map +1 -0
- package/dist/import/parser.d.ts +125 -0
- package/dist/import/parser.d.ts.map +1 -0
- package/dist/import/report.d.ts +26 -0
- package/dist/import/report.d.ts.map +1 -0
- package/dist/import/testdata/fixtures.d.ts +41 -0
- package/dist/import/testdata/fixtures.d.ts.map +1 -0
- package/dist/import/v2.d.ts +73 -0
- package/dist/import/v2.d.ts.map +1 -0
- package/dist/index.d.ts +31 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/init-templates.d.ts +27 -0
- package/dist/init-templates.d.ts.map +1 -0
- package/dist/integrity.json +22 -12
- package/dist/k8s.d.ts +107 -0
- package/dist/k8s.d.ts.map +1 -0
- package/dist/lint/audit-catalog.d.ts +2 -1
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/post-synth/graf101.d.ts +2 -2
- package/dist/lint/post-synth/graf102.d.ts +1 -1
- package/dist/lint/post-synth/graf104.d.ts +2 -2
- package/dist/lint/post-synth/graf106.d.ts +2 -2
- package/dist/lint/post-synth/graf107.d.ts +1 -1
- package/dist/lint/post-synth/graf108.d.ts +8 -0
- package/dist/lint/post-synth/graf108.d.ts.map +1 -0
- package/dist/lint/post-synth/graf109.d.ts +8 -0
- package/dist/lint/post-synth/graf109.d.ts.map +1 -0
- package/dist/lint/post-synth/graf110.d.ts +8 -0
- package/dist/lint/post-synth/graf110.d.ts.map +1 -0
- package/dist/lint/post-synth/graf111.d.ts +8 -0
- package/dist/lint/post-synth/graf111.d.ts.map +1 -0
- package/dist/lint/post-synth/graf112.d.ts +8 -0
- package/dist/lint/post-synth/graf112.d.ts.map +1 -0
- package/dist/lint/post-synth/graf113.d.ts +8 -0
- package/dist/lint/post-synth/graf113.d.ts.map +1 -0
- package/dist/lint/post-synth/graf114.d.ts +8 -0
- package/dist/lint/post-synth/graf114.d.ts.map +1 -0
- package/dist/lint/post-synth/graf115.d.ts +8 -0
- package/dist/lint/post-synth/graf115.d.ts.map +1 -0
- package/dist/lint/post-synth/grafana-helpers.d.ts +7 -5
- package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/rules/literal-secret.d.ts +7 -3
- package/dist/lint/rules/literal-secret.d.ts.map +1 -1
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/members.d.ts +27 -0
- package/dist/members.d.ts.map +1 -0
- package/dist/meta.json +205 -0
- package/dist/okf/index.md +53 -4
- package/dist/okf/rules/GRAF002.md +3 -2
- package/dist/okf/rules/GRAF101.md +3 -2
- package/dist/okf/rules/GRAF102.md +1 -0
- package/dist/okf/rules/GRAF104.md +2 -2
- package/dist/okf/rules/GRAF106.md +2 -2
- package/dist/okf/rules/GRAF108.md +11 -0
- package/dist/okf/rules/GRAF109.md +15 -0
- package/dist/okf/rules/GRAF110.md +11 -0
- package/dist/okf/rules/GRAF111.md +11 -0
- package/dist/okf/rules/GRAF112.md +16 -0
- package/dist/okf/rules/GRAF113.md +16 -0
- package/dist/okf/rules/GRAF114.md +11 -0
- package/dist/okf/rules/GRAF115.md +11 -0
- package/dist/okf/types/AdhocVariable.md +9 -0
- package/dist/okf/types/AlertListPanel.md +9 -0
- package/dist/okf/types/AlertQuery.md +9 -0
- package/dist/okf/types/AlertRule.md +9 -0
- package/dist/okf/types/AlertRuleGroup.md +9 -0
- package/dist/okf/types/AzureMonitorQuery.md +9 -0
- package/dist/okf/types/BarChartPanel.md +9 -0
- package/dist/okf/types/BarGaugePanel.md +9 -0
- package/dist/okf/types/BigQueryQuery.md +9 -0
- package/dist/okf/types/CanvasPanel.md +9 -0
- package/dist/okf/types/ClassicConditionsExpression.md +9 -0
- package/dist/okf/types/CloudMonitoringQuery.md +9 -0
- package/dist/okf/types/CloudWatchQuery.md +9 -0
- package/dist/okf/types/ContactPoint.md +14 -0
- package/dist/okf/types/Dashboard.md +2 -1
- package/dist/okf/types/Datasource.md +3 -2
- package/dist/okf/types/DatasourceProvisioning.md +9 -0
- package/dist/okf/types/ElasticsearchQuery.md +9 -0
- package/dist/okf/types/ExternalDatasource.md +15 -0
- package/dist/okf/types/FlameGraphPanel.md +9 -0
- package/dist/okf/types/Folder.md +9 -0
- package/dist/okf/types/GeomapPanel.md +9 -0
- package/dist/okf/types/GroupByVariable.md +9 -0
- package/dist/okf/types/HistogramPanel.md +9 -0
- package/dist/okf/types/MSSQLQuery.md +9 -0
- package/dist/okf/types/MathExpression.md +9 -0
- package/dist/okf/types/MuteTiming.md +13 -0
- package/dist/okf/types/MySQLQuery.md +9 -0
- package/dist/okf/types/NodeGraphPanel.md +9 -0
- package/dist/okf/types/NotificationPolicy.md +9 -0
- package/dist/okf/types/NotificationTemplate.md +9 -0
- package/dist/okf/types/PieChartPanel.md +9 -0
- package/dist/okf/types/PostgresQuery.md +9 -0
- package/dist/okf/types/PyroscopeQuery.md +9 -0
- package/dist/okf/types/ReduceExpression.md +9 -0
- package/dist/okf/types/ResampleExpression.md +9 -0
- package/dist/okf/types/SqlExpression.md +9 -0
- package/dist/okf/types/StateTimelinePanel.md +9 -0
- package/dist/okf/types/StatusHistoryPanel.md +9 -0
- package/dist/okf/types/SwitchVariable.md +9 -0
- package/dist/okf/types/ThresholdExpression.md +9 -0
- package/dist/okf/types/TrendPanel.md +9 -0
- package/dist/okf/types/XYChartPanel.md +9 -0
- package/dist/op/activities/grafana-apply.d.ts +86 -0
- package/dist/op/activities/grafana-apply.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +9 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/builders.d.ts +24 -0
- package/dist/op/builders.d.ts.map +1 -0
- package/dist/ownership.d.ts +78 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/panel-options.d.ts +65 -0
- package/dist/panel-options.d.ts.map +1 -0
- package/dist/panels.d.ts +46 -9
- package/dist/panels.d.ts.map +1 -1
- package/dist/pin.d.ts +29 -7
- package/dist/pin.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/promql-check.d.ts +51 -0
- package/dist/promql-check.d.ts.map +1 -0
- package/dist/query-models.d.ts +95 -0
- package/dist/query-models.d.ts.map +1 -0
- package/dist/query.d.ts +116 -18
- package/dist/query.d.ts.map +1 -1
- package/dist/rules/graf101.ts +3 -3
- package/dist/rules/graf102.ts +1 -1
- package/dist/rules/graf104.ts +3 -3
- package/dist/rules/graf106.ts +3 -3
- package/dist/rules/graf107.ts +1 -1
- package/dist/rules/graf108.ts +17 -0
- package/dist/rules/graf109.ts +17 -0
- package/dist/rules/graf110.ts +17 -0
- package/dist/rules/graf111.ts +17 -0
- package/dist/rules/graf112.ts +17 -0
- package/dist/rules/graf113.ts +17 -0
- package/dist/rules/graf114.ts +17 -0
- package/dist/rules/graf115.ts +17 -0
- package/dist/rules/grafana-helpers.ts +27 -10
- package/dist/rules/literal-secret.ts +60 -6
- package/dist/schema/azuremonitor.gen.d.ts +354 -0
- package/dist/schema/azuremonitor.gen.d.ts.map +1 -0
- package/dist/schema/barchart.gen.d.ts +198 -0
- package/dist/schema/barchart.gen.d.ts.map +1 -0
- package/dist/schema/bargauge.gen.d.ts +97 -0
- package/dist/schema/bargauge.gen.d.ts.map +1 -0
- package/dist/schema/bigquery.gen.d.ts +93 -0
- package/dist/schema/bigquery.gen.d.ts.map +1 -0
- package/dist/schema/canvas.gen.d.ts +152 -0
- package/dist/schema/canvas.gen.d.ts.map +1 -0
- package/dist/schema/cloudwatch.gen.d.ts +394 -0
- package/dist/schema/cloudwatch.gen.d.ts.map +1 -0
- package/dist/schema/dashboard.gen.d.ts +196 -21
- package/dist/schema/dashboard.gen.d.ts.map +1 -1
- package/dist/schema/elasticsearch.gen.d.ts +444 -0
- package/dist/schema/elasticsearch.gen.d.ts.map +1 -0
- package/dist/schema/expr.gen.d.ts +606 -0
- package/dist/schema/expr.gen.d.ts.map +1 -0
- package/dist/schema/gauge.gen.d.ts.map +1 -1
- package/dist/schema/geomap.gen.d.ts +100 -0
- package/dist/schema/geomap.gen.d.ts.map +1 -0
- package/dist/schema/googlecloudmonitoring.gen.d.ts +312 -0
- package/dist/schema/googlecloudmonitoring.gen.d.ts.map +1 -0
- package/dist/schema/grafanapyroscope.gen.d.ts +60 -0
- package/dist/schema/grafanapyroscope.gen.d.ts.map +1 -0
- package/dist/schema/heatmap.gen.d.ts.map +1 -1
- package/dist/schema/histogram.gen.d.ts +132 -0
- package/dist/schema/histogram.gen.d.ts.map +1 -0
- package/dist/schema/index.d.ts +18 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/logs.gen.d.ts +1 -0
- package/dist/schema/logs.gen.d.ts.map +1 -1
- package/dist/schema/loki.gen.d.ts.map +1 -1
- package/dist/schema/nodegraph.gen.d.ts +49 -0
- package/dist/schema/nodegraph.gen.d.ts.map +1 -0
- package/dist/schema/piechart.gen.d.ts +127 -0
- package/dist/schema/piechart.gen.d.ts.map +1 -0
- package/dist/schema/prometheus.gen.d.ts.map +1 -1
- package/dist/schema/stat.gen.d.ts.map +1 -1
- package/dist/schema/statetimeline.gen.d.ts +124 -0
- package/dist/schema/statetimeline.gen.d.ts.map +1 -0
- package/dist/schema/statushistory.gen.d.ts +114 -0
- package/dist/schema/statushistory.gen.d.ts.map +1 -0
- package/dist/schema/table.gen.d.ts +35 -3
- package/dist/schema/table.gen.d.ts.map +1 -1
- package/dist/schema/tempo.gen.d.ts.map +1 -1
- package/dist/schema/text.gen.d.ts.map +1 -1
- package/dist/schema/timeseries.gen.d.ts +5 -1
- package/dist/schema/timeseries.gen.d.ts.map +1 -1
- package/dist/schema/trend.gen.d.ts +180 -0
- package/dist/schema/trend.gen.d.ts.map +1 -0
- package/dist/schema/xychart.gen.d.ts +145 -0
- package/dist/schema/xychart.gen.d.ts.map +1 -0
- package/dist/schema-validate.d.ts +39 -4
- package/dist/schema-validate.d.ts.map +1 -1
- package/dist/serializer.d.ts +11 -3
- package/dist/serializer.d.ts.map +1 -1
- package/dist/skill-defs.d.ts.map +1 -1
- package/dist/skills/chant-grafana-alerting.md +49 -0
- package/dist/skills/chant-grafana-operations.md +108 -0
- package/dist/skills/chant-grafana-provisioning.md +3 -3
- package/dist/skills/chant-grafana.md +15 -8
- package/dist/spec/fetch-units-cli.d.ts +3 -0
- package/dist/spec/fetch-units-cli.d.ts.map +1 -0
- package/dist/spec/overlay.d.ts +43 -0
- package/dist/spec/overlay.d.ts.map +1 -0
- package/dist/spec/schemas.d.ts +21 -13
- package/dist/spec/schemas.d.ts.map +1 -1
- package/dist/spec/schemas.gen.d.ts +3 -0
- package/dist/spec/schemas.gen.d.ts.map +1 -0
- package/dist/spec/units.d.ts +35 -0
- package/dist/spec/units.d.ts.map +1 -0
- package/dist/spec/units.gen.d.ts +2 -0
- package/dist/spec/units.gen.d.ts.map +1 -0
- package/dist/transformations.d.ts +459 -0
- package/dist/transformations.d.ts.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/validate-alerting.d.ts +65 -0
- package/dist/validate-alerting.d.ts.map +1 -0
- package/dist/validate-output.d.ts +62 -9
- package/dist/validate-output.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validation.d.ts +14 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/variables.d.ts +109 -7
- package/dist/variables.d.ts.map +1 -1
- package/package.json +12 -4
- package/src/actions/actions.test.ts +24 -0
- package/src/actions/grafana.ts +40 -0
- package/src/actions/index.ts +1 -0
- package/src/alerting-build.ts +376 -0
- package/src/alerting.e2e.test.ts +212 -0
- package/src/alerting.test.ts +272 -0
- package/src/alerting.ts +435 -0
- package/src/annotations.ts +84 -0
- package/src/api/apply.test.ts +256 -0
- package/src/api/apply.ts +394 -0
- package/src/api/bind.ts +58 -0
- package/src/api/client.ts +148 -0
- package/src/api/converge.ts +63 -0
- package/src/api/dashboards.ts +247 -0
- package/src/api/datasources.ts +33 -0
- package/src/api/fake-grafana-writes.ts +201 -0
- package/src/api/fake-grafana.ts +190 -0
- package/src/api/folders.ts +339 -0
- package/src/api/library-panels.ts +101 -0
- package/src/build.test.ts +351 -10
- package/src/build.ts +294 -55
- package/src/catalog.ts +104 -2
- package/src/codegen/docs.ts +50 -10
- package/src/codegen/generate.ts +27 -1
- package/src/codegen/schema-types.ts +16 -6
- package/src/composites/agent-dashboard.ts +6 -3
- package/src/composites/catalog.test.ts +2 -2
- package/src/composites/catalog.ts +82 -0
- package/src/composites/composites.test.ts +73 -9
- package/src/composites/index.ts +4 -2
- package/src/composites/queries.e2e.test.ts +374 -0
- package/src/composites/red-dashboard.ts +83 -12
- package/src/composites/shared.ts +14 -2
- package/src/composites/slo-alert-rules.ts +149 -0
- package/src/config.test.ts +61 -0
- package/src/config.ts +138 -0
- package/src/contact-point-secrets.ts +63 -0
- package/src/dashboard.ts +68 -9
- package/src/datasource-refs.test.ts +56 -0
- package/src/datasource-refs.ts +213 -0
- package/src/datasource-settings.test.ts +106 -0
- package/src/datasource-settings.ts +941 -0
- package/src/datasource.ts +123 -11
- package/src/deep-observe-hooks.ts +267 -0
- package/src/deep-observe.test.ts +311 -0
- package/src/deep-observe.ts +187 -0
- package/src/describe-resources.test.ts +271 -0
- package/src/describe-resources.ts +244 -0
- package/src/detect.ts +82 -5
- package/src/export-resources.test.ts +129 -0
- package/src/export-resources.ts +84 -0
- package/src/folder.ts +118 -0
- package/src/generated/lexicon-grafana.json +205 -0
- package/src/import/alerting-roundtrip.test.ts +161 -0
- package/src/import/alerting.ts +500 -0
- package/src/import/edits.ts +95 -0
- package/src/import/embedded.test.ts +45 -0
- package/src/import/embedded.ts +47 -0
- package/src/import/generated-types.e2e.test.ts +130 -0
- package/src/import/generator.test.ts +210 -0
- package/src/import/generator.ts +463 -0
- package/src/import/live-export.ts +264 -0
- package/src/import/mappings.ts +336 -0
- package/src/import/model.ts +117 -0
- package/src/import/normalize-alerting.ts +101 -0
- package/src/import/normalize.test.ts +117 -0
- package/src/import/normalize.ts +393 -0
- package/src/import/parser.test.ts +516 -0
- package/src/import/parser.ts +1387 -0
- package/src/import/report.ts +62 -0
- package/src/import/roundtrip.test.ts +563 -0
- package/src/import/testdata/fixtures.ts +137 -0
- package/src/import/v2.test.ts +292 -0
- package/src/import/v2.ts +804 -0
- package/src/import.e2e.test.ts +31 -84
- package/src/import.test.ts +9 -3
- package/src/index.ts +308 -14
- package/src/init-templates.test.ts +74 -0
- package/src/init-templates.ts +349 -0
- package/src/k8s.test.ts +98 -0
- package/src/k8s.ts +197 -0
- package/src/lint/audit-catalog.ts +68 -3
- package/src/lint/core-lint.test.ts +43 -0
- package/src/lint/post-synth/graf101.ts +3 -3
- package/src/lint/post-synth/graf102.ts +1 -1
- package/src/lint/post-synth/graf104.ts +3 -3
- package/src/lint/post-synth/graf106.ts +3 -3
- package/src/lint/post-synth/graf107.ts +1 -1
- package/src/lint/post-synth/graf108.ts +17 -0
- package/src/lint/post-synth/graf109.ts +17 -0
- package/src/lint/post-synth/graf110.ts +17 -0
- package/src/lint/post-synth/graf111.ts +17 -0
- package/src/lint/post-synth/graf112.ts +17 -0
- package/src/lint/post-synth/graf113.ts +17 -0
- package/src/lint/post-synth/graf114.ts +17 -0
- package/src/lint/post-synth/graf115.ts +17 -0
- package/src/lint/post-synth/grafana-helpers.ts +27 -10
- package/src/lint/post-synth/index.ts +16 -0
- package/src/lint/post-synth/post-synth.test.ts +333 -12
- package/src/lint/rules/literal-secret.ts +60 -6
- package/src/lint/rules/rules.test.ts +27 -0
- package/src/load-cost.test.ts +35 -0
- package/src/lsp/completions.test.ts +5 -0
- package/src/lsp/hover.test.ts +7 -0
- package/src/lsp/hover.ts +8 -1
- package/src/members.ts +68 -0
- package/src/observe.e2e.test.ts +255 -0
- package/src/op/activities/grafana-apply.e2e.test.ts +184 -0
- package/src/op/activities/grafana-apply.test.ts +243 -0
- package/src/op/activities/grafana-apply.ts +197 -0
- package/src/op/activities/index.ts +8 -0
- package/src/op/builders.test.ts +40 -0
- package/src/op/builders.ts +34 -0
- package/src/ownership.ts +122 -0
- package/src/panel-options.ts +66 -0
- package/src/panels.test.ts +53 -0
- package/src/panels.ts +148 -10
- package/src/pin.ts +69 -6
- package/src/plugin.test.ts +12 -2
- package/src/plugin.ts +75 -0
- package/src/promql-check.test.ts +108 -0
- package/src/promql-check.ts +193 -0
- package/src/query-models.ts +94 -0
- package/src/query.test.ts +166 -0
- package/src/query.ts +190 -20
- package/src/schema/azuremonitor.gen.ts +381 -0
- package/src/schema/barchart.gen.ts +221 -0
- package/src/schema/bargauge.gen.ts +111 -0
- package/src/schema/bigquery.gen.ts +110 -0
- package/src/schema/canvas.gen.ts +176 -0
- package/src/schema/cloudwatch.gen.ts +423 -0
- package/src/schema/dashboard.gen.ts +206 -22
- package/src/schema/elasticsearch.gen.ts +508 -0
- package/src/schema/expr.gen.ts +618 -0
- package/src/schema/gauge.gen.ts +2 -1
- package/src/schema/geomap.gen.ts +112 -0
- package/src/schema/googlecloudmonitoring.gen.ts +330 -0
- package/src/schema/grafanapyroscope.gen.ts +66 -0
- package/src/schema/heatmap.gen.ts +2 -1
- package/src/schema/histogram.gen.ts +151 -0
- package/src/schema/index.ts +18 -0
- package/src/schema/logs.gen.ts +3 -1
- package/src/schema/loki.gen.ts +2 -1
- package/src/schema/nodegraph.gen.ts +58 -0
- package/src/schema/piechart.gen.ts +146 -0
- package/src/schema/prometheus.gen.ts +2 -1
- package/src/schema/stat.gen.ts +2 -1
- package/src/schema/statetimeline.gen.ts +143 -0
- package/src/schema/statushistory.gen.ts +132 -0
- package/src/schema/table.gen.ts +41 -4
- package/src/schema/tempo.gen.ts +2 -1
- package/src/schema/text.gen.ts +2 -1
- package/src/schema/timeseries.gen.ts +7 -2
- package/src/schema/trend.gen.ts +208 -0
- package/src/schema/xychart.gen.ts +167 -0
- package/src/schema-overlay.test.ts +282 -0
- package/src/schema-validate.ts +199 -57
- package/src/schema.test.ts +4 -2
- package/src/serializer.test.ts +13 -1
- package/src/serializer.ts +11 -3
- package/src/skill-defs.ts +34 -0
- package/src/skills/chant-grafana-alerting.md +49 -0
- package/src/skills/chant-grafana-operations.md +108 -0
- package/src/skills/chant-grafana-provisioning.md +3 -3
- package/src/skills/chant-grafana.md +15 -8
- package/src/spec/fetch-cli.ts +3 -3
- package/src/spec/fetch-units-cli.ts +37 -0
- package/src/spec/overlay/canvas.overlay.json +142 -0
- package/src/spec/overlay/dashboard.overlay.json +378 -0
- package/src/spec/overlay/expr.overlay.json +14 -0
- package/src/spec/overlay/geomap.overlay.json +35 -0
- package/src/spec/overlay/logs.overlay.json +14 -0
- package/src/spec/overlay/nodegraph.overlay.json +31 -0
- package/src/spec/overlay/piechart.overlay.json +17 -0
- package/src/spec/overlay/table.overlay.json +103 -0
- package/src/spec/overlay/timeseries.overlay.json +21 -0
- package/src/spec/overlay/trend.overlay.json +17 -0
- package/src/spec/overlay/xychart.overlay.json +16 -0
- package/src/spec/overlay.ts +105 -0
- package/src/spec/schemas/azuremonitor.jsonschema.json +679 -0
- package/src/spec/schemas/barchart.jsonschema.json +419 -0
- package/src/spec/schemas/bargauge.jsonschema.json +224 -0
- package/src/spec/schemas/bigquery.jsonschema.json +290 -0
- package/src/spec/schemas/canvas.jsonschema.json +356 -0
- package/src/spec/schemas/cloudwatch.jsonschema.json +721 -0
- package/src/spec/schemas/dashboardv2.jsonschema.json +3387 -0
- package/src/spec/schemas/elasticsearch.jsonschema.json +1695 -0
- package/src/spec/schemas/expr.jsonschema.json +987 -0
- package/src/spec/schemas/geomap.jsonschema.json +220 -0
- package/src/spec/schemas/googlecloudmonitoring.jsonschema.json +488 -0
- package/src/spec/schemas/grafanapyroscope.jsonschema.json +93 -0
- package/src/spec/schemas/histogram.jsonschema.json +308 -0
- package/src/spec/schemas/nodegraph.jsonschema.json +77 -0
- package/src/spec/schemas/piechart.jsonschema.json +275 -0
- package/src/spec/schemas/statetimeline.jsonschema.json +324 -0
- package/src/spec/schemas/statushistory.jsonschema.json +292 -0
- package/src/spec/schemas/trend.jsonschema.json +449 -0
- package/src/spec/schemas/xychart.jsonschema.json +428 -0
- package/src/spec/schemas.gen.ts +40 -0
- package/src/spec/schemas.ts +30 -16
- package/src/spec/units.gen.ts +281 -0
- package/src/spec/units.ts +77 -0
- package/src/transformations.test.ts +65 -0
- package/src/transformations.ts +574 -0
- package/src/util.ts +8 -0
- package/src/validate-alerting.test.ts +255 -0
- package/src/validate-alerting.ts +430 -0
- package/src/validate-output.ts +427 -104
- package/src/validate.ts +28 -0
- package/src/validation.ts +27 -0
- package/src/variables.ts +120 -8
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classic dashboard JSON in a canonical form, so two dashboards Grafana
|
|
3
|
+
* treats the same compare equal.
|
|
4
|
+
*
|
|
5
|
+
* Grafana fills in a default for most keys a dashboard leaves out, derives
|
|
6
|
+
* some keys from others (a custom variable's `options` from its `query`),
|
|
7
|
+
* and resolves a query without a datasource to its panel's. A dashboard it
|
|
8
|
+
* exported and the same dashboard rebuilt by chant differ in exactly those
|
|
9
|
+
* ways, so both are put through `normalizeDashboard` before they are
|
|
10
|
+
* compared: keys at their default are removed, derived keys are removed,
|
|
11
|
+
* and references are written one way.
|
|
12
|
+
*
|
|
13
|
+
* The import round trip compares with it, the importer asks `isDefault`
|
|
14
|
+
* whether a key it cannot carry is worth a warning (a key at its default is
|
|
15
|
+
* not), and drift detection (#2946) can compare a stored dashboard with a
|
|
16
|
+
* built one the same way.
|
|
17
|
+
*
|
|
18
|
+
* Only the dashboard, panel, row, target, variable and link levels are
|
|
19
|
+
* touched. Nothing inside `options`, `fieldConfig`, `transformations` or a
|
|
20
|
+
* query model is: a `null` in there (a threshold step's base value) means
|
|
21
|
+
* something.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { customVariableOptions } from "../build";
|
|
25
|
+
|
|
26
|
+
type Json = Record<string, unknown>;
|
|
27
|
+
|
|
28
|
+
/** Grafana's value for a dashboard key the JSON leaves out. */
|
|
29
|
+
export const DASHBOARD_DEFAULTS: Readonly<Json> = {
|
|
30
|
+
editable: true,
|
|
31
|
+
fiscalYearStartMonth: 0,
|
|
32
|
+
graphTooltip: 0,
|
|
33
|
+
links: [],
|
|
34
|
+
tags: [],
|
|
35
|
+
time: { from: "now-6h", to: "now" },
|
|
36
|
+
timepicker: {},
|
|
37
|
+
timezone: "",
|
|
38
|
+
weekStart: "",
|
|
39
|
+
refresh: "",
|
|
40
|
+
liveNow: false,
|
|
41
|
+
preload: false,
|
|
42
|
+
description: "",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Grafana's value for a panel key the JSON leaves out. */
|
|
46
|
+
export const PANEL_DEFAULTS: Readonly<Json> = {
|
|
47
|
+
title: "",
|
|
48
|
+
description: "",
|
|
49
|
+
options: {},
|
|
50
|
+
targets: [],
|
|
51
|
+
transformations: [],
|
|
52
|
+
links: [],
|
|
53
|
+
transparent: false,
|
|
54
|
+
hideTimeOverride: false,
|
|
55
|
+
repeatDirection: "h",
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** Grafana's value for a row key the JSON leaves out. */
|
|
59
|
+
export const ROW_DEFAULTS: Readonly<Json> = {
|
|
60
|
+
collapsed: false,
|
|
61
|
+
panels: [],
|
|
62
|
+
title: "",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Grafana's value for a variable key the JSON leaves out, whatever the variable's type. */
|
|
66
|
+
export const VARIABLE_DEFAULTS: Readonly<Json> = {
|
|
67
|
+
hide: 0,
|
|
68
|
+
skipUrlSync: false,
|
|
69
|
+
label: "",
|
|
70
|
+
description: "",
|
|
71
|
+
multi: false,
|
|
72
|
+
includeAll: false,
|
|
73
|
+
allValue: "",
|
|
74
|
+
regex: "",
|
|
75
|
+
sort: 0,
|
|
76
|
+
current: {},
|
|
77
|
+
// Added by later Grafana versions, at the value that keeps the old behaviour.
|
|
78
|
+
allowCustomValue: true,
|
|
79
|
+
regexApplyTo: "value",
|
|
80
|
+
valuesFormat: "csv",
|
|
81
|
+
// Tag support was removed in Grafana 8; the keys linger in older dashboards.
|
|
82
|
+
useTags: false,
|
|
83
|
+
tagsQuery: "",
|
|
84
|
+
tagValuesQuery: "",
|
|
85
|
+
tags: [],
|
|
86
|
+
queryValue: "",
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** Per variable type, Grafana's value for a key the JSON leaves out, over `VARIABLE_DEFAULTS`. */
|
|
90
|
+
export const VARIABLE_TYPE_DEFAULTS: Readonly<Record<string, Json>> = {
|
|
91
|
+
query: { refresh: 1 },
|
|
92
|
+
adhoc: { filters: [], baseFilters: [], enableGroupBy: false },
|
|
93
|
+
datasource: { refresh: 1 },
|
|
94
|
+
interval: { refresh: 2, auto: false, auto_count: 30, auto_min: "10s" },
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/** The defaults chant writes into a dashboard or panel link, which Grafana reads as unset. */
|
|
98
|
+
export const LINK_DEFAULTS: Readonly<Json> = {
|
|
99
|
+
type: "link",
|
|
100
|
+
icon: "external link",
|
|
101
|
+
tooltip: "",
|
|
102
|
+
tags: [],
|
|
103
|
+
asDropdown: false,
|
|
104
|
+
targetBlank: false,
|
|
105
|
+
includeVars: false,
|
|
106
|
+
keepTime: false,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/** The annotation Grafana adds to every dashboard that has none: annotations and alerts from its own database. */
|
|
110
|
+
export const BUILTIN_ANNOTATION: Readonly<Json> = {
|
|
111
|
+
builtIn: 1,
|
|
112
|
+
datasource: { type: "grafana", uid: "-- Grafana --" },
|
|
113
|
+
enable: true,
|
|
114
|
+
hide: true,
|
|
115
|
+
iconColor: "rgba(0, 211, 255, 1)",
|
|
116
|
+
name: "Annotations & Alerts",
|
|
117
|
+
type: "dashboard",
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/** Keys of a stored dashboard that belong to that copy (its database id, save counter), not to the dashboard. */
|
|
121
|
+
export const BOOKKEEPING_KEYS: readonly string[] = ["id", "version", "iteration"];
|
|
122
|
+
|
|
123
|
+
/** The panel datasource Grafana writes when a panel's queries go to different datasources. */
|
|
124
|
+
export const MIXED_UID = "-- Mixed --";
|
|
125
|
+
|
|
126
|
+
export function isObject(v: unknown): v is Json {
|
|
127
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function deepEqual(a: unknown, b: unknown): boolean {
|
|
131
|
+
if (a === b) return true;
|
|
132
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
133
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
134
|
+
return a.every((x, i) => deepEqual(x, b[i]));
|
|
135
|
+
}
|
|
136
|
+
if (isObject(a) && isObject(b)) {
|
|
137
|
+
const ka = Object.keys(a).filter((k) => a[k] !== undefined);
|
|
138
|
+
const kb = Object.keys(b).filter((k) => b[k] !== undefined);
|
|
139
|
+
if (ka.length !== kb.length) return false;
|
|
140
|
+
return ka.every((k) => deepEqual(a[k], b[k]));
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** True when `value` is what Grafana assumes for `key` when it is left out (a `null` counts as left out). */
|
|
146
|
+
export function isDefault(defaults: Readonly<Json>, key: string, value: unknown): boolean {
|
|
147
|
+
if (!(key in defaults)) return false;
|
|
148
|
+
return value === null || value === undefined || deepEqual(value, defaults[key]);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Defaults for one variable type. */
|
|
152
|
+
export function variableDefaults(type: unknown): Json {
|
|
153
|
+
return { ...VARIABLE_DEFAULTS, ...(VARIABLE_TYPE_DEFAULTS[String(type)] ?? {}) };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function dropDefaults(obj: Json, defaults: Readonly<Json>): void {
|
|
157
|
+
for (const key of Object.keys(obj)) if (isDefault(defaults, key, obj[key])) delete obj[key];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const REF_IDS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
161
|
+
|
|
162
|
+
/** The refId Grafana (and chant) gives the query at `index` when it has none: A, B, … Z, AA, AB, … */
|
|
163
|
+
export function refIdAt(i: number): string {
|
|
164
|
+
return i < REF_IDS.length ? REF_IDS[i] : `${REF_IDS[Math.floor(i / REF_IDS.length) - 1]}${REF_IDS[i % REF_IDS.length]}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** `$name` and `[[name]]` written as `${name}`, the form a datasource variable's reference takes. */
|
|
168
|
+
export function canonicalVariableUid(uid: string): string {
|
|
169
|
+
const m = /^\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(uid) ?? /^\[\[([A-Za-z_][A-Za-z0-9_]*)\]\]$/.exec(uid);
|
|
170
|
+
return m ? `\${${m[1]}}` : uid;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function canonicalRef(ref: unknown): unknown {
|
|
174
|
+
if (!isObject(ref)) return ref;
|
|
175
|
+
const out = { ...ref };
|
|
176
|
+
if (typeof out.uid === "string") out.uid = canonicalVariableUid(out.uid);
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function sameRef(a: unknown, b: unknown): boolean {
|
|
181
|
+
return isObject(a) && isObject(b) && a.type === b.type && a.uid === b.uid;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function isMixed(ref: unknown): boolean {
|
|
185
|
+
return isObject(ref) && ref.uid === MIXED_UID;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** A custom or interval variable's `query` as the list of values Grafana splits it into. */
|
|
189
|
+
export function splitValues(query: string): string[] {
|
|
190
|
+
const out: string[] = [];
|
|
191
|
+
for (const m of query.matchAll(/(?:\\,|[^,])+/g)) {
|
|
192
|
+
const v = m[0].trim().replace(/\\,/g, ",");
|
|
193
|
+
if (v !== "") out.push(v);
|
|
194
|
+
}
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function normalizeLink(link: unknown): unknown {
|
|
199
|
+
if (!isObject(link)) return link;
|
|
200
|
+
const out = { ...link };
|
|
201
|
+
dropDefaults(out, LINK_DEFAULTS);
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Per datasource type, a query key's value when the target leaves it out.
|
|
207
|
+
* A Tempo query without `filters` has no search filters, which `TempoQuery`
|
|
208
|
+
* writes as `filters: []`.
|
|
209
|
+
*/
|
|
210
|
+
export const TARGET_DEFAULTS: Readonly<Record<string, Readonly<Json>>> = {
|
|
211
|
+
tempo: { filters: [] },
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
function normalizeTarget(target: unknown, index: number, panelDatasource: unknown): unknown {
|
|
215
|
+
if (!isObject(target)) return target;
|
|
216
|
+
const out = { ...target };
|
|
217
|
+
if (out.datasource === null || out.datasource === undefined) {
|
|
218
|
+
if (panelDatasource !== undefined && !isMixed(panelDatasource)) out.datasource = panelDatasource;
|
|
219
|
+
else delete out.datasource;
|
|
220
|
+
} else {
|
|
221
|
+
out.datasource = canonicalRef(out.datasource);
|
|
222
|
+
}
|
|
223
|
+
const type = isObject(out.datasource) ? out.datasource.type : undefined;
|
|
224
|
+
const defaults = typeof type === "string" ? TARGET_DEFAULTS[type] : undefined;
|
|
225
|
+
if (defaults) dropDefaults(out, defaults);
|
|
226
|
+
if (out.refId === undefined || out.refId === null || out.refId === "") out.refId = refIdAt(index);
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function normalizePanel(panel: unknown): unknown {
|
|
231
|
+
if (!isObject(panel)) return panel;
|
|
232
|
+
if (panel.type === "row") return normalizeRow(panel);
|
|
233
|
+
const out: Json = { ...panel };
|
|
234
|
+
for (const key of Object.keys(out)) if (out[key] === null) delete out[key];
|
|
235
|
+
const own = out.datasource === undefined ? undefined : canonicalRef(out.datasource);
|
|
236
|
+
const targets = Array.isArray(out.targets) ? out.targets.map((t, i) => normalizeTarget(t, i, own)) : [];
|
|
237
|
+
if (targets.length > 0) out.targets = targets;
|
|
238
|
+
else delete out.targets;
|
|
239
|
+
// The panel's datasource is the one its queries share, or Mixed when they differ.
|
|
240
|
+
const refs = targets.map((t) => (isObject(t) ? t.datasource : undefined));
|
|
241
|
+
if (refs.length > 0 && refs.every((r) => r !== undefined && sameRef(r, refs[0]))) out.datasource = refs[0];
|
|
242
|
+
else if (own !== undefined) out.datasource = own;
|
|
243
|
+
else delete out.datasource;
|
|
244
|
+
const fc = isObject(out.fieldConfig) ? out.fieldConfig : {};
|
|
245
|
+
out.fieldConfig = { defaults: isObject(fc.defaults) ? fc.defaults : {}, overrides: Array.isArray(fc.overrides) ? fc.overrides : [] };
|
|
246
|
+
if (Array.isArray(out.links)) out.links = out.links.map(normalizeLink);
|
|
247
|
+
dropDefaults(out, PANEL_DEFAULTS);
|
|
248
|
+
return out;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function normalizeRow(row: Json): Json {
|
|
252
|
+
const out: Json = { ...row };
|
|
253
|
+
for (const key of Object.keys(out)) if (out[key] === null) delete out[key];
|
|
254
|
+
if (out.datasource !== undefined) out.datasource = canonicalRef(out.datasource);
|
|
255
|
+
if (Array.isArray(out.panels)) out.panels = out.panels.map(normalizePanel);
|
|
256
|
+
dropDefaults(out, ROW_DEFAULTS);
|
|
257
|
+
return out;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function normalizeVariable(variable: unknown): unknown {
|
|
261
|
+
if (!isObject(variable)) return variable;
|
|
262
|
+
const out: Json = { ...variable };
|
|
263
|
+
const type = out.type;
|
|
264
|
+
if (out.datasource === null) delete out.datasource;
|
|
265
|
+
else if (out.datasource !== undefined) out.datasource = canonicalRef(out.datasource);
|
|
266
|
+
const query = typeof out.query === "string" ? out.query : undefined;
|
|
267
|
+
switch (type) {
|
|
268
|
+
case "query": {
|
|
269
|
+
// `definition` is the query as the editor shows it; Grafana reads `query` (an object query's text is its `query`).
|
|
270
|
+
const text = query ?? (isObject(out.query) && typeof out.query.query === "string" ? out.query.query : undefined);
|
|
271
|
+
if (out.definition === undefined || out.definition === "" || (text !== undefined && out.definition === text)) delete out.definition;
|
|
272
|
+
// Grafana runs the query again when the dashboard loads (or the time range changes).
|
|
273
|
+
if (out.refresh !== 0) delete out.options;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case "adhoc":
|
|
277
|
+
// The filters are the selection; Grafana reads neither of these for an ad hoc variable.
|
|
278
|
+
delete out.current;
|
|
279
|
+
delete out.options;
|
|
280
|
+
break;
|
|
281
|
+
case "groupby": {
|
|
282
|
+
// With nothing selected, Grafana starts from the default.
|
|
283
|
+
const cur = isObject(out.current) ? out.current : undefined;
|
|
284
|
+
const empty = !cur || Object.keys(cur).length === 0 || (Array.isArray(cur.value) && cur.value.length === 0);
|
|
285
|
+
if (empty || deepEqual(cur, out.defaultValue)) delete out.current;
|
|
286
|
+
if (Array.isArray(out.options) && out.options.length === 0) delete out.options;
|
|
287
|
+
// Always multi-value.
|
|
288
|
+
delete out.multi;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case "switch": {
|
|
292
|
+
// Grafana reads only the values: the enabled one first, the disabled one second, and the current one.
|
|
293
|
+
const value = (o: unknown): unknown => (isObject(o) ? (Array.isArray(o.value) ? o.value[0] : o.value) : undefined);
|
|
294
|
+
const opts = Array.isArray(out.options) ? out.options : [];
|
|
295
|
+
const on = value(opts[0]) ?? "true";
|
|
296
|
+
const off = value(opts[1]) ?? "false";
|
|
297
|
+
out.options = [on, off];
|
|
298
|
+
out.current = value(out.current) ?? off;
|
|
299
|
+
delete out.query;
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case "custom":
|
|
303
|
+
case "interval": {
|
|
304
|
+
const values = splitValues(query ?? "");
|
|
305
|
+
out.query = values.join(",");
|
|
306
|
+
delete out.options;
|
|
307
|
+
if (type === "custom" && (!isObject(out.current) || Object.keys(out.current).length === 0) && values.length > 0) {
|
|
308
|
+
// Grafana selects the first option, with a `text : value` item split into its text and value.
|
|
309
|
+
const first = customVariableOptions(query ?? "")[0];
|
|
310
|
+
if (first) out.current = { text: first.text, value: first.value };
|
|
311
|
+
}
|
|
312
|
+
out.refresh = type === "interval" ? 2 : out.refresh;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
case "datasource":
|
|
316
|
+
delete out.options;
|
|
317
|
+
break;
|
|
318
|
+
case "constant":
|
|
319
|
+
// Grafana shows a constant's value from `query` and never shows the variable.
|
|
320
|
+
delete out.options;
|
|
321
|
+
delete out.current;
|
|
322
|
+
delete out.hide;
|
|
323
|
+
break;
|
|
324
|
+
case "textbox": {
|
|
325
|
+
delete out.options;
|
|
326
|
+
const cur = isObject(out.current) ? out.current : undefined;
|
|
327
|
+
if (!cur || Object.keys(cur).length === 0 || (cur.value === (query ?? "") && (cur.text === undefined || cur.text === (query ?? "")))) {
|
|
328
|
+
delete out.current;
|
|
329
|
+
}
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (isObject(out.current)) {
|
|
334
|
+
const { selected: _selected, ...current } = out.current;
|
|
335
|
+
out.current = current;
|
|
336
|
+
}
|
|
337
|
+
dropDefaults(out, variableDefaults(type));
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** The forms Grafana has written its own pseudo-datasource in, over the versions. */
|
|
342
|
+
function isGrafanaDatasource(ds: unknown): boolean {
|
|
343
|
+
if (ds === "-- Grafana --" || ds === "grafana") return true;
|
|
344
|
+
if (!isObject(ds)) return false;
|
|
345
|
+
const keys = Object.keys(ds).filter((k) => ds[k] !== undefined);
|
|
346
|
+
if (keys.some((k) => k !== "type" && k !== "uid")) return false;
|
|
347
|
+
return (ds.uid === "-- Grafana --" || ds.uid === "grafana") && (ds.type === undefined || ds.type === "grafana" || ds.type === "datasource");
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** The target Grafana writes into the built-in annotation, which says what it says without one. */
|
|
351
|
+
const BUILTIN_ANNOTATION_TARGET = { limit: 100, matchAny: false, tags: [], type: "dashboard" };
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* True for the annotation Grafana adds to every dashboard (annotations and
|
|
355
|
+
* alerts from its own database), in any of the forms Grafana versions have
|
|
356
|
+
* written it: a dashboard with it and one without are the same dashboard.
|
|
357
|
+
*/
|
|
358
|
+
export function isBuiltinAnnotation(a: unknown): boolean {
|
|
359
|
+
if (!isObject(a) || a.builtIn !== 1 || !isGrafanaDatasource(a.datasource)) return false;
|
|
360
|
+
const { datasource: _ds, target, ...rest } = a;
|
|
361
|
+
if (target !== undefined && !deepEqual(target, BUILTIN_ANNOTATION_TARGET)) return false;
|
|
362
|
+
const { datasource: _builtinDs, ...expected } = BUILTIN_ANNOTATION;
|
|
363
|
+
return deepEqual(rest, expected);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function normalizeAnnotations(annotations: unknown): unknown {
|
|
367
|
+
const list = isObject(annotations) && Array.isArray(annotations.list) ? annotations.list : [];
|
|
368
|
+
const rest = list.filter((a) => !isBuiltinAnnotation(a));
|
|
369
|
+
return rest.length === 0 ? undefined : { list: rest };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* The dashboard in canonical form: bookkeeping keys and keys at their
|
|
374
|
+
* default removed, derived keys removed, every query with its datasource and
|
|
375
|
+
* refId, every panel with the datasource its queries share. Returns a copy;
|
|
376
|
+
* key order is not canonicalised (compare with `deepEqual` or `toEqual`).
|
|
377
|
+
*/
|
|
378
|
+
export function normalizeDashboard(dashboard: Json): Json {
|
|
379
|
+
const out: Json = { ...dashboard };
|
|
380
|
+
for (const key of BOOKKEEPING_KEYS) delete out[key];
|
|
381
|
+
for (const key of Object.keys(out)) if (out[key] === null) delete out[key];
|
|
382
|
+
const annotations = normalizeAnnotations(out.annotations);
|
|
383
|
+
if (annotations === undefined) delete out.annotations;
|
|
384
|
+
else out.annotations = annotations;
|
|
385
|
+
if (out.refresh === false) delete out.refresh;
|
|
386
|
+
if (Array.isArray(out.links)) out.links = out.links.map(normalizeLink);
|
|
387
|
+
if (Array.isArray(out.panels)) out.panels = out.panels.map(normalizePanel);
|
|
388
|
+
const list = isObject(out.templating) && Array.isArray(out.templating.list) ? out.templating.list : [];
|
|
389
|
+
if (list.length > 0) out.templating = { list: list.map(normalizeVariable) };
|
|
390
|
+
else delete out.templating;
|
|
391
|
+
dropDefaults(out, DASHBOARD_DEFAULTS);
|
|
392
|
+
return out;
|
|
393
|
+
}
|