schema

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package schema provides reflection-based struct introspection for generating kubectl explain-style documentation from Go struct tags.

Index

Constants

View Source
const ConfigSchemaID = "https://scafctl.dev/schemas/v1/config.json"

ConfigSchemaID is the JSON Schema ID for the config file.

View Source
const SolutionSchemaID = "https://scafctl.dev/schemas/v1/solution.json"

SolutionSchemaID is the JSON Schema ID for the solution file format.

Variables

This section is empty.

Functions

func GenerateConfigSchema

func GenerateConfigSchema() ([]byte, error)

GenerateConfigSchema generates a JSON Schema for the scafctl config file. It uses reflection to analyze the config.Config struct and its tags.

func GenerateConfigSchemaCompact

func GenerateConfigSchemaCompact() ([]byte, error)

GenerateConfigSchemaCompact generates a JSON Schema without indentation.

func GenerateSolutionSchema added in v0.5.0

func GenerateSolutionSchema() ([]byte, error)

GenerateSolutionSchema generates a JSON Schema for the Solution struct using Huma's schema generation which reads the struct tags (doc, example, pattern, maxLength, etc.) to produce a full OpenAPI-compatible schema.

func GenerateSolutionSchemaCompact added in v0.5.0

func GenerateSolutionSchemaCompact() ([]byte, error)

GenerateSolutionSchemaCompact generates a compact (no indentation) JSON Schema.

func RegisterKind

func RegisterKind(def *KindDefinition) error

RegisterKind registers a kind in the global registry.

Types

type FieldInfo

type FieldInfo struct {
	// Name is the field name as it appears in JSON/YAML (from json tag)
	Name string `json:"name" yaml:"name"`

	// GoName is the original Go field name
	GoName string `json:"goName" yaml:"goName"`

	// Type is the Go type name
	Type string `json:"type" yaml:"type"`

	// Kind is the reflect.Kind (struct, slice, map, etc.)
	Kind reflect.Kind `json:"kind" yaml:"kind"`

	// Description from the "doc" tag
	Description string `json:"description,omitempty" yaml:"description,omitempty"`

	// Required from the "required" tag
	Required bool `json:"required,omitempty" yaml:"required,omitempty"`

	// Example from the "example" tag
	Example string `json:"example,omitempty" yaml:"example,omitempty"`

	// Pattern from the "pattern" tag (regex)
	Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`

	// PatternDescription from the "patternDescription" tag
	PatternDescription string `json:"patternDescription,omitempty" yaml:"patternDescription,omitempty"`

	// Format from the "format" tag (uri, email, date, etc.)
	Format string `json:"format,omitempty" yaml:"format,omitempty"`

	// MinLength from the "minLength" tag
	MinLength *int `json:"minLength,omitempty" yaml:"minLength,omitempty"`

	// MaxLength from the "maxLength" tag
	MaxLength *int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`

	// Minimum from the "minimum" tag
	Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`

	// Maximum from the "maximum" tag
	Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`

	// MinItems from the "minItems" tag
	MinItems *int `json:"minItems,omitempty" yaml:"minItems,omitempty"`

	// MaxItems from the "maxItems" tag
	MaxItems *int `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`

	// Default from the "default" tag
	Default string `json:"default,omitempty" yaml:"default,omitempty"`

	// Enum values (if field is an enum type with known values)
	Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`

	// Deprecated from the "deprecated" tag
	Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`

	// Omitempty indicates if the field has omitempty in json tag
	Omitempty bool `json:"omitempty,omitempty" yaml:"omitempty,omitempty"`

	// ElemType is the element type for slices/arrays/maps
	ElemType string `json:"elemType,omitempty" yaml:"elemType,omitempty"`

	// ElemKind is the element's reflect.Kind for slices/arrays/maps
	ElemKind reflect.Kind `json:"elemKind,omitempty" yaml:"elemKind,omitempty"`

	// KeyType is the key type for maps
	KeyType string `json:"keyType,omitempty" yaml:"keyType,omitempty"`

	// NestedFields contains fields if this is a struct type
	NestedFields []FieldInfo `json:"nestedFields,omitempty" yaml:"nestedFields,omitempty"`

	// IsPointer indicates if the field is a pointer type
	IsPointer bool `json:"isPointer,omitempty" yaml:"isPointer,omitempty"`

	// IsExported indicates if the field is exported
	IsExported bool `json:"isExported,omitempty" yaml:"isExported,omitempty"`
}

FieldInfo represents introspected information about a struct field, extracted from Go struct tags.

func IntrospectField

func IntrospectField(v any, path string) (*FieldInfo, error)

IntrospectField returns field information for a specific field path. The path uses dot notation: "schema.properties" or "metadata.version"

