spec

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: 11 Imported by: 0

README

Package spec

The spec package provides shared types used across both the resolver and action systems in scafctl.

Overview

This package extracts common types that were originally in the pkg/resolver package but are now shared between resolvers and actions. This ensures consistent behavior and reduces code duplication.

Types

ValueRef

ValueRef represents a value that can be:

  • A literal value (string, number, boolean, array, map)
  • A resolver reference (rslvr: resolverName)
  • A CEL expression (expr: _.environment == 'prod')
  • A Go template (tmpl: "{{ ._.name }}")
// Literal value
value := &ValueRef{Literal: "hello"}

// Resolver reference
resolver := "config"
value := &ValueRef{Resolver: &resolver}

// CEL expression
expr := celexp.Expression("_.count + 1")
value := &ValueRef{Expr: &expr}

// Go template  
tmpl := gotmpl.GoTemplatingContent("Hello {{ ._.name }}")
value := &ValueRef{Tmpl: &tmpl}
IterationContext

IterationContext holds context for forEach iteration variables:

iterCtx := &IterationContext{
    Item:       currentElement,
    Index:      currentIndex,
    ItemAlias:  "region",    // Custom name for __item
    IndexAlias: "i",         // Custom name for __index
}
Condition

Condition wraps a CEL expression for conditional execution:

cond := &Condition{
    Expr: celexp.NewExpression("_.environment == 'prod'"),
}
ForEachClause

ForEachClause defines iteration over an array:

forEach := &ForEachClause{
    Item:        "region",   // Alias for __item
    Index:       "i",        // Alias for __index
    In:          &ValueRef{Literal: []string{"us-east", "eu-west"}},
    Concurrency: 5,          // Max parallel iterations
    OnError:     OnErrorContinue, // For actions only
}
OnErrorBehavior

OnErrorBehavior defines how to handle errors:

const (
    OnErrorFail     OnErrorBehavior = "fail"     // Stop and return error (default)
    OnErrorContinue OnErrorBehavior = "continue" // Continue execution
)
Type Coercion

Type coercion utilities for converting values between types:

// Coerce to string
str, err := CoerceType(42, TypeString) // "42"

// Coerce to int
num, err := CoerceType("42", TypeInt)  // 42

// Coerce to time
t, err := CoerceType("2026-01-14T12:00:00Z", TypeTime)

Usage

Import the package:

import "github.com/oakwood-commons/scafctl/pkg/spec"

The pkg/resolver package re-exports these types as aliases for backward compatibility:

// In pkg/resolver
type ValueRef = spec.ValueRef
type Condition = spec.Condition
// etc.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CoerceType

func CoerceType(value any, targetType Type) (any, error)

CoerceType attempts to coerce a value to the specified type. Returns the coerced value or an error if coercion is not possible.

Types

type Condition

type Condition struct {
	Expr *celexp.Expression `json:"expr" yaml:"expr" doc:"CEL expression that must evaluate to boolean" example:"_.environment == 'prod'"`
}

Condition represents a conditional execution clause. It wraps a CEL expression that must evaluate to a boolean value.

Supported YAML forms:

  • Boolean literal: when: true / when: false
  • String shorthand: when: "_.environment == 'prod'"
  • Explicit object: when: { expr: "_.environment == 'prod'" }
  • Expression alias: when: { expression: "_.environment == 'prod'" }

func (*Condition) Evaluate

func (c *Condition) Evaluate(ctx context.Context, resolverData map[string]any) (bool, error)

Evaluate evaluates the condition with the given resolver data. Returns true if the condition is met, false otherwise. Returns an error if evaluation fails or if the result is not a boolean.

func (*Condition) EvaluateWithAdditionalVars

func (c *Condition) EvaluateWithAdditionalVars(ctx context.Context, resolverData, additionalVars map[string]any) (bool, error)

EvaluateWithAdditionalVars evaluates the condition with additional variables. This is useful for evaluating conditions with __self set to a specific value.

func (*Condition) EvaluateWithSelf

func (c *Condition) EvaluateWithSelf(ctx context.Context, resolverData map[string]any, self any) (bool, error)

EvaluateWithSelf evaluates the condition with __self set to the provided value. This is used for until: conditions where __self should be the current resolved value.

func (Condition) MarshalJSON added in v0.10.0

func (c Condition) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshalling for Condition.

func (Condition) MarshalYAML added in v0.10.0

func (c Condition) MarshalYAML() (any, error)

MarshalYAML implements custom YAML marshalling for Condition. If the expression is a literal "true" or "false", it marshals as a boolean. Otherwise it uses the string shorthand form for compact output.

func (*Condition) UnmarshalJSON added in v0.10.0

func (c *Condition) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshalling for Condition. It supports boolean literals, string shorthand, and the explicit {"expr": "..."} form.

func (*Condition) UnmarshalYAML added in v0.10.0

func (c *Condition) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML implements custom YAML unmarshalling for Condition. It supports boolean literals, string shorthand, and the explicit {expr: ...} form.

type ForEachClause

