expr

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package expr is the funcd reference engine (ADR-0095): one typed `${{ … }}` expression grammar shared across the platform. The contents of `${{ … }}` are native JavaScript, parsed and evaluated by goja (pure-Go ECMAScript); funcd runs a type-checker over goja's parser AST that admits only a typed subset and rejects the rest at reconcile — so every expression is statically checkable against a JSON-Schema contract before anything runs, in a language users already know.

Two modes: Select (a reference or computed value, returned by Eval) and Condition (a boolean expression, returned by EvalBool). The lifecycle is always Parse → Check → Eval/EvalBool: Parse validates the grammar, Check validates every path/type/operator against a context-scoped Resolver, and Eval/EvalBool run the compiled program against the actual documents. Eval before a successful Check (or in the wrong mode) is a programming error surfaced as a fault.Internal, never a panic.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Expr

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

Expr is a parsed (and, after Check, validated) expression. It is safe to Check once and then Eval/EvalBool concurrently.

func Parse

func Parse(src string, mode Mode) (*Expr, error)

Parse validates the `${{ … }}` wrapper and parses its JavaScript with goja's parser. Grammar errors are positioned fault.Invalid. The whole source must be a single `${{ … }}` template — no surrounding text (no string interpolation).

func (*Expr) Check

func (e *Expr) Check(r Resolver) error

Check statically validates the expression against the resolver: every reference path exists and is typed, every operator/method matches its operand types, only the admitted JS subset is used, the defaults rule holds (an optional field must declare a default or be `!== undefined`-guarded), and — in Condition mode — the whole expression is boolean. It records the referenced roots and defaulted references so Eval needs no resolver.

func (*Expr) Eval

func (e *Expr) Eval(docs map[string]json.RawMessage) (json.RawMessage, error)

Eval evaluates a Select-mode expression against the documents (keyed by matched root) and returns the referenced or computed value. It must be called only after a successful Check on a Select-mode expression.

func (*Expr) EvalBool

func (e *Expr) EvalBool(docs map[string]json.RawMessage) (bool, error)

EvalBool evaluates a Condition-mode expression and returns its boolean result. It must be called only after a successful Check on a Condition-mode expression.

func (*Expr) Roots

func (e *Expr) Roots() []string

Roots reports the distinct root documents the expression references, populated after a successful Check (nil before).

type Field

type Field struct {
	// Type is the JSON-Schema type: "string", "number", "integer", "boolean",
	// "array" or "object". A Resolver typing paths from the actual documents leaves
	// it empty (with Required false) for a field missing from its document: only an
	// `X !== undefined` probe may read it, and that guard's && operand goes unread.
	Type string
	// Items is the element type when Type == "array"; empty otherwise.
	Items string
	// Required reports whether the field is required by its schema.
	Required bool
	// HasDefault reports whether the schema declares a default for the field.
	HasDefault bool
	// Default is the declared default, substituted at evaluation when absent.
	Default json.RawMessage
}

Field is what a Resolver reports for a resolved path: the JSON-Schema type, the element type for arrays, whether the field is required, and its declared default.

type Mode

type Mode int

Mode selects the grammar's evaluation mode.

const (
	// Select allows a reference or computed value and returns it from Eval.
	Select Mode = iota
	// Condition requires a boolean expression and returns it from EvalBool.
	Condition
)

type Resolver

type Resolver interface {
	// Roots reports the root documents this resolver exposes.
	Roots() []string
	// Resolve reports the Field at path under root: fault.NotFound when the path is
	// absent from the schema, fault.Invalid for a malformed request.
	Resolve(root string, path []string) (Field, error)
}

Resolver answers path lookups against a consumer's JSON-Schema contracts. Implementations are context-scoped: Roots reports the exposed root documents (Check matches an expression's leading member segments against it, longest-first) and Resolve reports the Field at a path under one of those roots.

Jump to

Keyboard shortcuts

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