mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Docs: Add Schema maturity docs (#61963)
* Docs: Add Schema maturity docs * Remove 'which category' section from maturity.md Co-authored-by: sam boyer <sdboyer@grafana.com> * Remove Maturity process guides from maturity.md Co-authored-by: sam boyer <sdboyer@grafana.com> * Remove Defaults and Field optionality from maturity.md Co-authored-by: sam boyer <sdboyer@grafana.com> * Remove MaybeRemove section from maturity.md Co-authored-by: sam boyer <sdboyer@grafana.com> * Remove Milestone 3 and 4 from maturity.md Co-authored-by: sam boyer <sdboyer@grafana.com> * Rearrange schema maturity docs * Regenerate schema docs after merge with main * Update Maturity docs headers, keep single h1 * Update wording in Schema docs Co-authored-by: Tania <yalyna.ts@gmail.com> * Regenerate docs after merge with main --------- Co-authored-by: sam boyer <sdboyer@grafana.com> Co-authored-by: Tania <yalyna.ts@gmail.com>
This commit is contained in:
parent
121260e0dd
commit
0fcc864bbb
@ -7,4 +7,25 @@ _build:
|
||||
|
||||
# Grafana schema
|
||||
|
||||
{{< section >}}
|
||||
> Grafana’s schemas, kind system and related code generation are in active development.
|
||||
|
||||
Grafana is moving to a schema-centric model of development, where schemas are the single source of truth that specify
|
||||
the shape of objects - for example, dashboards, datasources, users - in the frontend, backend, and plugin code.
|
||||
Eventually, all of Grafana’s object types will be schematized within the “Kind System.” Kinds, their schemas, the Kind
|
||||
system rules, and associated code generators will collectively provide a clear, consistent foundation for Grafana’s
|
||||
APIs, documentation, persistent storage, clients, as-code tooling, and so forth.
|
||||
|
||||
It’s exciting to imagine the possibilities that a crisp, consistent development workflow will enable - this is why
|
||||
companies build [developer platforms](https://internaldeveloperplatform.org/)! At the same time, it’s also
|
||||
overwhelming - any schema system that can meet Grafana’s complex requirements will necessarily have a lot of moving
|
||||
parts. Additionally, we must account for having Grafana continue to work as we make the transition - a prerequisite
|
||||
for every large-scale refactoring.
|
||||
|
||||
In the Grafana ecosystem, there are three basic Kind categories and associated schema categories:
|
||||
- [Core Kinds]({{< relref "core/" >}})
|
||||
- Custom Kinds
|
||||
- [Composable Kinds]({{< relref "composable/" >}})
|
||||
|
||||
The schema authoring workflow for each varies, as does the path to maturity.
|
||||
[Grafana Kinds - From Zero to Maturity]({{< relref "maturity/" >}}) contains general reference material applicable to
|
||||
all Kind-writing, and links to the guides for each category of Kind.
|
||||
|
@ -8,7 +8,7 @@ title: AlertGroupsPanelCfg kind
|
||||
|
||||
## AlertGroupsPanelCfg
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: AnnotationsListPanelCfg kind
|
||||
|
||||
## AnnotationsListPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: AzureMonitorDataQuery kind
|
||||
|
||||
## AzureMonitorDataQuery
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: BarChartPanelCfg kind
|
||||
|
||||
## BarChartPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: BarGaugePanelCfg kind
|
||||
|
||||
## BarGaugePanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: CloudWatchDataQuery kind
|
||||
|
||||
## CloudWatchDataQuery
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: DashboardListPanelCfg kind
|
||||
|
||||
## DashboardListPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: DebugPanelCfg kind
|
||||
|
||||
## DebugPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: ElasticsearchDataQuery kind
|
||||
|
||||
## ElasticsearchDataQuery
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: GaugePanelCfg kind
|
||||
|
||||
## GaugePanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: HistogramPanelCfg kind
|
||||
|
||||
## HistogramPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: LokiDataQuery kind
|
||||
|
||||
## LokiDataQuery
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: NewsPanelCfg kind
|
||||
|
||||
## NewsPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: NodeGraphPanelCfg kind
|
||||
|
||||
## NodeGraphPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: PhlareDataQuery kind
|
||||
|
||||
## PhlareDataQuery
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: PieChartPanelCfg kind
|
||||
|
||||
## PieChartPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: StateTimelinePanelCfg kind
|
||||
|
||||
## StateTimelinePanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: StatPanelCfg kind
|
||||
|
||||
## StatPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: StatusHistoryPanelCfg kind
|
||||
|
||||
## StatusHistoryPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: TempoDataQuery kind
|
||||
|
||||
## TempoDataQuery
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: TestDataDataQuery kind
|
||||
|
||||
## TestDataDataQuery
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: TextPanelCfg kind
|
||||
|
||||
## TextPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: XYChartPanelCfg kind
|
||||
|
||||
## XYChartPanelCfg
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ title: Dashboard kind
|
||||
|
||||
## Dashboard
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
A Grafana dashboard.
|
||||
|
@ -8,7 +8,7 @@ title: LibraryPanel kind
|
||||
|
||||
## LibraryPanel
|
||||
|
||||
#### Maturity: experimental
|
||||
#### Maturity: [experimental](../../../maturity/#experimental)
|
||||
#### Version: 0.0
|
||||
|
||||
A standalone panel
|
||||
|
@ -8,7 +8,7 @@ title: Playlist kind
|
||||
|
||||
## Playlist
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
A playlist is a series of dashboards that is automatically rotated in the browser, on a configurable interval.
|
||||
|
@ -8,7 +8,7 @@ title: Preferences kind
|
||||
|
||||
## Preferences
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
The user or team frontend preferences
|
||||
|
@ -8,7 +8,7 @@ title: PublicDashboard kind
|
||||
|
||||
## PublicDashboard
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
Public dashboard configuration
|
||||
|
@ -8,7 +8,7 @@ title: ServiceAccount kind
|
||||
|
||||
## ServiceAccount
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
system account
|
||||
|
@ -8,7 +8,7 @@ title: Team kind
|
||||
|
||||
## Team
|
||||
|
||||
#### Maturity: merged
|
||||
#### Maturity: [merged](../../../maturity/#merged)
|
||||
#### Version: 0.0
|
||||
|
||||
A team is a named grouping of Grafana users to which access control rules may be assigned.
|
||||
|
292
docs/sources/developers/kinds/maturity.md
Normal file
292
docs/sources/developers/kinds/maturity.md
Normal file
@ -0,0 +1,292 @@
|
||||
---
|
||||
keywords:
|
||||
- grafana
|
||||
- schema
|
||||
- maturity
|
||||
title: Grafana Kinds - From Zero to Maturity
|
||||
weight: 300
|
||||
---
|
||||
|
||||
# Grafana Kinds - From Zero to Maturity
|
||||
|
||||
> Grafana’s schema, Kind, and related codegen systems are under intense development.
|
||||
|
||||
Fear of unknown impacts leads to defensive coding, slow PRs, circular arguments, and an overall hesitance to engage.
|
||||
That friction alone is sufficient to sink a large-scale project. This guide seeks to counteract this friction by
|
||||
defining an end goal for all schemas: “mature.” This is the word we’re using to refer to the commonsense notion of “this
|
||||
software reached 1.0.”
|
||||
|
||||
In general, 1.0/mature suggests: “we’ve thought about this thing, done the necessary experimenting, know what it is, and
|
||||
feel confident about presenting it to the world.” In the context of schemas intended to act as a single source of truth
|
||||
driving many use cases, we can intuitively phrase maturity as:
|
||||
|
||||
- The schema follows general best practices (e.g. good comments, follows field type rules), and the team owning the
|
||||
schema believes that the fields described in the schema are accurate.
|
||||
- Automation propagates the schema as source of truth to every relevant
|
||||
[domain](https://docs.google.com/document/d/13Rv395_T8WTLBgdL-2rbXKu0fx_TW-Q9yz9x6oBjm6g/edit#heading=h.67pop2k2f8fq)
|
||||
(for example: types in frontend, backend, as-code; plugins SDK; docs; APIs and storage; search indexing)
|
||||
|
||||
This intuitive definition gets us pointed in the right direction. But we can’t just jump straight there - we have to
|
||||
approach it methodically. To that end, this doc outlines four (ok five, but really, four) basic maturity milestones that
|
||||
we expect Kinds and their schemas to progress through:
|
||||
|
||||
- *(Planned - Put a Kind name on the official TODO list)*
|
||||
- **Merged** - Get an initial schema written down. Not final. Not perfect.
|
||||
- **Experimental** - Kind schemas are the source of truth for basic working code.
|
||||
- **Stable** - Kind schemas are the source of truth for all target domains.
|
||||
- **Mature** - The operational transition path for the Kind is battle-tested and reliable.
|
||||
|
||||
These milestones have functional definitions, tied to code and enforced in CI. A Kind having reached a particular
|
||||
milestone corresponds to properties of the code that are enforced in CI; advancing to the next milestone likely has a
|
||||
direct impact on code generation and runtime behavior.
|
||||
|
||||
Finally, the above definitions imply that maturity for *individual Kinds/schemas* depends on *the Kind system* being
|
||||
mature, as well. This is by design: **Grafana Labs does not intend to publicize any single schema as mature until
|
||||
[certain schema system milestones are met](https://github.com/orgs/grafana/projects/133/views/8).**
|
||||
|
||||
## Schema Maturity Milestones
|
||||
|
||||
Maturity milestones are a linear progression. Each milestone implies that the conditions of its predecessors continue to
|
||||
be met.
|
||||
|
||||
Reaching a particular milestone implies that the properties of all prior milestones are still met.
|
||||
|
||||
### (Milestone 0 - Planned) {#planned}
|
||||
|
||||
| **Goal** | Put a Kind name on the official TODO list: [Kind Schematization Progress Tracker](https://docs.google.com/spreadsheets/d/1DL6nZHyX42X013QraWYbKsMmHozLrtXDj8teLKvwYMY/edit#gid=0) |
|
||||
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Reached when** | The planned Kind is listed in the relevant sheet of the progress tracker with a link to track / be able to see when exactly it is planned and who is responsible for doing it |
|
||||
| **Common hurdles** | Existing definitions may not correspond clearly to an object boundary - e.g. playlists are currently in denormalized SQL tables playlist and playlist_item |
|
||||
| **Public-facing guarantees** | None |
|
||||
| **customer-facing stage** | None |
|
||||
|
||||
### Milestone 1 - Merged {#merged}
|
||||
|
||||
| **Goal** | Get an initial schema written down. Not final. Not perfect. |
|
||||
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Reached when** | A PR introducing the initial version of a schema has been merged. |
|
||||
| **Common hurdles** | Getting comfortable with Thema and CUE<br/>Figuring out where all the existing definitions of the Kind are<br/>Knowing whether it’s safe to omit possibly-crufty fields from the existing definitions when writing the schema |
|
||||
| **Public-facing guarantees** | None |
|
||||
| **User-facing stage** | None |
|
||||
|
||||
### Milestone 2 - Experimental {#experimental}
|
||||
|
||||
| **Goal** | Schemas are the source of truth for basic working code. |
|
||||
|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Reached when** | Go and TypeScript types generated from schema are used in all relevant production code, having replaced handwritten type definitions (if any). |
|
||||
| **Common hurdles** | Compromises on field definitions that seemed fine to reach “committed” start to feel unacceptable<br/>Ergonomics of generated code may start to bite<br/>Aligning with the look and feel of related schemas |
|
||||
| **Public-facing guarantees** | Kinds are available for as-code usage in [grok](https://github.com/grafana/grok), and in tools downstream of grok, following all of grok’s standard patterns. |
|
||||
| **Stage comms** | Internal users:- Start using the schema and give feedback internally to help move to the next stage.External users:- Align with the [experimental](https://docs.google.com/document/d/1lqp0hALax2PT7jSObsX52EbQmIDFnLFMqIbBrJ4EYCE/edit#heading=h.ehl5iy7pcjvq) stage in the release definition document. - Experimental schemas will be discoverable, and from a customer PoV should never be used in production, but they can be explored and we are more than happy to receive feedback |
|
||||
|
||||
|
||||
## Schema-writing guidelines
|
||||
|
||||
### Avoid anonymous nested structs
|
||||
|
||||
***Always name your sub-objects.***
|
||||
|
||||
In CUE, nesting structs is like nesting objects in JSON, and just as easy:
|
||||
~~~ json
|
||||
one: {
|
||||
two: {
|
||||
three: {
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
While these can be accurately represented in other languages, they aren’t especially friendly to work with:
|
||||
|
||||
~~~ typescript
|
||||
// TypeScript
|
||||
export interface One {
|
||||
two: {
|
||||
three: string;
|
||||
};
|
||||
}
|
||||
~~~
|
||||
|
||||
~~~ go
|
||||
// Go
|
||||
type One struct {
|
||||
Two struct {
|
||||
Three string `json:"three"`
|
||||
} `json:"two"`
|
||||
}
|
||||
~~~
|
||||
|
||||
Instead, within your schema, prefer to make root-level definitions with the appropriate attributes:
|
||||
|
||||
~~~ cue
|
||||
// Cue
|
||||
one: {
|
||||
two: #Two
|
||||
#Two: {
|
||||
three: string
|
||||
} @cuetsy(kind="interface")
|
||||
}
|
||||
~~~
|
||||
|
||||
~~~ Typescript
|
||||
// TypeScript
|
||||
export interface Two {
|
||||
three: string;
|
||||
}
|
||||
export interface One {
|
||||
two: Two;
|
||||
}
|
||||
~~~
|
||||
|
||||
~~~ Go
|
||||
// Go
|
||||
type One struct {
|
||||
Two Two `json:"two"`
|
||||
}
|
||||
type Two struct {
|
||||
Three string `json:"three"`
|
||||
}
|
||||
~~~
|
||||
|
||||
### Use precise numeric types
|
||||
|
||||
***Use precise numeric types like `float64` or `uint32`. Never use `number`.***
|
||||
|
||||
Never use `number` for a numeric type in a schema.
|
||||
|
||||
Instead, use a specific, sized type like `int64` or `float32`. This makes your intent precisely clear.
|
||||
TypeScript will still represent these fields with `number`, but other languages (e.g. Go, Protobuf) can be more precise.
|
||||
|
||||
Unlike in Go, int and uint are not your friends. These correspond to `math/big` types. Use a sized type,
|
||||
like `uint32` or `int32`, unless the use case specifically requires a huge numeric space.
|
||||
|
||||
### No explicit `null`
|
||||
|
||||
***Do not use `null` as a type in any schema.***
|
||||
|
||||
This one is tricky to think about, and requires some background.
|
||||
|
||||
Historically, Grafana’s dashboard JSON has often contained fields with the explicit value `null`.
|
||||
This was problematic, because explicit `null` introduces an ambiguity: is a JSON field being present
|
||||
with value null meaningfully different from the field being absent? That is, should a program behave differently
|
||||
if it encounters a null vs. an absent field?
|
||||
|
||||
In almost all cases, the answer is “no.” Thus, the ambiguity: if both explicit null and absence are *accepted*
|
||||
by a system, it pushes responsibility onto anyone writing code in that system to decide, case-by-case,
|
||||
whether the two are *intended to be meaningfully different*, and therefore whether behavior should be different.
|
||||
|
||||
CUE does have a `null` type, and only accepts data containing `nulls` as valid if the schema explicitly allows a `null`.
|
||||
That means, by default, using CUE for schemas removes the possibility of ambiguity in code that receives data validated
|
||||
by those schemas, even if the language they’re writing in still allows for ambiguity. (Javascript does, Go doesn’t.)
|
||||
|
||||
As a schema author, this means you’re being unambiguous by default - no `nulls`. That’s good! The only question is
|
||||
whether it’s worth explicitly allowing a `null` for some particular case:
|
||||
~~~ Cue
|
||||
someField: int32 | null
|
||||
~~~
|
||||
|
||||
The *only* time this *may* be a good idea is if your field needs to be able to represent a value
|
||||
that is not otherwise acceptable within the value space - for example, if `someField` needs to be able to contain
|
||||
[Infinity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY).
|
||||
When such values are serialized to null by default, it can be convenient to accept null in the schema - but even then,
|
||||
explicit null is unlikely to be the best way to represent such values, because it is so subtle and falsey.
|
||||
|
||||
**Above all, DO NOT accept `null` in a schema simply because current behavior sometimes unintentionally produces a `null`.**
|
||||
Schematization is an opportunity to get rid of this ambiguity. Fix the accidental null-producing behavior, instead.
|
||||
|
||||
### Issues
|
||||
|
||||
- If a schema has a "kind" field and its set as enum, it generates a Kind alias that conflicts with the generated
|
||||
Kind struct.
|
||||
- Byte fields are existing in Go but not in TS, so the generator fails.
|
||||
- **omitempty** is useful when we return things like json.RawMessage (alias of []byte) because Postgres saves this
|
||||
information as `nil`, when MySQL and SQLite save it as `{}`. If we found it in the rest of the cases, it isn't necessary
|
||||
to set `?` in the field in the schema.
|
||||
|
||||
|
||||
## Schema Attributes
|
||||
|
||||
Grafana’s schema system relies on [CUE attributes](https://cuelang.org/docs/references/spec/#attributes)declared on
|
||||
properties within schemas to control some aspects of code generation behavior.
|
||||
In a schema, an attribute is the whole of `@cuetsy(kind=”type”)`:
|
||||
|
||||
~~~ Cue
|
||||
field: string @cuetsy(kind="type")
|
||||
~~~
|
||||
|
||||
CUE attributes are purely informational - they cannot influence CUE evaluation behavior, including the types being
|
||||
expressed in a Thema schema.
|
||||
|
||||
CUE attributes have three parts. In `@cuetsy(kind=”type”)`, those are:
|
||||
- name - `@cuetsy`
|
||||
- arg - `kind`
|
||||
- argval - `“type”`
|
||||
|
||||
Any given attribute may consist of `{name}`, `{name,arg}`, or `{name,arg,argval}`. These three levels form a tree
|
||||
(meaning of any argval is specific to its arg, which is specific to its name). The following documentation represents
|
||||
this tree using a header hierarchy.
|
||||
|
||||
### @cuetsy
|
||||
|
||||
These attributes control the behavior of the [cuetsy code generator](https://github.com/grafana/cuetsy), which converts
|
||||
CUE to TypeScript. We include only the kind arg here for brevity; cuetsy’s README has the canonical documentation on all
|
||||
supported args and argvals, and their intended usage.
|
||||
|
||||
Notes:
|
||||
- Only top-level fields in a Thema schema are scanned for `@cuetsy` attributes.
|
||||
- Grafana’s code generators hardcode that an interface (`@cuetsy(kind=”interface”)`) is generated to represent the root
|
||||
schema object, unless it is known to be a [grouped lineage](https://docs.google.com/document/d/13Rv395_T8WTLBgdL-2rbXKu0fx_TW-Q9yz9x6oBjm6g/edit#heading=h.vx7stzpxtw4t).
|
||||
|
||||
#### kind
|
||||
|
||||
Indicates the kind of TypeScript symbol that should be generated for that schema field.
|
||||
|
||||
#### interface
|
||||
|
||||
Generate the schema field as a TS interface. Field must be struct-kinded.
|
||||
|
||||
#### enum
|
||||
|
||||
Generate the schema field as a TS enum. Field must be either int-kinded (numeric enums) or string-kinded (string enums).
|
||||
|
||||
#### type
|
||||
|
||||
Generate the schema field as a TS type alias.
|
||||
|
||||
### @grafana
|
||||
|
||||
These attributes control code generation behaviors that are specific to Grafana core. Some may also be supported
|
||||
in plugin code generators.
|
||||
|
||||
#### TSVeneer
|
||||
|
||||
Applying a TSVeneer arg to a field in a schema indicates that the schema author wants to enrich the generated type
|
||||
(for example by adding generic type parameters), so code generation should expect a handwritten
|
||||
[veneer](https://docs.google.com/document/d/13Rv395_T8WTLBgdL-2rbXKu0fx_TW-Q9yz9x6oBjm6g/edit#heading=h.bmtjq0bb1yxp).
|
||||
|
||||
TSVeneer requires at least one argval, each of which impacts TypeScript code generation in its own way.
|
||||
Multiple argvals may be given, separated by `|`.
|
||||
|
||||
A TSVeneer arg has no effect if it is applied to a field that is not exported as a standalone TypeScript type
|
||||
(which usually means a CUE field that also has an `@cuetsy(kind=)` attribute).
|
||||
|
||||
#### type
|
||||
|
||||
A handwritten veneer is needed to refine the raw generated TypeScript type, for example by adding generics.
|
||||
See [the dashboard types veneer](https://github.com/grafana/grafana/blob/5f93e67419e9587363d1fc1e6f1f4a8044eb54d0/packages/grafana-schema/src/veneer/dashboard.types.ts)
|
||||
for an example, and [some](https://github.com/grafana/grafana/blob/5f93e67419e9587363d1fc1e6f1f4a8044eb54d0/kinds/dashboard/dashboard_kind.cue#L12)
|
||||
[corresponding](https://github.com/grafana/grafana/blob/5f93e67419e9587363d1fc1e6f1f4a8044eb54d0/kinds/dashboard/dashboard_kind.cue#L143)
|
||||
CUE attributes.
|
||||
|
||||
### @grafanamaturity
|
||||
|
||||
These attributes are used to support iterative development of a schema towards maturity.
|
||||
|
||||
Grafana code generators and CI enforce that schemas marked as mature MUST NOT have any `@grafanamaturity` attributes.
|
||||
|
||||
#### NeedsExpertReview
|
||||
|
||||
Indicates that a non-expert on that schema wrote the field, and was not fully confident in its type and/or docs.
|
||||
|
||||
Primarily useful on very large schemas, like the dashboard schema, for getting *something* written down for a given
|
||||
field that at least makes validation tests pass, but making clear that the field isn’t necessarily properly correct.
|
||||
|
||||
No argval is accepted. (Use a `//` comment to say more about the attention that’s needed.)
|
@ -71,7 +71,7 @@ func (j docsJenny) Generate(kind kindsys.Kind) (*codejen.File, error) {
|
||||
data := templateData{
|
||||
KindName: kindProps.Name,
|
||||
KindVersion: kind.Lineage().Latest().Version().String(),
|
||||
KindMaturity: string(kindProps.Maturity),
|
||||
KindMaturity: fmt.Sprintf("[%s](../../../maturity/#%[1]s)", kindProps.Maturity),
|
||||
KindDescription: kindProps.Description,
|
||||
Markdown: "{{ .Markdown 1 }}",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user