Writing a TransformScript
Every TransformScript has the same two-part structure: a header of directives, followed by a body that is a single expression producing the result. The two parts are separated by a --- line. Understanding this structure tells you where to declare your inputs, outputs, and reusable values, and where the actual transformation logic goes.
%files 1.0
input json
output json
var greeting = "Hello, "
---
{ message: greeting ++ payload.name }
The --- separator divides the header from the body. A script with no --- is invalid. The split happens at the first ---, so a literal --- placed inside the header ends the header early.
The Header
The header is a sequence of directives, one per line. It supports // and # line comments and /* … */ block comments. Every directive is optional. A bare --- <expr> is a valid script.
| Directive | Form | Purpose |
|---|---|---|
| Version | %files 1.0 (or %fts 1.0) | Declares the dialect and version. %dw 2.0 is accepted for DataWeave compatibility. The version is pinned exactly: %files must be 1.0 and %dw must be 2.0. Anything else is an error. |
input | input <format> [prop=value, …] | Declares how payload is deserialized. Defining it twice is an error. |
output | output <format> [prop=value, …] | Declares how the result is serialized. Defining it twice is an error. |
var | var name = <expr> | A named binding, evaluated once and available in the body. |
fun | fun name(params) = <expr> | A named function available in the body. |
ns | ns <prefix> <uri> | Declares an XML namespace prefix for use in selectors and output. |
import | import … | Accepted and ignored. TransformScript is single-script and has no imports. See Differences from DataWeave. |
Any other directive is an error. The input and output directives take an optional comma-separated list of prop=value properties. Values may be quoted, with \n, \t, and \uXXXX escapes, or unquoted. Unquoted true, false, null, and numbers are coerced to their types.
The Inputs
A running script has access to a small set of root variables built for Automations:
payloadis the file's contents. When the payload is supplied as raw bytes or a string, it is deserialized using the format from theinputdirective if one is declared, or the format auto-detected from the file's extension (.csvbecomes CSV,.jsonbecomes JSON, and so on). See Input and Output Formats. An already-parsed value passes through unchanged. Its shape depends on the format: a JSON object, an array of CSV rows, an EDI segment structure, and so on.attributesis metadata about the Automation Run, supplied by the platform when the script runs inside an Automation.varsholds values from earlier Automation steps. Headervarbindings are also available as ordinary variables in the body.
Referencing a name that isn't bound evaluates to null rather than raising an error. A script that reads attributes outside of an Automation simply sees null.
The Body
The body is a single expression. There are no statement lists. You introduce intermediate values with header var and fun, with the using(…) binding form, or with a do { … --- … } block. The expression is typically an object or array literal that assembles the output, but it can be any expression: a function chain, a match, a conditional, or a scalar.
Size Limits
Files are read fully into memory. TransformScript does not stream. Input is limited to 100 MB and output to 200 MB.
Output Formats
The output directive selects how the result is serialized:
output value | Serializes to |
|---|---|
json | JSON |
ndjson | newline-delimited JSON |
csv | CSV |
xlsx | Excel spreadsheet |
xml | XML |
yaml | YAML |
urlencoded | application/x-www-form-urlencoded |
hl7 | HL7 v2 |
edifact | EDIFACT |
x12 | X12 |
MIME types are accepted in place of the short names, for example application/json. An unknown format raises an error. With no output directive, the script yields the raw value with no serialized form. The same set of formats backs the input directive. See Input and Output Formats.
Examples
JSON in, JSON out, with a header var:
%files 1.0
input json
output json
var greeting = "Hello, "
---
{ message: greeting ++ payload.name, count: sizeOf(payload.items) }
{"name":"Alice","items":[1,2,3]} → {"message":"Hello, Alice","count":3}
CSV in, where the payload becomes an array of row objects, and JSON out:
%files 1.0
input csv
output json
---
payload map (row) -> { name: row.name, upper_name: upper(row.name) }
name,age / bob,30 / cara,40 → [{"name":"bob","upper_name":"BOB"},{"name":"cara","upper_name":"CARA"}]
A header fun, with no payload:
%files 1.0
output json
fun double(x) = x * 2
---
double(21)
→ 42
Related
- Syntax covers the lexical and expression grammar.
- Functions and Lambdas covers how functions are called and how lambdas work.
- Input and Output Formats covers per-format payload shaping.
- Differences from DataWeave covers where TransformScript diverges from DataWeave.
- Function Library lists the built-in functions.
- TransformScript is the landing page for the language.