type FormatOptions

type FormatOptions struct {
	// ShowNestedFields controls whether to expand nested struct fields
	ShowNestedFields bool

	// MaxDepth limits how deep to recurse into nested types
	MaxDepth int

	// ShowValidation controls whether to show validation rules
	ShowValidation bool

	// Compact uses a more compact output format
	Compact bool
}

FormatOptions controls how schema information is displayed.

func DefaultFormatOptions

func DefaultFormatOptions() FormatOptions

DefaultFormatOptions returns sensible defaults for formatting.

type Formatter

type Formatter struct {
	// contains filtered or unexported fields
}

Formatter handles rendering schema information to the terminal.

func NewFormatterWithWriter

func NewFormatterWithWriter(w *writer.Writer) *Formatter

NewFormatterWithWriter creates a formatter with an existing writer.

func (*Formatter) FormatField

func (f *Formatter) FormatField(info *FieldInfo)

FormatField renders a single FieldInfo in kubectl explain style.

func (*Formatter) FormatType

func (f *Formatter) FormatType(info *TypeInfo)

FormatType renders a TypeInfo in kubectl explain style.

func (*Formatter) WithOptions

func (f *Formatter) WithOptions(opts FormatOptions) *Formatter

WithOptions sets formatting options.

type KindDefinition

type KindDefinition struct {
	// Name is the kind name used in CLI (e.g., "provider", "solution")
	Name string

	// Aliases are alternative names (e.g., "providers", "prov")
	Aliases []string

	// Description is a brief explanation of the kind
	Description string

	// TypeInstance is a pointer to the type for reflection
	// Use: (*MyType)(nil)
	TypeInstance any

	// TypeInfo is the cached introspected type information
	TypeInfo *TypeInfo
}

KindDefinition holds metadata and type information for an explainable kind.

func GetKind

func GetKind(name string) (*KindDefinition, error)

GetKind retrieves a kind from the global registry.

func ListKinds

func ListKinds() ([]*KindDefinition, error)

ListKinds returns all kinds from the global registry.

type KindRegistry

type KindRegistry struct {
	// contains filtered or unexported fields
}

KindRegistry manages the collection of explainable types.

func GetGlobalRegistry

func GetGlobalRegistry() (*KindRegistry, error)

GetGlobalRegistry returns the global kind registry after ensuring built-in kinds are registered.

func NewKindRegistry

func NewKindRegistry() *KindRegistry

NewKindRegistry creates a new kind registry.

func (*KindRegistry) Get

func (r *KindRegistry) Get(name string) (*KindDefinition, bool)

Get retrieves a kind definition by name or alias.

func (*KindRegistry) List

func (r *KindRegistry) List() []*KindDefinition

List returns all unique kind definitions (excluding aliases).

func (*KindRegistry) Names

func (r *KindRegistry) Names() []string

Names returns all registered kind names (primary names only).

func (*KindRegistry) Register

func (r *KindRegistry) Register(def *KindDefinition) error

Register adds a kind definition to the registry.

type TypeInfo

type TypeInfo struct {
	// Name is the type name
	Name string `json:"name" yaml:"name"`

	// Package is the package path
	Package string `json:"package" yaml:"package"`

	// Description from the type's doc comment (not available via reflection)
	Description string `json:"description,omitempty" yaml:"description,omitempty"`

	// Kind is the reflect.Kind
	Kind reflect.Kind `json:"kind" yaml:"kind"`

	// Fields contains information about struct fields (if struct type)
	Fields []FieldInfo `json:"fields,omitempty" yaml:"fields,omitempty"`
}

TypeInfo represents introspected information about a Go type.

func IntrospectType

func IntrospectType(v any) (*TypeInfo, error)

IntrospectType returns detailed information about a Go type by examining its struct tags. Pass a pointer to the type: IntrospectType((*MyStruct)(nil))

type Violation added in v0.5.0

type Violation struct {
	// Path is the dot-notation location of the violation (e.g., "spec.resolvers.env.resolve.with[0]").
	Path string `json:"path" yaml:"path"`
	// Message is a human-readable description of the violation.
	Message string `json:"message" yaml:"message"`
}

Violation represents a single validation error found when validating data against the solution JSON schema.

func ValidateSolutionAgainstSchema added in v0.5.0

func ValidateSolutionAgainstSchema(data any) ([]Violation, error)

ValidateSolutionAgainstSchema validates raw data (parsed from YAML/JSON as map[string]any) against the generated solution JSON schema. It returns a list of violations, or an error if the schema itself could not be compiled.

The data parameter should be the result of unmarshalling YAML into a plain any (not into a typed Solution struct), so that unknown fields are preserved for detection.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL