Skip to content

Expression Node Context

Expression nodes execute JavaScript code inside a secure sandbox. This page documents all variables, objects, and libraries available within the expression runtime.


Global Variables

These variables are injected into every expression execution and provide access to the workflow trigger context, input data, and environment information.

$models

An array of Model instances built from the model collection that triggered the workflow. Each entry wraps a raw document from the component, giving you access to its fields.

For model CRUD events (Create, Update, Delete), this contains the documents involved in the operation. For manually triggered workflows, it contains whatever documents were selected.

const first = $models[0];
const name = first.data.name;

models is an alias for $models.

$args

Contains contextual arguments passed from the model operation that triggered the workflow.

Event Contents
Create / Before::Create null
Update / Before::Update { current_revision: {...} } — the document state before the update
Delete / Before::Delete null
Subsequent nodes Merged results from all previously completed nodes
// In an Update workflow — access the previous document revision
const previousDoc = $args?.current_revision;

How $args evolves between nodes

On the trigger node, $args reflects the original model operation arguments. On subsequent expression nodes, the input data merges results from all completed parent nodes. Each completed node's results (keyed by node name) become part of the input available to downstream nodes.

$context

An object containing metadata about the event that triggered the workflow.

Field Type Description
event string The event name (e.g. "Create", "Before::Update", "Delete")
initiator object The user or service that triggered the operation
component string The component reference (slug)
extension object \| null The extension that owns this workflow, or null for component-level workflows
schema string The schema name for multi-schema components
const eventName = $context.event;       // "Create"
const componentRef = $context.component; // "products"
const schema = $context.schema;          // "default"

$event

A shorthand for the event name. Equivalent to $context.event.

if ($event === "Before::Create") {
    // pre-create logic
}

Possible values: "Create", "Before::Create", "Update", "Before::Update", "Delete", "Before::Delete".

$initiator

The user or service account that triggered the model operation. Shorthand for $context.initiator.

Field Type Description
uuid string The user's unique identifier
identificator string The user's login identifier (e.g. email)
name string The user's display name
const userName = $initiator.name;
const userUUID = $initiator.uuid;

$config

The component's configuration object for the current environment. This is the config map defined in the component settings.

const apiKey = $config.api_key;
const webhookUrl = $config.webhook_url;

For extension workflows, $config contains the extension's own configuration rather than the parent component's.

$globalEnv

Global environment variables defined at the project level. These are key-value pairs set in the project's global environment configuration.

const stripeKey = $globalEnv.STRIPE_SECRET_KEY;

$currentEnv

A string indicating the current environment. Typically "dev", "stage", or "prod".

if ($currentEnv === "prod") {
    // production-only logic
}

I/O and Data Flow

io

The I/O object controls data flow between nodes.

Method Description
io.pipe(data) Passes data to downstream nodes
io.each(array) Passes an array to a connected Each node for iteration
io.getPipedDataOf(nodeName) Retrieves data piped from a specific upstream node
// pipe transformed data to downstream nodes
io.pipe({ orderId: $models[0].data.uuid, total: 99.99 });
// pass a list of items to an Each node
io.each($models.map(m => m.data));
// in a downstream node, read piped data from a specific upstream node
const data = io.getPipedDataOf("Transform Order");
const orderId = data?.orderId;

Available Libraries

All libraries are pre-loaded and available as global objects within the expression sandbox.

Core Utilities

Global Description
moment Moment.js — date/time manipulation
_ Lodash — utility library
Handlebars Handlebars — template engine
Buffer Node.js Buffer operations

Security & Encoding

Global Description
BCrypt Password hashing with bcrypt
Crypto Cryptographic operations (Node.js crypto)
JWT JSON Web Token creation and verification
Buffer Binary data operations

Debugging

Global Description
Debug Debug data collector — data added via Debug appears in workflow execution logs
Decorator Modify the response data returned by the workflow (used in Before:: events)

SDK

The Protokol SDK is available as $sdk, a factory class that returns a versioned SDK instance:

const { Component } = $sdk.version('0.9')

const products = new Component("products")
const { settings } = await products.settings()

Note

The SDK inside expressions uses the service context of the current project and environment. Authentication is handled automatically.


Error Handling

RetryableError

Throw a RetryableError to signal that the expression failed due to a transient issue and should be retried by the workflow engine.

throw RetryableError("External API temporarily unavailable");

See RetryableError for retry behavior and backoff details.

Regular Errors

Throw a standard Error to fail the node permanently (no retry):

throw new Error("Validation failed: missing required field");

Execution Environment

Property Value
Memory limit 64 MB (default)
Timeout 60 seconds (default)
Async support Full async/await support

Warning

Expressions run in an isolated sandbox. Node.js system modules (e.g. fs, path) are not available. Use the provided platform services instead.