Expression
Expression protocol schemas
Expression Protocol
Canonical wire format for all "expression"-shaped metadata across ObjectStack (formula fields, predicates, conditions, criteria, visibility rules, seed dynamic values, …).
The persisted form is { dialect, source } (and, after objectstack compile normalization, { dialect, ast }). String-only shorthand is
accepted at input time for developer ergonomics; build emits the canonical
envelope.
Dialects
| dialect | engine | use |
|---|---|---|
cel | @objectstack/formula (cel-js + ObjectStack stdlib) | formulas, predicates, seed dynamic values |
cron | cron-parser | job schedules |
template | {{var}} interpolation at evaluate time (same variable scope as CEL) | notification subjects/bodies, titleFormat, prompt templates |
Those three are the whole list — it is exactly the ExpressionDialect enum
below. Procedural JavaScript is not a dialect: it is the L2 authoring
surface, the sandboxed, capability-gated ScriptBody { language: 'js' } in
hook/action bodies. A js row stood in this table long after the dialect was
retired in #3278 (ADR-0058 addendum); ExpressionSchema rejects
dialect: 'js'.
SQL fragments (analytics joins, partial indexes) are intentionally not routed through this schema — they stay driver-native because their security posture and portability story differ.
See also: content/docs/concepts/north-star.mdx §8 "No private expression DSL"
Source: packages/spec/src/shared/expression.zod.ts
TypeScript Usage
import { CronExpressionInputSchema, ExpressionSchema, ExpressionDialect, ExpressionInputSchema, ExpressionMetaSchema, PredicateSchema, PredicateInputSchema, TemplateExpressionInputSchema } from '@objectstack/spec/shared';
import type { CronExpressionInput, Expression, ExpressionDialect, ExpressionInput, ExpressionMeta, Predicate, PredicateInput, TemplateExpressionInput } from '@objectstack/spec/shared';
// Validate data
const result = CronExpressionInputSchema.parse(data);CronExpressionInput
Union Options
This schema accepts one of the following structures:
Option 1
Type: string
Option 2
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| dialect | Enum<'cel' | 'cron' | 'template'> | ✅ | |
| source | string | optional | |
| ast | any | optional | |
| meta | { rationale?: string; generatedBy?: string } | optional |
Expression
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| dialect | Enum<'cel' | 'cron' | 'template'> | ✅ | |
| source | string | optional | |
| ast | any | optional | |
| meta | { rationale?: string; generatedBy?: string } | optional |
ExpressionDialect
Allowed Values
celcrontemplate
ExpressionInput
Union Options
This schema accepts one of the following structures:
Option 1
Type: string
Option 2
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| dialect | Enum<'cel' | 'cron' | 'template'> | ✅ | |
| source | string | optional | |
| ast | any | optional | |
| meta | { rationale?: string; generatedBy?: string } | optional |
ExpressionMeta
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| rationale | string | optional | |
| generatedBy | string | optional |
Predicate
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| dialect | Enum<'cel' | 'cron' | 'template'> | ✅ | |
| source | string | optional | |
| ast | any | optional | |
| meta | { rationale?: string; generatedBy?: string } | optional |
PredicateInput
Union Options
This schema accepts one of the following structures:
Option 1
Type: string
Option 2
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| dialect | Enum<'cel' | 'cron' | 'template'> | ✅ | |
| source | string | optional | |
| ast | any | optional | |
| meta | { rationale?: string; generatedBy?: string } | optional |
TemplateExpressionInput
Union Options
This schema accepts one of the following structures:
Option 1
Type: string
Option 2
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| dialect | Enum<'cel' | 'cron' | 'template'> | ✅ | |
| source | string | optional | |
| ast | any | optional | |
| meta | { rationale?: string; generatedBy?: string } | optional |