codegen: Introduce TS codegen veneer (#54816)

* Split all named types out into defs, etc.

* Use latest cuetsy, refactor generators accordingly

* Return AST type from plugin TS generator

* Near-complete checkin of TS veneer code generator

* First full completed pass

* Improve the attribute name

* Defer use of the dashboard veneer type to follow-up

* Remove dummy index, prettier on veneer

* Fix merge errors in gen.go

* Add match field to SpecialValueMap

* Fix backend lint errors
This commit is contained in:
sam boyer
2022-09-26 11:26:18 -04:00
committed by GitHub
parent f8240e4b0a
commit e2ff875976
26 changed files with 1920 additions and 517 deletions

View File

@@ -12,6 +12,8 @@ seqs: [
{
schemas: [
{// 0.0
@grafana(TSVeneer="type")
// Unique numeric identifier for the dashboard.
// TODO must isolate or remove identifiers local to a Grafana instance...?
id?: int64
@@ -192,6 +194,59 @@ seqs: [
steps: [...#Threshold] @reviewme()
} @cuetsy(kind="interface") @reviewme()
// TODO docs
#ValueMapping: #ValueMap | #RangeMap | #RegexMap | #SpecialValueMap @cuetsy(kind="type") @reviewme()
// TODO docs
#MappingType: "value" | "range" | "regex" | "special" @cuetsy(kind="enum",memberNames="ValueToText|RangeToText|RegexToText|SpecialValue") @reviewme()
// TODO docs
#ValueMap: {
type: #MappingType & "value"
options: [string]: #ValueMappingResult
} @cuetsy(kind="interface")
// TODO docs
#RangeMap: {
type: #MappingType & "range"
options: {
// to and from are `number | null` in current ts, really not sure what to do
from: int32 @reviewme()
to: int32 @reviewme()
result: #ValueMappingResult
}
} @cuetsy(kind="interface") @reviewme()
// TODO docs
#RegexMap: {
type: #MappingType & "regex"
options: {
pattern: string
result: #ValueMappingResult
}
} @cuetsy(kind="interface") @reviewme()
// TODO docs
#SpecialValueMap: {
type: #MappingType & "special"
options: {
match: "true" | "false"
pattern: string
result: #ValueMappingResult
}
} @cuetsy(kind="interface") @reviewme()
// TODO docs
#SpecialValueMatch: "true" | "false" | "null" | "nan" | "null+nan" | "empty" @cuetsy(kind="enum",memberNames="True|False|Null|NaN|NullAndNan|Empty")
// TODO docs
#ValueMappingResult: {
text?: string
color?: string
icon?: string
index?: int32
} @cuetsy(kind="interface")
// TODO docs
// FIXME this is extremely underspecfied; wasn't obvious which typescript types corresponded to it
#Transformation: {
@@ -282,82 +337,82 @@ seqs: [
// plugin schemas.
options: {...} @reviewme()
fieldConfig: {
defaults: {
// The display value for this field. This supports template variables blank is auto
displayName?: string @reviewme()
fieldConfig: #FieldConfigSource
} @cuetsy(kind="interface") @grafana(TSVeneer="type") @reviewme()
// This can be used by data sources that return and explicit naming structure for values and labels
// When this property is configured, this value is used rather than the default naming strategy.
displayNameFromDS?: string @reviewme()
#FieldConfigSource: {
defaults: #FieldConfig
overrides: [...{
matcher: #MatcherConfig
properties: [...#DynamicConfigValue]
}] @reviewme()
} @cuetsy(kind="interface") @grafana(TSVeneer="type") @reviewme()
// Human readable field metadata
description?: string @reviewme()
#MatcherConfig: {
id: string | *"" @reviewme()
options?: _ @reviewme()
} @cuetsy(kind="interface")
// An explict path to the field in the datasource. When the frame meta includes a path,
// This will default to `${frame.meta.path}/${field.name}
//
// When defined, this value can be used as an identifier within the datasource scope, and
// may be used to update the results
path?: string @reviewme()
#DynamicConfigValue: {
id: string | *"" @reviewme()
value?: _ @reviewme()
}
// True if data source can write a value to the path. Auth/authz are supported separately
writeable?: bool @reviewme()
#FieldConfig: {
// The display value for this field. This supports template variables blank is auto
displayName?: string @reviewme()
// True if data source field supports ad-hoc filters
filterable?: bool @reviewme()
// This can be used by data sources that return and explicit naming structure for values and labels
// When this property is configured, this value is used rather than the default naming strategy.
displayNameFromDS?: string @reviewme()
// Numeric Options
unit?: string @reviewme()
// Human readable field metadata
description?: string @reviewme()
// Significant digits (for display)
decimals?: number @reviewme()
// An explict path to the field in the datasource. When the frame meta includes a path,
// This will default to `${frame.meta.path}/${field.name}
//
// When defined, this value can be used as an identifier within the datasource scope, and
// may be used to update the results
path?: string @reviewme()
min?: number @reviewme()
max?: number @reviewme()
// True if data source can write a value to the path. Auth/authz are supported separately
writeable?: bool @reviewme()
// Convert input values into a display string
//
// TODO this one corresponds to a complex type with
// generics on the typescript side. Ouch. Will
// either need special care, or we'll just need to
// accept a very loosely specified schema. It's very
// unlikely we'll be able to translate cue to
// typescript generics in the general case, though
// this particular one *may* be able to work.
mappings?: [...{...}] @reviewme()
// True if data source field supports ad-hoc filters
filterable?: bool @reviewme()
// Map numeric values to states
thresholds?: #ThresholdsConfig @reviewme()
// Numeric Options
unit?: string @reviewme()
// // Map values to a display color
color?: #FieldColor @reviewme()
// Significant digits (for display)
decimals?: number @reviewme()
// // Used when reducing field values
// nullValueMode?: NullValueMode
min?: number @reviewme()
max?: number @reviewme()
// // The behavior when clicking on a result
links?: [...] @reviewme()
// Convert input values into a display string
mappings?: [...#ValueMapping] @reviewme()
// Alternative to empty string
noValue?: string @reviewme()
// Map numeric values to states
thresholds?: #ThresholdsConfig @reviewme()
// custom is specified by the PanelFieldConfig field
// in panel plugin schemas.
custom?: {...} @reviewme()
} @reviewme()
overrides: [...{
matcher: {
id: string | *"" @reviewme()
options?: _ @reviewme()
}
properties: [...{
id: string | *"" @reviewme()
value?: _ @reviewme()
}]
}] @reviewme()
}
} @cuetsy(kind="interface") @reviewme()
// Map values to a display color
color?: #FieldColor @reviewme()
// Used when reducing field values
// nullValueMode?: NullValueMode
// The behavior when clicking on a result
links?: [...] @reviewme()
// Alternative to empty string
noValue?: string @reviewme()
// custom is specified by the PanelFieldConfig field
// in panel plugin schemas.
custom?: {...} @reviewme()
} @cuetsy(kind="interface") @grafana(TSVeneer="type") @reviewme()
// Row panel
#RowPanel: {

