diff --git a/Makefile b/Makefile index a5353e95567..e4a261acb4b 100644 --- a/Makefile +++ b/Makefile @@ -135,7 +135,7 @@ i18n-extract-enterprise: @echo "Skipping i18n extract for Enterprise: not enabled" else i18n-extract-enterprise: - @echo "Extracting i18n strings for Enterprise" + @echo "Extracting i18n strings for Enterprise" cd public/locales/enterprise && yarn run i18next-cli extract --sync-primary endif @@ -227,6 +227,10 @@ fix-cue: gen-jsonnet: go generate ./devenv/jsonnet +.PHONY: gen-themes +gen-themes: + go generate ./pkg/services/preference + .PHONY: update-workspace update-workspace: gen-go @echo "updating workspace" @@ -244,6 +248,7 @@ build-go-fast: ## Build all Go binaries without updating workspace. .PHONY: build-backend build-backend: ## Build Grafana backend. @echo "build backend" + $(MAKE) gen-themes $(GO) run build.go $(GO_BUILD_FLAGS) build-backend .PHONY: build-air diff --git a/package.json b/package.json index 72a8f638cb6..a6887b216e4 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,7 @@ "stats": "webpack --mode production --config scripts/webpack/webpack.prod.js --profile --json > compilation-stats.json", "storybook": "yarn workspace @grafana/ui storybook --ci", "storybook:build": "yarn workspace @grafana/ui storybook:build", - "themes-schema": "typescript-json-schema ./tsconfig.json NewThemeOptions --include 'packages/grafana-data/src/themes/createTheme.ts' --out public/app/features/theme-playground/schema.generated.json", - "themes-generate": "yarn themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --conditions=@grafana-app/source --platform=node --tsconfig=./scripts/cli/tsconfig.json | node", + "themes-generate": "yarn workspace @grafana/data themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --conditions=@grafana-app/source --platform=node --tsconfig=./scripts/cli/tsconfig.json | node", "themes:usage": "eslint . --ignore-pattern '*.test.ts*' --ignore-pattern '*.spec.ts*' --cache --plugin '@grafana' --rule '{ @grafana/theme-token-usage: \"error\" }'", "typecheck": "tsc --noEmit && yarn run packages:typecheck", "plugins:build-bundled": "echo 'bundled plugins are no longer supported'", @@ -254,7 +253,6 @@ "ts-jest": "29.4.0", "ts-node": "10.9.2", "typescript": "5.9.2", - "typescript-json-schema": "^0.65.1", "webpack": "5.101.0", "webpack-assets-manifest": "^5.1.0", "webpack-cli": "6.0.1", @@ -265,7 +263,7 @@ "webpackbar": "^7.0.0", "yaml": "^2.0.0", "yargs": "^18.0.0", - "zod": "^4.0.0" + "zod": "^4.3.0" }, "dependencies": { "@bsull/augurs": "^0.10.0", diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index df595973cca..384666ea7f8 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -47,11 +47,12 @@ "LICENSE_APACHE2" ], "scripts": { - "build": "tsc -p ./tsconfig.build.json && rollup -c rollup.config.ts --configPlugin esbuild", + "build": "yarn themes-schema && tsc -p ./tsconfig.build.json && rollup -c rollup.config.ts --configPlugin esbuild", "clean": "rimraf ./dist ./compiled ./unstable ./package.tgz", "typecheck": "tsc --emitDeclarationOnly false --noEmit", "prepack": "cp package.json package.json.bak && node ../../scripts/prepare-npm-package.js", - "postpack": "mv package.json.bak package.json" + "postpack": "mv package.json.bak package.json", + "themes-schema": "tsx ./src/themes/scripts/generateSchema.ts" }, "dependencies": { "@braintree/sanitize-url": "7.0.1", @@ -81,10 +82,12 @@ "tinycolor2": "1.6.0", "tslib": "2.8.1", "uplot": "1.6.32", - "xss": "^1.0.14" + "xss": "^1.0.14", + "zod": "^4.3.0" }, "devDependencies": { "@grafana/scenes": "6.38.0", + "@rollup/plugin-json": "6.1.0", "@rollup/plugin-node-resolve": "16.0.1", "@testing-library/react": "16.3.0", "@types/history": "4.7.11", @@ -101,6 +104,7 @@ "rollup": "^4.22.4", "rollup-plugin-esbuild": "6.2.1", "rollup-plugin-node-externals": "^8.0.0", + "tsx": "^4.21.0", "typescript": "5.9.2" }, "peerDependencies": { diff --git a/packages/grafana-data/rollup.config.ts b/packages/grafana-data/rollup.config.ts index 87008ddc45f..0c40d731724 100644 --- a/packages/grafana-data/rollup.config.ts +++ b/packages/grafana-data/rollup.config.ts @@ -1,3 +1,4 @@ +import json from '@rollup/plugin-json'; import { createRequire } from 'node:module'; import { entryPoint, plugins, esmOutput, cjsOutput } from '../rollup.config.parts'; @@ -8,13 +9,13 @@ const pkg = rq('./package.json'); export default [ { input: entryPoint, - plugins, + plugins: [...plugins, json()], output: [cjsOutput(pkg, 'grafana-data'), esmOutput(pkg, 'grafana-data')], treeshake: false, }, { input: 'src/unstable.ts', - plugins, + plugins: [...plugins, json()], output: [cjsOutput(pkg, 'grafana-data'), esmOutput(pkg, 'grafana-data')], treeshake: false, }, diff --git a/packages/grafana-data/src/internal/index.ts b/packages/grafana-data/src/internal/index.ts index e2dab753baa..1b1e3c64a7d 100644 --- a/packages/grafana-data/src/internal/index.ts +++ b/packages/grafana-data/src/internal/index.ts @@ -106,3 +106,4 @@ export { findNumericFieldMinMax } from '../field/fieldOverrides'; export { type PanelOptionsSupplier } from '../panel/PanelPlugin'; export { sanitize, sanitizeUrl } from '../text/sanitize'; export { type NestedValueAccess, type NestedPanelOptions, isNestedPanelOptions } from '../utils/OptionsUIBuilders'; +export { NewThemeOptionsSchema } from '../themes/createTheme'; diff --git a/packages/grafana-data/src/themes/createColors.ts b/packages/grafana-data/src/themes/createColors.ts index 09b94fd3b3e..ee7beab02d6 100644 --- a/packages/grafana-data/src/themes/createColors.ts +++ b/packages/grafana-data/src/themes/createColors.ts @@ -1,83 +1,103 @@ import { merge } from 'lodash'; +import { z } from 'zod'; import { alpha, darken, emphasize, getContrastRatio, lighten } from './colorManipulator'; import { palette } from './palette'; -import { DeepPartial, ThemeRichColor } from './types'; +import { DeepRequired, ThemeRichColor, ThemeRichColorInputSchema } from './types'; +const ThemeColorsModeSchema = z.enum(['light', 'dark']); /** @internal */ -export type ThemeColorsMode = 'light' | 'dark'; +export type ThemeColorsMode = z.infer; +const createThemeColorsBaseSchema = (color: TColor) => + z + .object({ + mode: ThemeColorsModeSchema, + + primary: color, + secondary: color, + info: color, + error: color, + success: color, + warning: color, + + text: z.object({ + primary: z.string().optional(), + secondary: z.string().optional(), + disabled: z.string().optional(), + link: z.string().optional(), + /** Used for auto white or dark text on colored backgrounds */ + maxContrast: z.string().optional(), + }), + + background: z.object({ + /** Dashboard and body background */ + canvas: z.string().optional(), + /** Primary content pane background (panels etc) */ + primary: z.string().optional(), + /** Cards and elements that need to stand out on the primary background */ + secondary: z.string().optional(), + /** + * For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark + * themes it has a brighter shade to help give it contrast against the primary background. + **/ + elevated: z.string().optional(), + }), + + border: z.object({ + weak: z.string().optional(), + medium: z.string().optional(), + strong: z.string().optional(), + }), + + gradients: z.object({ + brandVertical: z.string().optional(), + brandHorizontal: z.string().optional(), + }), + + action: z.object({ + /** Used for selected menu item / select option */ + selected: z.string().optional(), + /** + * @alpha (Do not use from plugins) + * Used for selected items when background only change is not enough (Currently only used for FilterPill) + **/ + selectedBorder: z.string().optional(), + /** Used for hovered menu item / select option */ + hover: z.string().optional(), + /** Used for button/colored background hover opacity */ + hoverOpacity: z.number().optional(), + /** Used focused menu item / select option */ + focus: z.string().optional(), + /** Used for disabled buttons and inputs */ + disabledBackground: z.string().optional(), + /** Disabled text */ + disabledText: z.string().optional(), + /** Disablerd opacity */ + disabledOpacity: z.number().optional(), + }), + + hoverFactor: z.number(), + contrastThreshold: z.number(), + tonalOffset: z.number(), + }) + .partial(); + +// Need to override the zod type to include the generic properly /** @internal */ -export interface ThemeColorsBase { - mode: ThemeColorsMode; - +export type ThemeColorsBase = DeepRequired< + Omit< + z.infer>, + 'primary' | 'secondary' | 'info' | 'error' | 'success' | 'warning' + > +> & { primary: TColor; secondary: TColor; info: TColor; error: TColor; success: TColor; warning: TColor; - - text: { - primary: string; - secondary: string; - disabled: string; - link: string; - /** Used for auto white or dark text on colored backgrounds */ - maxContrast: string; - }; - - background: { - /** Dashboard and body background */ - canvas: string; - /** Primary content pane background (panels etc) */ - primary: string; - /** Cards and elements that need to stand out on the primary background */ - secondary: string; - /** - * For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark - * themes it has a brighter shade to help give it contrast against the primary background. - **/ - elevated: string; - }; - - border: { - weak: string; - medium: string; - strong: string; - }; - - gradients: { - brandVertical: string; - brandHorizontal: string; - }; - - action: { - /** Used for selected menu item / select option */ - selected: string; - /** - * @alpha (Do not use from plugins) - * Used for selected items when background only change is not enough (Currently only used for FilterPill) - **/ - selectedBorder: string; - /** Used for hovered menu item / select option */ - hover: string; - /** Used for button/colored background hover opacity */ - hoverOpacity: number; - /** Used focused menu item / select option */ - focus: string; - /** Used for disabled buttons and inputs */ - disabledBackground: string; - /** Disabled text */ - disabledText: string; - /** Disablerd opacity */ - disabledOpacity: number; - }; - - hoverFactor: number; - contrastThreshold: number; - tonalOffset: number; -} +}; export interface ThemeHoverStrengh {} @@ -89,8 +109,10 @@ export interface ThemeColors extends ThemeColorsBase { emphasize(color: string, amount?: number): string; } +export const ThemeColorsInputSchema = createThemeColorsBaseSchema(ThemeRichColorInputSchema); + /** @internal */ -export type ThemeColorsInput = DeepPartial>; +export type ThemeColorsInput = z.infer; class DarkColors implements ThemeColorsBase> { mode: ThemeColorsMode = 'dark'; diff --git a/packages/grafana-data/src/themes/createShape.ts b/packages/grafana-data/src/themes/createShape.ts index 42291fb78d0..f454eda6861 100644 --- a/packages/grafana-data/src/themes/createShape.ts +++ b/packages/grafana-data/src/themes/createShape.ts @@ -1,3 +1,5 @@ +import { z } from 'zod'; + /** @beta */ export interface ThemeShape { /** @@ -34,9 +36,12 @@ export interface Radii { } /** @internal */ -export interface ThemeShapeInput { - borderRadius?: number; -} +export const ThemeShapeInputSchema = z.object({ + borderRadius: z.int().nonnegative().optional(), +}); + +/** @internal */ +export type ThemeShapeInput = z.infer; export function createShape(options: ThemeShapeInput): ThemeShape { const baseBorderRadius = options.borderRadius ?? 6; diff --git a/packages/grafana-data/src/themes/createSpacing.ts b/packages/grafana-data/src/themes/createSpacing.ts index 2fa047b3e68..1ba51c61917 100644 --- a/packages/grafana-data/src/themes/createSpacing.ts +++ b/packages/grafana-data/src/themes/createSpacing.ts @@ -1,11 +1,15 @@ // Code based on Material UI // The MIT License (MIT) // Copyright (c) 2014 Call-Em-All +import { z } from 'zod'; /** @internal */ -export type ThemeSpacingOptions = { - gridSize?: number; -}; +export const ThemeSpacingOptionsSchema = z.object({ + gridSize: z.int().positive().optional(), +}); + +/** @internal */ +export type ThemeSpacingOptions = z.infer; /** @internal */ export type ThemeSpacingArgument = number | string; diff --git a/packages/grafana-data/src/themes/createTheme.ts b/packages/grafana-data/src/themes/createTheme.ts index fd4d8080a4e..a4fa773cf52 100644 --- a/packages/grafana-data/src/themes/createTheme.ts +++ b/packages/grafana-data/src/themes/createTheme.ts @@ -1,28 +1,37 @@ +import * as z from 'zod'; + import { createBreakpoints } from './breakpoints'; -import { createColors, ThemeColorsInput } from './createColors'; +import { createColors, ThemeColorsInputSchema } from './createColors'; import { createComponents } from './createComponents'; import { createShadows } from './createShadows'; -import { createShape, ThemeShapeInput } from './createShape'; -import { createSpacing, ThemeSpacingOptions } from './createSpacing'; +import { createShape, ThemeShapeInputSchema } from './createShape'; +import { createSpacing, ThemeSpacingOptionsSchema } from './createSpacing'; import { createTransitions } from './createTransitions'; -import { createTypography, ThemeTypographyInput } from './createTypography'; +import { createTypography, ThemeTypographyInputSchema } from './createTypography'; import { createV1Theme } from './createV1Theme'; -import { createVisualizationColors, ThemeVisualizationColorsInput } from './createVisualizationColors'; +import { createVisualizationColors, ThemeVisualizationColorsInputSchema } from './createVisualizationColors'; import { GrafanaTheme2 } from './types'; import { zIndex } from './zIndex'; -/** @internal */ -export interface NewThemeOptions { - name?: string; - colors?: ThemeColorsInput; - spacing?: ThemeSpacingOptions; - shape?: ThemeShapeInput; - typography?: ThemeTypographyInput; - visualization?: ThemeVisualizationColorsInput; -} +export const NewThemeOptionsSchema = z.object({ + name: z.string(), + id: z.string(), + colors: ThemeColorsInputSchema.optional(), + spacing: ThemeSpacingOptionsSchema.optional(), + shape: ThemeShapeInputSchema.optional(), + typography: ThemeTypographyInputSchema.optional(), + visualization: ThemeVisualizationColorsInputSchema.optional(), +}); /** @internal */ -export function createTheme(options: NewThemeOptions = {}): GrafanaTheme2 { +export type NewThemeOptions = z.infer; + +/** @internal */ +export function createTheme( + options: Omit & { + name?: NewThemeOptions['name']; + } = {} +): GrafanaTheme2 { const { name, colors: colorsInput = {}, diff --git a/packages/grafana-data/src/themes/createTypography.ts b/packages/grafana-data/src/themes/createTypography.ts index 25c5fa7c91b..3504e52d2fa 100644 --- a/packages/grafana-data/src/themes/createTypography.ts +++ b/packages/grafana-data/src/themes/createTypography.ts @@ -1,6 +1,7 @@ // Code based on Material UI // The MIT License (MIT) // Copyright (c) 2014 Call-Em-All +import { z } from 'zod'; import { ThemeColors } from './createColors'; @@ -40,18 +41,20 @@ export interface ThemeTypographyVariant { letterSpacing?: string; } -export interface ThemeTypographyInput { - fontFamily?: string; - fontFamilyMonospace?: string; - fontSize?: number; - fontWeightLight?: number; - fontWeightRegular?: number; - fontWeightMedium?: number; - fontWeightBold?: number; - // hat's the font-size on the html element. +export const ThemeTypographyInputSchema = z.object({ + fontFamily: z.string().optional(), + fontFamilyMonospace: z.string().optional(), + fontSize: z.number().positive().optional(), + fontWeightLight: z.number().positive().optional(), + fontWeightRegular: z.number().positive().optional(), + fontWeightMedium: z.number().positive().optional(), + fontWeightBold: z.number().positive().optional(), + // what's the font-size on the html element. // 16px is the default font-size used by browsers. - htmlFontSize?: number; -} + htmlFontSize: z.number().positive().optional(), +}); + +export type ThemeTypographyInput = z.infer; const defaultFontFamily = "'Inter', 'Helvetica', 'Arial', sans-serif"; const defaultFontFamilyMonospace = "'Roboto Mono', monospace"; diff --git a/packages/grafana-data/src/themes/createVisualizationColors.ts b/packages/grafana-data/src/themes/createVisualizationColors.ts index fca963c9c07..90acbbc2144 100644 --- a/packages/grafana-data/src/themes/createVisualizationColors.ts +++ b/packages/grafana-data/src/themes/createVisualizationColors.ts @@ -1,3 +1,5 @@ +import { z } from 'zod'; + import { FALLBACK_COLOR } from '../types/fieldColor'; import { ThemeColors } from './createColors'; @@ -26,29 +28,44 @@ export interface ThemeVizColor { type ThemeVizColorName = 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple'; -type ThemeVizColorShadeName = - | `super-light-${T}` - | `light-${T}` - | T - | `semi-dark-${T}` - | `dark-${T}`; +const createShadeSchema = (color: T extends ThemeVizColorName ? T : never) => + z.enum([`super-light-${color}`, `light-${color}`, color, `semi-dark-${color}`, `dark-${color}`]); -type ThemeVizHueGeneric = T extends ThemeVizColorName - ? { - name: T; - shades: Array>; - } - : never; +type ThemeVizColorShadeName = z.infer>>; + +const createHueSchema = (color: T extends ThemeVizColorName ? T : never) => + z.object({ + name: z.literal(color), + shades: z.array( + z.object({ + color: z.string(), + name: createShadeSchema(color), + aliases: z.array(z.string()).optional(), + primary: z.boolean().optional(), + }) + ), + }); + +const ThemeVizHueSchema = z.union([ + createHueSchema('red'), + createHueSchema('orange'), + createHueSchema('yellow'), + createHueSchema('green'), + createHueSchema('blue'), + createHueSchema('purple'), +]); /** * @alpha */ -export type ThemeVizHue = ThemeVizHueGeneric; +export type ThemeVizHue = z.infer; -export type ThemeVisualizationColorsInput = { - hues?: ThemeVizHue[]; - palette?: string[]; -}; +export const ThemeVisualizationColorsInputSchema = z.object({ + hues: z.array(ThemeVizHueSchema).optional(), + palette: z.array(z.string()).optional(), +}); + +export type ThemeVisualizationColorsInput = z.infer; /** * @internal diff --git a/packages/grafana-data/src/themes/registry.ts b/packages/grafana-data/src/themes/registry.ts index c4cf352b622..4fca3c5d7be 100644 --- a/packages/grafana-data/src/themes/registry.ts +++ b/packages/grafana-data/src/themes/registry.ts @@ -1,6 +1,6 @@ import { Registry, RegistryItem } from '../utils/Registry'; -import { createTheme } from './createTheme'; +import { createTheme, NewThemeOptionsSchema } from './createTheme'; import * as extraThemes from './themeDefinitions'; import { GrafanaTheme2 } from './types'; @@ -42,9 +42,6 @@ export function getBuiltInThemes(allowedExtras: string[]) { return sortedThemes; } -/** - * There is also a backend list at pkg/services/preference/themes.go - */ const themeRegistry = new Registry(() => { return [ { id: 'system', name: 'System preference', build: getSystemPreferenceTheme }, @@ -53,13 +50,19 @@ const themeRegistry = new Registry(() => { ]; }); -for (const [id, theme] of Object.entries(extraThemes)) { - themeRegistry.register({ - id, - name: theme.name ?? '', - build: () => createTheme(theme), - isExtra: true, - }); +for (const [name, json] of Object.entries(extraThemes)) { + const result = NewThemeOptionsSchema.safeParse(json); + if (!result.success) { + console.error(`Invalid theme definition for theme ${name}: ${result.error.message}`); + } else { + const theme = result.data; + themeRegistry.register({ + id: theme.id, + name: theme.name, + build: () => createTheme(theme), + isExtra: true, + }); + } } function getSystemPreferenceTheme() { diff --git a/packages/grafana-data/src/themes/schema.generated.json b/packages/grafana-data/src/themes/schema.generated.json new file mode 100644 index 00000000000..366ab9c05d6 --- /dev/null +++ b/packages/grafana-data/src/themes/schema.generated.json @@ -0,0 +1,608 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "colors": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": ["light", "dark"] + }, + "primary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "main": { + "type": "string" + }, + "shade": { + "type": "string" + }, + "text": { + "type": "string" + }, + "border": { + "type": "string" + }, + "transparent": { + "type": "string" + }, + "borderTransparent": { + "type": "string" + }, + "contrastText": { + "type": "string" + } + }, + "additionalProperties": false + }, + "secondary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "main": { + "type": "string" + }, + "shade": { + "type": "string" + }, + "text": { + "type": "string" + }, + "border": { + "type": "string" + }, + "transparent": { + "type": "string" + }, + "borderTransparent": { + "type": "string" + }, + "contrastText": { + "type": "string" + } + }, + "additionalProperties": false + }, + "info": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "main": { + "type": "string" + }, + "shade": { + "type": "string" + }, + "text": { + "type": "string" + }, + "border": { + "type": "string" + }, + "transparent": { + "type": "string" + }, + "borderTransparent": { + "type": "string" + }, + "contrastText": { + "type": "string" + } + }, + "additionalProperties": false + }, + "error": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "main": { + "type": "string" + }, + "shade": { + "type": "string" + }, + "text": { + "type": "string" + }, + "border": { + "type": "string" + }, + "transparent": { + "type": "string" + }, + "borderTransparent": { + "type": "string" + }, + "contrastText": { + "type": "string" + } + }, + "additionalProperties": false + }, + "success": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "main": { + "type": "string" + }, + "shade": { + "type": "string" + }, + "text": { + "type": "string" + }, + "border": { + "type": "string" + }, + "transparent": { + "type": "string" + }, + "borderTransparent": { + "type": "string" + }, + "contrastText": { + "type": "string" + } + }, + "additionalProperties": false + }, + "warning": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "main": { + "type": "string" + }, + "shade": { + "type": "string" + }, + "text": { + "type": "string" + }, + "border": { + "type": "string" + }, + "transparent": { + "type": "string" + }, + "borderTransparent": { + "type": "string" + }, + "contrastText": { + "type": "string" + } + }, + "additionalProperties": false + }, + "text": { + "type": "object", + "properties": { + "primary": { + "type": "string" + }, + "secondary": { + "type": "string" + }, + "disabled": { + "type": "string" + }, + "link": { + "type": "string" + }, + "maxContrast": { + "type": "string" + } + }, + "additionalProperties": false + }, + "background": { + "type": "object", + "properties": { + "canvas": { + "type": "string" + }, + "primary": { + "type": "string" + }, + "secondary": { + "type": "string" + }, + "elevated": { + "type": "string" + } + }, + "additionalProperties": false + }, + "border": { + "type": "object", + "properties": { + "weak": { + "type": "string" + }, + "medium": { + "type": "string" + }, + "strong": { + "type": "string" + } + }, + "additionalProperties": false + }, + "gradients": { + "type": "object", + "properties": { + "brandVertical": { + "type": "string" + }, + "brandHorizontal": { + "type": "string" + } + }, + "additionalProperties": false + }, + "action": { + "type": "object", + "properties": { + "selected": { + "type": "string" + }, + "selectedBorder": { + "type": "string" + }, + "hover": { + "type": "string" + }, + "hoverOpacity": { + "type": "number" + }, + "focus": { + "type": "string" + }, + "disabledBackground": { + "type": "string" + }, + "disabledText": { + "type": "string" + }, + "disabledOpacity": { + "type": "number" + } + }, + "additionalProperties": false + }, + "hoverFactor": { + "type": "number" + }, + "contrastThreshold": { + "type": "number" + }, + "tonalOffset": { + "type": "number" + } + }, + "additionalProperties": false + }, + "spacing": { + "type": "object", + "properties": { + "gridSize": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + } + }, + "additionalProperties": false + }, + "shape": { + "type": "object", + "properties": { + "borderRadius": { + "type": "integer", + "minimum": 0, + "maximum": 9007199254740991 + } + }, + "additionalProperties": false + }, + "typography": { + "type": "object", + "properties": { + "fontFamily": { + "type": "string" + }, + "fontFamilyMonospace": { + "type": "string" + }, + "fontSize": { + "type": "number", + "exclusiveMinimum": 0 + }, + "fontWeightLight": { + "type": "number", + "exclusiveMinimum": 0 + }, + "fontWeightRegular": { + "type": "number", + "exclusiveMinimum": 0 + }, + "fontWeightMedium": { + "type": "number", + "exclusiveMinimum": 0 + }, + "fontWeightBold": { + "type": "number", + "exclusiveMinimum": 0 + }, + "htmlFontSize": { + "type": "number", + "exclusiveMinimum": 0 + } + }, + "additionalProperties": false + }, + "visualization": { + "type": "object", + "properties": { + "hues": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "red" + }, + "shades": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "name": { + "type": "string", + "enum": ["super-light-red", "light-red", "red", "semi-dark-red", "dark-red"] + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "primary": { + "type": "boolean" + } + }, + "required": ["color", "name"], + "additionalProperties": false + } + } + }, + "required": ["name", "shades"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "orange" + }, + "shades": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "name": { + "type": "string", + "enum": ["super-light-orange", "light-orange", "orange", "semi-dark-orange", "dark-orange"] + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "primary": { + "type": "boolean" + } + }, + "required": ["color", "name"], + "additionalProperties": false + } + } + }, + "required": ["name", "shades"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "yellow" + }, + "shades": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "name": { + "type": "string", + "enum": ["super-light-yellow", "light-yellow", "yellow", "semi-dark-yellow", "dark-yellow"] + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "primary": { + "type": "boolean" + } + }, + "required": ["color", "name"], + "additionalProperties": false + } + } + }, + "required": ["name", "shades"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "green" + }, + "shades": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "name": { + "type": "string", + "enum": ["super-light-green", "light-green", "green", "semi-dark-green", "dark-green"] + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "primary": { + "type": "boolean" + } + }, + "required": ["color", "name"], + "additionalProperties": false + } + } + }, + "required": ["name", "shades"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "blue" + }, + "shades": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "name": { + "type": "string", + "enum": ["super-light-blue", "light-blue", "blue", "semi-dark-blue", "dark-blue"] + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "primary": { + "type": "boolean" + } + }, + "required": ["color", "name"], + "additionalProperties": false + } + } + }, + "required": ["name", "shades"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "purple" + }, + "shades": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "name": { + "type": "string", + "enum": ["super-light-purple", "light-purple", "purple", "semi-dark-purple", "dark-purple"] + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "primary": { + "type": "boolean" + } + }, + "required": ["color", "name"], + "additionalProperties": false + } + } + }, + "required": ["name", "shades"], + "additionalProperties": false + } + ] + } + }, + "palette": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "required": ["name", "id"], + "additionalProperties": false +} diff --git a/packages/grafana-data/src/themes/scripts/generateSchema.ts b/packages/grafana-data/src/themes/scripts/generateSchema.ts new file mode 100644 index 00000000000..09369f5e67f --- /dev/null +++ b/packages/grafana-data/src/themes/scripts/generateSchema.ts @@ -0,0 +1,19 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +import { NewThemeOptionsSchema } from '../createTheme'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +fs.writeFileSync( + path.join(__dirname, '../schema.generated.json'), + JSON.stringify( + NewThemeOptionsSchema.toJSONSchema({ + target: 'draft-07', + }), + undefined, + 2 + ) +); diff --git a/packages/grafana-data/src/themes/themeDefinitions/aubergine.json b/packages/grafana-data/src/themes/themeDefinitions/aubergine.json new file mode 100644 index 00000000000..4baf4f3f439 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/aubergine.json @@ -0,0 +1,50 @@ +{ + "name": "Aubergine", + "id": "aubergine", + "colors": { + "mode": "dark", + "border": { + "weak": "#4F2A3D", + "medium": "#6A3C4B", + "strong": "#8C5A69" + }, + "text": { + "primary": "#E5D0D6", + "secondary": "#D1A8C4", + "disabled": "#B7A0A6", + "link": "#A56BB6", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#8C5A69" + }, + "secondary": { + "main": "#6A3C4B", + "text": "#D1A8C4", + "border": "#8C5A69" + }, + "background": { + "canvas": "#2E1F2D", + "primary": "#3C2136", + "secondary": "#4A2D47", + "elevated": "#4A2D47" + }, + "action": { + "hover": "#6A3C4B", + "selected": "#8C5A69", + "selectedBorder": "#FFB300", + "focus": "#A56BB6", + "hoverOpacity": 0.1, + "disabledText": "#B7A0A6", + "disabledBackground": "#4A2D47", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #6A3C4B 0%, #A56BB6 100%)", + "brandVertical": "linear-gradient(0deg, #6A3C4B 0%, #A56BB6 100%)" + }, + "contrastThreshold": 4, + "hoverFactor": 0.07, + "tonalOffset": 0.15 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/aubergine.ts b/packages/grafana-data/src/themes/themeDefinitions/aubergine.ts deleted file mode 100644 index 967621ebc60..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/aubergine.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const aubergineTheme: NewThemeOptions = { - name: 'Aubergine', - colors: { - mode: 'dark', - border: { - weak: '#4F2A3D', - medium: '#6A3C4B', - strong: '#8C5A69', - }, - text: { - primary: '#E5D0D6', - secondary: '#D1A8C4', - disabled: '#B7A0A6', - link: '#A56BB6', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#8C5A69', - }, - secondary: { - main: '#6A3C4B', - text: '#D1A8C4', - border: '#8C5A69', - }, - background: { - canvas: '#2E1F2D', - primary: '#3C2136', - secondary: '#4A2D47', - elevated: '#4A2D47', - }, - action: { - hover: '#6A3C4B', - selected: '#8C5A69', - selectedBorder: '#FFB300', - focus: '#A56BB6', - hoverOpacity: 0.1, - disabledText: '#B7A0A6', - disabledBackground: '#4A2D47', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #6A3C4B 0%, #A56BB6 100%)', - brandVertical: 'linear-gradient(0deg, #6A3C4B 0%, #A56BB6 100%)', - }, - contrastThreshold: 4, - hoverFactor: 0.07, - tonalOffset: 0.15, - }, -}; - -export default aubergineTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/debug.json b/packages/grafana-data/src/themes/themeDefinitions/debug.json new file mode 100644 index 00000000000..a9cce4c5e21 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/debug.json @@ -0,0 +1,60 @@ +{ + "name": "Debug", + "id": "debug", + "colors": { + "mode": "dark", + "background": { + "canvas": "#000033", + "primary": "#000044", + "secondary": "#000055", + "elevated": "#000055" + }, + "text": { + "primary": "#bbbb00", + "secondary": "#888800", + "disabled": "#444400", + "link": "#dddd00", + "maxContrast": "#ffff00" + }, + "border": { + "weak": "#ff000044", + "medium": "#ff000088", + "strong": "#ff0000ff" + }, + "primary": { + "border": "#ff000088", + "text": "#cccc00", + "contrastText": "#ffff00", + "shade": "#9900dd" + }, + "secondary": { + "border": "#ff000088", + "text": "#cccc00", + "contrastText": "#ffff00", + "shade": "#9900dd" + }, + "info": { + "shade": "#9900dd" + }, + "warning": { + "shade": "#9900dd" + }, + "success": { + "shade": "#9900dd" + }, + "error": { + "shade": "#9900dd" + }, + "action": { + "hover": "#9900dd", + "focus": "#6600aa", + "selected": "#440088" + } + }, + "shape": { + "borderRadius": 8 + }, + "spacing": { + "gridSize": 10 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/debug.ts b/packages/grafana-data/src/themes/themeDefinitions/debug.ts deleted file mode 100644 index 22e577faf2c..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/debug.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -/** - * a very ugly theme that is useful for debugging and checking if the theme is applied correctly - * borders are red, - * backgrounds are blue, - * text is yellow, - * and grafana loves you <3 - * (also corners are rounded, action states (hover, focus, selected) are purple) - */ -const debugTheme: NewThemeOptions = { - name: 'Debug', - colors: { - mode: 'dark', - background: { - canvas: '#000033', - primary: '#000044', - secondary: '#000055', - elevated: '#000055', - }, - text: { - primary: '#bbbb00', - secondary: '#888800', - disabled: '#444400', - link: '#dddd00', - maxContrast: '#ffff00', - }, - border: { - weak: '#ff000044', - medium: '#ff000088', - strong: '#ff0000ff', - }, - primary: { - border: '#ff000088', - text: '#cccc00', - contrastText: '#ffff00', - shade: '#9900dd', - }, - secondary: { - border: '#ff000088', - text: '#cccc00', - contrastText: '#ffff00', - shade: '#9900dd', - }, - info: { - shade: '#9900dd', - }, - warning: { - shade: '#9900dd', - }, - success: { - shade: '#9900dd', - }, - error: { - shade: '#9900dd', - }, - action: { - hover: '#9900dd', - focus: '#6600aa', - selected: '#440088', - }, - }, - shape: { - borderRadius: 8, - }, - spacing: { - gridSize: 10, - }, -}; - -export default debugTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/desertbloom.json b/packages/grafana-data/src/themes/themeDefinitions/desertbloom.json new file mode 100644 index 00000000000..1c2304aaff8 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/desertbloom.json @@ -0,0 +1,71 @@ +{ + "name": "Desert bloom", + "id": "desertbloom", + "colors": { + "mode": "light", + "border": { + "weak": "rgba(0, 0, 0, 0.12)", + "medium": "rgba(0, 0, 0, 0.20)", + "strong": "rgba(0, 0, 0, 0.30)" + }, + "text": { + "primary": "#333333", + "secondary": "#555555", + "disabled": "rgba(0, 0, 0, 0.5)", + "link": "#1A82E2", + "maxContrast": "#000000" + }, + "primary": { + "main": "#FF6F61", + "text": "#FE6F61", + "border": "#E55B4D", + "name": "primary", + "shade": "#E55B4D", + "transparent": "#FF6F6126", + "contrastText": "#FFFFFF", + "borderTransparent": "#FF6F6140" + }, + "secondary": { + "main": "#FFFFFF", + "text": "#695f53", + "border": "#d9cec0", + "name": "secondary", + "shade": "#d9cec0", + "transparent": "#FFFFFF26", + "contrastText": "#4c4339", + "borderTransparent": "#FFFFFF40" + }, + "info": { + "main": "#1A82E2" + }, + "success": { + "main": "#4CAF50" + }, + "warning": { + "main": "#FFC107" + }, + "background": { + "canvas": "#FFF8F0", + "primary": "#FFFFFF", + "secondary": "#f9f3e8", + "elevated": "#FFFFFF" + }, + "action": { + "hover": "rgba(168, 156, 134, 0.12)", + "selected": "rgba(168, 156, 134, 0.36)", + "selectedBorder": "#FF6F61", + "focus": "rgba(168, 156, 134, 0.50)", + "hoverOpacity": 0.08, + "disabledText": "rgba(168, 156, 134, 0.5)", + "disabledBackground": "rgba(168, 156, 134, 0.06)", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg,rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)", + "brandVertical": "linear-gradient(0deg, rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.03, + "tonalOffset": 0.15 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts b/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts deleted file mode 100644 index 8a86b73a0f7..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const desertBloomTheme: NewThemeOptions = { - name: 'Desert bloom', - colors: { - mode: 'light', - border: { - weak: 'rgba(0, 0, 0, 0.12)', - medium: 'rgba(0, 0, 0, 0.20)', - strong: 'rgba(0, 0, 0, 0.30)', - }, - text: { - primary: '#333333', - secondary: '#555555', - disabled: 'rgba(0, 0, 0, 0.5)', - link: '#1A82E2', - maxContrast: '#000000', - }, - primary: { - main: '#FF6F61', - text: '#FE6F61', - border: '#E55B4D', - name: 'primary', - shade: '#E55B4D', - transparent: '#FF6F6126', - contrastText: '#FFFFFF', - borderTransparent: '#FF6F6140', - }, - secondary: { - main: '#FFFFFF', - text: '#695f53', - border: '#d9cec0', - name: 'secondary', - shade: '#d9cec0', - transparent: '#FFFFFF26', - contrastText: '#4c4339', - borderTransparent: '#FFFFFF40', - }, - info: { - main: '#1A82E2', - }, - success: { - main: '#4CAF50', - }, - warning: { - main: '#FFC107', - }, - background: { - canvas: '#FFF8F0', - primary: '#FFFFFF', - secondary: '#f9f3e8', - elevated: '#FFFFFF', - }, - action: { - hover: 'rgba(168, 156, 134, 0.12)', - selected: 'rgba(168, 156, 134, 0.36)', - selectedBorder: '#FF6F61', - focus: 'rgba(168, 156, 134, 0.50)', - hoverOpacity: 0.08, - disabledText: 'rgba(168, 156, 134, 0.5)', - disabledBackground: 'rgba(168, 156, 134, 0.06)', - disabledOpacity: 0.38, - }, - - gradients: { - brandHorizontal: 'linear-gradient(270deg,rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)', - brandVertical: 'linear-gradient(0deg, rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)', - }, - contrastThreshold: 3, - hoverFactor: 0.03, - tonalOffset: 0.15, - }, -}; - -export default desertBloomTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/gildedgrove.json b/packages/grafana-data/src/themes/themeDefinitions/gildedgrove.json new file mode 100644 index 00000000000..a147afbbe76 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/gildedgrove.json @@ -0,0 +1,62 @@ +{ + "name": "Gilded grove", + "id": "gildedgrove", + "colors": { + "mode": "dark", + "border": { + "weak": "rgba(200, 200, 180, 0.12)", + "medium": "rgba(200, 200, 180, 0.20)", + "strong": "rgba(200, 200, 180, 0.30)" + }, + "text": { + "primary": "rgb(250, 250, 239)", + "secondary": "rgba(200, 200, 180, 0.85)", + "disabled": "rgba(200, 200, 180, 0.6)", + "link": "#FEAC34", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#FEAC34", + "text": "#FFD783", + "border": "#FFD783", + "name": "primary", + "shade": "rgb(255, 173, 80)", + "transparent": "#FEAC3426", + "contrastText": "#111614", + "borderTransparent": "#FFD78340" + }, + "secondary": { + "main": "rgba(200, 200, 180, 0.10)", + "shade": "rgba(200, 200, 180, 0.14)", + "transparent": "rgba(200, 200, 180, 0.08)", + "text": "rgb(200, 200, 180)", + "contrastText": "rgb(200, 200, 180)", + "border": "rgba(200, 200, 180, 0.08)", + "name": "secondary", + "borderTransparent": "rgba(200, 200, 180, 0.25)" + }, + "background": { + "canvas": "#111614", + "primary": "#1d2220", + "secondary": "#27312E", + "elevated": "#27312E" + }, + "action": { + "hover": "rgba(200, 200, 180, 0.16)", + "selected": "rgba(200, 200, 180, 0.12)", + "selectedBorder": "#FEAC34", + "focus": "rgba(200, 200, 180, 0.16)", + "hoverOpacity": 0.08, + "disabledText": "rgba(200, 200, 180, 0.6)", + "disabledBackground": "rgba(200, 200, 180, 0.04)", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #FEAC34 0%, #FFD783 100%)", + "brandVertical": "linear-gradient(0.01deg, #FEAC34 0.01%, #FFD783 99.99%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.03, + "tonalOffset": 0.15 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/gildedgrove.ts b/packages/grafana-data/src/themes/themeDefinitions/gildedgrove.ts deleted file mode 100644 index bfa3e121329..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/gildedgrove.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const gildedGroveTheme: NewThemeOptions = { - name: 'Gilded grove', - colors: { - mode: 'dark', - border: { - weak: 'rgba(200, 200, 180, 0.12)', - medium: 'rgba(200, 200, 180, 0.20)', - strong: 'rgba(200, 200, 180, 0.30)', - }, - text: { - primary: 'rgb(250, 250, 239)', - secondary: 'rgba(200, 200, 180, 0.85)', - disabled: 'rgba(200, 200, 180, 0.6)', - link: '#FEAC34', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#FEAC34', - text: '#FFD783', - border: '#FFD783', - name: 'primary', - shade: 'rgb(255, 173, 80)', - transparent: '#FEAC3426', - contrastText: '#111614', - borderTransparent: '#FFD78340', - }, - secondary: { - main: 'rgba(200, 200, 180, 0.10)', - shade: 'rgba(200, 200, 180, 0.14)', - transparent: 'rgba(200, 200, 180, 0.08)', - text: 'rgb(200, 200, 180)', - contrastText: 'rgb(200, 200, 180)', - border: 'rgba(200, 200, 180, 0.08)', - name: 'secondary', - borderTransparent: 'rgba(200, 200, 180, 0.25)', - }, - background: { - canvas: '#111614', - primary: '#1d2220', - secondary: '#27312E', - elevated: '#27312E', - }, - action: { - hover: 'rgba(200, 200, 180, 0.16)', - selected: 'rgba(200, 200, 180, 0.12)', - selectedBorder: '#FEAC34', - focus: 'rgba(200, 200, 180, 0.16)', - hoverOpacity: 0.08, - disabledText: 'rgba(200, 200, 180, 0.6)', - disabledBackground: 'rgba(200, 200, 180, 0.04)', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #FEAC34 0%, #FFD783 100%)', - brandVertical: 'linear-gradient(0.01deg, #FEAC34 0.01%, #FFD783 99.99%)', - }, - contrastThreshold: 3, - hoverFactor: 0.03, - tonalOffset: 0.15, - }, -}; - -export default gildedGroveTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/gloom.json b/packages/grafana-data/src/themes/themeDefinitions/gloom.json new file mode 100644 index 00000000000..8558c942511 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/gloom.json @@ -0,0 +1,52 @@ +{ + "name": "Gloom", + "id": "gloom", + "colors": { + "mode": "dark", + "border": { + "weak": "rgba(210, 210, 220, 0.12)", + "medium": "rgba(210, 210, 220, 0.20)", + "strong": "rgba(210, 210, 220, 0.30)" + }, + "text": { + "primary": "rgb(210, 210, 220)", + "secondary": "rgba(210, 210, 220, 0.65)", + "disabled": "rgba(210, 210, 220, 0.48)", + "link": "#f99a5c", + "maxContrast": "#FFF" + }, + "primary": { + "main": "#ff934d", + "text": "#f99a5c", + "border": "#ff934d", + "name": "primary" + }, + "secondary": { + "main": "rgba(195, 195, 245, 0.10)", + "shade": "rgba(195, 195, 245, 0.14)", + "transparent": "rgba(195, 195, 245, 0.08)", + "text": "rgba(195, 195, 245)", + "contrastText": "rgb(195, 195, 245)", + "border": "rgba(195, 195, 245, 0.08)" + }, + "background": { + "canvas": "#000", + "primary": "#121118", + "secondary": "#211e28", + "elevated": "#211e28" + }, + "action": { + "hover": "rgba(195, 195, 245, 0.07)", + "selected": "rgba(195, 195, 245, 0.11)", + "selectedBorder": "#ff934d", + "focus": "rgba(195, 195, 245, 0.07)", + "hoverOpacity": 0.05, + "disabledText": "rgba(210, 210, 220, 0.48)", + "disabledBackground": "rgba(210, 210, 220, 0.04)", + "disabledOpacity": 0.38 + }, + "contrastThreshold": 3, + "hoverFactor": 0.03, + "tonalOffset": 0.15 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/gloom.ts b/packages/grafana-data/src/themes/themeDefinitions/gloom.ts deleted file mode 100644 index 49c105626fb..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/gloom.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -/** - * Torkel's GrafanaCon theme - * very WIP state - */ - -const whiteBase = `210, 210, 220`; -const secondaryBase = `195, 195, 245`; - -//const brandMain = '#3d71d9'; -//const brandText = '#6e9fff'; -const brandMain = '#ff934d'; -const brandText = '#f99a5c'; -const disabledText = `rgba(${whiteBase}, 0.48)`; - -const gloomTheme: NewThemeOptions = { - name: 'Gloom', - colors: { - mode: 'dark', - border: { - weak: `rgba(${whiteBase}, 0.12)`, - medium: `rgba(${whiteBase}, 0.20)`, - strong: `rgba(${whiteBase}, 0.30)`, - }, - - text: { - primary: `rgb(${whiteBase})`, - secondary: `rgba(${whiteBase}, 0.65)`, - disabled: disabledText, - link: brandText, - maxContrast: '#FFF', - }, - - primary: { - main: brandMain, - text: brandText, - border: brandMain, - name: 'primary', - }, - - secondary: { - main: `rgba(${secondaryBase}, 0.10)`, - shade: `rgba(${secondaryBase}, 0.14)`, - transparent: `rgba(${secondaryBase}, 0.08)`, - text: `rgba(${secondaryBase})`, - contrastText: `rgb(${secondaryBase})`, - border: `rgba(${secondaryBase}, 0.08)`, - }, - - background: { - canvas: '#000', - primary: '#121118', - secondary: '#211e28', - elevated: '#211e28', - }, - - action: { - hover: `rgba(${secondaryBase}, 0.07)`, - selected: `rgba(${secondaryBase}, 0.11)`, - selectedBorder: brandMain, - focus: `rgba(${secondaryBase}, 0.07)`, - hoverOpacity: 0.05, - disabledText: disabledText, - disabledBackground: `rgba(${whiteBase}, 0.04)`, - disabledOpacity: 0.38, - }, - - // gradients: { - // brandHorizontal: 'linear-gradient(270deg, #ff934d 0%, #FEAC34 100%)', - // brandVertical: 'linear-gradient(0.01deg, #ff934d 0.01%, #FEAC34 99.99%)', - // }, - - contrastThreshold: 3, - hoverFactor: 0.03, - tonalOffset: 0.15, - }, -}; - -export default gloomTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/index.ts b/packages/grafana-data/src/themes/themeDefinitions/index.ts index 151ae00593e..b4270192032 100644 --- a/packages/grafana-data/src/themes/themeDefinitions/index.ts +++ b/packages/grafana-data/src/themes/themeDefinitions/index.ts @@ -1,12 +1,12 @@ -export { default as aubergine } from './aubergine'; -export { default as debug } from './debug'; -export { default as desertbloom } from './desertbloom'; -export { default as gildedgrove } from './gildedgrove'; -export { default as mars } from './mars'; -export { default as matrix } from './matrix'; -export { default as sapphiredusk } from './sapphiredusk'; -export { default as synthwave } from './synthwave'; -export { default as tron } from './tron'; -export { default as victorian } from './victorian'; -export { default as zen } from './zen'; -export { default as gloom } from './gloom'; +export { default as aubergine } from './aubergine.json'; +export { default as debug } from './debug.json'; +export { default as desertbloom } from './desertbloom.json'; +export { default as gildedgrove } from './gildedgrove.json'; +export { default as mars } from './mars.json'; +export { default as matrix } from './matrix.json'; +export { default as sapphiredusk } from './sapphiredusk.json'; +export { default as synthwave } from './synthwave.json'; +export { default as tron } from './tron.json'; +export { default as victorian } from './victorian.json'; +export { default as zen } from './zen.json'; +export { default as gloom } from './gloom.json'; diff --git a/packages/grafana-data/src/themes/themeDefinitions/mars.json b/packages/grafana-data/src/themes/themeDefinitions/mars.json new file mode 100644 index 00000000000..1aeb874f018 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/mars.json @@ -0,0 +1,50 @@ +{ + "name": "Mars", + "id": "mars", + "colors": { + "mode": "dark", + "border": { + "weak": "rgba(210, 90, 60, 0.2)", + "medium": "rgba(210, 90, 60, 0.35)", + "strong": "rgba(210, 90, 60, 0.5)" + }, + "text": { + "primary": "#DDDDDD", + "secondary": "#BBBBBB", + "disabled": "rgba(221, 221, 221, 0.5)", + "link": "#FF6F61", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#FF6F61" + }, + "secondary": { + "main": "#6a2f2f", + "text": "#BBBBBB", + "border": "rgba(210, 90, 60, 0.2)" + }, + "background": { + "canvas": "#3C1E1E", + "primary": "#522626", + "secondary": "#6A2F2F", + "elevated": "#6A2F2F" + }, + "action": { + "hover": "rgba(210, 90, 60, 0.16)", + "selected": "rgba(210, 90, 60, 0.12)", + "selectedBorder": "#FF6F61", + "focus": "rgba(210, 90, 60, 0.16)", + "hoverOpacity": 0.08, + "disabledText": "rgba(221, 221, 221, 0.5)", + "disabledBackground": "rgba(210, 90, 60, 0.08)", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #FF6F61 0%, #D25A3C 100%)", + "brandVertical": "linear-gradient(0.01deg, #FF6F61 0.01%, #D25A3C 99.99%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.05, + "tonalOffset": 0.2 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/mars.ts b/packages/grafana-data/src/themes/themeDefinitions/mars.ts deleted file mode 100644 index f1db51e23b2..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/mars.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const marsTheme: NewThemeOptions = { - name: 'Mars', - colors: { - mode: 'dark', - border: { - weak: 'rgba(210, 90, 60, 0.2)', - medium: 'rgba(210, 90, 60, 0.35)', - strong: 'rgba(210, 90, 60, 0.5)', - }, - text: { - primary: '#DDDDDD', - secondary: '#BBBBBB', - disabled: 'rgba(221, 221, 221, 0.5)', - link: '#FF6F61', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#FF6F61', - }, - secondary: { - main: '#6a2f2f', - text: '#BBBBBB', - border: 'rgba(210, 90, 60, 0.2)', - }, - background: { - canvas: '#3C1E1E', - primary: '#522626', - secondary: '#6A2F2F', - elevated: '#6A2F2F', - }, - action: { - hover: 'rgba(210, 90, 60, 0.16)', - selected: 'rgba(210, 90, 60, 0.12)', - selectedBorder: '#FF6F61', - focus: 'rgba(210, 90, 60, 0.16)', - hoverOpacity: 0.08, - disabledText: 'rgba(221, 221, 221, 0.5)', - disabledBackground: 'rgba(210, 90, 60, 0.08)', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #FF6F61 0%, #D25A3C 100%)', - brandVertical: 'linear-gradient(0.01deg, #FF6F61 0.01%, #D25A3C 99.99%)', - }, - contrastThreshold: 3, - hoverFactor: 0.05, - tonalOffset: 0.2, - }, -}; - -export default marsTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/matrix.json b/packages/grafana-data/src/themes/themeDefinitions/matrix.json new file mode 100644 index 00000000000..a64a7ccce40 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/matrix.json @@ -0,0 +1,41 @@ +{ + "name": "Matrix", + "id": "matrix", + "colors": { + "mode": "dark", + "background": { + "canvas": "#000000", + "primary": "#020202", + "secondary": "#080808", + "elevated": "#080808" + }, + "text": { + "primary": "#00c017", + "secondary": "#008910", + "disabled": "#006a0c", + "link": "#00ff41", + "maxContrast": "#00ff41" + }, + "border": { + "weak": "#008f1144", + "medium": "#008f1188", + "strong": "#008910" + }, + "primary": { + "main": "#008910" + }, + "secondary": { + "text": "#008910" + }, + "gradients": { + "brandVertical": "linear-gradient(0deg, #008910 0%, #00ff41 100%)", + "brandHorizontal": "linear-gradient(90deg, #008910 0%, #00ff41 100%)" + } + }, + "shape": { + "borderRadius": 0 + }, + "typography": { + "fontFamily": "monospace" + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/matrix.ts b/packages/grafana-data/src/themes/themeDefinitions/matrix.ts deleted file mode 100644 index 51c58b9b394..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/matrix.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const matrixTheme: NewThemeOptions = { - name: 'Matrix', - colors: { - mode: 'dark', - background: { - canvas: '#000000', - primary: '#020202', - secondary: '#080808', - elevated: '#080808', - }, - text: { - primary: '#00c017', - secondary: '#008910', - disabled: '#006a0c', - link: '#00ff41', - maxContrast: '#00ff41', - }, - border: { - weak: '#008f1144', - medium: '#008f1188', - strong: '#008910', - }, - primary: { - main: '#008910', - }, - secondary: { - text: '#008910', - }, - gradients: { - brandVertical: 'linear-gradient(0deg, #008910 0%, #00ff41 100%)', - brandHorizontal: 'linear-gradient(90deg, #008910 0%, #00ff41 100%)', - }, - }, - shape: { - borderRadius: 0, - }, - typography: { - fontFamily: 'monospace', - }, -}; - -export default matrixTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/sapphiredusk.json b/packages/grafana-data/src/themes/themeDefinitions/sapphiredusk.json new file mode 100644 index 00000000000..8d5f7731f05 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/sapphiredusk.json @@ -0,0 +1,76 @@ +{ + "name": "Sapphire dusk", + "id": "sapphiredusk", + "colors": { + "mode": "dark", + "border": { + "weak": "#232e47", + "medium": "#2c3853", + "strong": "#404d6b" + }, + "text": { + "primary": "#FFFFFF", + "secondary": "#bcccdd", + "disabled": "#838da5", + "link": "#93EBF0", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#93EBF0", + "text": "#a8e9ed", + "border": "#93ebf0", + "name": "primary", + "shade": "#c0f5d9", + "transparent": "#93EBF029", + "contrastText": "#111614", + "borderTransparent": "#93ebf040" + }, + "secondary": { + "main": "#2c364f", + "shade": "#36415e", + "transparent": "rgba(200, 200, 180, 0.08)", + "text": "#d1dfff", + "contrastText": "#acfeff", + "border": "rgba(200, 200, 180, 0.08)", + "name": "secondary", + "borderTransparent": "rgba(200, 200, 180, 0.25)" + }, + "info": { + "main": "#4d4593", + "text": "#a8e9ed", + "border": "#5d54a7" + }, + "error": { + "main": "#c63370" + }, + "success": { + "main": "#1A7F4B" + }, + "warning": { + "main": "#D448EA" + }, + "background": { + "canvas": "#1e273d", + "primary": "#12192e", + "secondary": "#212c47", + "elevated": "#212c47" + }, + "action": { + "hover": "#364057", + "selected": "#364260", + "selectedBorder": "#D448EA", + "focus": "#364057", + "hoverOpacity": 0.08, + "disabledText": "#838da5", + "disabledBackground": "rgba(54, 64, 87, 0.2)", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #D346EF 0%, #2C83FE 100%)", + "brandVertical": "linear-gradient(0deg, #D346EF 0%, #2C83FE 100%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.03, + "tonalOffset": 0.15 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/sapphiredusk.ts b/packages/grafana-data/src/themes/themeDefinitions/sapphiredusk.ts deleted file mode 100644 index c777c61b055..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/sapphiredusk.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const sapphireDuskTheme: NewThemeOptions = { - name: 'Sapphire dusk', - colors: { - mode: 'dark', - border: { - weak: '#232e47', - medium: '#2c3853', - strong: '#404d6b', - }, - text: { - primary: '#FFFFFF', - secondary: '#bcccdd', - disabled: '#838da5', - link: '#93EBF0', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#93EBF0', - text: '#a8e9ed', - border: '#93ebf0', - name: 'primary', - shade: '#c0f5d9', - transparent: '#93EBF029', - contrastText: '#111614', - borderTransparent: '#93ebf040', - }, - secondary: { - main: '#2c364f', - shade: '#36415e', - transparent: 'rgba(200, 200, 180, 0.08)', - text: '#d1dfff', - contrastText: '#acfeff', - border: 'rgba(200, 200, 180, 0.08)', - name: 'secondary', - borderTransparent: 'rgba(200, 200, 180, 0.25)', - }, - info: { - main: '#4d4593', - text: '#a8e9ed', - border: '#5d54a7', - }, - error: { - main: '#c63370', - }, - success: { - main: '#1A7F4B', - }, - warning: { - main: '#D448EA', - }, - background: { - canvas: '#1e273d', - primary: '#12192e', - secondary: '#212c47', - elevated: '#212c47', - }, - action: { - hover: '#364057', - selected: '#364260', - selectedBorder: '#D448EA', - focus: '#364057', - hoverOpacity: 0.08, - disabledText: '#838da5', - disabledBackground: 'rgba(54, 64, 87, 0.2)', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #D346EF 0%, #2C83FE 100%)', - brandVertical: 'linear-gradient(0deg, #D346EF 0%, #2C83FE 100%)', - }, - contrastThreshold: 3, - hoverFactor: 0.03, - tonalOffset: 0.15, - }, -}; - -export default sapphireDuskTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/synthwave.json b/packages/grafana-data/src/themes/themeDefinitions/synthwave.json new file mode 100644 index 00000000000..377f09f2585 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/synthwave.json @@ -0,0 +1,50 @@ +{ + "name": "Synthwave", + "id": "synthwave", + "colors": { + "mode": "dark", + "border": { + "weak": "rgba(255, 20, 147, 0.12)", + "medium": "rgba(255, 20, 147, 0.20)", + "strong": "rgba(255, 20, 147, 0.30)" + }, + "text": { + "primary": "#E0E0E0", + "secondary": "rgba(224, 224, 224, 0.75)", + "disabled": "rgba(224, 224, 224, 0.5)", + "link": "#FF69B4", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#FF1493" + }, + "secondary": { + "main": "#37183a", + "text": "rgba(224, 224, 224, 0.75)", + "border": "rgba(255, 20, 147, 0.10)" + }, + "background": { + "canvas": "#1A1A2E", + "primary": "#16213E", + "secondary": "#0F3460", + "elevated": "#0F3460" + }, + "action": { + "hover": "rgba(255, 20, 147, 0.16)", + "selected": "rgba(255, 20, 147, 0.12)", + "selectedBorder": "#FF1493", + "focus": "rgba(255, 20, 147, 0.16)", + "hoverOpacity": 0.08, + "disabledText": "rgba(224, 224, 224, 0.5)", + "disabledBackground": "rgba(255, 20, 147, 0.08)", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #FF1493 0%, #1E90FF 100%)", + "brandVertical": "linear-gradient(0.01deg, #FF1493 0.01%, #1E90FF 99.99%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.03, + "tonalOffset": 0.15 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/synthwave.ts b/packages/grafana-data/src/themes/themeDefinitions/synthwave.ts deleted file mode 100644 index 5fc53cda0bb..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/synthwave.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const synthwaveTheme: NewThemeOptions = { - name: 'Synthwave', - colors: { - mode: 'dark', - border: { - weak: 'rgba(255, 20, 147, 0.12)', - medium: 'rgba(255, 20, 147, 0.20)', - strong: 'rgba(255, 20, 147, 0.30)', - }, - text: { - primary: '#E0E0E0', - secondary: 'rgba(224, 224, 224, 0.75)', - disabled: 'rgba(224, 224, 224, 0.5)', - link: '#FF69B4', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#FF1493', - }, - secondary: { - main: '#37183a', - text: 'rgba(224, 224, 224, 0.75)', - border: 'rgba(255, 20, 147, 0.10)', - }, - background: { - canvas: '#1A1A2E', - primary: '#16213E', - secondary: '#0F3460', - elevated: '#0F3460', - }, - action: { - hover: 'rgba(255, 20, 147, 0.16)', - selected: 'rgba(255, 20, 147, 0.12)', - selectedBorder: '#FF1493', - focus: 'rgba(255, 20, 147, 0.16)', - hoverOpacity: 0.08, - disabledText: 'rgba(224, 224, 224, 0.5)', - disabledBackground: 'rgba(255, 20, 147, 0.08)', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #FF1493 0%, #1E90FF 100%)', - brandVertical: 'linear-gradient(0.01deg, #FF1493 0.01%, #1E90FF 99.99%)', - }, - contrastThreshold: 3, - hoverFactor: 0.03, - tonalOffset: 0.15, - }, -}; - -export default synthwaveTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/tron.json b/packages/grafana-data/src/themes/themeDefinitions/tron.json new file mode 100644 index 00000000000..a92cf07fcb0 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/tron.json @@ -0,0 +1,50 @@ +{ + "name": "Tron", + "id": "tron", + "colors": { + "mode": "dark", + "border": { + "weak": "rgba(0, 255, 255, 0.12)", + "medium": "rgba(0, 255, 255, 0.20)", + "strong": "rgba(0, 255, 255, 0.30)" + }, + "text": { + "primary": "#E0E0E0", + "secondary": "rgba(224, 224, 224, 0.75)", + "disabled": "rgba(224, 224, 224, 0.5)", + "link": "#00FFFF", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#00FFFF" + }, + "secondary": { + "main": "#0b2e36", + "text": "rgba(224, 224, 224, 0.75)", + "border": "rgba(0, 255, 255, 0.10)" + }, + "background": { + "canvas": "#0A0F18", + "primary": "#0F1B2A", + "secondary": "#152234", + "elevated": "#152234" + }, + "action": { + "hover": "rgba(0, 255, 255, 0.16)", + "selected": "rgba(0, 255, 255, 0.12)", + "selectedBorder": "#00FFFF", + "focus": "rgba(0, 255, 255, 0.16)", + "hoverOpacity": 0.08, + "disabledText": "rgba(224, 224, 224, 0.5)", + "disabledBackground": "rgba(0, 255, 255, 0.08)", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #00FFFF 0%, #29ABE2 100%)", + "brandVertical": "linear-gradient(0.01deg, #00FFFF 0.01%, #29ABE2 99.99%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.05, + "tonalOffset": 0.2 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/tron.ts b/packages/grafana-data/src/themes/themeDefinitions/tron.ts deleted file mode 100644 index a9f0b8c3ed4..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/tron.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const tronTheme: NewThemeOptions = { - name: 'Tron', - colors: { - mode: 'dark', - border: { - weak: 'rgba(0, 255, 255, 0.12)', - medium: 'rgba(0, 255, 255, 0.20)', - strong: 'rgba(0, 255, 255, 0.30)', - }, - text: { - primary: '#E0E0E0', - secondary: 'rgba(224, 224, 224, 0.75)', - disabled: 'rgba(224, 224, 224, 0.5)', - link: '#00FFFF', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#00FFFF', - }, - secondary: { - main: '#0b2e36', - text: 'rgba(224, 224, 224, 0.75)', - border: 'rgba(0, 255, 255, 0.10)', - }, - background: { - canvas: '#0A0F18', - primary: '#0F1B2A', - secondary: '#152234', - elevated: '#152234', - }, - action: { - hover: 'rgba(0, 255, 255, 0.16)', - selected: 'rgba(0, 255, 255, 0.12)', - selectedBorder: '#00FFFF', - focus: 'rgba(0, 255, 255, 0.16)', - hoverOpacity: 0.08, - disabledText: 'rgba(224, 224, 224, 0.5)', - disabledBackground: 'rgba(0, 255, 255, 0.08)', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #00FFFF 0%, #29ABE2 100%)', - brandVertical: 'linear-gradient(0.01deg, #00FFFF 0.01%, #29ABE2 99.99%)', - }, - contrastThreshold: 3, - hoverFactor: 0.05, - tonalOffset: 0.2, - }, -}; - -export default tronTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/victorian.json b/packages/grafana-data/src/themes/themeDefinitions/victorian.json new file mode 100644 index 00000000000..14483578450 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/victorian.json @@ -0,0 +1,54 @@ +{ + "name": "Victorian", + "id": "victorian", + "colors": { + "mode": "dark", + "border": { + "weak": "#3A2C22", + "medium": "#3A2C22", + "strong": "#4B3D32" + }, + "text": { + "primary": "#D9D0A2", + "secondary": "#C4B89B", + "disabled": "#A89F91", + "link": "#C28A4D", + "maxContrast": "#FFFFFF" + }, + "primary": { + "main": "#C28A4D" + }, + "secondary": { + "main": "#3A2C22", + "text": "#C4B89B", + "border": "#4B3D32" + }, + "background": { + "canvas": "#1F1510", + "primary": "#2C1A13", + "secondary": "#402A21", + "elevated": "#402A21" + }, + "action": { + "hover": "#3A2C22", + "selected": "#4B3D32", + "selectedBorder": "#C28A4D", + "focus": "#C28A4D", + "hoverOpacity": 0.1, + "disabledText": "#A89F91", + "disabledBackground": "#402A21", + "disabledOpacity": 0.38 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #D9D0a1 0%, #C28A4D 100%)", + "brandVertical": "linear-gradient(0.01deg, #D9D0a1 0.01%, #C28A4D 99.99%)" + }, + "contrastThreshold": 4, + "hoverFactor": 0.07, + "tonalOffset": 0.15 + }, + "typography": { + "fontFamily": "\"Georgia\", \"Times New Roman\", serif", + "fontFamilyMonospace": "'Courier New', monospace" + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/victorian.ts b/packages/grafana-data/src/themes/themeDefinitions/victorian.ts deleted file mode 100644 index 32ddbcb244e..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/victorian.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const victorianTheme: NewThemeOptions = { - name: 'Victorian', - colors: { - mode: 'dark', - border: { - weak: '#3A2C22', - medium: '#3A2C22', - strong: '#4B3D32', - }, - text: { - primary: '#D9D0A2', - secondary: '#C4B89B', - disabled: '#A89F91', - link: '#C28A4D', - maxContrast: '#FFFFFF', - }, - primary: { - main: '#C28A4D', - }, - secondary: { - main: '#3A2C22', - text: '#C4B89B', - border: '#4B3D32', - }, - background: { - canvas: '#1F1510', - primary: '#2C1A13', - secondary: '#402A21', - elevated: '#402A21', - }, - action: { - hover: '#3A2C22', - selected: '#4B3D32', - selectedBorder: '#C28A4D', - focus: '#C28A4D', - hoverOpacity: 0.1, - disabledText: '#A89F91', - disabledBackground: '#402A21', - disabledOpacity: 0.38, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #D9D0a1 0%, #C28A4D 100%)', - brandVertical: 'linear-gradient(0.01deg, #D9D0a1 0.01%, #C28A4D 99.99%)', - }, - contrastThreshold: 4, - hoverFactor: 0.07, - tonalOffset: 0.15, - }, - typography: { - fontFamily: '"Georgia", "Times New Roman", serif', - fontFamilyMonospace: "'Courier New', monospace", - }, -}; - -export default victorianTheme; diff --git a/packages/grafana-data/src/themes/themeDefinitions/zen.json b/packages/grafana-data/src/themes/themeDefinitions/zen.json new file mode 100644 index 00000000000..99a8b900052 --- /dev/null +++ b/packages/grafana-data/src/themes/themeDefinitions/zen.json @@ -0,0 +1,50 @@ +{ + "name": "Zen", + "id": "zen", + "colors": { + "mode": "light", + "text": { + "primary": "#333333", + "secondary": "#666666", + "disabled": "#B8B8B8", + "link": "#4F9F6E", + "maxContrast": "#000000" + }, + "border": { + "weak": "#B1B7B3", + "medium": "#A2A8A2", + "strong": "#7C7F7A" + }, + "primary": { + "main": "#6D8E6D" + }, + "secondary": { + "main": "#E0E0E0", + "text": "#666666", + "border": "#A2A8A2" + }, + "background": { + "canvas": "#F4F4F4", + "primary": "#E9E9E9", + "secondary": "#D8D8D8", + "elevated": "#E9E9E9" + }, + "action": { + "hover": "#D1D1D1", + "selected": "#B8B8B8", + "selectedBorder": "#88B88B", + "hoverOpacity": 0.1, + "focus": "#D1D1D1", + "disabledBackground": "#E0E0E0", + "disabledText": "#B8B8B8", + "disabledOpacity": 0.5 + }, + "gradients": { + "brandHorizontal": "linear-gradient(270deg, #88B88B 0%, #6D8E6D 100%)", + "brandVertical": "linear-gradient(0.01deg, #88B88B 0.01%, #6D8E6D 99.99%)" + }, + "contrastThreshold": 3, + "hoverFactor": 0.03, + "tonalOffset": 0.2 + } +} diff --git a/packages/grafana-data/src/themes/themeDefinitions/zen.ts b/packages/grafana-data/src/themes/themeDefinitions/zen.ts deleted file mode 100644 index f2735f41b74..00000000000 --- a/packages/grafana-data/src/themes/themeDefinitions/zen.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NewThemeOptions } from '../createTheme'; - -const zenTheme: NewThemeOptions = { - name: 'Zen', - colors: { - mode: 'light', - text: { - primary: '#333333', - secondary: '#666666', - disabled: '#B8B8B8', - link: '#4F9F6E', - maxContrast: '#000000', - }, - border: { - weak: '#B1B7B3', - medium: '#A2A8A2', - strong: '#7C7F7A', - }, - primary: { - main: '#6D8E6D', - }, - secondary: { - main: '#E0E0E0', - text: '#666666', - border: '#A2A8A2', - }, - background: { - canvas: '#F4F4F4', - primary: '#E9E9E9', - secondary: '#D8D8D8', - elevated: '#E9E9E9', - }, - action: { - hover: '#D1D1D1', - selected: '#B8B8B8', - selectedBorder: '#88B88B', - hoverOpacity: 0.1, - focus: '#D1D1D1', - disabledBackground: '#E0E0E0', - disabledText: '#B8B8B8', - disabledOpacity: 0.5, - }, - gradients: { - brandHorizontal: 'linear-gradient(270deg, #88B88B 0%, #6D8E6D 100%)', - brandVertical: 'linear-gradient(0.01deg, #88B88B 0.01%, #6D8E6D 99.99%)', - }, - contrastThreshold: 3, - hoverFactor: 0.03, - tonalOffset: 0.2, - }, -}; - -export default zenTheme; diff --git a/packages/grafana-data/src/themes/types.ts b/packages/grafana-data/src/themes/types.ts index f586937cf3c..d77c53062d3 100644 --- a/packages/grafana-data/src/themes/types.ts +++ b/packages/grafana-data/src/themes/types.ts @@ -1,3 +1,5 @@ +import { z } from 'zod'; + import { GrafanaTheme } from '../types/theme'; import { ThemeBreakpoints } from './breakpoints'; @@ -35,27 +37,36 @@ export interface GrafanaTheme2 { flags: {}; } -/** @alpha */ -export interface ThemeRichColor { +export const ThemeRichColorInputSchema = z.object({ /** color intent (primary, secondary, info, error, etc) */ - name: string; + name: z.string().optional(), /** Main color */ - main: string; + main: z.string().optional(), /** Used for hover */ - shade: string; + shade: z.string().optional(), /** Used for text */ - text: string; + text: z.string().optional(), /** Used for borders */ - border: string; + border: z.string().optional(), /** Used subtly colored backgrounds */ - transparent: string; + transparent: z.string().optional(), /** Used for weak colored borders like larger alert/banner boxes and smaller badges and tags */ - borderTransparent: string; + borderTransparent: z.string().optional(), /** Text color for text ontop of main */ - contrastText: string; -} + contrastText: z.string().optional(), +}); + +export const ThemeRichColorSchema = ThemeRichColorInputSchema.required(); + +/** @alpha */ +export type ThemeRichColor = z.infer; /** @internal */ export type DeepPartial = { [P in keyof T]?: DeepPartial; }; + +/** @internal */ +export type DeepRequired = Required<{ + [P in keyof T]: T[P] extends Required ? T[P] : DeepRequired; +}>; diff --git a/packages/grafana-data/src/unstable.ts b/packages/grafana-data/src/unstable.ts index 8a42447206f..3200085428a 100644 --- a/packages/grafana-data/src/unstable.ts +++ b/packages/grafana-data/src/unstable.ts @@ -9,5 +9,4 @@ * and be subject to the standard policies */ -// This is a dummy export so typescript doesn't error importing an "empty module" -export const unstable = {}; +export { default as themeJsonSchema } from './themes/schema.generated.json'; diff --git a/pkg/services/preference/generate_themes.go b/pkg/services/preference/generate_themes.go new file mode 100644 index 00000000000..464e26dbea2 --- /dev/null +++ b/pkg/services/preference/generate_themes.go @@ -0,0 +1,90 @@ +//go:build ignore + +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" +) + +type Colors struct { + Mode string `json:"mode"` +} + +type ThemeDefinition struct { + Colors Colors `json:"colors"` + Id string `json:"id"` +} + +func main() { + themesPath := filepath.Join("..", "..", "..", "packages", "grafana-data", "src", "themes", "themeDefinitions") + + // Check if the themes directory exists + if _, err := os.Stat(themesPath); os.IsNotExist(err) { + fmt.Fprintf(os.Stderr, "Themes directory not found: %s\n", themesPath) + os.Exit(1) + } + + output := `// Code generated by go generate; DO NOT EDIT. + +package pref + +var themes = []ThemeDTO{ + {ID: "light", Type: "light"}, + {ID: "dark", Type: "dark"}, + {ID: "system", Type: "dark"}, +` + + err := filepath.WalkDir(themesPath, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + + // Only process json files + if d.IsDir() || !strings.HasSuffix(d.Name(), ".json") { + return nil + } + + fileBytes, readErr := os.ReadFile(path) + if readErr != nil { + fmt.Fprintf(os.Stderr, "Error reading file %s: %v\n", path, readErr) + return nil // Continue processing other files + } + + var themeDef ThemeDefinition + jsonErr := json.Unmarshal(fileBytes, &themeDef) + if jsonErr != nil { + fmt.Fprintf(os.Stderr, "Error parsing JSON from %s: %v\n", path, jsonErr) + return nil // Continue processing other files + } + + themeId := themeDef.Id + themeType := "dark" // default fallback + if themeDef.Colors.Mode != "" { + themeType = themeDef.Colors.Mode + } + + output += fmt.Sprintf("\t{ID: %q, Type: %q, IsExtra: true},\n", themeId, themeType) + + return nil + }) + + if err != nil { + fmt.Fprintf(os.Stderr, "Error walking themes directory: %v\n", err) + os.Exit(1) + } + + output += "}\n" + + // Write the generated file + outputPath := filepath.Join("themes_generated.go") + if err := os.WriteFile(outputPath, []byte(output), 0644); err != nil { + fmt.Fprintf(os.Stderr, "Error writing output file: %v\n", err) + os.Exit(1) + } + + fmt.Printf("Successfully generated themes_generated.go\n") +} diff --git a/pkg/services/preference/themes.go b/pkg/services/preference/themes.go index 73366b64d6d..e7164921ccd 100644 --- a/pkg/services/preference/themes.go +++ b/pkg/services/preference/themes.go @@ -1,3 +1,5 @@ +//go:generate go run generate_themes.go + package pref type ThemeDTO struct { @@ -6,24 +8,6 @@ type ThemeDTO struct { IsExtra bool `json:"isExtra"` } -var themes = []ThemeDTO{ - {ID: "light", Type: "light"}, - {ID: "dark", Type: "dark"}, - {ID: "system", Type: "dark"}, - {ID: "debug", Type: "dark", IsExtra: true}, - {ID: "aubergine", Type: "dark", IsExtra: true}, - {ID: "desertbloom", Type: "light", IsExtra: true}, - {ID: "gildedgrove", Type: "dark", IsExtra: true}, - {ID: "mars", Type: "dark", IsExtra: true}, - {ID: "matrix", Type: "dark", IsExtra: true}, - {ID: "sapphiredusk", Type: "dark", IsExtra: true}, - {ID: "synthwave", Type: "dark", IsExtra: true}, - {ID: "tron", Type: "dark", IsExtra: true}, - {ID: "victorian", Type: "dark", IsExtra: true}, - {ID: "zen", Type: "light", IsExtra: true}, - {ID: "gloom", Type: "dark", IsExtra: true}, -} - func GetThemeByID(id string) *ThemeDTO { for _, theme := range themes { if theme.ID == id { diff --git a/pkg/services/preference/themes_generated.go b/pkg/services/preference/themes_generated.go new file mode 100644 index 00000000000..ff09e0f4935 --- /dev/null +++ b/pkg/services/preference/themes_generated.go @@ -0,0 +1,21 @@ +// Code generated by go generate; DO NOT EDIT. + +package pref + +var themes = []ThemeDTO{ + {ID: "light", Type: "light"}, + {ID: "dark", Type: "dark"}, + {ID: "system", Type: "dark"}, + {ID: "aubergine", Type: "dark", IsExtra: true}, + {ID: "debug", Type: "dark", IsExtra: true}, + {ID: "desertbloom", Type: "light", IsExtra: true}, + {ID: "gildedgrove", Type: "dark", IsExtra: true}, + {ID: "gloom", Type: "dark", IsExtra: true}, + {ID: "mars", Type: "dark", IsExtra: true}, + {ID: "matrix", Type: "dark", IsExtra: true}, + {ID: "sapphiredusk", Type: "dark", IsExtra: true}, + {ID: "synthwave", Type: "dark", IsExtra: true}, + {ID: "tron", Type: "dark", IsExtra: true}, + {ID: "victorian", Type: "dark", IsExtra: true}, + {ID: "zen", Type: "light", IsExtra: true}, +} diff --git a/public/app/features/theme-playground/README.md b/public/app/features/theme-playground/README.md deleted file mode 100644 index c0b370c9734..00000000000 --- a/public/app/features/theme-playground/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Regenerating the schema - -The json schema for the theme options is generated using [typescript-json-schema](https://github.com/YousefED/typescript-json-schema). The schema should be regenerated automatically if the types change. If you need to manually regenerate, run `yarn themes-schema`. diff --git a/public/app/features/theme-playground/ThemePlayground.tsx b/public/app/features/theme-playground/ThemePlayground.tsx index 2a8da67b340..85dee240c7f 100644 --- a/public/app/features/theme-playground/ThemePlayground.tsx +++ b/public/app/features/theme-playground/ThemePlayground.tsx @@ -2,7 +2,8 @@ import { css } from '@emotion/css'; import { useId, useState } from 'react'; import { createTheme, GrafanaTheme2, NewThemeOptions } from '@grafana/data'; -import { experimentalThemeDefinitions } from '@grafana/data/internal'; +import { experimentalThemeDefinitions, NewThemeOptionsSchema } from '@grafana/data/internal'; +import { themeJsonSchema } from '@grafana/data/unstable'; import { t } from '@grafana/i18n'; import { useChromeHeaderHeight } from '@grafana/runtime'; import { CodeEditor, Combobox, Field, Stack, useStyles2 } from '@grafana/ui'; @@ -16,24 +17,33 @@ import { getNavModel } from '../../core/selectors/navModel'; import { ThemeProvider } from '../../core/utils/ConfigProvider'; import { useDispatch, useSelector } from '../../types/store'; -import schema from './schema.generated.json'; - const themeMap: Record = { dark: { name: 'Dark', + id: 'dark', colors: { mode: 'dark', }, }, light: { name: 'Light', + id: 'light', colors: { mode: 'light', }, }, - ...experimentalThemeDefinitions, }; +// Add additional themes +for (const [name, json] of Object.entries(experimentalThemeDefinitions)) { + const result = NewThemeOptionsSchema.safeParse(json); + if (!result.success) { + console.error(`Invalid theme definition for theme ${name}: ${result.error.message}`); + } else { + themeMap[result.data.id] = result.data; + } +} + const themeOptions = Object.entries(themeMap).map(([key, theme]) => ({ label: theme.name, value: key, @@ -59,16 +69,20 @@ export default function ThemePlayground() { const theme = createTheme(themeInput); setTheme(theme); } catch (error) { - dispatch(notifyApp(createErrorNotification(`Failed to create theme: ${error}`))); + dispatch(notifyApp(createErrorNotification('Failed to create theme', `${error}`))); } }; const onEditorBlur = (value: string) => { try { - const themeInput: NewThemeOptions = JSON.parse(value); - updateThemePreview(themeInput); + const themeInput = NewThemeOptionsSchema.safeParse(JSON.parse(value)); + if (!themeInput.success) { + dispatch(notifyApp(createErrorNotification('Failed to parse theme', themeInput.error.issues[0].message))); + } else { + updateThemePreview(themeInput.data); + } } catch (error) { - dispatch(notifyApp(createErrorNotification(`Failed to parse JSON: ${error}`))); + dispatch(notifyApp(createErrorNotification('Failed to parse JSON', `${error}`))); } }; @@ -115,7 +129,7 @@ export default function ThemePlayground() { { uri: 'theme-schema', fileMatch: ['*'], - schema, + schema: themeJsonSchema, }, ], }); diff --git a/public/app/features/theme-playground/schema.generated.json b/public/app/features/theme-playground/schema.generated.json deleted file mode 100644 index 936471ba6ea..00000000000 --- a/public/app/features/theme-playground/schema.generated.json +++ /dev/null @@ -1,551 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "definitions": { - "DeepPartial>": { - "properties": { - "action": { - "$ref": "#/definitions/DeepPartial<{selected:string;selectedBorder:string;hover:string;hoverOpacity:number;focus:string;disabledBackground:string;disabledText:string;disabledOpacity:number;}>" - }, - "background": { - "$ref": "#/definitions/DeepPartial<{canvas:string;primary:string;secondary:string;elevated:string;}>" - }, - "border": { - "$ref": "#/definitions/DeepPartial<{weak:string;medium:string;strong:string;}>" - }, - "contrastThreshold": { - "type": "number" - }, - "error": { - "$ref": "#/definitions/DeepPartial" - }, - "gradients": { - "$ref": "#/definitions/DeepPartial<{brandVertical:string;brandHorizontal:string;}>" - }, - "hoverFactor": { - "type": "number" - }, - "info": { - "$ref": "#/definitions/DeepPartial" - }, - "mode": { - "enum": [ - "dark", - "light" - ], - "type": "string" - }, - "primary": { - "$ref": "#/definitions/DeepPartial" - }, - "secondary": { - "$ref": "#/definitions/DeepPartial" - }, - "success": { - "$ref": "#/definitions/DeepPartial" - }, - "text": { - "$ref": "#/definitions/DeepPartial<{primary:string;secondary:string;disabled:string;link:string;maxContrast:string;}>" - }, - "tonalOffset": { - "type": "number" - }, - "warning": { - "$ref": "#/definitions/DeepPartial" - } - }, - "type": "object" - }, - "DeepPartial": { - "properties": { - "border": { - "description": "Used for borders", - "type": "string" - }, - "borderTransparent": { - "description": "Used for weak colored borders like larger alert/banner boxes and smaller badges and tags", - "type": "string" - }, - "contrastText": { - "description": "Text color for text ontop of main", - "type": "string" - }, - "main": { - "description": "Main color", - "type": "string" - }, - "name": { - "description": "color intent (primary, secondary, info, error, etc)", - "type": "string" - }, - "shade": { - "description": "Used for hover", - "type": "string" - }, - "text": { - "description": "Used for text", - "type": "string" - }, - "transparent": { - "description": "Used subtly colored backgrounds", - "type": "string" - } - }, - "type": "object" - }, - "DeepPartial<{brandVertical:string;brandHorizontal:string;}>": { - "properties": { - "brandHorizontal": { - "type": "string" - }, - "brandVertical": { - "type": "string" - } - }, - "type": "object" - }, - "DeepPartial<{canvas:string;primary:string;secondary:string;elevated:string;}>": { - "properties": { - "canvas": { - "description": "Dashboard and body background", - "type": "string" - }, - "elevated": { - "description": "For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark\nthemes it has a brighter shade to help give it contrast against the primary background.", - "type": "string" - }, - "primary": { - "description": "Primary content pane background (panels etc)", - "type": "string" - }, - "secondary": { - "description": "Cards and elements that need to stand out on the primary background", - "type": "string" - } - }, - "type": "object" - }, - "DeepPartial<{primary:string;secondary:string;disabled:string;link:string;maxContrast:string;}>": { - "properties": { - "disabled": { - "type": "string" - }, - "link": { - "type": "string" - }, - "maxContrast": { - "description": "Used for auto white or dark text on colored backgrounds", - "type": "string" - }, - "primary": { - "type": "string" - }, - "secondary": { - "type": "string" - } - }, - "type": "object" - }, - "DeepPartial<{selected:string;selectedBorder:string;hover:string;hoverOpacity:number;focus:string;disabledBackground:string;disabledText:string;disabledOpacity:number;}>": { - "properties": { - "disabledBackground": { - "description": "Used for disabled buttons and inputs", - "type": "string" - }, - "disabledOpacity": { - "description": "Disablerd opacity", - "type": "number" - }, - "disabledText": { - "description": "Disabled text", - "type": "string" - }, - "focus": { - "description": "Used focused menu item / select option", - "type": "string" - }, - "hover": { - "description": "Used for hovered menu item / select option", - "type": "string" - }, - "hoverOpacity": { - "description": "Used for button/colored background hover opacity", - "type": "number" - }, - "selected": { - "description": "Used for selected menu item / select option", - "type": "string" - }, - "selectedBorder": { - "type": "string" - } - }, - "type": "object" - }, - "DeepPartial<{weak:string;medium:string;strong:string;}>": { - "properties": { - "medium": { - "type": "string" - }, - "strong": { - "type": "string" - }, - "weak": { - "type": "string" - } - }, - "type": "object" - }, - "ThemeShapeInput": { - "properties": { - "borderRadius": { - "type": "number" - } - }, - "type": "object" - }, - "ThemeTypographyInput": { - "properties": { - "fontFamily": { - "type": "string" - }, - "fontFamilyMonospace": { - "type": "string" - }, - "fontSize": { - "type": "number" - }, - "fontWeightBold": { - "type": "number" - }, - "fontWeightLight": { - "type": "number" - }, - "fontWeightMedium": { - "type": "number" - }, - "fontWeightRegular": { - "type": "number" - }, - "htmlFontSize": { - "type": "number" - } - }, - "type": "object" - }, - "ThemeVizColor<\"blue\">": { - "properties": { - "aliases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "name": { - "$ref": "#/definitions/ThemeVizColorShadeName_4" - }, - "primary": { - "type": "boolean" - } - }, - "type": "object" - }, - "ThemeVizColor<\"green\">": { - "properties": { - "aliases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "name": { - "$ref": "#/definitions/ThemeVizColorShadeName_3" - }, - "primary": { - "type": "boolean" - } - }, - "type": "object" - }, - "ThemeVizColor<\"orange\">": { - "properties": { - "aliases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "name": { - "$ref": "#/definitions/ThemeVizColorShadeName_1" - }, - "primary": { - "type": "boolean" - } - }, - "type": "object" - }, - "ThemeVizColor<\"purple\">": { - "properties": { - "aliases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "name": { - "$ref": "#/definitions/ThemeVizColorShadeName_5" - }, - "primary": { - "type": "boolean" - } - }, - "type": "object" - }, - "ThemeVizColor<\"red\">": { - "properties": { - "aliases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "name": { - "$ref": "#/definitions/ThemeVizColorShadeName" - }, - "primary": { - "type": "boolean" - } - }, - "type": "object" - }, - "ThemeVizColor<\"yellow\">": { - "properties": { - "aliases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "name": { - "$ref": "#/definitions/ThemeVizColorShadeName_2" - }, - "primary": { - "type": "boolean" - } - }, - "type": "object" - }, - "ThemeVizColorShadeName": { - "enum": [ - "dark-red", - "light-red", - "red", - "semi-dark-red", - "super-light-red" - ], - "type": "string" - }, - "ThemeVizColorShadeName_1": { - "enum": [ - "dark-orange", - "light-orange", - "orange", - "semi-dark-orange", - "super-light-orange" - ], - "type": "string" - }, - "ThemeVizColorShadeName_2": { - "enum": [ - "dark-yellow", - "light-yellow", - "semi-dark-yellow", - "super-light-yellow", - "yellow" - ], - "type": "string" - }, - "ThemeVizColorShadeName_3": { - "enum": [ - "dark-green", - "green", - "light-green", - "semi-dark-green", - "super-light-green" - ], - "type": "string" - }, - "ThemeVizColorShadeName_4": { - "enum": [ - "blue", - "dark-blue", - "light-blue", - "semi-dark-blue", - "super-light-blue" - ], - "type": "string" - }, - "ThemeVizColorShadeName_5": { - "enum": [ - "dark-purple", - "light-purple", - "purple", - "semi-dark-purple", - "super-light-purple" - ], - "type": "string" - }, - "ThemeVizHue": { - "anyOf": [ - { - "properties": { - "name": { - "const": "red", - "type": "string" - }, - "shades": { - "items": { - "$ref": "#/definitions/ThemeVizColor<\"red\">" - }, - "type": "array" - } - }, - "type": "object" - }, - { - "properties": { - "name": { - "const": "orange", - "type": "string" - }, - "shades": { - "items": { - "$ref": "#/definitions/ThemeVizColor<\"orange\">" - }, - "type": "array" - } - }, - "type": "object" - }, - { - "properties": { - "name": { - "const": "yellow", - "type": "string" - }, - "shades": { - "items": { - "$ref": "#/definitions/ThemeVizColor<\"yellow\">" - }, - "type": "array" - } - }, - "type": "object" - }, - { - "properties": { - "name": { - "const": "green", - "type": "string" - }, - "shades": { - "items": { - "$ref": "#/definitions/ThemeVizColor<\"green\">" - }, - "type": "array" - } - }, - "type": "object" - }, - { - "properties": { - "name": { - "const": "blue", - "type": "string" - }, - "shades": { - "items": { - "$ref": "#/definitions/ThemeVizColor<\"blue\">" - }, - "type": "array" - } - }, - "type": "object" - }, - { - "properties": { - "name": { - "const": "purple", - "type": "string" - }, - "shades": { - "items": { - "$ref": "#/definitions/ThemeVizColor<\"purple\">" - }, - "type": "array" - } - }, - "type": "object" - } - ] - } - }, - "properties": { - "colors": { - "$ref": "#/definitions/DeepPartial>" - }, - "name": { - "type": "string" - }, - "shape": { - "$ref": "#/definitions/ThemeShapeInput" - }, - "spacing": { - "properties": { - "gridSize": { - "type": "number" - } - }, - "type": "object" - }, - "typography": { - "$ref": "#/definitions/ThemeTypographyInput" - }, - "visualization": { - "properties": { - "hues": { - "items": { - "$ref": "#/definitions/ThemeVizHue" - }, - "type": "array" - }, - "palette": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - } - }, - "type": "object" -} - diff --git a/yarn.lock b/yarn.lock index 1b4710e4062..41cc10d8353 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1964,6 +1964,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/aix-ppc64@npm:0.27.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/android-arm64@npm:0.25.8" @@ -1971,6 +1978,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-arm64@npm:0.27.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/android-arm@npm:0.25.8" @@ -1978,6 +1992,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-arm@npm:0.27.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/android-x64@npm:0.25.8" @@ -1985,6 +2006,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-x64@npm:0.27.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/darwin-arm64@npm:0.25.8" @@ -1992,6 +2020,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/darwin-arm64@npm:0.27.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/darwin-x64@npm:0.25.8" @@ -1999,6 +2034,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/darwin-x64@npm:0.27.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/freebsd-arm64@npm:0.25.8" @@ -2006,6 +2048,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/freebsd-arm64@npm:0.27.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/freebsd-x64@npm:0.25.8" @@ -2013,6 +2062,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/freebsd-x64@npm:0.27.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-arm64@npm:0.25.8" @@ -2020,6 +2076,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-arm64@npm:0.27.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-arm@npm:0.25.8" @@ -2027,6 +2090,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-arm@npm:0.27.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-ia32@npm:0.25.8" @@ -2034,6 +2104,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-ia32@npm:0.27.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-loong64@npm:0.25.8" @@ -2041,6 +2118,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-loong64@npm:0.27.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-mips64el@npm:0.25.8" @@ -2048,6 +2132,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-mips64el@npm:0.27.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-ppc64@npm:0.25.8" @@ -2055,6 +2146,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-ppc64@npm:0.27.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-riscv64@npm:0.25.8" @@ -2062,6 +2160,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-riscv64@npm:0.27.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-s390x@npm:0.25.8" @@ -2069,6 +2174,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-s390x@npm:0.27.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/linux-x64@npm:0.25.8" @@ -2076,6 +2188,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-x64@npm:0.27.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/netbsd-arm64@npm:0.25.8" @@ -2083,6 +2202,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/netbsd-arm64@npm:0.27.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/netbsd-x64@npm:0.25.8" @@ -2090,6 +2216,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/netbsd-x64@npm:0.27.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/openbsd-arm64@npm:0.25.8" @@ -2097,6 +2230,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openbsd-arm64@npm:0.27.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/openbsd-x64@npm:0.25.8" @@ -2104,6 +2244,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openbsd-x64@npm:0.27.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openharmony-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/openharmony-arm64@npm:0.25.8" @@ -2111,6 +2258,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openharmony-arm64@npm:0.27.2" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/sunos-x64@npm:0.25.8" @@ -2118,6 +2272,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/sunos-x64@npm:0.27.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/win32-arm64@npm:0.25.8" @@ -2125,6 +2286,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-arm64@npm:0.27.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/win32-ia32@npm:0.25.8" @@ -2132,6 +2300,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-ia32@npm:0.27.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.25.8": version: 0.25.8 resolution: "@esbuild/win32-x64@npm:0.25.8" @@ -2139,6 +2314,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-x64@npm:0.27.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0": version: 4.7.0 resolution: "@eslint-community/eslint-utils@npm:4.7.0" @@ -3109,6 +3291,7 @@ __metadata: "@grafana/scenes": "npm:6.38.0" "@grafana/schema": "npm:12.4.0-pre" "@leeoniya/ufuzzy": "npm:1.0.19" + "@rollup/plugin-json": "npm:6.1.0" "@rollup/plugin-node-resolve": "npm:16.0.1" "@testing-library/react": "npm:16.3.0" "@types/d3-interpolate": "npm:^3.0.0" @@ -3147,9 +3330,11 @@ __metadata: string-hash: "npm:^1.1.3" tinycolor2: "npm:1.6.0" tslib: "npm:2.8.1" + tsx: "npm:^4.21.0" typescript: "npm:5.9.2" uplot: "npm:1.6.32" xss: "npm:^1.0.14" + zod: "npm:^4.3.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 @@ -10766,15 +10951,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.11.9": - version: 18.19.129 - resolution: "@types/node@npm:18.19.129" - dependencies: - undici-types: "npm:~5.26.4" - checksum: 10/0db4cb246d6012b1b523661a59c2e8e0b24527f1c02cfa3deb8e0b884492a07f2547c5353f56272b70037408e3dbe690ae923b8073fd7b0814e389148245e59f - languageName: node - linkType: hard - "@types/nodemailer@npm:*": version: 6.4.15 resolution: "@types/nodemailer@npm:6.4.15" @@ -17190,6 +17366,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.27.0": + version: 0.27.2 + resolution: "esbuild@npm:0.27.2" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.2" + "@esbuild/android-arm": "npm:0.27.2" + "@esbuild/android-arm64": "npm:0.27.2" + "@esbuild/android-x64": "npm:0.27.2" + "@esbuild/darwin-arm64": "npm:0.27.2" + "@esbuild/darwin-x64": "npm:0.27.2" + "@esbuild/freebsd-arm64": "npm:0.27.2" + "@esbuild/freebsd-x64": "npm:0.27.2" + "@esbuild/linux-arm": "npm:0.27.2" + "@esbuild/linux-arm64": "npm:0.27.2" + "@esbuild/linux-ia32": "npm:0.27.2" + "@esbuild/linux-loong64": "npm:0.27.2" + "@esbuild/linux-mips64el": "npm:0.27.2" + "@esbuild/linux-ppc64": "npm:0.27.2" + "@esbuild/linux-riscv64": "npm:0.27.2" + "@esbuild/linux-s390x": "npm:0.27.2" + "@esbuild/linux-x64": "npm:0.27.2" + "@esbuild/netbsd-arm64": "npm:0.27.2" + "@esbuild/netbsd-x64": "npm:0.27.2" + "@esbuild/openbsd-arm64": "npm:0.27.2" + "@esbuild/openbsd-x64": "npm:0.27.2" + "@esbuild/openharmony-arm64": "npm:0.27.2" + "@esbuild/sunos-x64": "npm:0.27.2" + "@esbuild/win32-arm64": "npm:0.27.2" + "@esbuild/win32-ia32": "npm:0.27.2" + "@esbuild/win32-x64": "npm:0.27.2" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/7f1229328b0efc63c4184a61a7eb303df1e99818cc1d9e309fb92600703008e69821e8e984e9e9f54a627da14e0960d561db3a93029482ef96dc82dd267a60c2 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -18785,6 +19050,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10/4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0 + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" @@ -18794,6 +19069,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "function-bind@npm:^1.1.2": version: 1.1.2 resolution: "function-bind@npm:1.1.2" @@ -19008,6 +19292,15 @@ __metadata: languageName: node linkType: hard +"get-tsconfig@npm:^4.7.5": + version: 4.13.0 + resolution: "get-tsconfig@npm:4.13.0" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: 10/3603c6da30e312636e4c20461e779114c9126601d1eca70ee4e36e3e3c00e3c21892d2d920027333afa2cc9e20998a436b14abe03a53cde40742581cb0e9ceb2 + languageName: node + linkType: hard + "get-uri@npm:^6.0.1": version: 6.0.5 resolution: "get-uri@npm:6.0.5" @@ -19254,7 +19547,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.0.3, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7": +"glob@npm:^7.0.3, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -19796,7 +20089,6 @@ __metadata: tween-functions: "npm:^1.2.0" type-fest: "npm:^4.18.2" typescript: "npm:5.9.2" - typescript-json-schema: "npm:^0.65.1" uplot: "npm:1.6.32" uuid: "npm:11.1.0" vis-data: "npm:^8.0.0" @@ -19812,7 +20104,7 @@ __metadata: whatwg-fetch: "npm:3.6.20" yaml: "npm:^2.0.0" yargs: "npm:^18.0.0" - zod: "npm:^4.0.0" + zod: "npm:^4.3.0" dependenciesMeta: cypress: built: true @@ -26756,13 +27048,6 @@ __metadata: languageName: node linkType: hard -"path-equal@npm:^1.2.5": - version: 1.2.5 - resolution: "path-equal@npm:1.2.5" - checksum: 10/fa4ef398dea6bd7bf36c5fe62b5f5c2c14fe1f1340cf355eb8a40c86577318dfa0401df86464bb0cc33ed227f115b2afec10d1adaa64260dedbbc23d33f3abbb - languageName: node - linkType: hard - "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -30218,13 +30503,6 @@ __metadata: languageName: node linkType: hard -"safe-stable-stringify@npm:^2.2.0": - version: 2.5.0 - resolution: "safe-stable-stringify@npm:2.5.0" - checksum: 10/2697fa186c17c38c3ca5309637b4ac6de2f1c3d282da27cd5e1e3c88eca0fb1f9aea568a6aabdf284111592c8782b94ee07176f17126031be72ab1313ed46c5c - languageName: node - linkType: hard - "safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -32786,7 +33064,7 @@ __metadata: languageName: node linkType: hard -"ts-node@npm:10.9.2, ts-node@npm:^10.9.1": +"ts-node@npm:10.9.2": version: 10.9.2 resolution: "ts-node@npm:10.9.2" dependencies: @@ -32893,6 +33171,22 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.21.0": + version: 4.21.0 + resolution: "tsx@npm:4.21.0" + dependencies: + esbuild: "npm:~0.27.0" + fsevents: "npm:~2.3.3" + get-tsconfig: "npm:^4.7.5" + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 10/7afedeff855ba98c47dc28b33d7e8e253c4dc1f791938db402d79c174bdf806b897c1a5f91e5b1259c112520c816f826b4c5d98f0bad7e95b02dec66fedb64d2 + languageName: node + linkType: hard + "tuf-js@npm:^2.2.1": version: 2.2.1 resolution: "tuf-js@npm:2.2.1" @@ -33128,24 +33422,6 @@ __metadata: languageName: node linkType: hard -"typescript-json-schema@npm:^0.65.1": - version: 0.65.1 - resolution: "typescript-json-schema@npm:0.65.1" - dependencies: - "@types/json-schema": "npm:^7.0.9" - "@types/node": "npm:^18.11.9" - glob: "npm:^7.1.7" - path-equal: "npm:^1.2.5" - safe-stable-stringify: "npm:^2.2.0" - ts-node: "npm:^10.9.1" - typescript: "npm:~5.5.0" - yargs: "npm:^17.1.1" - bin: - typescript-json-schema: bin/typescript-json-schema - checksum: 10/50a1935378639d5d47e452702766a3fdab22e1d06192f26f81b79e0da504e71af987ff21cb13909479a202aad8d1216a654f16ebda2ee2056b5f859584b4c7d2 - languageName: node - linkType: hard - "typescript-string-operations@npm:^1.4.1": version: 1.5.1 resolution: "typescript-string-operations@npm:1.5.1" @@ -33153,7 +33429,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.5.4, typescript@npm:~5.5.0": +"typescript@npm:5.5.4": version: 5.5.4 resolution: "typescript@npm:5.5.4" bin: @@ -33183,7 +33459,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.5.4#optional!builtin, typescript@patch:typescript@npm%3A~5.5.0#optional!builtin": +"typescript@patch:typescript@npm%3A5.5.4#optional!builtin": version: 5.5.4 resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=379a07" bin: @@ -33272,13 +33548,6 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~5.26.4": - version: 5.26.5 - resolution: "undici-types@npm:5.26.5" - checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd - languageName: node - linkType: hard - "undici-types@npm:~7.16.0": version: 7.16.0 resolution: "undici-types@npm:7.16.0" @@ -34824,7 +35093,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.1.1, yargs@npm:^17.3.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2": +"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.3.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -34948,13 +35217,20 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.25 || ^4.0, zod@npm:^4.0.0": +"zod@npm:^3.25 || ^4.0": version: 4.1.13 resolution: "zod@npm:4.1.13" checksum: 10/0679190318928f69fcb07751063719de232c663b13955fcdb55db59839569d39f3f29b955cb0cba7af0b724233f88c06b3e84c550397ad4e68f8088fa6799d88 languageName: node linkType: hard +"zod@npm:^4.3.0": + version: 4.3.5 + resolution: "zod@npm:4.3.5" + checksum: 10/3148bd52e56ab7c1641ec397e6be6eddbb1d8f5db71e95baab9bb9622a0ea49d8a385885fc1c22b90fa6d8c5234e051f4ef5d469cfe3fb90198d5a91402fd89c + languageName: node + linkType: hard + "zstddec@npm:^0.1.0": version: 0.1.0 resolution: "zstddec@npm:0.1.0"