@uipath/maestro-builder-sdk 6.25.1 → 6.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api-index.md CHANGED
@@ -57,13 +57,13 @@ could hand you spans for a version you do not have.
57
57
  | `apiWorkflow` | function | `dist/core/actions.d.ts:1658-1692` | Actions | Invoke a deployed API workflow — a coded workflow published to Orchestrator, run as a serverless job rather than by a… |
58
58
  | `ApiWorkflowInputs` | interface | `dist/core/actions.d.ts:411-442` | Option shapes | 5 field(s) |
59
59
  | `AppRef` | interface | `dist/nodes/hitl/flow/spec.d.ts:140-185` | Supporting types | A deployed Action App that supplies a human task's form — the `'action-app'` variant's subject. |
60
- | `ArmBuilder` | class | `dist/flow-sdk.d.ts:1187-1210` | Builders | The sub-builder an ARM callback receives — a `StepList` that can also name itself with `.label(...)`. |
60
+ | `ArmBuilder` | class | `dist/flow-sdk.d.ts:1193-1216` | Builders | The sub-builder an ARM callback receives — a `StepList` that can also name itself with `.label(...)`. |
61
61
  | `AskedField` | interface | `dist/core/actions.d.ts:79-89` | Supporting types | A value the reviewer FILLS IN: read downstream with `out('<step>', '<id>')`. |
62
62
  | `batchTransform` | function | `dist/nodes/ai-patterns/flow/factories.d.ts:49-83` | Actions | Add AI-generated columns to a CSV — the platform's **Batch transform** node, `uipath.pattern.batch-transform` (service… |
63
63
  | `BatchTransformInputs` | interface | `dist/nodes/ai-patterns/flow/spec.d.ts:48-63` | Option shapes | 4 field(s) |
64
64
  | `BindingContribution` | interface | `dist/core/node-classes.d.ts:80-101` | Supporting types | A resource binding a contribution hoists to the flow's top-level `bindings` array — the shape the `.flow` format… |
65
65
  | `BuiltEntryPoint` | interface | `dist/flow-sdk.d.ts:695-707` | Supporting types | One additional flow root, built by `.entryPoint()`. |
66
- | `BuiltFlow` | interface | `dist/flow-sdk.d.ts:708-743` | Supporting types | 15 field(s) |
66
+ | `BuiltFlow` | interface | `dist/flow-sdk.d.ts:708-749` | Supporting types | 16 field(s) |
67
67
  | `BuiltinToolName` | type | `dist/core/actions.d.ts:1066-1067` | Supporting types | The three platform-shipped built-in tools (fixed registry types). |
68
68
  | `BuiltinToolRef` | interface | `dist/core/actions.d.ts:1199-1219` | Supporting types | A platform built-in tool. |
69
69
  | `BuiltInValidatorGuardrail` | interface | `dist/core/actions.d.ts:762-803` | Supporting types | A platform-shipped validator, configured by parameters. |
@@ -128,11 +128,11 @@ could hand you spans for a version you do not have.
128
128
  | `FilterCondition` | type | `dist/nodes/transform/flow/spec.d.ts:10-11` | Supporting types | Comparison a filter rule applies to a field. |
129
129
  | `FilterMatch` | type | `dist/nodes/transform/flow/spec.d.ts:8-9` | Supporting types | How a filter combines its rules: every rule must match, or any one. |
130
130
  | `FilterRule` | interface | `dist/nodes/transform/flow/spec.d.ts:12-24` | Supporting types | 3 field(s) |
131
- | `flow` | function | `dist/flow-sdk.d.ts:1493-1508` | Flow construction | Start building a flow with the given id. |
131
+ | `flow` | function | `dist/flow-sdk.d.ts:1541-1556` | Flow construction | Start building a flow with the given id. |
132
132
  | `FlowAction` | class | `dist/core/node-classes.d.ts:162-168` | Supporting types | A node placed as a step — pass an instance to `.step(name, …)`. |
133
133
  | `FlowActionSpec` | type | `dist/flow-sdk.d.ts:53-54` | Supporting types | What `.step()` accepts here: the shared actions plus this SDK's subflow. |
134
134
  | `FlowActionSpecs` | interface | `dist/core/actions.d.ts:1443-1520` | Supporting types | Every action kind, keyed by kind, to the body of its spec — the arm's fields other than `kind`. |
135
- | `FlowBuilder` | class | `dist/flow-sdk.d.ts:1211-1492` | Builders | 13 member(s) |
135
+ | `FlowBuilder` | class | `dist/flow-sdk.d.ts:1217-1540` | Builders | 14 member(s) |
136
136
  | `FlowLayout` | interface | `dist/flow-sdk.d.ts:681-694` | Supporting types | Designer layout for a flow, keyed by AUTHOR-level ids: node entries by step name (plus the trigger id and `end`), edge… |
137
137
  | `FlowNode` | class | `dist/core/node-classes.d.ts:126-161` | Supporting types | The abstract root of every definition-backed node the builder can place. |
138
138
  | `FlowResource` | class | `dist/core/node-classes.d.ts:176-183` | Supporting types | A node attached to another semantic node — an inline agent's tool, context, memory, or escalation. |
@@ -225,11 +225,11 @@ could hand you spans for a version you do not have.
225
225
  | `SendMessageInputs` | interface | `dist/nodes/conversation/flow/spec.d.ts:8-27` | Option shapes | 4 field(s) |
226
226
  | `ShownField` | interface | `dist/core/actions.d.ts:63-78` | Supporting types | A value the reviewer READS: shown on the form, filled in from the flow. |
227
227
  | `Step` | type | `dist/flow-sdk.d.ts:484-603` | Supporting types | |
228
- | `StepList` | class | `dist/flow-sdk.d.ts:744-1186` | Builders | Collects a sequence of steps. |
228
+ | `StepList` | class | `dist/flow-sdk.d.ts:750-1192` | Builders | Collects a sequence of steps. |
229
229
  | `STICKY_NOTE_COLORS` | const | `dist/flow-sdk.d.ts:634-639` | Flow construction | The designer's sticky-note palette. |
230
230
  | `StickyNote` | interface | `dist/flow-sdk.d.ts:646-680` | Supporting types | A canvas sticky note — free text pinned to the diagram, for the humans reading it. |
231
231
  | `StickyNoteColor` | type | `dist/flow-sdk.d.ts:640-645` | Supporting types | A sticky note's swatch. |
232
- | `subflow` | function | `dist/flow-sdk.d.ts:1509-1548` | Flow construction | Run another flow as one step, and read back what it returns. |
232
+ | `subflow` | function | `dist/flow-sdk.d.ts:1557-1596` | Flow construction | Run another flow as one step, and read back what it returns. |
233
233
  | `SubflowSpec` | interface | `dist/flow-sdk.d.ts:45-52` | Supporting types | A step that runs a child flow. |
234
234
  | `summarize` | function | `dist/nodes/ai-patterns/flow/factories.d.ts:8-48` | Actions | Summarize a document with citations — the platform's **Summarize** node. |
235
235
  | `SummarizeInputs` | interface | `dist/nodes/ai-patterns/flow/spec.d.ts:8-40` | Option shapes | 3 field(s) |
@@ -5,12 +5,12 @@
5
5
 
6
6
  # Maestro Builder SDK — member index
7
7
 
8
- **A lookup table of 1113 rows — match one name in it, do not read it.**
8
+ **A lookup table of 1115 rows — match one name in it, do not read it.**
9
9
  Grep or search for the member you have; the row it lands on is the whole
10
10
  answer. Reading top to bottom costs ~20x what the one row does and tells you
11
11
  nothing you asked for.
12
12
 
13
- Every field and method of every exported shape — 1113 across
13
+ Every field and method of every exported shape — 1115 across
14
14
  200 interfaces and classes — keyed by the MEMBER's own name.
15
15
 
16
16
  **Use this when the name you have is a field or a method**, which is usually
@@ -28,7 +28,7 @@ truncated summary would, for less. Read the span.
28
28
  Member names repeat across shapes (`name` is declared on 69 of them), so the
29
29
  `Declared on` column is what makes a match actionable. For the whole shape
30
30
  rather than the one field, look that name up in [`api-index.md`](api-index.md) —
31
- which is why its span is not repeated on all 1113 rows here.
31
+ which is why its span is not repeated on all 1115 rows here.
32
32
 
33
33
  **A name that misses both indexes is probably not part of the API.** The one
34
34
  that comes up is a RUNTIME output key — a human task's `Action`, a step's
@@ -66,7 +66,7 @@ not find it either.
66
66
  | `app` | property | `HumanTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1337-1338` |
67
67
  | `appSystemName` | property | `AppRef` | `dist/nodes/hitl/flow/spec.d.ts:170-175` |
68
68
  | `appVersion` | property | `HumanTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1339-1340` |
69
- | `armLabel` | property | `ArmBuilder` | `dist/flow-sdk.d.ts:1199` |
69
+ | `armLabel` | property | `ArmBuilder` | `dist/flow-sdk.d.ts:1205` |
70
70
  | `assignee` | property | `HitlRecipient` | `dist/nodes/hitl/flow/spec.d.ts:52-63` |
71
71
  | `async` | property | `OrchestratorAsyncOpts` | `dist/bpmn/bpmn-sdk.d.ts:1281-1285` |
72
72
  | `atRiskPercentage` | property | `EscalationOpts` | `dist/case/case-sdk.d.ts:132-137` |
@@ -97,14 +97,14 @@ not find it either.
97
97
  | `body` | property | `TypedContextRow` | `dist/bpmn/typed-node.d.ts:176-181` |
98
98
  | `body` | property | `TypedInputRow` | `dist/bpmn/typed-node.d.ts:207-208` |
99
99
  | `boundaryEvent` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2239-2246` |
100
- | `branch` | method | `StepList` | `dist/flow-sdk.d.ts:943-961` |
100
+ | `branch` | method | `StepList` | `dist/flow-sdk.d.ts:949-967` |
101
101
  | `branches` | property | `HttpInputsBase` | `dist/nodes/http/flow/spec.d.ts:25-30` |
102
- | `break` | method | `StepList` | `dist/flow-sdk.d.ts:1071-1080` |
102
+ | `break` | method | `StepList` | `dist/flow-sdk.d.ts:1077-1086` |
103
103
  | `breakEnabled` | property | `DoWhileOptions` | `dist/flow-sdk.d.ts:481-482` |
104
104
  | `breakEnabled` | property | `LoopOptions` | `dist/flow-sdk.d.ts:468-472` |
105
105
  | `build` | method | `BpmnBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3483-3488` |
106
106
  | `build` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1269-1274` |