View File

@@ -90,6 +90,17 @@ const (
HeatmapPanelTypeHeatmap HeatmapPanelType = "heatmap"
)
// Defines values for MappingType.
const (
MappingTypeRange MappingType = "range"
MappingTypeRegex MappingType = "regex"
MappingTypeSpecial MappingType = "special"
MappingTypeValue MappingType = "value"
)
// Defines values for PanelRepeatDirection.
const (
PanelRepeatDirectionH PanelRepeatDirection = "h"
@@ -97,11 +108,48 @@ const (
PanelRepeatDirectionV PanelRepeatDirection = "v"
)
// Defines values for RangeMapType.
const (
RangeMapTypeRange RangeMapType = "range"
)
// Defines values for RegexMapType.
const (
RegexMapTypeRegex RegexMapType = "regex"
)
// Defines values for RowPanelType.
const (
RowPanelTypeRow RowPanelType = "row"
)
// Defines values for SpecialValueMapOptionsMatch.
const (
SpecialValueMapOptionsMatchFalse SpecialValueMapOptionsMatch = "false"
SpecialValueMapOptionsMatchTrue SpecialValueMapOptionsMatch = "true"
)
// Defines values for SpecialValueMapType.
const (
SpecialValueMapTypeSpecial SpecialValueMapType = "special"
)
// Defines values for SpecialValueMatch.
const (
SpecialValueMatchEmpty SpecialValueMatch = "empty"
SpecialValueMatchFalse SpecialValueMatch = "false"
SpecialValueMatchNan SpecialValueMatch = "nan"
SpecialValueMatchNull SpecialValueMatch = "null"
SpecialValueMatchNullNan SpecialValueMatch = "null+nan"
SpecialValueMatchTrue SpecialValueMatch = "true"
)
// Defines values for ThresholdsConfigMode.
const (
ThresholdsConfigModeAbsolute ThresholdsConfigMode = "absolute"
@@ -116,6 +164,11 @@ const (
ThresholdsModePercentage ThresholdsMode = "percentage"
)
// Defines values for ValueMapType.
const (
ValueMapTypeValue ValueMapType = "value"
)
// Defines values for VariableModelType.
const (
VariableModelTypeAdhoc VariableModelType = "adhoc"
@@ -336,6 +389,15 @@ type DashboardLink struct {
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type DashboardLinkType string
// DynamicConfigValue is the Go representation of a dashboard.DynamicConfigValue.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type DynamicConfigValue struct {
Id string `json:"id"`
Value *interface{} `json:"value,omitempty"`
}
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
@@ -363,6 +425,126 @@ type FieldColorModeId string
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type FieldColorSeriesByMode string
// FieldConfig is the Go representation of a dashboard.FieldConfig.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type FieldConfig struct {
// TODO docs
Color *FieldColor `json:"color,omitempty"`
// custom is specified by the PanelFieldConfig field
// in panel plugin schemas.
Custom *map[string]interface{} `json:"custom,omitempty"`
// Significant digits (for display)
Decimals *float32 `json:"decimals,omitempty"`
// Human readable field metadata
Description *string `json:"description,omitempty"`
// The display value for this field. This supports template variables blank is auto
DisplayName *string `json:"displayName,omitempty"`
// This can be used by data sources that return and explicit naming structure for values and labels
// When this property is configured, this value is used rather than the default naming strategy.
DisplayNameFromDS *string `json:"displayNameFromDS,omitempty"`
// True if data source field supports ad-hoc filters
Filterable *bool `json:"filterable,omitempty"`
// The behavior when clicking on a result
Links *[]interface{} `json:"links,omitempty"`
// Convert input values into a display string
Mappings *[]ValueMapping `json:"mappings,omitempty"`
Max *float32 `json:"max,omitempty"`
Min *float32 `json:"min,omitempty"`
// Alternative to empty string
NoValue *string `json:"noValue,omitempty"`
// An explict path to the field in the datasource. When the frame meta includes a path,
// This will default to `${frame.meta.path}/${field.name}
//
// When defined, this value can be used as an identifier within the datasource scope, and
// may be used to update the results
Path *string `json:"path,omitempty"`
Thresholds *ThresholdsConfig `json:"thresholds,omitempty"`
// Numeric Options
Unit *string `json:"unit,omitempty"`
// True if data source can write a value to the path. Auth/authz are supported separately
Writeable *bool `json:"writeable,omitempty"`
}
// FieldConfigSource is the Go representation of a dashboard.FieldConfigSource.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type FieldConfigSource struct {
Defaults struct {
// TODO docs
Color *FieldColor `json:"color,omitempty"`
// custom is specified by the PanelFieldConfig field
// in panel plugin schemas.
Custom *map[string]interface{} `json:"custom,omitempty"`
// Significant digits (for display)
Decimals *float32 `json:"decimals,omitempty"`
// Human readable field metadata
Description *string `json:"description,omitempty"`
// The display value for this field. This supports template variables blank is auto
DisplayName *string `json:"displayName,omitempty"`
// This can be used by data sources that return and explicit naming structure for values and labels
// When this property is configured, this value is used rather than the default naming strategy.
DisplayNameFromDS *string `json:"displayNameFromDS,omitempty"`
// True if data source field supports ad-hoc filters
Filterable *bool `json:"filterable,omitempty"`
// The behavior when clicking on a result
Links *[]interface{} `json:"links,omitempty"`
// Convert input values into a display string
Mappings *[]ValueMapping `json:"mappings,omitempty"`
Max *float32 `json:"max,omitempty"`
Min *float32 `json:"min,omitempty"`
// Alternative to empty string
NoValue *string `json:"noValue,omitempty"`
// An explict path to the field in the datasource. When the frame meta includes a path,
// This will default to `${frame.meta.path}/${field.name}
//
// When defined, this value can be used as an identifier within the datasource scope, and
// may be used to update the results
Path *string `json:"path,omitempty"`
Thresholds *ThresholdsConfig `json:"thresholds,omitempty"`
// Numeric Options
Unit *string `json:"unit,omitempty"`
// True if data source can write a value to the path. Auth/authz are supported separately
Writeable *bool `json:"writeable,omitempty"`
} `json:"defaults"`
Overrides []struct {
Matcher struct {
Id string `json:"id"`
Options *interface{} `json:"options,omitempty"`
} `json:"matcher"`
Properties []struct {
Id string `json:"id"`
Value *interface{} `json:"value,omitempty"`
} `json:"properties"`
} `json:"overrides"`
}
// GraphPanel is the Go representation of a dashboard.GraphPanel.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
@@ -413,6 +595,21 @@ type HeatmapPanel struct {
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type HeatmapPanelType string
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type MappingType string
// MatcherConfig is the Go representation of a dashboard.MatcherConfig.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type MatcherConfig struct {
Id string `json:"id"`
Options *interface{} `json:"options,omitempty"`
}
// Model panels. Panels are canonically defined inline
// because they share a version timeline with the dashboard
// schema; they do not evolve independently.
@@ -453,21 +650,13 @@ type Panel struct {
// True if data source field supports ad-hoc filters
Filterable *bool `json:"filterable,omitempty"`
// // The behavior when clicking on a result
// The behavior when clicking on a result
Links *[]interface{} `json:"links,omitempty"`
// Convert input values into a display string
//
// TODO this one corresponds to a complex type with
// generics on the typescript side. Ouch. Will
// either need special care, or we'll just need to
// accept a very loosely specified schema. It's very
// unlikely we'll be able to translate cue to
// typescript generics in the general case, though
// this particular one *may* be able to work.
Mappings *[]map[string]interface{} `json:"mappings,omitempty"`
Max *float32 `json:"max,omitempty"`
Min *float32 `json:"min,omitempty"`
Mappings *[]ValueMapping `json:"mappings,omitempty"`
Max *float32 `json:"max,omitempty"`
Min *float32 `json:"min,omitempty"`
// Alternative to empty string
NoValue *string `json:"noValue,omitempty"`
@@ -568,6 +757,54 @@ type Panel struct {
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type PanelRepeatDirection string
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type RangeMap struct {
Options struct {
// to and from are `number | null` in current ts, really not sure what to do
From int32 `json:"from"`
Result struct {
Color *string `json:"color,omitempty"`
Icon *string `json:"icon,omitempty"`
Index *int32 `json:"index,omitempty"`
Text *string `json:"text,omitempty"`
} `json:"result"`
To int32 `json:"to"`
} `json:"options"`
Type RangeMapType `json:"type"`
}
// RangeMapType is the Go representation of a RangeMap.Type.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type RangeMapType string
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type RegexMap struct {
Options struct {
Pattern string `json:"pattern"`
Result struct {
Color *string `json:"color,omitempty"`
Icon *string `json:"icon,omitempty"`
Index *int32 `json:"index,omitempty"`
Text *string `json:"text,omitempty"`
} `json:"result"`
} `json:"options"`
Type RegexMapType `json:"type"`
}
// RegexMapType is the Go representation of a RegexMap.Type.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type RegexMapType string
// Row panel
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
@@ -596,6 +833,42 @@ type RowPanel struct {
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type RowPanelType string
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type SpecialValueMap struct {
Options struct {
Match SpecialValueMapOptionsMatch `json:"match"`
Pattern string `json:"pattern"`
Result struct {
Color *string `json:"color,omitempty"`
Icon *string `json:"icon,omitempty"`
Index *int32 `json:"index,omitempty"`
Text *string `json:"text,omitempty"`
} `json:"result"`
} `json:"options"`
Type SpecialValueMapType `json:"type"`
}
// SpecialValueMapOptionsMatch is the Go representation of a SpecialValueMap.Options.Match.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type SpecialValueMapOptionsMatch string
// SpecialValueMapType is the Go representation of a SpecialValueMap.Type.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type SpecialValueMapType string
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type SpecialValueMatch string
// Schema for panel targets is specified by datasource
// plugins. We use a placeholder definition, which the Go
// schema loader either left open/as-is with the Base
@@ -671,6 +944,38 @@ type Transformation struct {
Options map[string]interface{} `json:"options"`
}
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type ValueMap struct {
Options map[string]interface{} `json:"options"`
Type ValueMapType `json:"type"`
}
// ValueMapType is the Go representation of a ValueMap.Type.
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type ValueMapType string
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type ValueMapping interface{}
// TODO docs
//
// THIS TYPE IS INTENDED FOR INTERNAL USE BY THE GRAFANA BACKEND, AND IS SUBJECT TO BREAKING CHANGES.
// Equivalent Go types at stable import paths are provided in https://github.com/grafana/grok.
type ValueMappingResult struct {
Color *string `json:"color,omitempty"`
Icon *string `json:"icon,omitempty"`
Index *int32 `json:"index,omitempty"`
Text *string `json:"text,omitempty"`
}
// FROM: packages/grafana-data/src/types/templateVars.ts
// TODO docs
// TODO what about what's in public/app/features/types.ts?