TypeScript transforms (escape hatch)
When the declarative DSL cannot express a transform cleanly, drop to code with a
ts step. It runs a custom TypeScript function you write in your project.
Config first, TypeScript second. Reach for a
tsstep only when the step list genuinely cannot express the logic — a non-trivial computation, branching the DSL can't model, or shaping that would be a long tail of fake-control-flow steps. Most transforms should stay declarative; they are easier to read, validate, and review.
The contract: JSON in, JSON out
A custom function is a pure function from a JSON value to a JSON value:
// functions/initials.ts
interface Order {
first?: string;
last?: string;
[key: string]: unknown;
}
export default (order: Order): Order => ({
...order,
initials: `${order.first?.[0] ?? ''}${order.last?.[0] ?? ''}`.toUpperCase(),
});
- One default export, a function.
- Input and output are plain JSON (objects, arrays, scalars) — not Weavster's internal model.
- The result is taken through a JSON boundary, so anything non-JSON (functions,
undefined) is dropped.
Keep it pure JSON → JSON. The local CLI runs your function as ordinary JavaScript, but the production runtime executes transforms as WASM — a function that stays pure JSON in/out is portable to both. Reaching for Node-only APIs works locally but will not port.
The _ts step
steps:
- _ts:
module: initials # functions/initials.ts
# from: order # optional: operate on a subpath (default: whole document)
# to: order # optional: where to write (default: the root)
module— the filefunctions/<module>.tsin your project; its default export is called.from— path to read and pass to the function. Omit for the whole document.to— path to write the result. Omit to replace the root.
Errors
A missing function file, a module without a default-export function, or an error thrown
inside the function all surface as a TransformError naming the step and module:
step 3 (_ts): no function "initials" at .../functions/initials.ts
step 3 (_ts): boom
The function is loaded on demand when weavster test runs the flow; no build step is needed.