expr

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package expr is the runtime's expression engine. It wraps Common Expression Language (CEL) so processors and sources compile and evaluate expressions the same way without touching cel-go internals.

Expressions are compiled once (at flow-build time, so a bad expression fails fast at startup) and evaluated many times against an activation: a map of the variable names declared at compile time to their per-evaluation values.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnterminatedTemplate = errors.New("unterminated {{ in template")

ErrUnterminatedTemplate reports a {{ with no matching }} in a template.

View Source
var MessageVars = []string{"body", "vars", "eventID", "correlationID", "env", nowVar}

MessageVars is the canonical set of variables every message expression may reference: the decoded body, the message variables, the two identifiers, the resolved environment, and the evaluation time. Blocks and connectors compile message expressions through CompileMessage rather than naming these themselves, so the set stays defined in exactly one place.

View Source
var SourcePayloadVars = []string{nowVar, "settings"}

SourcePayloadVars are the variables a source's payload expression may reference when it builds the initial message: the trigger time and the source's static settings. A source has produced no message yet, so the message variables (MessageVars) are not in scope.

View Source
var TemplateVars = unionVars(MessageVars, SourcePayloadVars)

TemplateVars are the variables a template's {{ }} spans may reference: the union of every scope a template can be rendered from, since the same template resource may be rendered by a message expression (body, vars, env, …) or by a source payload (now, settings). A span naming a variable that is not in the scope it is actually rendered from fails at render, not at parse — the parse cannot know which scope will reach it.

Functions

func EnvActivation

func EnvActivation(env map[string]string) map[string]any

EnvActivation materializes a resolved env map into the form CEL expects once at build time, so it can be shared across every message a block processes. A nil or empty env yields a non-nil empty map, keeping env.NAME a missing-key error rather than a null-deref.

func MessageActivation

func MessageActivation(msg *types.Message, env map[string]any) map[string]any

MessageActivation maps a message and its resolved env onto the variables a message expression (compiled via CompileMessage, which declares MessageVars) can reference. It is the single definition of the activation shape: blocks and connectors build their activation through it rather than assembling the map with literal keys, so MessageVars and this function never drift apart. now is the evaluation time (use string(now) to render it in a JSON body).

func RegisterMessageExtension

func RegisterMessageExtension(ext MessageExtension)

RegisterMessageExtension adds ext to the extensions every message expression is compiled with. Call it from an init function; this is the single place a new CEL capability is wired in for the whole runtime.

func SourcePayloadActivation

func SourcePayloadActivation(settings map[string]any) map[string]any

SourcePayloadActivation maps a source's fire time and static settings onto the SourcePayloadVars a source payload expression references. It is the single definition of the source-payload activation shape (paired with SourcePayloadVars).

Types

type MessageContext

type MessageContext struct {
	// Resources loads resources (e.g. templates) a function needs. It is never nil
	// inside an extension: the compile substitutes the no-op loader when unset.
	Resources core.ResourceLoader
	// Vars are the variable names in scope for the expression being compiled —
	// MessageVars for a message expression, SourcePayloadVars for a source payload.
	// An extension that hands the activation to a function (templateResource does,
	// via a macro) must build it from these rather than assuming the message set.
	Vars []string
}

MessageContext carries the per-compile inputs a message extension may need.

type MessageExtension

type MessageExtension func(MessageContext) []cel.EnvOption

MessageExtension contributes CEL environment options (custom functions, macros) to every message expression, given the compile context. Registering one exposes a new capability to every message expression at once — no call-site changes.

type Program

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

Program is a compiled, reusable expression. It is safe for concurrent evaluation, matching the MessageProcessor thread-safety contract.

func Compile

func Compile(expression string, vars ...string) (*Program, error)

Compile checks and compiles expression, declaring each name in vars as a dynamically typed variable available to the expression. It returns an error the caller can surface at startup when the expression is malformed. Message expressions should use CompileMessage instead, which adds the standard message variables plus the registered extensions (e.g. templateResource).

func CompileMessage

func CompileMessage(res core.ResourceLoader, expression string) (*Program, error)

CompileMessage compiles a message expression: it declares the standard message variables (MessageVars) and applies every registered extension bound to res. Every block and connector that evaluates CEL against a message compiles through this, so a capability added via RegisterMessageExtension becomes available everywhere without editing call sites. res may be nil (a no-op loader is used).

func CompileSourcePayload

func CompileSourcePayload(res core.ResourceLoader, expression string) (*Program, error)

CompileSourcePayload compiles a source payload expression with SourcePayloadVars and every registered message extension, so a capability wired in through RegisterMessageExtension — templateResource(id) among them — works in a payload exactly as it does in a message expression, resolved against the source's own scope. res may be nil (a no-op loader is used).

func CompileWithOptions

func CompileWithOptions(expression string, vars []string, opts ...cel.EnvOption) (*Program, error)

CompileWithOptions compiles expression declaring each name in vars as a dynamically typed variable and applying any extra environment options (custom functions, macros). It is the single low-level compile path; Compile and CompileMessage are thin wrappers over it.

func (*Program) Eval

func (p *Program) Eval(activation map[string]any) (any, error)

Eval evaluates the program against activation and returns the result as a JSON-native Go value (string, float64, bool, nil, map[string]any, []any). Keys absent from activation are simply unbound; referencing them yields an evaluation error.

func (*Program) EvalString

func (p *Program) EvalString(activation map[string]any) (string, error)

EvalString evaluates the program and renders the result as a string. A string result is returned verbatim; any other value is rendered as compact JSON so objects and arrays log readably.

type Template

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

Template is a parsed text template — a sequence of literal and expression segments. It is immutable after parsing and safe for concurrent rendering.

func ParseTemplate

func ParseTemplate(text string) (*Template, error)

ParseTemplate splits text into literal and {{ expression }} segments, compiling each expression once (with TemplateVars) so a malformed expression fails at build time rather than per render.

func (*Template) Render

func (t *Template) Render(act map[string]any) (string, error)

Render evaluates each expression segment against act and concatenates the results with the literal segments.

type TemplateRegistry

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

TemplateRegistry loads and caches parsed templates by id so repeated renders and concurrent workers reuse one compiled template. It is safe for concurrent use.

func NewTemplateRegistry

func NewTemplateRegistry(loader core.ResourceLoader) *TemplateRegistry

NewTemplateRegistry returns a registry backed by loader, falling back to the no-op loader (every template missing) when loader is nil.

func (*TemplateRegistry) Get

func (r *TemplateRegistry) Get(ctx context.Context, id string) (*Template, error)

Get returns the parsed template for id, loading and parsing it on first use and caching it thereafter. Unlike a missing env resource, a referenced template that does not exist is an error.

type TemplateResolver

type TemplateResolver func(id string, ctx map[string]any) (string, error)

TemplateResolver renders the template resource id against ctx — the variables in scope where templateResource(id) was called (body, vars, env, ...). It returns the rendered text or an error the CEL evaluation surfaces.

Jump to

Keyboard shortcuts

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