107
- | `build` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1485-1491` |
107
+ | `build` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1533-1539` |
108
108
  | `businessRule` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2527-2573` |
109
109
  | `by` | property | `LookupResolution` | `dist/core/lookups.d.ts:164` |
110
110
  | `by` | property | `LookupSpec` | `dist/core/lookups.d.ts:27-28` |
@@ -172,7 +172,7 @@ not find it either.
172
172
  | `context` | property | `RegistryTypeSpec` | `dist/bpmn/typed-node.d.ts:87` |
173
173
  | `contextRows` | property | `ActivityNodeOpts` | `dist/bpmn/bpmn-sdk.d.ts:1528-1535` |
174
174
  | `contextVerbatim` | property | `ActivityNodeOpts` | `dist/bpmn/bpmn-sdk.d.ts:1600-1605` |
175
- | `continue` | method | `StepList` | `dist/flow-sdk.d.ts:1081-1095` |
175
+ | `continue` | method | `StepList` | `dist/flow-sdk.d.ts:1087-1101` |
176
176
  | `contribute` | method | `FlowNode` | `dist/core/node-classes.d.ts:144-153` |
177
177
  | `conversationalAgent` | property | `FlowActionSpecs` | `dist/core/actions.d.ts:1479-1482` |
178
178
  | `conversationContext` | property | `FlowActionSpecs` | `dist/nodes/conversation/flow/spec.d.ts:55-58` |
@@ -207,6 +207,8 @@ not find it either.
207
207
  | `defaultOf` | property | `PendingExit` | `dist/bpmn/bpmn-sdk.d.ts:1924-1925` |
208
208
  | `deferDate` | property | `QueueItemInputs` | `dist/nodes/queue/flow/spec.d.ts:48-49` |
209
209
  | `definition` | property | `NodeContribution` | `dist/core/node-classes.d.ts:111-112` |
210
+ | `definitions` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:734-739` |
211
+ | `definitions` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1433-1473` |
210
212
  | `delay` | property | `FlowActionSpecs` | `dist/nodes/delay/flow/spec.d.ts:38-41` |
211
213
  | `dependsOn` | property | `LookupSpec` | `dist/core/lookups.d.ts:34-35` |
212
214
  | `description` | property | `AgentMemoryRef` | `dist/core/actions.d.ts:1187` |
@@ -223,7 +225,7 @@ not find it either.
223
225
  | `description` | property | `CustomGuardrail` | `dist/core/actions.d.ts:755` |
224
226
  | `description` | property | `EscalationRef` | `dist/core/actions.d.ts:1349-1350` |
225
227
  | `description` | property | `EventTriggerOpts` | `dist/case/case-sdk.d.ts:241` |
226
- | `description` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1235-1242` |
228
+ | `description` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1242-1249` |
227
229
  | `description` | property | `HttpRequestToolRef` | `dist/core/actions.d.ts:1154` |
228
230
  | `description` | property | `IxpExtractInputs` | `dist/core/actions.d.ts:337-344` |
229
231
  | `description` | property | `IxpToolRef` | `dist/core/actions.d.ts:1327-1328` |
@@ -265,7 +267,7 @@ not find it either.
265
267
  | `document` | property | `HitlInputs` | `dist/nodes/hitl/flow/spec.d.ts:252-256` |
266
268
  | `documentClassify` | property | `FlowActionSpecs` | `dist/nodes/document/flow/spec.d.ts:56-59` |
267
269
  | `documentId` | property | `DocValidationInputs` | `dist/nodes/hitl/flow/spec.d.ts:84-85` |
268
- | `doWhile` | method | `StepList` | `dist/flow-sdk.d.ts:1046-1070` |
270
+ | `doWhile` | method | `StepList` | `dist/flow-sdk.d.ts:1052-1076` |
269
271
  | `dueDate` | property | `QueueItemInputs` | `dist/nodes/queue/flow/spec.d.ts:50-51` |
270
272
  | `duration` | property | `TimerSpec` | `dist/bpmn/bpmn-sdk.d.ts:33-34` |
271
273
  | `dynamicExtract` | property | `FlowActionSpecs` | `dist/nodes/document/flow/spec.d.ts:60-63` |
@@ -289,12 +291,12 @@ not find it either.
289
291
  | `entity` | property | `DataServiceOpts` | `dist/bpmn/bpmn-sdk.d.ts:1090-1091` |
290
292
  | `entry` | property | `BuiltStage` | `dist/case/case-sdk.d.ts:528` |
291
293
  | `entry` | property | `BuiltTask` | `dist/case/case-sdk.d.ts:520` |
292
- | `entryPoint` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1301-1351` |
294
+ | `entryPoint` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1308-1358` |
293
295
  | `entryPointId` | property | `ProcessMetadata` | `dist/bpmn/bpmn-sdk.d.ts:534-539` |
294
- | `entryPoints` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:734-735` |
296
+ | `entryPoints` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:740-741` |
295
297
  | `entryWhen` | method | `StageBuilder` | `dist/case/case-sdk.d.ts:1004-1011` |
296
298
  | `entryWhen` | method | `TaskBuilder` | `dist/case/case-sdk.d.ts:947-956` |
297
- | `err` | method | `StepList` | `dist/flow-sdk.d.ts:752-777` |
299
+ | `err` | method | `StepList` | `dist/flow-sdk.d.ts:758-783` |
298
300
  | `error` | property | `BoundaryOpts` | `dist/bpmn/bpmn-sdk.d.ts:750-754` |
299
301
  | `error` | property | `EndOpts` | `dist/bpmn/bpmn-sdk.d.ts:696-706` |
300
302
  | `error` | property | `EventSubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:1842-1847` |
@@ -459,7 +461,7 @@ not find it either.
459
461
  | `inclusiveGateway` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2266-2273` |
460
462
  | `inlineAgent` | property | `FlowActionSpecs` | `dist/core/actions.d.ts:1491-1494` |
461
463
  | `input` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1160-1185` |
462
- | `input` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1426-1438` |
464
+ | `input` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1474-1486` |
463
465
  | `input` | property | `HumanTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1355-1356` |
464
466
  | `input` | property | `OrchestratorOpts` | `dist/bpmn/bpmn-sdk.d.ts:1241-1242` |
465
467
  | `input` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3068-3076` |
@@ -532,7 +534,7 @@ not find it either.
532
534
  | `kind` | property | `SubflowSpec` | `dist/flow-sdk.d.ts:47` |
533
535
  | `kind` | property | `WhenExpression` | `dist/case/case-sdk.d.ts:99-100` |
534
536
  | `kValue` | property | `AgentMemoryRef` | `dist/core/actions.d.ts:1194-1195` |
535
- | `label` | method | `ArmBuilder` | `dist/flow-sdk.d.ts:1200-1209` |
537
+ | `label` | method | `ArmBuilder` | `dist/flow-sdk.d.ts:1206-1215` |
536
538
  | `label` | property | `AskedField` | `dist/core/actions.d.ts:83-84` |
537
539
  | `label` | property | `BuiltStage` | `dist/case/case-sdk.d.ts:523` |
538
540
  | `label` | property | `InOutField` | `dist/core/actions.d.ts:99-100` |
@@ -546,7 +548,7 @@ not find it either.
546
548
  | `layout` | property | `BuiltCase` | `dist/case/case-sdk.d.ts:646-647` |
547
549
  | `layout` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:730-731` |
548
550
  | `layout` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1139-1159` |
549
- | `layout` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1243-1253` |
551
+ | `layout` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1250-1260` |
550
552
  | `limit` | property | `DataFabricReadInputs` | `dist/nodes/data-fabric/flow/spec.d.ts:95-100` |
551
553
  | `limit` | property | `DoWhileOptions` | `dist/flow-sdk.d.ts:479-480` |
552
554
  | `literal` | property | `Expr` | `dist/core/expr.d.ts:18` |
@@ -556,7 +558,7 @@ not find it either.
556
558
  | `lookups` | property | `ConnectorMeta` | `dist/core/connectors.d.ts:76-87` |
557
559
  | `loop` | property | `ActivityNodeFields` | `dist/bpmn/bpmn-sdk.d.ts:335-336` |
558
560
  | `loop` | property | `ActivityOpts` | `dist/bpmn/bpmn-sdk.d.ts:832-833` |
559
- | `loop` | method | `StepList` | `dist/flow-sdk.d.ts:1034-1045` |
561
+ | `loop` | method | `StepList` | `dist/flow-sdk.d.ts:1040-1051` |
560
562
  | `managed` | property | `HttpInputsBase` | `dist/nodes/http/flow/spec.d.ts:37-67` |
561
563
  | `marksCaseComplete` | property | `BuiltCaseExitCondition` | `dist/case/case-sdk.d.ts:354` |
562
564
  | `marksStageComplete` | property | `BuiltExitCondition` | `dist/case/case-sdk.d.ts:321` |
@@ -645,7 +647,7 @@ not find it either.
645
647
  | `name` | property | `EventSubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:1840-1841` |
646
648
  | `name` | property | `EventTriggerOpts` | `dist/case/case-sdk.d.ts:240` |
647
649
  | `name` | property | `ExternalTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1499-1500` |
648
- | `name` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1227-1234` |
650
+ | `name` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1234-1241` |
649
651
  | `name` | property | `FlowOpts` | `dist/bpmn/bpmn-sdk.d.ts:1637-1638` |
650
652
  | `name` | property | `GatewayOpts` | `dist/bpmn/bpmn-sdk.d.ts:760-761` |
651
653
  | `name` | property | `HandlerOpts` | `dist/bpmn/bpmn-sdk.d.ts:1735-1736` |
@@ -707,7 +709,7 @@ not find it either.
707
709
  | `onError` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3259-3266` |
708
710
  | `onError` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3267-3274` |
709
711
  | `onError` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3275-3283` |
710
- | `onError` | method | `StepList` | `dist/flow-sdk.d.ts:832-892` |
712
+ | `onError` | method | `StepList` | `dist/flow-sdk.d.ts:838-898` |
711
713
  | `onMessage` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3302-3310` |
712
714
  | `onMessage` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3311-3319` |
713
715
  | `onTimer` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3284-3292` |
@@ -725,7 +727,7 @@ not find it either.
725
727
  | `outcomes` | property | `EscalationRef` | `dist/core/actions.d.ts:1395-1400` |
726
728
  | `outcomes` | property | `HitlInputs` | `dist/nodes/hitl/flow/spec.d.ts:211-225` |
727
729
  | `output` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1186-1198` |
728
- | `output` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1439-1474` |
730
+ | `output` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1487-1522` |
729
731
  | `output` | property | `RegistryTypeSpec` | `dist/bpmn/typed-node.d.ts:90` |
730
732
  | `output` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3077-3085` |
731
733
  | `outputColumns` | property | `BatchTransformInputs` | `dist/nodes/ai-patterns/flow/spec.d.ts:56-60` |