type ForEachClause struct {
	// Item is the variable name alias for the current element.
	// Creates both __item (always) and this custom name.
	// Optional - if not specified, only __item is available.
	Item string `` /* 210-byte string literal not displayed */

	// Index is the variable name alias for the current 0-based index.
	// Creates both __index (always) and this custom name.
	// Optional - if not specified, only __index is available.
	Index string `` /* 199-byte string literal not displayed */

	// In specifies the array to iterate over.
	// Optional - defaults to __self (current transform value) for resolvers.
	In *ValueRef `json:"in,omitempty" yaml:"in,omitempty" doc:"Array to iterate over (default: __self for resolvers)"`

	// Concurrency limits parallel execution.
	// 0 (default) means unlimited parallelism.
	Concurrency int `` /* 129-byte string literal not displayed */

	// OnError defines behavior when an iteration fails.
	// This field is only used by actions; resolvers ignore it.
	OnError OnErrorBehavior `json:"onError,omitempty" yaml:"onError,omitempty" doc:"Error handling behavior (actions only)" example:"fail" default:"fail"`

	// KeepSkipped controls whether items skipped by a when condition are
	// retained as nil entries in the output array.
	// By default (false), skipped items are removed so the output contains
	// only the items that were actually processed. Set to true when you need
	// the output array to remain index-aligned with the input array.
	KeepSkipped bool `` /* 135-byte string literal not displayed */
}

ForEachClause defines iteration over an array. When present, the associated operation is executed once per array element and results are collected into an output array preserving order.

type IterationContext

type IterationContext struct {
	Item       any    `json:"-" yaml:"-" doc:"Current array element (__item)"`
	Index      int    `json:"-" yaml:"-" doc:"Current index (__index)"`
	ItemAlias  string `json:"-" yaml:"-" doc:"Custom name for item (if specified)"`
	IndexAlias string `json:"-" yaml:"-" doc:"Custom name for index (if specified)"`
}

IterationContext holds the context for forEach iteration variables. It provides access to the current item and index during iteration.

type OnErrorBehavior

type OnErrorBehavior string

OnErrorBehavior defines how to handle errors during execution. It is used by both resolvers and actions to control error propagation.

const (
	// OnErrorFail stops execution and returns the error.
	// This is the default for transform and action phases.
	// In the resolve phase, the default is OnErrorContinue (fallback chain semantics).
	OnErrorFail OnErrorBehavior = "fail"

	// OnErrorContinue continues execution despite errors.
	// For resolve phase: tries the next source (this is the default).
	// For transform phase: skips the failed step, keeps current value.
	// For actions: continues with remaining iterations or actions.
	OnErrorContinue OnErrorBehavior = "continue"
)

func (OnErrorBehavior) IsValid

func (b OnErrorBehavior) IsValid() bool

IsValid returns true if the behavior is a valid OnErrorBehavior value.

func (OnErrorBehavior) OrDefault

func (b OnErrorBehavior) OrDefault() OnErrorBehavior

OrDefault returns the behavior or the default (OnErrorFail) if empty.

type Type

type Type string

Type represents the type of a resolved value.

const (
	TypeString   Type = "string"
	TypeInt      Type = "int"   // int64 internally
	TypeFloat    Type = "float" // float64
	TypeBool     Type = "bool"
	TypeArray    Type = "array"    // []any (heterogeneous)
	TypeObject   Type = "object"   // map[string]any
	TypeTime     Type = "time"     // time.Time
	TypeDuration Type = "duration" // time.Duration
	TypeAny      Type = "any"
)

type ValueRef

type ValueRef struct {
	Literal  any                         `json:"-" yaml:"-"`
	Resolver *string                     `` /* 198-byte string literal not displayed */
	Expr     *celexp.Expression          `json:"expr,omitempty" yaml:"expr,omitempty" doc:"CEL expression to evaluate"`
	Tmpl     *gotmpl.GoTemplatingContent `json:"tmpl,omitempty" yaml:"tmpl,omitempty" doc:"Go template to execute"`
}

ValueRef represents a value that can be literal, resolver reference, expression, or template. It is used throughout the resolver and action systems to provide flexible value specification.

func (ValueRef) MarshalJSON added in v0.7.0

func (v ValueRef) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshalling for ValueRef. Mirrors MarshalYAML to ensure consistent serialization across formats.

func (ValueRef) MarshalYAML added in v0.7.0

func (v ValueRef) MarshalYAML() (any, error)

MarshalYAML implements custom YAML marshalling for ValueRef. This is required to survive the deepCopySolution YAML round-trip used in compose/bundling. Without it, the Literal field (tagged yaml:"-") would be silently dropped during marshaling.

func (*ValueRef) ReferencedVariables added in v0.7.0

func (v *ValueRef) ReferencedVariables() map[string]struct{}

ReferencedVariables returns the set of all variable names referenced by this ValueRef. It collects top-level variables, underscore-prefixed variables, and template references in a single pass. Use this instead of calling ReferencesVariable multiple times to avoid redundant expression parsing.

func (*ValueRef) ReferencesVariable

func (v *ValueRef) ReferencesVariable(varName string) bool

ReferencesVariable checks if the ValueRef references a specific variable name. This is useful for detecting references to __actions, __self, __item, etc. For expressions, it checks both top-level variables (like __actions, __self) and underscore-prefixed variables (like _.environment).

func (*ValueRef) Resolve

func (v *ValueRef) Resolve(ctx context.Context, resolverData map[string]any, self any) (any, error)

Resolve resolves the ValueRef to a concrete value. This is a convenience method that calls ResolveWithIterationContext with nil iteration context.

func (*ValueRef) ResolveWithIterationContext

func (v *ValueRef) ResolveWithIterationContext(ctx context.Context, resolverData map[string]any, self any, iterCtx *IterationContext) (any, error)

ResolveWithIterationContext resolves the ValueRef with optional forEach iteration context. It handles literal values, resolver references, CEL expressions, and Go templates.

func (*ValueRef) UnmarshalJSON added in v0.7.0

func (v *ValueRef) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshalling for ValueRef. Mirrors UnmarshalYAML to ensure consistent deserialization across formats.

func (*ValueRef) UnmarshalYAML

func (v *ValueRef) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML implements custom YAML unmarshalling for ValueRef. It handles scalar values, sequences, and mappings appropriately.

Jump to

Keyboard shortcuts

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