schema

package
v0.32.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: Apache-2.0 Imports: 15 Imported by: 1

Documentation

Overview

Package schema provides the `@schema NAME { Field Type `json:"..." default:"..." validate:"..."` ... }` directive. The declaration lands in meta["schemas"]. A `:schema=NAME` modifier on a declared `@pipeline` applies defaults and validates its input at every invocation boundary.

Typical use:

@schema TestUser {
  Name string `json:"name" default:"guest" validate:"required"`
}
@pipeline greet:schema=TestUser
  runtime.noop
@end

ApplyDefaults returns a new effective payload map, and schema validation passes that map to the pipeline's first action.

Index

Constants

View Source
const ID = "schema"

Variables

View Source
var Directive = compiler.Directive{
	Name:    "schema",
	Example: `@schema Plan { Summary string }`,
	Handler: handleDirective,
}

Directive parses `@schema NAME { ... }` into a Schema appended to meta["schemas"]. Duplicate names are a compile error.

View Source
var SchemaModifier = compiler.String("schema",
	func(b *action.Builder[any, any], name string) *action.Builder[any, any] {
		return b.Tag("schema:" + name)
	})

SchemaModifier attaches a schema name to an atom as metadata. Declared pipeline input validation is applied by the pipeline materializer using the pipeline header's :schema=NAME modifier.

View Source
var ValidateAction = action.New("schema.validate", func(ctx context.Context, req ValidateRequest) (any, error) {
	if req.Name == "" {
		return nil, xerr.BadRequest("schema.validate: schema name is required (use @{ name: \"SchemaName\" })")
	}

	schemas, _ := schemasContextKey.From(ctx)
	targetSchema, ok := schemas[req.Name]
	if !ok {
		return nil, xerr.NotFound("schema.validate: schema '" + req.Name + "' not registered in workflow")
	}

	targetPayload := req.Payload
	if targetPayload == nil {
		targetPayload, _ = rootInputKey.From(ctx)
	}

	if targetPayload == nil {
		return nil, xerr.BadRequest("schema.validate: no payload available to validate")
	}

	effective, err := ApplyDefaultsAndValidate(ctx, targetSchema, targetPayload)
	if err != nil {
		return nil, err
	}

	return effective, nil
}).Description("Validate payload against a declared @schema").
	Tag("schema", "validation").
	Build()

Functions

func ApplyDefaults added in v0.30.2

func ApplyDefaults(schema Schema, payload any) (map[string]any, error)

ApplyDefaults returns a copy of payload with each missing field filled from its schema field's `default` tag. Explicitly supplied values, including nil, are preserved. The input map is never modified.

Scalar defaults are parsed according to the declared field type. Slice, map, and struct defaults use JSON values, for example `default:"[1,2]"` or `default:"{\"enabled\":true}"`.

func ApplyDefaultsAndValidate added in v0.31.0

func ApplyDefaultsAndValidate(ctx context.Context, schema Schema, payload any) (map[string]any, error)

ApplyDefaultsAndValidate returns the effective payload after applying missing defaults and validating the declared fields. Explicit input values, including typed slice values, are preserved.

func Bundle

func Bundle(_ map[string]string) compiler.Bundle

func Library added in v0.12.0

func Library() action.Library

func SplitFields added in v0.17.0

func SplitFields(s Schema) (payload, config []string)

func ToJSONSchema added in v0.22.0

func ToJSONSchema(s Schema) map[string]any

func Validate

func Validate(ctx context.Context, schema Schema, payload any) error

Validate applies missing defaults and checks payload against the declared schema.

For every field that is present, the check proceeds in two stages:

  1. Go-kind check (checkFieldKind): the payload value's kind must match the schema field's declared type.
  2. Tag check (validation.Var): when the field carries a `validate:"..."` tag beyond bare "required", the value is validated against the tag expression using the same validator/v10 instance that powers validation.Struct.

The presence check for validate:"required" is handled inline, so a missing field reports as "is required" without invoking the validator. An empty string for a required field is also reported as "is required" because validator/v10 treats empty as the zero value.

ctx is threaded from the caller so context-aware custom rules registered via validation.RegisterCustom see the live context, and so a canceled invocation aborts validation promptly.

func WithContextSchemas added in v0.12.0

func WithContextSchemas(ctx context.Context, schemas []Schema) context.Context

Types

type Field

type Field struct {
	Name     string
	JSONName string
	Type     string
	Kind     Kind
	ElemType string
	Pointer  bool
	Slice    bool
	Map      bool
	Tags     map[string]string
	Embed    string
}

type Kind

type Kind uint8
const (
	KindString Kind = iota
	KindInt
	KindFloat
	KindBool
	KindAny
	KindStruct
)

type Schema

type Schema struct {
	Name   string
	Fields []Field
}

func ByName

func ByName(meta map[string]any, name string) (Schema, bool)

func SchemasFromMap

func SchemasFromMap(meta map[string]any) []Schema

type ValidateRequest added in v0.12.0

type ValidateRequest struct {
	Name    string `json:"name"              validate:"required"`
	Payload any    `json:"payload,omitempty"`
}

Jump to

Keyboard shortcuts

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