@@ -761,7 +763,7 @@ not find it either.
761
763
  | `pageRange` | property | `DynamicExtractInputs` | `dist/nodes/document/flow/spec.d.ts:49-50` |
762
764
  | `pageRange` | property | `IxpExtractInputs` | `dist/core/actions.d.ts:326-327` |
763
765
  | `parallel` | property | `LoopOptions` | `dist/flow-sdk.d.ts:461-462` |
764
- | `parallel` | method | `StepList` | `dist/flow-sdk.d.ts:998-1033` |
766
+ | `parallel` | method | `StepList` | `dist/flow-sdk.d.ts:1004-1039` |
765
767
  | `parallelGateway` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2256-2265` |
766
768
  | `parameters` | property | `ConnectorEventOpts` | `dist/bpmn/bpmn-sdk.d.ts:1479-1480` |
767
769
  | `parameters` | property | `HttpOpts` | `dist/bpmn/bpmn-sdk.d.ts:1140-1145` |
@@ -860,7 +862,7 @@ not find it either.
860
862
  | `retry` | property | `ActivityOpts` | `dist/bpmn/bpmn-sdk.d.ts:830-831` |
861
863
  | `retryable` | property | `ErrorMappingRow` | `dist/bpmn/bpmn-sdk.d.ts:308-309` |
862
864
  | `retryCount` | property | `HttpInputsBase` | `dist/nodes/http/flow/spec.d.ts:109-123` |
863
- | `return` | method | `StepList` | `dist/flow-sdk.d.ts:1176-1185` |
865
+ | `return` | method | `StepList` | `dist/flow-sdk.d.ts:1182-1191` |
864
866
  | `returnCitations` | property | `SummarizeInputs` | `dist/nodes/ai-patterns/flow/spec.d.ts:34-39` |
865
867
  | `returns` | property | `AgentInputs` | `dist/core/actions.d.ts:641-660` |
866
868
  | `returns` | property | `ApiWorkflowInputs` | `dist/core/actions.d.ts:429-441` |
@@ -901,7 +903,7 @@ not find it either.
901
903
  | `schemaVersion` | method | `BpmnBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3375-3404` |
902
904
  | `schemaVersion` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:714-720` |
903
905
  | `schemaVersion` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1068-1094` |
904
- | `schemaVersion` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1386-1425` |
906
+ | `schemaVersion` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1393-1432` |
905
907
  | `scope` | property | `EscalationRecipient` | `dist/case/case-sdk.d.ts:121` |
906
908
  | `scopes` | property | `GuardrailSelector` | `dist/core/actions.d.ts:701` |
907
909
  | `script` | property | `FlowActionSpecs` | `dist/nodes/script/flow/spec.d.ts:47-50` |
@@ -973,16 +975,16 @@ not find it either.
973
975
  | `startName` | property | `EventSubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:1887-1888` |
974
976
  | `startPayload` | property | `EventSubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:1889-1890` |
975
977
  | `startProcess` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2459-2478` |
976
- | `step` | method | `StepList` | `dist/flow-sdk.d.ts:778-788` |
978
+ | `step` | method | `StepList` | `dist/flow-sdk.d.ts:784-794` |
977
979
  | `steps` | property | `BuiltEntryPoint` | `dist/flow-sdk.d.ts:705-706` |
978
980
  | `steps` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:724` |
979
- | `steps` | property | `StepList` | `dist/flow-sdk.d.ts:746` |
980
- | `stepSwitch` | method | `StepList` | `dist/flow-sdk.d.ts:789-831` |
981
- | `stepToList` | method | `StepList` | `dist/flow-sdk.d.ts:906-934` |
982
- | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1127-1155` |
983
- | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1156-1175` |
981
+ | `steps` | property | `StepList` | `dist/flow-sdk.d.ts:752` |
982
+ | `stepSwitch` | method | `StepList` | `dist/flow-sdk.d.ts:795-837` |
983
+ | `stepToList` | method | `StepList` | `dist/flow-sdk.d.ts:912-940` |
984
+ | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1133-1161` |
985
+ | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1162-1181` |
984
986
  | `stickyNotes` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:732-733` |
985
- | `stickyNotes` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1254-1279` |
987
+ | `stickyNotes` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1261-1286` |
986
988
  | `storageBucket` | property | `DocValidationInputs` | `dist/nodes/hitl/flow/spec.d.ts:82-83` |
987
989
  | `strategy` | property | `LookupSpec` | `dist/core/lookups.d.ts:33` |
988
990
  | `style` | property | `CaseNodeLayout` | `dist/case/case-sdk.d.ts:597-598` |
@@ -995,7 +997,7 @@ not find it either.
995
997
  | `subType` | property | `VarSpec` | `dist/flow-sdk.d.ts:84-85` |
996
998
  | `summarize` | property | `FlowActionSpecs` | `dist/nodes/ai-patterns/flow/spec.d.ts:66-69` |
997
999
  | `summary` | property | `CaseAppConfig` | `dist/case/case-sdk.d.ts:585-586` |
998
- | `switch` | method | `StepList` | `dist/flow-sdk.d.ts:962-997` |
1000
+ | `switch` | method | `StepList` | `dist/flow-sdk.d.ts:968-1003` |
999
1001
  | `systemPrompt` | property | `ConversationalAgentInputs` | `dist/core/actions.d.ts:134-139` |
1000
1002
  | `systemPrompt` | property | `InlineAgentInputs` | `dist/core/actions.d.ts:814-863` |
1001
1003
  | `systemPrompt` | property | `VoiceAgentInputs` | `dist/core/actions.d.ts:221-226` |
@@ -1020,7 +1022,7 @@ not find it either.
1020
1022
  | `temperature` | property | `InlineAgentInputs` | `dist/core/actions.d.ts:924-925` |
1021
1023
  | `temperature` | property | `VoiceSettings` | `dist/core/actions.d.ts:213-214` |
1022
1024
  | `terminate` | property | `EndOpts` | `dist/bpmn/bpmn-sdk.d.ts:692-693` |
1023
- | `terminate` | method | `StepList` | `dist/flow-sdk.d.ts:1096-1126` |
1025
+ | `terminate` | method | `StepList` | `dist/flow-sdk.d.ts:1102-1132` |
1024
1026
  | `threshold` | property | `ContextIndexRef` | `dist/core/actions.d.ts:1438-1439` |
1025
1027
  | `timeCycle` | property | `BuiltTrigger` | `dist/case/case-sdk.d.ts:201-202` |
1026
1028
  | `timeout` | property | `HttpInputsBase` | `dist/nodes/http/flow/spec.d.ts:91-108` |
@@ -1044,11 +1046,11 @@ not find it either.
1044
1046
  | `trigger` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:725-727` |
1045
1047
  | `trigger` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1224-1232` |
1046
1048
  | `trigger` | property | `EscalationOpts` | `dist/case/case-sdk.d.ts:128-129` |
1047
- | `trigger` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1280-1300` |
1049
+ | `trigger` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1287-1307` |
1048
1050
  | `trigger` | property | `StartOpts` | `dist/bpmn/bpmn-sdk.d.ts:624-671` |
1049
1051
  | `triggeredByEvent` | property | `SubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:976-977` |
1050
- | `triggerId` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:736-742` |
1051
- | `triggerId` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1352-1371` |
1052
+ | `triggerId` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:742-748` |
1053
+ | `triggerId` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1359-1378` |
1052
1054
  | `triggerOptions` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:728-729` |
1053
1055
  | `triggers` | property | `BuiltCase` | `dist/case/case-sdk.d.ts:644-645` |
1054
1056
  | `triggers` | property | `CaseLayout` | `dist/case/case-sdk.d.ts:620-621` |
@@ -1104,7 +1106,7 @@ not find it either.
1104
1106
  | `value` | property | `TypedInputRow` | `dist/bpmn/typed-node.d.ts:205-206` |
1105
1107
  | `values` | property | `DataFabricCreateInputs` | `dist/nodes/data-fabric/flow/spec.d.ts:132-137` |
1106
1108
  | `var` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1199-1223` |
