Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.cloudcruise.com/llms.txt

Use this file to discover all available pages before exploring further.

The Transform node runs operations that read from and write to the session context. Use it for data shaping, cleanup, combining fields, accumulating results across a loop, or execution-state updates. Each operation has a type, a target dot-path under context.*, and (for non-DELETE ops) a value that is a raw JSONata expression. Operations in the same node run top-to-bottom and each one sees the writes of the ones before it.
The value field is raw JSONata, not a template. Do not wrap it in {{...}} — reference variables directly (e.g. context.inputs.email ~> $trim, not {{context.inputs.email}} ~> $trim).

Parameters

ParameterTypeRequiredDescription
operationsarrayYesOrdered list of operations, each { type, target, value? }

Operation Fields

FieldTypeRequiredDescription
typestringYesSET or DELETE
targetstringYesDot-path under context.* where the result is written. Missing intermediate objects are auto-created
valuestringYes (except DELETE)Raw JSONata expression evaluated against the session context

Operation Types

TypeSemantics
SETAssign the evaluated value to target, creating the path if it doesn’t exist
DELETERemove the value at target. value is ignored
For object-merging and array manipulation, use SET combined with JSONata’s built-in $merge and $append functions — there is no dedicated merge or append operation type.
WantUse
Shallow-merge an object into a targetSET context.x = $merge([context.x, {new_field: 'value'}])
Flat-concatenate two arraysSET context.combined = $append(context.a, context.b)
Append one element to an arraySET context.results = $append(context.results, [item])

Examples

Normalize an Input

Clean up an email before typing it into a form:
{
  "id": "abc123",
  "name": "Normalize email",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.email_clean",
        "value": "context.inputs.email ~> $trim ~> $lowercase"
      }
    ]
  }
}
Reference it downstream with {{context.email_clean}}.

Combine Fields

Derive a full name from two inputs:
{
  "id": "abc123",
  "name": "Build full name",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.full_name",
        "value": "context.inputs.first & ' ' & context.inputs.last"
      }
    ]
  }
}

Combine Two Arrays

Flat-concatenate two arrays using JSONata’s $append:
{
  "id": "abc123",
  "name": "Combine arrays",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.combined",
        "value": "$append(context.inputs.array1, context.inputs.array2)"
      }
    ]
  }
}
$append([1, 2], [3, 4]) produces [1, 2, 3, 4]. Note that & is string concatenation in JSONata, not array — use $append for arrays.

Accumulate Loop Results

Inside a loop body, append processed items into an array using $append:
{
  "id": "abc123",
  "name": "Collect order summary",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.collected_orders",
        "value": "$append(context.collected_orders, [{'id': context.runtime.current_order.id, 'total': $number(context.runtime.current_order.amount)}])"
      }
    ]
  }
}
The single-element array ([{...}]) wrapping is what makes $append flat-concatenate one item — passing the bare object would also work ($append flattens), but the array form makes intent obvious.

Enrich an Extracted Object

Add metadata to a record that was extracted earlier:
{
  "id": "abc123",
  "name": "Tag with source",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      {
        "type": "SET",
        "target": "context.extracted_profile",
        "value": "$merge([context.extracted_profile, {'extracted_at': $now(), 'source': 'crm'}])"
      }
    ]
  }
}

Clean Up Before End

Drop scratch paths so they don’t show up in the webhook payload:
{
  "id": "abc123",
  "name": "Clean scratch",
  "action": "TRANSFORM",
  "parameters": {
    "operations": [
      { "type": "DELETE", "target": "context.internal_scratch" },
      { "type": "DELETE", "target": "context.tmp_html" }
    ]
  }
}

Notes

  • Targets must start with context.. Anything else is rejected by validation because downstream nodes can’t read it.
  • Later operations in the same node see earlier writes, so you can derive values in stages within one Transform.