Add a narrow node that validates a Dynamic value against one real record or union type, turning an open-ended blob into ordinary typed fields.
When you need this
Section titled “When you need this”Use a narrow node when a value in your flow is declared Dynamic — its shape wasn’t fixed in
advance — but by this point in the flow you know, or can check, exactly which real type it has to be.
narrow validates the value against that type and hands back an ordinary typed value: every node
downstream reads named fields instead of an open-ended blob.
- Write
<stem>.node.yaml:node: "narrow", adescription,from, andto. That’s the whole spec — there’s noinoroutto declare. fromis a reference to theDynamicvalue being narrowed. It has to resolve to something whose declared type is literallyDynamic—aqven checkrejects anarrownode pointed at a value that’s already typed.tonames a record or union type from the project’s own type registry, not a built-in scalar.aqven checkrejects atothat isn’t a real record or union type.- At run time, AQVEN validates the value against
to’s fields, the same rules any other typed field follows. If the value doesn’t fit, the node fails instead of passing something malformed further down the flow. - The node’s own output is the narrowed value itself — downstream,
$<narrow node id>.outreads it directly, not$<narrow node id>.out.<field>.
Example
Section titled “Example”This is the showcase project’s to_record node, in its support_case flow: it narrows the case
record an earlier loop node filled in — declared Dynamic there because its shape depends on which
kind of case it turns out to be — down to CaseRecord, a discriminated union with three variants:
defect, delivery, question. Create it yourself with:
aqven new my_project --template showcaseHere’s the real file:
apiVersion: "aqven/v1"kind: "Node"node: "narrow"description: "Narrows the record down to a static case type by its kind"from: "$record.out.record"to: "CaseRecord"Narrowing turns $record.out.record — an untyped Dynamic reference — into a plain CaseRecord
value: everywhere downstream, $to_record.out reads as an ordinary typed field, the same as if it had
never been Dynamic at all.
See also
Section titled “See also”- How to handle a shape you don’t know in advance — the rest of the
Dynamicstory: whyrecord’s output needed this in the first place, and the other ways AQVEN handles a shape that isn’t fixed. - How to repeat a step with a limit —
record, theloopnode whoseDynamicoutput this example narrows. - How to route by a value —
route, which switches onto_record’s narrowed output right after this node runs. - The engineering loop — what to do when a run’s output isn’t what you expected.
- Node specifications — every field on
NarrowNodeSpec, generated from the code. - Type specifications — how a discriminated union like
CaseRecordis declared.