1107
- | `var` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1475-1484` |
1109
+ | `var` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1523-1532` |
1108
1110
  | `var` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3059-3067` |
1109
1111
  | `var` | property | `TaskOutputBinding` | `dist/case/case-sdk.d.ts:494-495` |
1110
1112
  | `var` | property | `TypedOutputRow` | `dist/bpmn/typed-node.d.ts:251-252` |
@@ -1127,7 +1129,7 @@ not find it either.
1127
1129
  | `version` | property | `ConnectorToolRef` | `dist/core/actions.d.ts:1232-1233` |
1128
1130
  | `version` | property | `EventSubscription` | `dist/core/actions.d.ts:2116` |
1129
1131
  | `version` | property | `ExternalTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1507-1508` |
1130
- | `version` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1372-1385` |
1132
+ | `version` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1379-1392` |
1131
1133
  | `version` | property | `NodeOptions` | `dist/flow-sdk.d.ts:373-380` |
1132
1134
  | `version` | property | `TriggerMeta` | `dist/core/connectors.d.ts:126` |
1133
1135
  | `version` | property | `TriggerOptions` | `dist/core/actions.d.ts:2073-2074` |
package/dist/check.js CHANGED
@@ -29,7 +29,7 @@ import { ownEntry } from './core/own-entry.js';
29
29
  import { FLOW_NODE_TYPES } from './flow-node-registry.js';
30
30
  import { stepExits } from './flow-step-exits.js';
31
31
  import { plainHttpOnErrorMessage } from './nodes/http/flow/family.js';
32
- import { resolveVersion } from './core/nodes/versioned.js';
32
+ import { resolveVersion, resolveVersionCarried } from './core/nodes/versioned.js';
33
33
  import { declaredErrorPortRefusal } from './core/error-port.js';
34
34
  export function check(built, opts = {}) {
35
35
  let diags = [];
@@ -275,7 +275,7 @@ function checkFlow(built, ancestors, opts = {}) {
275
275
  declared.add(s.name); // a step's output is referenceable by name
276
276
  }
277
277
  if ((s.kind === 'stepToList' || s.kind === 'stepToRef') && s.port === 'error')
278
- checkOnError(s, prevPortSource, diags, prevPortSource && checkedSteps.get(prevPortSource.name));
278
+ checkOnError(s, prevPortSource, diags, prevPortSource && checkedSteps.get(prevPortSource.name), carriedLookup([built, ...ancestors]));
279
279
  if ((s.kind === 'stepToList' || s.kind === 'stepToRef') && s.port.startsWith('branch-')) {
280
280
  const want = s.port.slice('branch-'.length);
281
281
  const prevSpec = prevAction?.spec;
@@ -381,7 +381,7 @@ function checkFlow(built, ancestors, opts = {}) {
381
381
  prevPortSource = s;
382
382
  const registered = registeredKind(s.spec);
383
383
  if (registered) {
384
- const { placed, checked } = checkRegisteredStep(registered, s, exprs, errorSource, opts, diags, typeOf, triggerId);
384
+ const { placed, checked } = checkRegisteredStep(registered, s, exprs, errorSource, opts, diags, typeOf, triggerId, carriedLookup([built, ...ancestors]));
385
385
  checkedSteps.set(s.name, checked);
386
386
  if (placed)
387
387
  registeredSteps.set(s.name, checked);
@@ -3977,6 +3977,11 @@ const LOOP_FIELDS = new Set(['currentItem', 'currentIteration', 'collection', 'o
3977
3977
  * before the 2.4 default (#868); its own fields are not audited here.
3978
3978
  */
3979
3979
  const LOOP_FIELDS_1_0_0 = new Set(['currentItem', 'currentIndex', 'collection', 'output', 'error']);
3980
+ /** The {@link CarriedLookup} over `scopes` — the flow being checked first, then its ancestors. */
3981
+ function carriedLookup(scopes) {
3982
+ const all = scopes.flatMap((b) => b.definitions ?? []);
3983
+ return Object.assign((typeName, version) => all.find((d) => d.nodeType === typeName && d.version === version), { versions: (typeName) => [...new Set(all.filter((d) => d.nodeType === typeName).map((d) => String(d.version)))] });
3984
+ }
3980
3985
  /** The registered node type for a spec's kind, or undefined (a custom FlowAction has no kind). */
3981
3986
  function registeredKind(spec) {
3982
3987
  const kind = spec?.kind;
@@ -3994,14 +3999,15 @@ function registeredKind(spec) {
3994
3999
  * which serialize enforces (#942) and the type's tests pin; an author cannot
3995
4000
  * cause the gap, so there is no author diagnostic to report.
3996
4001
  */
3997
- function checkRegisteredStep(entry, s, exprs, errorSource, opts, diags, typeOf, triggerId) {
4002
+ function checkRegisteredStep(entry, s, exprs, errorSource, opts, diags, typeOf, triggerId, carried) {
3998
4003
  const spec = s.spec;
3999
4004
  /** The step's node-local rules and expressions, as `impl` defines them. */
4000
- const runRules = (impl) => {
4005
+ const runRules = (impl, version = impl.version, carriedDef) => {
4001
4006
  const ctx = {
4002
4007
  step: s.name,
4003
- version: impl.version,
4004
- definition: () => bundledDefinition(impl.typeName, impl.version),
4008
+ // At a carried version, the version and definition serialize emits.
4009
+ version,
4010
+ definition: () => carriedDef ?? bundledDefinition(impl.typeName, impl.version),
4005
4011
  report: (code, message, suggestion) => diags.push(catalogued(entry, s.name, code, message, suggestion)),
4006
4012
  declaredRef: (js) => {
4007
4013
  const name = declaredRefName(js, triggerId);
@@ -4024,8 +4030,14 @@ function checkRegisteredStep(entry, s, exprs, errorSource, opts, diags, typeOf,
4024
4030
  return ctx;
4025
4031
  };
4026
4032
  let impl;
4033
+ let version;
4034
+ let carriedDef;
4027
4035
  try {
4028
- impl = resolveVersion(entry.type, spec, s.options?.version, `step "${s.name}"`);
4036
+ // A pin the registry lacks but the flow carries resolves (#1128), as in serialize.
4037
+ const resolved = resolveVersionCarried(entry.type, spec, s.options?.version, `step "${s.name}"`, carried);
4038
+ impl = resolved.impl;
4039
+ version = resolved.version;
4040
+ carriedDef = resolved.carried;
4029
4041
  }
4030
4042
  catch (e) {
4031
4043
  // A select() that picks an unregistered version is the node type's bug, not the author's pin.
@@ -4043,8 +4055,14 @@ function checkRegisteredStep(entry, s, exprs, errorSource, opts, diags, typeOf,
4043
4055
  checked: { entry, impl: fallback, spec, placement: { step: s.name, kind: fallback.kind, spec, version: fallback.version }, ctx: fallbackCtx },
4044
4056
  };
4045
4057
  }
4046
- const ctx = runRules(impl);
4047
- return { placed: true, checked: { entry, impl, spec, placement: { step: s.name, kind: impl.kind, spec, version: impl.version }, ctx } };
4058
+ const ctx = runRules(impl, version, carriedDef);
4059
+ return {
4060
+ placed: true,
4061
+ checked: {
4062
+ entry, impl, spec, placement: { step: s.name, kind: impl.kind, spec, version }, ctx,
4063
+ ...(carriedDef !== undefined ? { carried: carriedDef } : {}),
4064
+ },
4065
+ };
4048
4066
  }
4049
4067
  /** Every non-literal Expr reachable in `value`, as expressions to check. */
4050
4068
  function pushDeepExprs(value, step, errorSource, out) {
@@ -4171,7 +4189,7 @@ const ERROR_ENVELOPE_FIELDS = ['code', 'message', 'detail', 'category', 'status'
4171
4189
  */
4172
4190
  function checkOnError(_handler, step, diags,
4173
4191
  /** The step's registry record, when its kind is registered and its version resolved. */
4174
- placed) {
4192
+ placed, carried) {
4175
4193
  // The builder refuses a handler with no eligible step before it, so a missing
4176
4194
  // source here means a hand-built `BuiltFlow`; there is nothing to say about it.
4177
4195
  if (!step)
@@ -4243,7 +4261,7 @@ placed) {
4243
4261
  }
4244
4262
  }
4245
4263
  else {
4246
- const def = bundledDefinition(impl.typeName, impl.version);
4264
+ const def = placed.carried ?? bundledDefinition(impl.typeName, impl.version);
4247
4265
  if (def !== undefined && !definitionHasErrorPort(def)) {
4248
4266
  diags.push({ level: 'error', code: 'ONERROR_NO_ERROR_PORT', message: typedNoErrorPortMessage(step.name, impl.kind, def), step: step.name });
4249
4267
  return;
@@ -4262,7 +4280,12 @@ placed) {
4262
4280
  // A version the SDK does not bundle (an inline agent's registry version) has
4263
4281
  // no definition here to ask; version resolution reports that, not this check.
4264
4282
  const bundledType = bundledActionNodeType(spec);
4265
- const bundledDef = bundledType ? bundledDefinition(bundledType, actionVersion(spec, step.options?.version)) : undefined;
4283
+ // A version the flow CARRIES (`.definitions()`, #1128) answers the same way
4284
+ // a bundled one does: it is the definition serialize will emit.
4285
+ const pinned = step.options?.version;
4286
+ const bundledDef = bundledType
4287
+ ? bundledDefinition(bundledType, actionVersion(spec, pinned)) ?? (pinned !== undefined ? carried?.(bundledType, pinned) : undefined)
4288
+ : undefined;
4266
4289
  // A per-tenant family: ask the definition serialize synthesizes for it (#1040).
4267
4290
  let perCallDef;
4268
4291
  if (!bundledType) {
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Node definitions a flow CARRIES — the third source a pinned `{ version }`
3
+ * resolves from, after the SDK's bundle (#1128).
4
+ *
5
+ * Every `.flow` file holds the exact definition of every node it uses, in
6
+ * `definitions[]`. The SDK bundles only the versions it was released with, so
7
+ * a version the registry served later (`node add` writes
8
+ * `uipath.human-in-the-loop.quick-form@1.6`; the SDK ships 1.0 and 1.1) used
9
+ * to be refused, and the source decompile wrote for an untouched product flow
10
+ * did not compile. A carried definition closes that: decompile copies the
11
+ * file's own entry into `.definitions([...])`, and compile resolves the pin
12
+ * against it.
13
+ *
14
+ * A carried definition is an exact copy of a real one, never a way to invent a
15
+ * version. So it is validated the way a `rawNode` snapshot manifest is: it
16
+ * names its own `nodeType` and `version`, and it has the `display.label` every
17
+ * node manifest has.
18
+ */
19
+ /** A carried definition, by its `<nodeType>@<version>` key. */
20
+ export type CarriedDefinitions = ReadonlyMap<string, Record<string, unknown>>;
21
+ /**
22
+ * Why `manifest` cannot be carried, or `undefined` when it can.
23
+ *
24
+ * For instance `{ nodeType: 'x', version: '1.0' }` is refused for lacking
25
+ * `display.label`.
26
+ */
27
+ export declare function carriedDefinitionRefusal(manifest: unknown, where: string): string | undefined;
28
+ /**
29
+ * Index `manifests` by `<nodeType>@<version>`. Throws on an invalid manifest,
30
+ * or on two different manifests for one pair (which one compiles would be a
31
+ * guess).
32
+ */
33
+ export declare function indexCarriedDefinitions(manifests: readonly unknown[], where: string, into?: Map<string, Record<string, unknown>>): Map<string, Record<string, unknown>>;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Node definitions a flow CARRIES — the third source a pinned `{ version }`
3
+ * resolves from, after the SDK's bundle (#1128).
4
+ *
5
+ * Every `.flow` file holds the exact definition of every node it uses, in
6
+ * `definitions[]`. The SDK bundles only the versions it was released with, so
7
+ * a version the registry served later (`node add` writes
8
+ * `uipath.human-in-the-loop.quick-form@1.6`; the SDK ships 1.0 and 1.1) used
9
+ * to be refused, and the source decompile wrote for an untouched product flow
10
+ * did not compile. A carried definition closes that: decompile copies the
11
+ * file's own entry into `.definitions([...])`, and compile resolves the pin
12
+ * against it.
13
+ *
14
+ * A carried definition is an exact copy of a real one, never a way to invent a
15
+ * version. So it is validated the way a `rawNode` snapshot manifest is: it
16
+ * names its own `nodeType` and `version`, and it has the `display.label` every
17
+ * node manifest has.
18
+ */
19
+ /**
20
+ * Why `manifest` cannot be carried, or `undefined` when it can.
21
+ *
22
+ * For instance `{ nodeType: 'x', version: '1.0' }` is refused for lacking
23
+ * `display.label`.
24
+ */
25
+ export function carriedDefinitionRefusal(manifest, where) {
26
+ if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
27
+ return `${where}: a carried definition must be a node manifest object.`;
28
+ }
29
+ const m = manifest;
30
+ if (typeof m.nodeType !== 'string' || !m.nodeType || typeof m.version !== 'string' || !m.version) {
31
+ return `${where}: a carried definition must name its exact nodeType and version.`;
32
+ }
33
+ if (typeof m.display?.label !== 'string' || !m.display.label) {
34
+ return `${where}: the carried definition ${m.nodeType}@${m.version} lacks display.label — not a valid node manifest.`;
35
+ }
36
+ return undefined;
37
+ }
38
+ /**
39
+ * Index `manifests` by `<nodeType>@<version>`. Throws on an invalid manifest,
40
+ * or on two different manifests for one pair (which one compiles would be a
41
+ * guess).
42
+ */
43
+ export function indexCarriedDefinitions(manifests, where, into = new Map()) {
44
+ for (const m of manifests) {
45
+ const refusal = carriedDefinitionRefusal(m, where);
46
+ if (refusal)
47
+ throw new Error(refusal);
48
+ const def = m;
49
+ const key = `${def.nodeType}@${def.version}`;
50
+ const prior = into.get(key);
51
+ if (prior !== undefined && stableJson(prior) !== stableJson(def)) {
52
+ throw new Error(`${where}: two different carried definitions for ${key}. Keep the one the file holds.`);
53
+ }
54
+ into.set(key, def);
55
+ }
56
+ return into;
57
+ }
58
+ /** `JSON.stringify` with object keys sorted, so two copies of one manifest compare equal whatever their key order. */
59
+ function stableJson(value) {
60
+ return JSON.stringify(value, (_key, v) => (v && typeof v === 'object' && !Array.isArray(v)
61
+ ? Object.fromEntries(Object.keys(v).sort().map((k) => [k, v[k]]))
62
+ : v));
63
+ }
@@ -48,3 +48,38 @@ export declare function asVersioned<Ctx extends ArtifactContexts>(t: AnyNodeType
48
48
  * node type's bug, not the author's, and throws as an internal SDK error.
49
49
  */
50
50
  export declare function resolveVersion<Spec, Ctx extends ArtifactContexts>(t: VersionedNodeType<Spec, unknown, Ctx>, spec: Spec, requested: string | undefined, where: string): NodeType<Spec, unknown, Ctx>;
51
+ /**
52
+ * Looks up a definition the flow carries (`.definitions()`) for `typeName@version`.
53
+ * `versions`, when present, lists every version of `typeName` the flow carries,
54
+ * so a refusal can name them.
55
+ */
56
+ export type CarriedDefinitionLookup = ((typeName: string, version: string) => Record<string, unknown> | undefined) & {
57
+ readonly versions?: (typeName: string) => readonly string[];
58
+ };
59
+ /** What {@link resolveVersionCarried} resolved: the implementation, the version to emit, and a carried definition when one answered. */
60
+ export interface ResolvedNodeVersion<Impl> {
61
+ readonly impl: Impl;
62
+ /** The version the node is emitted at — `impl.version`, or the carried version. */
63
+ readonly version: string;
64
+ /** The definition the FLOW carries for `typeName@version`, when the registry has no implementation at that version. */
65
+ readonly carried?: Record<string, unknown>;
66
+ }
67
+ /**
68
+ * {@link resolveVersion} with the third definition source (#1128): a definition
69
+ * the flow CARRIES (`.definitions()`, decompile's copy of the file's own
70
+ * `definitions[]` entry).
71
+ *
72
+ * Order: a registered version resolves as before. An explicit version the type
73
+ * does not register, but the flow carries, is emitted AT that version with the
74
+ * carried definition, through the implementation the type would use unpinned
75
+ * (`select(spec)`, else the default) — the registry has no implementation of
76
+ * its own for it, and the node keeps the version the file pins instead of being
77
+ * refused. Anything else is refused as {@link resolveVersion} refuses it, except
78
+ * that an unregistered pin also names the versions the flow carries and the
79
+ * `.definitions()` remedy.
80
+ *
81
+ * For instance a file pinning `core.action.script@1.0` (registered: 1.0.0, 1.1)
82
+ * and carrying that definition emits the node at 1.0 through the default
83
+ * implementation.
84
+ */
85
+ export declare function resolveVersionCarried<Spec, Ctx extends ArtifactContexts>(t: VersionedNodeType<Spec, unknown, Ctx>, spec: Spec, requested: string | undefined, where: string, carried: CarriedDefinitionLookup | undefined): ResolvedNodeVersion<NodeType<Spec, unknown, Ctx>>;
@@ -44,3 +44,38 @@ export function resolveVersion(t, spec, requested, where) {
44
44
  }
45
45
  return impl;
46
46
  }
47
+ /**
48
+ * {@link resolveVersion} with the third definition source (#1128): a definition
49
+ * the flow CARRIES (`.definitions()`, decompile's copy of the file's own
50
+ * `definitions[]` entry).
51
+ *
52
+ * Order: a registered version resolves as before. An explicit version the type
53
+ * does not register, but the flow carries, is emitted AT that version with the
54
+ * carried definition, through the implementation the type would use unpinned
55
+ * (`select(spec)`, else the default) — the registry has no implementation of
56
+ * its own for it, and the node keeps the version the file pins instead of being
57
+ * refused. Anything else is refused as {@link resolveVersion} refuses it, except
58
+ * that an unregistered pin also names the versions the flow carries and the
59
+ * `.definitions()` remedy.
60
+ *
61
+ * For instance a file pinning `core.action.script@1.0` (registered: 1.0.0, 1.1)
62
+ * and carrying that definition emits the node at 1.0 through the default
63
+ * implementation.
64
+ */
65
+ export function resolveVersionCarried(t, spec, requested, where, carried) {
66
+ if (requested !== undefined && !ownEntry(t.versions, requested)) {
67
+ const def = carried?.(t.typeName, requested);
68
+ if (def !== undefined) {
69
+ return { impl: resolveVersion(t, spec, undefined, where), version: requested, carried: def };
70
+ }
71
+ // Refused: name both sources, and the way to add the second one.
72
+ const registered = Object.keys(t.versions).sort().join(', ');
73
+ const carriedVersions = [...(carried?.versions?.(t.typeName) ?? [])].sort();
74
+ throw new Error(`${where} requests ${t.typeName}@${requested}, but this SDK registers only ${registered}`
75
+ + (carriedVersions.length > 0 ? ` and the flow carries only ${carriedVersions.join(', ')}` : '')
76
+ + '. Versions are exact — omit { version } to use the default, request one listed here, or carry '
77
+ + "that version's definition (the .flow file's definitions[] entry) with .definitions([...]).");
78
+ }
79
+ const impl = resolveVersion(t, spec, requested, where);
80
+ return { impl, version: impl.version };
81
+ }
package/dist/decompile.js CHANGED
@@ -83,6 +83,13 @@ let runDefs = new Map();
83
83
  * agent that has to edit the file next.
84
84
  */
85
85
  let runRawManifests = [];
86
+ /**
87
+ * The file's definitions for pinned pairs this SDK cannot resolve, by
88
+ * `<type>@<version>` → hoisted const name (#1128). Emitted once, in
89
+ * `.definitions([...])`, so compile resolves the pin against the file's own
90
+ * definition and the node keeps its version even when the author edits it.
91
+ */
92
+ let runCarried = new Map();
86
93
  let runStrict = false;
87
94
  /** `DecompileOptions.warn` for the current run, and the messages already sent to it (one line per finding). */
88
95
  let runWarn;
@@ -131,22 +138,21 @@ function verClause(node) {
131
138
  + `the file's definitions[] disagrees with the instance.`);
