fix: promote variable defaultValue to a named oneOf component

The list variable defaultValue was an inline string | []string oneOf,
which downstream codegen can't canonicalize: tfplugingen-openapi rejects
the inline scalar-or-array multi-type, and oapi-codegen has no named type
to attach the union's Marshal/UnmarshalJSON to.

Shape the vendored variable.DefaultValue as the named VariableDefaultValue
oneOf via a reflector InterceptSchema hook and let defaultValue $ref it,
instead of overriding the property inline. Regenerate the OpenAPI spec and
frontend client accordingly.
This commit is contained in:
grandwizard28
2026-06-26 11:52:21 +05:30
parent 85902343bc
commit 94de803e7f
5 changed files with 47 additions and 32 deletions

View File

@@ -2971,11 +2971,7 @@ components:
customAllValue:
type: string
defaultValue:
oneOf:
- type: string
- items:
type: string
type: array
$ref: '#/components/schemas/VariableDefaultValue'
display:
$ref: '#/components/schemas/DashboardtypesDisplay'
name:
@@ -7895,7 +7891,11 @@ components:
- id
type: object
VariableDefaultValue:
type: object
oneOf:
- type: string
- items:
type: string
type: array
ZeustypesGettableHost:
properties:
hosts:

View File

@@ -4564,6 +4564,8 @@ export type DashboardtypesLayoutDTO =
export enum DashboardtypesVariableEnvelopeGithubComSigNozSignozPkgTypesDashboardtypesListVariableSpecDTOKind {
ListVariable = 'ListVariable',
}
export type VariableDefaultValueDTO = string | string[];
export enum DashboardtypesVariablePluginVariantGithubComSigNozSignozPkgTypesDashboardtypesDynamicVariableSpecDTOKind {
'signoz/DynamicVariable' = 'signoz/DynamicVariable',
}
@@ -4629,8 +4631,6 @@ export enum DashboardtypesListVariableSpecSortDTO {
'alphabetical-ci-asc' = 'alphabetical-ci-asc',
'alphabetical-ci-desc' = 'alphabetical-ci-desc',
}
export type DashboardtypesListVariableSpecDTODefaultValue = string | string[];
export interface DashboardtypesListVariableSpecDTO {
/**
* @type boolean
@@ -4648,7 +4648,7 @@ export interface DashboardtypesListVariableSpecDTO {
* @type string
*/
customAllValue?: string;
defaultValue?: DashboardtypesListVariableSpecDTODefaultValue;
defaultValue?: VariableDefaultValueDTO;
display: DashboardtypesDisplayDTO;
/**
* @type string
@@ -9023,10 +9023,6 @@ export interface TypesUserDTO {
updatedAt?: string;
}
export interface VariableDefaultValueDTO {
[key: string]: unknown;
}
export interface ZeustypesHostDTO {
/**
* @type boolean

View File

@@ -2,7 +2,7 @@ import {
DashboardtypesListVariableSpecSortDTO,
TelemetrytypesSignalDTO,
} from 'api/generated/services/sigNoz.schemas';
import type { DashboardtypesListVariableSpecDTODefaultValue } from 'api/generated/services/sigNoz.schemas';
import type { VariableDefaultValueDTO } from 'api/generated/services/sigNoz.schemas';
import { sortBy } from 'lodash-es';
/**
@@ -136,7 +136,7 @@ export interface VariableFormModel {
* Runtime-selected default, not editable in the management tab yet; carried
* through edits so saving a definition doesn't clobber it.
*/
defaultValue?: DashboardtypesListVariableSpecDTODefaultValue;
defaultValue?: VariableDefaultValueDTO;
}
export function emptyVariableFormModel(): VariableFormModel {

View File

@@ -39,6 +39,7 @@ import (
"github.com/SigNoz/signoz/pkg/statsreporter"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/zeus"
"github.com/perses/spec/go/dashboard/variable"
"github.com/swaggest/jsonschema-go"
"github.com/swaggest/openapi-go"
"github.com/swaggest/openapi-go/openapi3"
@@ -104,6 +105,41 @@ func NewOpenAPI(ctx context.Context, instrumentation instrumentation.Instrumenta
return defaultDefName
}))
// variable.DefaultValue (perses) is the string | []string union used by a
// list variable's defaultValue. It marshals as a scalar-or-array, so its
// reflected struct shape (a bare object) is wrong. Emit it as a named oneOf
// component (VariableDefaultValue) and let defaultValue $ref it, instead of
// inlining the union onto the property: a named component gives downstream
// codegen a hook to canonicalize — oapi-codegen generates the union's
// Marshal/UnmarshalJSON and skaff's scalar-union pre-pass flattens it to a
// string attribute. An inline oneOf has no such component to hook.
reflector.JSONSchemaReflector().DefaultOptions = append(reflector.JSONSchemaReflector().DefaultOptions, jsonschema.InterceptSchema(func(params jsonschema.InterceptSchemaParams) (bool, error) {
if !params.Processed || !params.Value.IsValid() {
return false, nil
}
typ := params.Value.Type()
if typ.Kind() == reflect.Pointer {
typ = typ.Elem()
}
if typ != reflect.TypeOf(variable.DefaultValue{}) {
return false, nil
}
stringItem := jsonschema.String.ToSchemaOrBool()
params.Schema.Type = nil
params.Schema.Properties = nil
params.Schema.WithOneOf(
jsonschema.String.ToSchemaOrBool(),
(&jsonschema.Schema{}).
WithType(jsonschema.Array.Type()).
WithItems(jsonschema.Items{SchemaOrBool: &stringItem}).
ToSchemaOrBool(),
)
return false, nil
}))
reflector.Spec.WithInfo(*(&openapi3.Info{}).
WithTitle("SigNoz").
WithDescription("OpenTelemetry-Native Logs, Metrics and Traces in a single pane").

View File

@@ -156,23 +156,6 @@ type ListVariableSpec struct {
Name string `json:"name" required:"true" minLength:"1"`
}
// PrepareJSONSchema types defaultValue as the string | []string union.
func (ListVariableSpec) PrepareJSONSchema(s *jsonschema.Schema) error {
if _, ok := s.Properties["defaultValue"]; !ok {
return nil
}
stringItem := jsonschema.String.ToSchemaOrBool()
defaultValue := (&jsonschema.Schema{}).WithOneOf(
jsonschema.String.ToSchemaOrBool(),
(&jsonschema.Schema{}).
WithType(jsonschema.Array.Type()).
WithItems(jsonschema.Items{SchemaOrBool: &stringItem}).
ToSchemaOrBool(),
)
s.Properties["defaultValue"] = defaultValue.ToSchemaOrBool()
return nil
}
// validate mirrors perses ListVariableSpec validation (plus the digits-only name
// check perses only applies to text variables); run by decodeSpec on unmarshal.
func (s *ListVariableSpec) validate() error {