132
139
  }
133
140
  }
134
- // A pin the SDK cannot resolve: `serialize` resolves an explicit { version }
135
- // exactly (design §2.6) — a registered type against its registered versions,
136
- // any other type against the bundle. Keeping that pin would emit source
137
- // `compile` refuses (#1128: quick-form@1.6 from `node add`, @1.4 from
138
- // `migrate`, script@1.0 from a pre-migrate file), so the source omits it: the
139
- // node compiles at the SDK's default, and `merge --baseline` keeps the
140
- // UNTOUCHED original node, with its own version and definition, verbatim
141
- // (`nodeUnchanged` ignores typeVersion). Interim: a node the author EDITS is
142
- // re-emitted at the default — the root fix is for compile to accept the
143
- // definition the file carries.
141
+ // A pin the SDK cannot resolve (design §2.6: exact, against the registered
142
+ // or bundled versions) is kept when the file carries that pair's definition:
143
+ // `.definitions([...])` hands it to compile (#1128). With no definition to
144
+ // carry, keeping the pin would emit source `compile` refuses, so the source
145
+ // omits it: the node compiles at the SDK's default, and `merge --baseline`
146
+ // keeps the UNTOUCHED original node verbatim (`nodeUnchanged` ignores
147
+ // typeVersion).
144
148
  //
145
149
  // A type with no SDK-known version at all (a connector, a published-resource
146
150
  // `uipath.core.*` node, a rawNode) resolves its version elsewhere, so its pin
147
151
  // is kept.
152
+ if (runCarried.has(`${node.type}@${tv}`))
153
+ return `version: ${tsLiteral(tv)}`;
148
154
  const registered = FLOW_NODE_TYPES.byTypeName(node.type);
149
- const shipped = registered ? Object.keys(registered.type.versions) : bundledVersions(node.type);
155
+ const shipped = shippedVersions(node.type);
150
156
  if (shipped.length > 0 && !shipped.includes(tv)) {
151
157
  const known = `${node.type}@${shipped.join(', ')}`;
152
158
  if (runStrict) {
@@ -161,6 +167,15 @@ function verClause(node) {
161
167
  }
162
168
  return `version: ${tsLiteral(tv)}`;
163
169
  }
170
+ /**
171
+ * The versions this SDK resolves a `{ version }` of `type` against: a
172
+ * registered type's registered versions, any other type's bundled ones; `[]`
173
+ * for a type it ships at no version (a connector, a published resource).
174
+ */
175
+ function shippedVersions(type) {
176
+ const registered = FLOW_NODE_TYPES.byTypeName(type);
177
+ return registered ? Object.keys(registered.type.versions) : bundledVersions(type);
178
+ }
164
179
  function verArg(node) {
165
180
  const clause = verClause(node);
166
181
  return clause ? `, { ${clause} }` : '';
@@ -1494,6 +1509,92 @@ function unsupportedSpec(node, imp, o) {
1494
1509
  // is a safe structural stand-in, and the marker records what it replaced.
1495
1510
  return `${imp.use('mock')}() /* TODO: unsupported node type ${commentText(node.type)} */`;
1496
1511
  }
1512
+ /**
1513
+ * Every pinned `<type>@<version>` in the file (root and subflows) that this SDK
1514
+ * cannot resolve, for a type it ships at some version, and that the file's
1515
+ * `definitions[]` holds — mapped to the const name decompile hoists the
1516
+ * definition under. For instance a quick-form node at 1.6 maps
1517
+ * `uipath.human-in-the-loop.quick-form@1.6` → `quickFormV1_6Definition`.
1518
+ */
1519
+ function carriedPairs(flow) {
1520
+ const out = new Map();
1521
+ const taken = new Set();
1522
+ const scopes = [flow.nodes ?? [], ...Object.values(flow.subflows ?? {}).map((sf) => sf?.nodes ?? [])];
1523
+ for (const n of scopes.flat()) {
1524
+ const key = `${n.type}@${n.typeVersion}`;
1525
+ if (!n.typeVersion || out.has(key) || !runDefs.has(key))
1526
+ continue;
1527
+ const shipped = shippedVersions(n.type);
1528
+ if (shipped.length === 0 || shipped.includes(n.typeVersion))
1529
+ continue;
1530
+ const base = `${camel(String(n.type).split('.').pop() ?? 'node')}V${String(n.typeVersion).replace(/[^A-Za-z0-9]+/g, '_')}Definition`;
1531
+ let name = base;
1532
+ for (let i = 2; taken.has(name); i++)
1533
+ name = `${base}${i}`;
1534
+ taken.add(name);
1535
+ out.set(key, name);
1536
+ warnCarriedInputDrift(n, runDefs.get(key));
1537
+ }
1538
+ return out;
1539
+ }
1540
+ /**
1541
+ * The input names a definition declares: its `inputDefaults` keys and the
1542
+ * top-level `inputs.<name>` its form fields edit. For instance quick-form@1.1
1543
+ * gives `recipient, schema`.
1544
+ */
1545
+ function definitionInputNames(def) {
1546
+ const names = new Set(Object.keys(def?.inputDefaults ?? {}));
1547
+ const visit = (v) => {
1548
+ if (Array.isArray(v)) {
1549
+ v.forEach(visit);
1550
+ return;
1551
+ }
1552
+ if (!v || typeof v !== 'object')
1553
+ return;
1554
+ const field = v.name;
1555
+ if (typeof field === 'string' && field.startsWith('inputs.'))
1556
+ names.add(field.slice('inputs.'.length).split(/[.[]/)[0]);
1557
+ for (const child of Object.values(v))
1558
+ visit(child);
1559
+ };
1560
+ visit(def?.form);
1561
+ return [...names].sort();
1562
+ }
1563
+ /** Compare two dotted versions numerically: `1.10` sorts after `1.9`. */
1564
+ function compareVersions(a, b) {
1565
+ const pa = a.split('.').map(Number);
1566
+ const pb = b.split('.').map(Number);
1567
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
1568
+ const d = (pa[i] ?? 0) - (pb[i] ?? 0);
1569
+ if (d !== 0)
1570
+ return d;
1571
+ }
1572
+ return 0;
1573
+ }
1574
+ /**
1575
+ * Warn when a carried definition's inputs differ from the nearest version the
1576
+ * SDK ships (the highest one below the carried version, else the lowest). An
1577
+ * edited node keeps the file's pin, but its inputs are rebuilt in the SDK's
1578
+ * shape, so a renamed input would be written under the wrong name. For
1579
+ * instance `node "review1" keeps quick-form@1.6 ...; its inputs differ from
1580
+ * 1.1 (assignee)`.
1581
+ */
1582
+ function warnCarriedInputDrift(node, carried) {
1583
+ const versions = shippedVersions(node.type).filter((v) => BUNDLED_DEFINITIONS[`${node.type}@${v}`]).sort(compareVersions);
1584
+ const below = versions.filter((v) => compareVersions(v, String(node.typeVersion)) < 0);
1585
+ const nearest = below.length > 0 ? below[below.length - 1] : versions[0];
1586
+ if (nearest === undefined)
1587
+ return;
1588
+ const shipped = BUNDLED_DEFINITIONS[`${node.type}@${nearest}`];
1589
+ const factoryVersion = nearest;
1590
+ const a = definitionInputNames(carried);
1591
+ const b = definitionInputNames(shipped);
1592
+ const differ = [...a.filter((x) => !b.includes(x)), ...b.filter((x) => !a.includes(x))].sort();
1593
+ if (differ.length === 0)
1594
+ return;
1595
+ warnOnce(`node ${tsLiteral(node.id)} keeps ${node.type}@${node.typeVersion} from the file's definitions[]; its inputs differ from `
1596
+ + `${factoryVersion} (${differ.join(', ')}), so an edit to it may need rawNode.`);
1597
+ }
1497
1598
  /** `some-node.id` → `someNodeId`, for a hoisted const name. */
1498
1599
  function camel(id) {
1499
1600
  const parts = String(id).split(/[^A-Za-z0-9]+/).filter(Boolean);
@@ -2923,6 +3024,7 @@ export function decompile(flow, options = {}) {
2923
3024
  if (!runDefs.has(d.nodeType))
2924
3025
  runDefs.set(d.nodeType, d);
2925
3026
  }
3027
+ runCarried = carriedPairs(flow);
2926
3028
  const imp = new Imports();
2927
3029
  const graph = new Graph(flow.nodes ?? [], flow.edges ?? []);
2928
3030
  const globals = readFlowGlobals(flow.variables, runStrict);
@@ -2956,6 +3058,8 @@ export function decompile(flow, options = {}) {
2956
3058
  if (typeof flow.description === 'string') {
2957
3059
  e.line(d, `.description(${tsLiteral(flow.description)})`);
2958
3060
  }
3061
+ if (runCarried.size > 0)
3062
+ e.line(d, `.definitions([${[...runCarried.values()].join(', ')}])`);
2959
3063
  // Trigger nodes. One root is the default: the isDefaultEntryPoint carrier
2960
3064
  // when the file marks one (a multi-root flow always does), else `start`.
2961
3065
  // A node's TYPE is not enough: `uipath.connector.event.<key>.<event>` is a
@@ -3042,7 +3146,8 @@ export function decompile(flow, options = {}) {
3042
3146
  const lay = layoutSeg(flow, (flow.nodes ?? []).filter((n) => !detachedIds.has(n.id)), (flow.edges ?? []).filter((edge) => !detachedIds.has(edge.sourceNodeId) && !detachedIds.has(edge.targetNodeId)));
3043
3147
  const layout = lay ? reindent(lay, ' ') : '';
3044
3148
  const chain = [header, eps, body, sticky, layout, ' .build();'].filter((s) => s.length > 0).join('\n');
3045
- const hoisted = runRawManifests
3149
+ const carriedConsts = [...runCarried].map(([key, name]) => [name, JSON.stringify(runDefs.get(key), null, 2)]);
3150
+ const hoisted = [...carriedConsts, ...runRawManifests]
3046
3151
  .map(([name, json]) => `const ${name} = ${json};`)
3047
3152
  .join('\n\n');
3048
3153
  return [imp.line(importSpecifier), hoisted, chain].filter((p) => p.length > 0).join('\n\n') + '\n';
@@ -97,7 +97,12 @@ export interface FlowSerializeContext {
97
97
  bind(entry: {
98
98
  readonly id: string;
99
99
  } & Readonly<Record<string, unknown>>): void;
100
- /** The bundled definition `<typeName>@<version>`, or undefined when the SDK does not ship it. */
100
+ /**
101
+ * The bundled definition `<typeName>@<version>`, else one the flow carries;
102
+ * undefined when neither exists. When the node is emitted at a carried
103
+ * version, asking for its own type answers with that carried definition at
104
+ * any `version`, so a type's defaults follow the file's definition.
105
+ */
101
106
  definition(typeName: string, version: string): unknown;
102
107
  /**
103
108
  * The flow's bindings so far, by id — read-only. For a type that SHARES a
@@ -186,8 +191,8 @@ export interface FlowCheckContext {
186
191
  /** The version the node will be emitted at. */
187
192
  readonly version: string;
188
193
  /**
189
- * The SDK's bundled definition of this step's node type at `version` (the one
190
- * serialize emits from), or undefined when the SDK does not ship it.
194
+ * The definition serialize emits this step from: the one the flow carries at
195
+ * a carried version, else the SDK's bundled one; undefined when neither exists.
191
196
  */
192
197
  definition(): unknown;
193
198
  /** Report a diagnostic on this step. Its severity is the family catalog's for `code`. */
@@ -731,6 +731,12 @@ export interface BuiltFlow {
731
731
  layout?: FlowLayout;
732
732
  /** Canvas sticky notes from `.stickyNotes()`. Inert annotations. */
733
733
  stickyNotes?: StickyNote[];
734
+ /**
735
+ * Node definitions the flow carries, from `.definitions()`: exact manifests a
736
+ * pinned `{ version }` resolves against when the SDK does not bundle that
737
+ * version.
738
+ */
739
+ definitions?: Record<string, unknown>[];
734
740
  /** Additional roots from `.entryPoint()`. The default root stays `.trigger()`/`.input()`. */
735
741
  entryPoints?: BuiltEntryPoint[];
736
742
  /**
@@ -1216,6 +1222,7 @@ declare class FlowBuilder extends StepList {
1216
1222
  private _stickyNotes?;
1217
1223
  private _version;
1218
1224
  private _schemaVersion?;
1225
+ private _definitions;
1219
1226
  private _inputs;
1220
1227
  private _outputs;
1221
1228
  private _vars;
@@ -1423,6 +1430,47 @@ declare class FlowBuilder extends StepList {
1423
1430
  * @defaultValue `'1.9'` — `FLOW_FORMAT_PROFILE.version`, the fleet write floor.
1424
1431
  */
1425
1432
  schemaVersion(version: string): this;
1433
+ /**
1434
+ * Carry node definitions this SDK does not bundle, so a `{ version }` pin on
1435
+ * one of those versions compiles.
1436
+ *
1437
+ * @remarks
1438
+ * A pinned `{ version }` resolves exactly (design §2.6): first against the
1439
+ * definitions the SDK was released with, then against the ones carried here.
1440
+ * Nothing else changes — an unpinned node still takes the SDK's default, and
1441
+ * a bundled version still compiles from the bundle.
1442
+ *
1443
+ * Its job is BROWNFIELD PRESERVATION. A `.flow` file holds the exact
1444
+ * definition of every node it uses, but the registry moves faster than an SDK
1445
+ * release: `uip maestro flow node add` writes
1446
+ * `uipath.human-in-the-loop.quick-form@1.6` while this SDK bundles 1.0 and
1447
+ * 1.1. `flow-decompile` copies the file's own entry into this call for each
1448
+ * such pair, so the decompiled source compiles unedited and a node you edit
1449
+ * keeps the file's version instead of moving to the SDK's.
1450
+ *
1451
+ * Each manifest must be an exact copy of one the platform served (from the
1452
+ * file's `definitions[]`, or `uip maestro flow registry get`): it names its
1453
+ * `nodeType` and `version`, and has a `display.label`. The SDK still emits
1454
+ * the node's inputs from its own factory, so a version whose inputs differ
1455
+ * from the SDK's shape needs `rawNode` instead.
1456
+ *
1457
+ * @example
1458
+ * **Keep a quick-form task at the version the file pins**
1459
+ * ```ts
1460
+ * // The .flow file's whole definitions[] entry for quick-form@1.6 (or
1461
+ * // `uip maestro flow registry get`), copied verbatim, as flow-decompile hoists it.
1462
+ * // A stub with only nodeType/version/display passes validation but breaks the canvas.
1463
+ * declare const quickFormV1_6Definition: Record<string, unknown>;
1464
+ * flow('review')
1465
+ * .definitions([quickFormV1_6Definition])
1466
+ * .step('review', hitl({ variant: 'quick-form', fields: [], outcomes: ['Submit'] }), { version: '1.6' });
1467
+ * ```
1468
+ *
1469
+ * @param manifests - Node manifests, each with its own `nodeType`, `version` and `display.label`.
1470
+ * @returns This builder, so calls chain.
1471
+ * @throws Error when a manifest is not a node manifest, or two differ for one `nodeType@version`.
1472
+ */
1473
+ definitions(manifests: readonly Record<string, unknown>[]): this;
1426
1474
  /**
1427
1475
  * Declare the flow's inputs. Read them with `input('<name>')`.
1428
1476
  *
package/dist/flow-sdk.js CHANGED
@@ -45,6 +45,7 @@ import { builtinActionSpec, builtinTriggerSpec, subscriptionFrom } from './core/
45
45
  import { checkFlowExpressions, FlowBuildError } from './flow-expr-check.js';
46
46
  import { FLOW_SCHEMA_VERSIONS } from './format-profile.js';
47
47
  import { schemaVersionRefusal } from './schema-version.js';
48
+ import { indexCarriedDefinitions } from './core/carried-definitions.js';
48
49
  export { FlowBuildError, checkFlowExpressions } from './flow-expr-check.js';
49
50
  const TYPE_NAMES = Object.values(types);
50
51
  /**
@@ -881,6 +882,7 @@ class FlowBuilder extends StepList {
881
882
  _stickyNotes;
882
883
  _version = '1.0.0';
883
884
  _schemaVersion;
885
+ _definitions = [];
884
886
  _inputs = [];
885
887
  _outputs = [];
886
888
  _vars = [];
@@ -1144,6 +1146,52 @@ class FlowBuilder extends StepList {
1144
1146
  this._schemaVersion = version;
1145
1147
  return this;
1146
1148
  }
1149
+ /**
1150
+ * Carry node definitions this SDK does not bundle, so a `{ version }` pin on
1151
+ * one of those versions compiles.
1152
+ *
1153
+ * @remarks
1154
+ * A pinned `{ version }` resolves exactly (design §2.6): first against the
1155
+ * definitions the SDK was released with, then against the ones carried here.
1156
+ * Nothing else changes — an unpinned node still takes the SDK's default, and
1157
+ * a bundled version still compiles from the bundle.
1158
+ *
1159
+ * Its job is BROWNFIELD PRESERVATION. A `.flow` file holds the exact
1160
+ * definition of every node it uses, but the registry moves faster than an SDK
1161
+ * release: `uip maestro flow node add` writes
1162
+ * `uipath.human-in-the-loop.quick-form@1.6` while this SDK bundles 1.0 and
1163
+ * 1.1. `flow-decompile` copies the file's own entry into this call for each
1164
+ * such pair, so the decompiled source compiles unedited and a node you edit
1165
+ * keeps the file's version instead of moving to the SDK's.
1166
+ *
1167
+ * Each manifest must be an exact copy of one the platform served (from the
1168
+ * file's `definitions[]`, or `uip maestro flow registry get`): it names its
1169
+ * `nodeType` and `version`, and has a `display.label`. The SDK still emits
1170
+ * the node's inputs from its own factory, so a version whose inputs differ
1171
+ * from the SDK's shape needs `rawNode` instead.
1172
+ *
1173
+ * @example
1174
+ * **Keep a quick-form task at the version the file pins**
1175
+ * ```ts
1176
+ * // The .flow file's whole definitions[] entry for quick-form@1.6 (or
1177
+ * // `uip maestro flow registry get`), copied verbatim, as flow-decompile hoists it.
1178
+ * // A stub with only nodeType/version/display passes validation but breaks the canvas.
1179
+ * declare const quickFormV1_6Definition: Record<string, unknown>;
1180
+ * flow('review')
1181
+ * .definitions([quickFormV1_6Definition])
1182
+ * .step('review', hitl({ variant: 'quick-form', fields: [], outcomes: ['Submit'] }), { version: '1.6' });
1183
+ * ```
1184
+ *
1185
+ * @param manifests - Node manifests, each with its own `nodeType`, `version` and `display.label`.
1186
+ * @returns This builder, so calls chain.
1187
+ * @throws Error when a manifest is not a node manifest, or two differ for one `nodeType@version`.
1188
+ */
1189
+ definitions(manifests) {
1190
+ const known = indexCarriedDefinitions(this._definitions, 'definitions()');
1191
+ indexCarriedDefinitions(manifests, 'definitions()', known);
1192
+ this._definitions = [...known.values()];
1193
+ return this;
1194
+ }
1147
1195
  /**
1148
1196
  * Declare the flow's inputs. Read them with `input('<name>')`.
1149
1197
  *
@@ -1234,6 +1282,7 @@ class FlowBuilder extends StepList {
1234
1282
  ...(this._stickyNotes !== undefined ? { stickyNotes: this._stickyNotes } : {}),
1235
1283
  version: this._version,
1236
1284
  ...(this._schemaVersion !== undefined ? { schemaVersion: this._schemaVersion } : {}),
1285
+ ...(this._definitions.length ? { definitions: this._definitions } : {}),
1237
1286
  inputs: this._inputs,
1238
1287
  outputs: this._outputs,
1239
1288
  vars: this._vars,
package/dist/merge.js CHANGED
@@ -142,7 +142,8 @@ export function mergeFlow(original, edited, options = {}) {
142
142
  finalNodes.push(withOriginalLayout(jsonClone(e), orig, layoutNodesOf(original)));
143
143
  if (orig && orig.type === e.type && orig.typeVersion !== e.typeVersion) {
144
144
  options.warn?.(`node ${JSON.stringify(e.id)} moved ${e.type}@${String(orig.typeVersion)} -> ${String(e.typeVersion)} `
145
- + `(the edited node takes the SDK's version; flow-builder-sdk#1167).`);
145
+ + `(the edited source does not pin ${String(orig.typeVersion)}; keep the { version } pin, `
146
+ + `with .definitions([...]) when the SDK does not bundle that version).`);
146
147
  }
147
148
  }
148
149
  }
package/dist/serialize.js CHANGED
@@ -19,7 +19,8 @@ import { planContributionBindings } from './core/contribution-bindings.js';
19
19
  import { declaredErrorPortRefusal, definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
20
20
  import { FLOW_NODE_TYPES } from './flow-node-registry.js';
21
21
  import { stepExits } from './flow-step-exits.js';
22
- import { resolveVersion } from './core/nodes/versioned.js';
22
+ import { resolveVersionCarried } from './core/nodes/versioned.js';
23
+ import { indexCarriedDefinitions } from './core/carried-definitions.js';
23
24
  import { FORM_FIELD_JSON_TYPE } from './core/form-field-type.js';
24
25
  import { connectionConnectors } from './bindings-v2.js';
25
26
  import { BindingRefusal, GUID_RE, bindingLabelRefusal, bindingMissingMessage, missingBindingLabels } from './core/binding-messages.js';
@@ -2271,8 +2272,8 @@ function declaresMemoryHandle(def) {
2271
2272
  * compiles. The corpus also carries 1.1 and 1.3; `shared/sample-flows/
2272
2273
  * inline-agent.flow` says 1.0, which appears in none of the 29.
2273
2274
  */
2274
- function inlineAgentDef(version, withMemory) {
2275
- const bundled = DEFS[`${INLINE_AGENT_TYPE}@${version}`];
2275
+ function inlineAgentDef(version, withMemory, resolve = (t, v) => DEFS[`${t}@${v}`]) {
2276
+ const bundled = resolve(INLINE_AGENT_TYPE, version);
2276
2277
  if (!bundled)
2277
2278
  return undefined;
2278
2279
  const def = jsonClone(bundled);
@@ -4240,6 +4241,17 @@ function stepNamesOf(steps, out = []) {
4240
4241
  return out;
4241
4242
  }
4242
4243
  export function serialize(built, opts = {}) {
4244
+ /**
4245
+ * Definitions the flow carries (`.definitions()`, #1128), by `type@version` —
4246
+ * the third source a pinned `{ version }` resolves from, after the bundle and
4247
+ * the node-type registry. A flow that carries nothing compiles exactly as
4248
+ * before. A subflow body sees its own carried definitions plus its
4249
+ * ancestors' (as `check` does), only while it is emitted.
4250
+ */
4251
+ let carriedDefs = indexCarriedDefinitions(built.definitions ?? [], `flow "${built.id}" .definitions()`);
4252
+ const carriedFor = Object.assign((type, version) => carriedDefs.get(`${type}@${version}`), { versions: (type) => [...carriedDefs.keys()].filter((k) => k.startsWith(`${type}@`)).map((k) => k.slice(type.length + 1)) });
4253
+ /** The exact definition of `type@version`: bundled, else carried, else `undefined`. */
4254
+ const definitionFor = (type, version) => DEFS[`${type}@${version}`] ?? carriedFor(type, version);
4243
4255
  /**
4244
4256
  * The `definitions[]` a flow carries, keyed by `type@version` — NOT by type.
4245
4257
  * One flow can legitimately hold two versions of the same family (a plain
@@ -4451,19 +4463,22 @@ export function serialize(built, opts = {}) {
4451
4463
  function makeNode(type, id, label, o = {}) {
4452
4464
  let def = o.def ?? defByType.get(type);
4453
4465
  if (o.requestedVersion !== undefined && def?.version !== o.requestedVersion) {
4454
- const exact = o.def ? undefined : DEFS[`${type}@${o.requestedVersion}`];
4466
+ const exact = o.def ? undefined : definitionFor(type, o.requestedVersion);
4455
4467
  if (!exact) {
4456
- // Name every version the SDK could have resolved: every bundled
4457
- // version of the type, else (a type built per resource, a connector)
4458
- // the definition in hand. Naming only the default sent the reader
4459
- // looking for a version that was shipped all along (#1128:
4468
+ // Name every version the SDK could have resolved: every bundled or
4469
+ // carried version of the type, else (a type built per resource, a
4470
+ // connector) the definition in hand. Naming only the default sent the
4471
+ // reader looking for a version that was shipped all along (#1128:
4460
4472
  // quick-form bundles 1.0 AND 1.1, and the message said 1.0).
4461
- const bundled = bundledVersions(type);
4462
- const resolvable = bundled.length > 0 ? bundled
4473
+ const prefix = `${type}@`;
4474
+ const carriedVersions = [...carriedDefs.keys()].filter((k) => k.startsWith(prefix)).map((k) => k.slice(prefix.length));
4475
+ const known = o.def ? [] : [...bundledVersions(type), ...carriedVersions];
4476
+ const resolvable = known.length > 0 ? known
4463
4477
  : [def?.version].filter((v) => typeof v === 'string');
4464
4478
  throw new Error(`"${label ?? id}" requests ${type}@${o.requestedVersion}, but this SDK resolves only `
4465
4479
  + `${type}@${resolvable.join(', ') || '<none>'}. Versions are exact — omit { version } to use `
4466
- + `the pinned default, or request a version this SDK ships.`);
4480
+ + `the pinned default, request a version this SDK ships, or carry that version's definition `
4481
+ + `(the .flow file's definitions[] entry) with .definitions([...]).`);
4467
4482
  }
4468
4483
  def = exact;
4469
4484
  }
@@ -4532,6 +4547,16 @@ export function serialize(built, opts = {}) {
4532
4547
  * a null. It is emitted here, always, so it cannot be forgotten.
4533
4548
  */
4534
4549
  function emitSubflowBody(child, nodeId) {
4550
+ const outer = carriedDefs;
4551
+ carriedDefs = indexCarriedDefinitions(child.definitions ?? [], `subflow "${nodeId}" .definitions()`, new Map(outer));
4552
+ try {
4553
+ return emitSubflowBodyIn(child, nodeId);
4554
+ }
4555
+ finally {
4556
+ carriedDefs = outer;
4557
+ }
4558
+ }
4559
+ function emitSubflowBodyIn(child, nodeId) {
4535
4560
  const childGlobals = emittableGlobals(child, `subflow "${nodeId}"`, 'subflow');
4536
4561
  const scope = newScope(childGlobals.outputs, childGlobals.vars, childGlobals.backing, childGlobals.backingReads);
4537
4562
  // Claim this copy's node ids UP FRONT, so the rename map is complete before
@@ -4807,7 +4832,11 @@ export function serialize(built, opts = {}) {
4807
4832
  function emitRegistered(entry, step, tails, scope, parentId) {
4808
4833
  const where = `step "${step.name}"`;
4809
4834
  const spec = step.spec;
4810
- const impl = resolveVersion(entry.type, spec, step.options?.version, where);
4835
+ // A pin the registry has no implementation for, but the flow carries, is
4836
+ // emitted at that version with the carried definition (#1128).
4837
+ const resolved = resolveVersionCarried(entry.type, spec, step.options?.version, where, carriedFor);
4838
+ const impl = resolved.impl;
4839
+ const version = resolved.version;
4811
4840
  const id = stepUid(scope, step.name);
4812
4841
  // As for every typed family: record the failure-envelope boundary before any
4813
4842
  // expression renders, so a handler reading this step resolves correctly.
@@ -4817,14 +4846,19 @@ export function serialize(built, opts = {}) {
4817
4846
  step: step.name,
4818
4847
  nodeId: id,
4819
4848
  flowId: built.id,
4820
- version: impl.version,
4849
+ version,
4821
4850
  pinnedVersion: step.options?.version,
4822
4851
  render: (value) => renderValue(value, scope.rename),
4823
4852
  renameRefs: (js) => renameRefs(js, scope.rename),
4824
4853
  stepNodeId: (name) => scope.stepNodeId.get(name) ?? name,
4825
4854
  mint: (seed) => stableId(`${built.id}:${id}:${seed}`),
4826
4855
  bind: (b) => { bound.push(b); },
4827
- definition: (typeName, version) => bundledDefinition(typeName, version),
4856
+ // At a carried version the node's own definition IS the carried one,
4857
+ // whatever version the implementation asks for (it was written for a
4858
+ // bundled one), so its defaults and outputs come from the file's entry.
4859
+ definition: (typeName, v) => (resolved.carried !== undefined && typeName === impl.typeName
4860
+ ? resolved.carried
4861
+ : bundledDefinition(typeName, v) ?? carriedFor(typeName, v)),
4828
4862
  bindings: resourceBindings,
4829
4863
  resolveBinding: (name, attribute, at) => resolveBinding(opts, name, attribute, at),
4830
4864
  bindConnection: (c) => {
@@ -4843,26 +4877,31 @@ export function serialize(built, opts = {}) {
4843
4877
  // The definition contract, both halves: a per-tenant type supplies its
4844
4878
  // definition, and a bundled type does not (its definition is the bundle's, and
4845
4879
  // makeNode records it, so the error-edge refusal and check ask the same one).
4846
- let def;
4880
+ let def = resolved.carried;
4847
4881
  if (impl.definition === 'bundled' && contribution.definition !== undefined) {
4848
- throw new Error(`internal SDK error: ${where}: bundled node type ${impl.typeName}@${impl.version} returned a definition; `
4882
+ throw new Error(`internal SDK error: ${where}: bundled node type ${impl.typeName}@${version} returned a definition; `
4849
4883
  + 'the bundle owns it — omit `definition`, or declare the type per-tenant.');
4850
4884
  }
4885
+ // A per-tenant type builds its definition from `ctx.definition(type, version)`,
4886
+ // which answers with the carried definition at a carried version, so the
4887
+ // contribution's own definition wins: it is the carried template plus this
4888
+ // instance's edits (a queue step's own resourceKey, for instance). Only a type
4889
+ // that supplies none at a carried version takes the carried definition as is.
4851
4890
  if (contribution.definition !== undefined) {
4852
- def = resolveContributionDefinition(contribution.definition, impl.version, where);
4891
+ def = resolveContributionDefinition(contribution.definition, version, where);
4853
4892
  }
4854
- else if (impl.definition === 'per-tenant') {
4855
- throw new Error(`internal SDK error: ${where}: per-tenant node type ${impl.typeName}@${impl.version} returned no definition.`);
4893
+ else if (impl.definition === 'per-tenant' && resolved.carried === undefined) {
4894
+ throw new Error(`internal SDK error: ${where}: per-tenant node type ${impl.typeName}@${version} returned no definition.`);
4856
4895
  }
4857
4896
  if (impl.definition === 'per-tenant') {
4858
4897
  const port = typeof impl.errorPort === 'function' ? impl.errorPort(spec) : impl.errorPort === true;
4859
4898
  // The declaration answers for check, which has no definition; here the
4860
4899
  // definition is in hand, and the two must agree (#1011).
4861
4900
  if (port && def !== undefined && !definitionHasErrorPort(def)) {
4862
- throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${impl.version} declares an error port, `
4901
+ throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${version} declares an error port, `
4863
4902
  + 'but the definition it supplied has no error handle and no supportsErrorHandling.');
4864
4903
  }
4865
- declaredErrorPorts.set(id, { port, typeName: impl.typeName, version: impl.version });
4904
+ declaredErrorPorts.set(id, { port, typeName: impl.typeName, version });
4866
4905
  }
4867
4906
  // A forward port is a handle the definition declares, one of the type's
4868
4907
  // author-named exits, or one the product derives (`derivesPort`: a human
@@ -4871,13 +4910,17 @@ export function serialize(built, opts = {}) {
4871
4910
  const exitPorts = new Set(exits && hasExits(exits) ? exits.map((e) => e.port) : []);
4872
4911
  for (const p of [...(contribution.port !== undefined ? [contribution.port] : []), ...(contribution.fanOut ?? []).map((f) => f.port)]) {
4873
4912
  if (exitPorts.has(p) || impl.derivesPort?.(spec, p)
4874
- || declaresForwardPort(def ?? bundledDefinition(impl.typeName, impl.version), p))
4913
+ || declaresForwardPort(def ?? bundledDefinition(impl.typeName, version), p))
4875
4914
  continue;
4876
- throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${impl.version} leaves by port "${p}", `
4915
+ throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${version} leaves by port "${p}", `
4877
4916
  + 'which its definition declares no source handle for, and the type neither lists as an exit nor derives.');
4878
4917
  }
4918
+ // A carried definition answers the error-edge refusal as a bundled one does
4919
+ // (makeNode records only the definitions it resolved itself).
4920
+ if (resolved.carried !== undefined)
4921
+ bundledNodeDefs.set(id, def ?? resolved.carried);
4879
4922
  return placeStepNode({
4880
- where, stepName: step.name, id, typeName: impl.typeName, requestedVersion: impl.version, def, contribution, bound, tails, scope, parentId,
4923
+ where, stepName: step.name, id, typeName: impl.typeName, requestedVersion: version, def, contribution, bound, tails, scope, parentId,
4881
4924
  trackOutcomes: true,
4882
4925
  });
4883
4926
  }
@@ -5041,11 +5084,12 @@ export function serialize(built, opts = {}) {
5041
5084
  // agent attaches memory keeps the handle for all of them.
5042
5085
  const withMemory = s.memory !== undefined
5043
5086
  || declaresMemoryHandle(emittedDefs.get(`${INLINE_AGENT_TYPE}@${version}`));
5044
- const def = inlineAgentDef(version, withMemory);
5087
+ const def = inlineAgentDef(version, withMemory, definitionFor);
5045
5088
  if (!def) {
5046
5089
  throw new Error(`"${step.name}" requests ${INLINE_AGENT_TYPE}@${version}, but this SDK resolves only `
5047
5090
  + `${INLINE_AGENT_VERSIONS.map((v) => `${INLINE_AGENT_TYPE}@${v}`).join(', ')}. Versions are exact — `
5048
- + `omit { version } to use the default (${INLINE_AGENT_DEFAULT_VERSION}), or request a version this SDK ships.`);
5091
+ + `omit { version } to use the default (${INLINE_AGENT_DEFAULT_VERSION}), request a version this SDK ships, `
5092
+ + `or carry that version's definition with .definitions([...]).`);
5049
5093
  }
5050
5094
  if (s.memory !== undefined && !declaresMemoryHandle(def)) {
5051
5095
  throw new Error(`"${step.name}" attaches \`memory\`, but ${INLINE_AGENT_TYPE}@${version} declares no \`memory\` handle. `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.25.1",
3
+ "version": "6.26.0",
4
4
  "description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.uipath.com/maestro",
@@ -92,5 +92,5 @@
92
92
  "@types/node": "^22.7.0",
93
93
  "esbuild": "^0.28.1"
94
94
  },
95
- "gitref": "384f76113bc43067b5ec5ea700534e9611e664ff"
95
+ "gitref": "6f62b8136efeafdce6dde0429c7d98a59a4661d2"
96
96
  }