@uipath/maestro-builder-sdk 6.17.0 → 6.17.1

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/README.md CHANGED
@@ -237,7 +237,7 @@ Work:
237
237
  `uipath.ixp.*` (`ixpExtract`)
238
238
 
239
239
  An error port (`.onError`, whose handler can rejoin the success path with
240
- `h.rejoin('step')`), per-arm labels, and switch arms with their own terminal
240
+ `h.stepToRef('step')`), per-arm labels, and switch arms with their own terminal
241
241
  outputs are constructs rather than node types.
242
242
 
243
243
  Anything that names a tenant resource — a release key, a published extraction
@@ -250,7 +250,7 @@ worked example per node type.
250
250
  - **Control flow & lifecycle** are *fluent methods* on the builder:
251
251
  `.name` · `.version` · `.input` · `.output` · `.var` · `.trigger` · `.step` ·
252
252
  `.branch` · `.switch` · `.parallel` · `.loop` · `.onError` (whose handler can
253
- end by rejoining the success path — `h.rejoin('step')`) · `.terminate` ·
253
+ end by rejoining the success path — `h.stepToRef('step')`) · `.terminate` ·
254
254
  `.return` · `.build`. Inside a `.branch` / `.switch` arm, `.label('…')` names
255
255
  that arm — the label round-trips to and from the `.flow`
256
256
  (`trueLabel` / `falseLabel` on a decision, the case `label` on a switch).
package/dist/api-index.md CHANGED
@@ -57,7 +57,7 @@ could hand you spans for a version you do not have.
57
57
  | `apiWorkflow` | function | `dist/core/actions.d.ts:2886-2920` | 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:1049-1080` | Option shapes | 5 field(s) |
59
59
  | `AppRef` | interface | `dist/core/actions.d.ts:506-551` | 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:1135-1158` | 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:1136-1159` | 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:354-364` | Supporting types | A value the reviewer FILLS IN: read downstream with `out('<step>', '<id>')`. |
62
62
  | `batchTransform` | function | `dist/core/actions.d.ts:2689-2723` | Actions | Add AI-generated columns to a CSV — the platform's **Batch transform** node, `uipath.pattern.batch-transform` (service… |
63
63
  | `BatchTransformInputs` | interface | `dist/core/actions.d.ts:846-861` | Option shapes | 4 field(s) |
@@ -118,7 +118,7 @@ could hand you spans for a version you do not have.
118
118
  | `endCall` | function | `dist/core/actions.d.ts:3014-3021` | Actions | Hang up (`uipath.conversational.voice.end-call`). |
119
119
  | `EndCallInputs` | interface | `dist/core/actions.d.ts:741-748` | Option shapes | 1 field(s) |
120
120
  | `entryInput` | function | `dist/core/expr.d.ts:62-72` | Expressions and types | Reference an ENTRY POINT's scoped input: `entryInput('nightly', 'batchDate')` reads `$vars.nightly.output.batchDate` —… |
121
- | `err` | function | `dist/core/expr.d.ts:153-240` | Expressions and types | Reference a FAILED step's error → `$vars.<step>.error[.<field>]`. |
121
+ | `err` | function | `dist/core/expr.d.ts:153-246` | Expressions and types | Reference a FAILED step's error → `$vars.<step>.error[.<field>]`. |
122
122
  | `ErrorEnvelopeField` | type | `dist/core/expr.d.ts:142-152` | Supporting types | The fields a failure envelope carries. |
123
123
  | `EscalationRef` | interface | `dist/core/actions.d.ts:1979-2045` | Supporting types | One escalation an inline agent may raise — an Action Center app task a human completes (the `coded-action-app` variant,… |
124
124
  | `EventFilter` | type | `dist/core/actions.d.ts:3436-3477` | Supporting types | One filter condition on the event payload. |
@@ -128,10 +128,10 @@ could hand you spans for a version you do not have.
128
128
  | `FilterCondition` | type | `dist/core/actions.d.ts:233-234` | Supporting types | Comparison a filter rule applies to a field. |
129
129
  | `FilterMatch` | type | `dist/core/actions.d.ts:231-232` | Supporting types | How a filter combines its rules: every rule must match, or any one. |
130
130
  | `FilterRule` | interface | `dist/core/actions.d.ts:235-247` | Supporting types | 3 field(s) |
131
- | `flow` | function | `dist/flow-sdk.d.ts:1429-1444` | Flow construction | Start building a flow with the given id. |
131
+ | `flow` | function | `dist/flow-sdk.d.ts:1430-1445` | Flow construction | Start building a flow with the given id. |
132
132
  | `FlowAction` | class | `dist/core/node-classes.d.ts:158-164` | Supporting types | A node placed as a step — pass an instance to `.step(name, …)`. |
133
133
  | `FlowActionSpec` | type | `dist/flow-sdk.d.ts:41-42` | Supporting types | What `.step()` accepts here: the shared actions plus this SDK's subflow. |
134
- | `FlowBuilder` | class | `dist/flow-sdk.d.ts:1159-1428` | Builders | 13 member(s) |
134
+ | `FlowBuilder` | class | `dist/flow-sdk.d.ts:1160-1429` | Builders | 13 member(s) |
135
135
  | `FlowLayout` | interface | `dist/flow-sdk.d.ts:649-662` | Supporting types | Designer layout for a flow, keyed by AUTHOR-level ids: node entries by step name (plus the trigger id and `end`), edge… |
136
136
  | `FlowNode` | class | `dist/core/node-classes.d.ts:122-157` | Supporting types | The abstract root of every definition-backed node the builder can place. |
137
137
  | `FlowResource` | class | `dist/core/node-classes.d.ts:172-179` | Supporting types | A node attached to another semantic node — an inline agent's tool, context, memory, or escalation. |
@@ -166,7 +166,7 @@ could hand you spans for a version you do not have.
166
166
  | `ixpExtract` | function | `dist/core/actions.d.ts:2724-2778` | Actions | Extract fields from a document with a published IxP project — the platform's **Extract** node (`uipath.ixp.*`, service… |
167
167
  | `IxpExtractInputs` | interface | `dist/core/actions.d.ts:879-953` | Option shapes | 9 field(s) |
168
168
  | `IxpToolRef` | interface | `dist/core/actions.d.ts:1940-1978` | Supporting types | A published IxP (Intelligent eXtraction Platform) project as a tool — the agent decides when to extract a document and… |
169
- | `js` | function | `dist/core/expr.d.ts:241-276` | Expressions and types | Build a raw JS *expression* (a condition or computation). |
169
+ | `js` | function | `dist/core/expr.d.ts:247-282` | Expressions and types | Build a raw JS *expression* (a condition or computation). |
170
170
  | `lit` | function | `dist/core/expr.d.ts:22-28` | Expressions and types | A constant value baked directly into a node input. |
171
171
  | `lookup` | function | `dist/core/lookups.d.ts:95-102` | Generated descriptors | Begin resolving a lookup field on a generated descriptor. |
172
172
  | `lookup` | function | `dist/core/lookups.d.ts:103-122` | Generated descriptors | Begin resolving a lookup field addressed by connector key and action. |
@@ -224,16 +224,16 @@ could hand you spans for a version you do not have.
224
224
  | `SendMessageInputs` | interface | `dist/core/actions.d.ts:624-643` | Option shapes | 4 field(s) |
225
225
  | `ShownField` | interface | `dist/core/actions.d.ts:338-353` | Supporting types | A value the reviewer READS: shown on the form, filled in from the flow. |
226
226
  | `Step` | type | `dist/flow-sdk.d.ts:460-571` | Supporting types | |
227
- | `StepList` | class | `dist/flow-sdk.d.ts:712-1134` | Builders | Collects a sequence of steps. |
227
+ | `StepList` | class | `dist/flow-sdk.d.ts:712-1135` | Builders | Collects a sequence of steps. |
228
228
  | `STICKY_NOTE_COLORS` | const | `dist/flow-sdk.d.ts:602-607` | Flow construction | The designer's sticky-note palette. |
229
229
  | `StickyNote` | interface | `dist/flow-sdk.d.ts:614-648` | Supporting types | A canvas sticky note — free text pinned to the diagram, for the humans reading it. |
230
230
  | `StickyNoteColor` | type | `dist/flow-sdk.d.ts:608-613` | Supporting types | A sticky note's swatch. |
231
- | `subflow` | function | `dist/flow-sdk.d.ts:1445-1484` | Flow construction | Run another flow as one step, and read back what it returns. |
231
+ | `subflow` | function | `dist/flow-sdk.d.ts:1446-1485` | Flow construction | Run another flow as one step, and read back what it returns. |
232
232
  | `SubflowSpec` | interface | `dist/flow-sdk.d.ts:33-40` | Supporting types | A step that runs a child flow. |
233
233
  | `summarize` | function | `dist/core/actions.d.ts:2648-2688` | Actions | Summarize a document with citations — the platform's **Summarize** node. |
234
234
  | `SummarizeInputs` | interface | `dist/core/actions.d.ts:806-838` | Option shapes | 3 field(s) |
235
235
  | `SwitchArm` | interface | `dist/flow-sdk.d.ts:329-334` | Supporting types | One arm of a built `.switch` (the serializer's view: body already collected). |
236
- | `tmpl` | function | `dist/core/expr.d.ts:277-287` | Expressions and types | Build a JS *string template* (for URLs, messages, etc.). |
236
+ | `tmpl` | function | `dist/core/expr.d.ts:283-293` | Expressions and types | Build a JS *string template* (for URLs, messages, etc.). |
237
237
  | `ToolRef` | type | `dist/core/actions.d.ts:1706-1715` | Supporting types | One tool on an inline agent — a discriminated union over the kinds the tenant's registry actually serves… |
238
238
  | `transform` | function | `dist/core/actions.d.ts:2550-2595` | Actions | Declare a Transform action — a chain of declarative operations over a collection. |
239
239
  | `Transformation` | type | `dist/core/actions.d.ts:248-249` | Supporting types | What a map does to a field's value. |
@@ -245,8 +245,8 @@ could hand you spans for a version you do not have.
245
245
  | `TriggerMeta` | interface | `dist/core/connectors.d.ts:120-129` | Generated descriptors | Runtime metadata a generated trigger descriptor carries. |
246
246
  | `TriggerOptions` | interface | `dist/core/actions.d.ts:3478-3525` | Option shapes | The typed `onEvent`/`waitForEvent` options — everything an EventSubscription carries except `connector`/`event`, which… |
247
247
  | `TriggerSpec` | type | `dist/flow-sdk.d.ts:150-168` | Supporting types | What starts the flow. |
248
- | `TypeDesc` | type | `dist/core/expr.d.ts:379` | Supporting types | |
249
- | `types` | const | `dist/core/expr.d.ts:363-378` | Expressions and types | Variable type descriptors (map to Flow variable `type` values). |
248
+ | `TypeDesc` | type | `dist/core/expr.d.ts:385` | Supporting types | |
249
+ | `types` | const | `dist/core/expr.d.ts:369-384` | Expressions and types | Variable type descriptors (map to Flow variable `type` values). |
250
250
  | `unresolvedLookupMessage` | function | `dist/core/lookups.d.ts:180-189` | Generated descriptors | The message for a lookup nothing has resolved — the command that fixes it. |
251
251
  | `v` | function | `dist/core/expr.d.ts:29-41` | Expressions and types | Reference a flow variable or output by name → `$vars.<name>`. |
252
252
  | `VarDecl` | interface | `dist/flow-sdk.d.ts:47-59` | Supporting types | 7 field(s) |
@@ -338,7 +338,7 @@ could hand you spans for a version you do not have.
338
338
  | `TriggerDescriptor` | type | `dist/core/connectors.d.ts:130-138` | Supporting types | A generated, typed connector-trigger descriptor: TriggerMeta branded with phantom `where`/output types. |
339
339
  | `TriggerMeta` | interface | `dist/core/connectors.d.ts:120-129` | Supporting types | Runtime metadata a generated trigger descriptor carries. |
340
340
  | `TriggerOptions` | interface | `dist/core/actions.d.ts:3478-3525` | Option shapes | The typed `onEvent`/`waitForEvent` options — everything an EventSubscription carries except `connector`/`event`, which… |
341
- | `TypeDesc` | type | `dist/core/expr.d.ts:379` | Supporting types | |
341
+ | `TypeDesc` | type | `dist/core/expr.d.ts:385` | Supporting types | |
342
342
  | `UnresolvedReferenceTaskKind` | type | `dist/case/case-sdk.d.ts:358-359` | Supporting types | Published-resource task kinds that the Case schema permits as unresolved skeletons. |
343
343
  | `WaitConnectorPlaceholderSpec` | interface | `dist/case/case-sdk.d.ts:360-370` | Supporting types | A `wait-for-connector` subscription: suspend on an Integration Service event. |
344
344
  | `WaitConnectorSpec` | type | `dist/case/case-sdk.d.ts:371-375` | Supporting types | A placeholder connector/operation pair, or a library-resolved event subscription using the same symbolic shape as Flow… |
@@ -437,7 +437,7 @@ could hand you spans for a version you do not have.
437
437
  | `TimerLike` | type | `dist/bpmn/bpmn-sdk.d.ts:40-41` | Supporting types | A timer as an ISO-8601 duration string (shorthand for `{ duration }`) or a full spec. |
438
438
  | `TimerSpec` | interface | `dist/bpmn/bpmn-sdk.d.ts:31-39` | Supporting types | ISO-8601 timer specification (one of duration / date / cycle). |
439
439
  | `TypedContextRow` | interface | `dist/bpmn/typed-node.d.ts:155-186` | Supporting types | One `uipath:context` input row, spelled out. |
440
- | `TypeDesc` | type | `dist/core/expr.d.ts:379` | Supporting types | |
440
+ | `TypeDesc` | type | `dist/core/expr.d.ts:385` | Supporting types | |
441
441
  | `TypedInputRow` | interface | `dist/bpmn/typed-node.d.ts:187-209` | Supporting types | One `uipath:input` payload row spelled out — the `separateInputs` counterpart of TypedContextRow. |
442
442
  | `TypedOutputRow` | interface | `dist/bpmn/typed-node.d.ts:246-285` | Supporting types | 9 field(s) |
443
443
  | `VarDirection` | type | `dist/bpmn/bpmn-sdk.d.ts:361-365` | Supporting types | How a variable is exposed: `'input'` (read-only entry input), `'output'` (a return value), or `'inputOutput'` (a mutable… |
@@ -63,7 +63,7 @@ not find it either.
63
63
  | `app` | property | `HumanTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1337-1338` |
64
64
  | `appSystemName` | property | `AppRef` | `dist/core/actions.d.ts:536-541` |
65
65
  | `appVersion` | property | `HumanTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1339-1340` |
66
- | `armLabel` | property | `ArmBuilder` | `dist/flow-sdk.d.ts:1147` |
66
+ | `armLabel` | property | `ArmBuilder` | `dist/flow-sdk.d.ts:1148` |
67
67
  | `assignee` | property | `HitlRecipient` | `dist/core/actions.d.ts:426-437` |
68
68
  | `async` | property | `OrchestratorAsyncOpts` | `dist/bpmn/bpmn-sdk.d.ts:1281-1285` |
69
69
  | `atRiskPercentage` | property | `EscalationOpts` | `dist/case/case-sdk.d.ts:132-137` |
@@ -93,14 +93,14 @@ not find it either.
93
93
  | `body` | property | `TypedContextRow` | `dist/bpmn/typed-node.d.ts:176-181` |
94
94
  | `body` | property | `TypedInputRow` | `dist/bpmn/typed-node.d.ts:207-208` |
95
95
  | `boundaryEvent` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2239-2246` |
96
- | `branch` | method | `StepList` | `dist/flow-sdk.d.ts:908-926` |
96
+ | `branch` | method | `StepList` | `dist/flow-sdk.d.ts:909-927` |
97
97
  | `branches` | property | `HttpInputsBase` | `dist/core/actions.d.ts:31-36` |
98
- | `break` | method | `StepList` | `dist/flow-sdk.d.ts:1034-1043` |
98
+ | `break` | method | `StepList` | `dist/flow-sdk.d.ts:1035-1044` |
99
99
  | `breakEnabled` | property | `DoWhileOptions` | `dist/flow-sdk.d.ts:457-458` |
100
100
  | `breakEnabled` | property | `LoopOptions` | `dist/flow-sdk.d.ts:444-448` |
101
101
  | `build` | method | `BpmnBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3483-3488` |
102
102
  | `build` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1269-1274` |
103
- | `build` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1421-1427` |
103
+ | `build` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1422-1428` |
104
104
  | `businessRule` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2527-2573` |
105
105
  | `by` | property | `LookupResolution` | `dist/core/lookups.d.ts:164` |
106
106
  | `by` | property | `LookupSpec` | `dist/core/lookups.d.ts:27-28` |
@@ -209,7 +209,7 @@ not find it either.
209
209
  | `description` | property | `CustomGuardrail` | `dist/core/actions.d.ts:1393` |
210
210
  | `description` | property | `EscalationRef` | `dist/core/actions.d.ts:1987-1988` |
211
211
  | `description` | property | `EventTriggerOpts` | `dist/case/case-sdk.d.ts:241` |
212
- | `description` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1183-1190` |
212
+ | `description` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1184-1191` |
213
213
  | `description` | property | `HttpRequestToolRef` | `dist/core/actions.d.ts:1792` |
214
214
  | `description` | property | `IxpExtractInputs` | `dist/core/actions.d.ts:945-952` |
215
215
  | `description` | property | `IxpToolRef` | `dist/core/actions.d.ts:1965-1966` |
@@ -250,7 +250,7 @@ not find it either.
250
250
  | `displayName` | property | `TriggerMeta` | `dist/core/connectors.d.ts:127-128` |
251
251
  | `document` | property | `HitlInputs` | `dist/core/actions.d.ts:618-622` |
252
252
  | `documentId` | property | `DocValidationInputs` | `dist/core/actions.d.ts:458-459` |
253
- | `doWhile` | method | `StepList` | `dist/flow-sdk.d.ts:1009-1033` |
253
+ | `doWhile` | method | `StepList` | `dist/flow-sdk.d.ts:1010-1034` |
254
254
  | `dueDate` | property | `QueueItemInputs` | `dist/core/actions.d.ts:2122-2123` |
255
255
  | `duration` | property | `TimerSpec` | `dist/bpmn/bpmn-sdk.d.ts:33-34` |
256
256
  | `dynamicFewShotLearning` | property | `AgentMemoryRef` | `dist/core/actions.d.ts:1828-1829` |
@@ -272,7 +272,7 @@ not find it either.
272
272
  | `entity` | property | `DataServiceOpts` | `dist/bpmn/bpmn-sdk.d.ts:1090-1091` |
273
273
  | `entry` | property | `BuiltStage` | `dist/case/case-sdk.d.ts:528` |
274
274
  | `entry` | property | `BuiltTask` | `dist/case/case-sdk.d.ts:520` |
275
- | `entryPoint` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1247-1297` |
275
+ | `entryPoint` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1248-1298` |
276
276
  | `entryPointId` | property | `ProcessMetadata` | `dist/bpmn/bpmn-sdk.d.ts:534-539` |
277
277
  | `entryPoints` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:702-703` |
278
278
  | `entryWhen` | method | `StageBuilder` | `dist/case/case-sdk.d.ts:1004-1011` |
@@ -438,7 +438,7 @@ not find it either.
438
438
  | `inclusive` | property | `ChooseOpts` | `dist/bpmn/bpmn-sdk.d.ts:1820-1824` |
439
439
  | `inclusiveGateway` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2266-2273` |
440
440
  | `input` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1160-1185` |
441
- | `input` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1372-1384` |
441
+ | `input` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1373-1385` |
442
442
  | `input` | property | `HumanTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1355-1356` |
443
443
  | `input` | property | `OrchestratorOpts` | `dist/bpmn/bpmn-sdk.d.ts:1241-1242` |
444
444
  | `input` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3068-3076` |
@@ -510,7 +510,7 @@ not find it either.
510
510
  | `kind` | property | `SubflowSpec` | `dist/flow-sdk.d.ts:35` |
511
511
  | `kind` | property | `WhenExpression` | `dist/case/case-sdk.d.ts:99-100` |
512
512
  | `kValue` | property | `AgentMemoryRef` | `dist/core/actions.d.ts:1832-1833` |
513
- | `label` | method | `ArmBuilder` | `dist/flow-sdk.d.ts:1148-1157` |
513
+ | `label` | method | `ArmBuilder` | `dist/flow-sdk.d.ts:1149-1158` |
514
514
  | `label` | property | `AskedField` | `dist/core/actions.d.ts:358-359` |
515
515
  | `label` | property | `BuiltStage` | `dist/case/case-sdk.d.ts:523` |
516
516
  | `label` | property | `InOutField` | `dist/core/actions.d.ts:374-375` |
@@ -524,7 +524,7 @@ not find it either.
524
524
  | `layout` | property | `BuiltCase` | `dist/case/case-sdk.d.ts:646-647` |
525
525
  | `layout` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:698-699` |
526
526
  | `layout` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1139-1159` |
527
- | `layout` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1191-1201` |
527
+ | `layout` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1192-1202` |
528
528
  | `limit` | property | `DataFabricReadInputs` | `dist/core/actions.d.ts:2243-2248` |
529
529
  | `limit` | property | `DoWhileOptions` | `dist/flow-sdk.d.ts:455-456` |
530
530
  | `literal` | property | `Expr` | `dist/core/expr.d.ts:18` |
@@ -534,7 +534,7 @@ not find it either.
534
534
  | `lookups` | property | `ConnectorMeta` | `dist/core/connectors.d.ts:76-87` |
535
535
  | `loop` | property | `ActivityNodeFields` | `dist/bpmn/bpmn-sdk.d.ts:335-336` |
536
536
  | `loop` | property | `ActivityOpts` | `dist/bpmn/bpmn-sdk.d.ts:832-833` |
537
- | `loop` | method | `StepList` | `dist/flow-sdk.d.ts:997-1008` |
537
+ | `loop` | method | `StepList` | `dist/flow-sdk.d.ts:998-1009` |
538
538
  | `managed` | property | `HttpInputsBase` | `dist/core/actions.d.ts:43-73` |
539
539
  | `marksCaseComplete` | property | `BuiltCaseExitCondition` | `dist/case/case-sdk.d.ts:354` |
540
540
  | `marksStageComplete` | property | `BuiltExitCondition` | `dist/case/case-sdk.d.ts:321` |
@@ -622,7 +622,7 @@ not find it either.
622
622
  | `name` | property | `EventSubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:1840-1841` |
623
623
  | `name` | property | `EventTriggerOpts` | `dist/case/case-sdk.d.ts:240` |
624
624
  | `name` | property | `ExternalTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1499-1500` |
625
- | `name` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1175-1182` |
625
+ | `name` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1176-1183` |
626
626
  | `name` | property | `FlowOpts` | `dist/bpmn/bpmn-sdk.d.ts:1637-1638` |
627
627
  | `name` | property | `GatewayOpts` | `dist/bpmn/bpmn-sdk.d.ts:760-761` |
628
628
  | `name` | property | `HandlerOpts` | `dist/bpmn/bpmn-sdk.d.ts:1735-1736` |
@@ -684,7 +684,7 @@ not find it either.
684
684
  | `onError` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3259-3266` |
685
685
  | `onError` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3267-3274` |
686
686
  | `onError` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3275-3283` |
687
- | `onError` | method | `StepList` | `dist/flow-sdk.d.ts:800-861` |
687
+ | `onError` | method | `StepList` | `dist/flow-sdk.d.ts:800-862` |
688
688
  | `onMessage` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3302-3310` |
689
689
  | `onMessage` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3311-3319` |
690
690
  | `onTimer` | method | `ActivityBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3284-3292` |
@@ -702,7 +702,7 @@ not find it either.
702
702
  | `outcomes` | property | `EscalationRef` | `dist/core/actions.d.ts:2033-2038` |
703
703
  | `outcomes` | property | `HitlInputs` | `dist/core/actions.d.ts:577-591` |
704
704
  | `output` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1186-1198` |
705
- | `output` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1385-1410` |
705
+ | `output` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1386-1411` |
706
706
  | `output` | property | `RegistryTypeSpec` | `dist/bpmn/typed-node.d.ts:90` |
707
707
  | `output` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3077-3085` |
708
708
  | `outputColumns` | property | `BatchTransformInputs` | `dist/core/actions.d.ts:854-858` |
@@ -738,7 +738,7 @@ not find it either.
738
738
  | `pageRange` | property | `DynamicExtractInputs` | `dist/core/actions.d.ts:2407-2408` |
739
739
  | `pageRange` | property | `IxpExtractInputs` | `dist/core/actions.d.ts:934-935` |
740
740
  | `parallel` | property | `LoopOptions` | `dist/flow-sdk.d.ts:437-438` |
741
- | `parallel` | method | `StepList` | `dist/flow-sdk.d.ts:961-996` |
741
+ | `parallel` | method | `StepList` | `dist/flow-sdk.d.ts:962-997` |
742
742
  | `parallelGateway` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:2256-2265` |
743
743
  | `parameters` | property | `ConnectorEventOpts` | `dist/bpmn/bpmn-sdk.d.ts:1479-1480` |
744
744
  | `parameters` | property | `HttpOpts` | `dist/bpmn/bpmn-sdk.d.ts:1140-1145` |
@@ -835,7 +835,7 @@ not find it either.
835
835
  | `retry` | property | `ActivityOpts` | `dist/bpmn/bpmn-sdk.d.ts:830-831` |
836
836
  | `retryable` | property | `ErrorMappingRow` | `dist/bpmn/bpmn-sdk.d.ts:308-309` |
837
837
  | `retryCount` | property | `HttpInputsBase` | `dist/core/actions.d.ts:115-129` |
838
- | `return` | method | `StepList` | `dist/flow-sdk.d.ts:1124-1133` |
838
+ | `return` | method | `StepList` | `dist/flow-sdk.d.ts:1125-1134` |
839
839
  | `returnCitations` | property | `SummarizeInputs` | `dist/core/actions.d.ts:832-837` |
840
840
  | `returns` | property | `AgentInputs` | `dist/core/actions.d.ts:1279-1298` |
841
841
  | `returns` | property | `ApiWorkflowInputs` | `dist/core/actions.d.ts:1067-1079` |
@@ -875,7 +875,7 @@ not find it either.
875
875
  | `schemaVersion` | method | `BpmnBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3375-3404` |
876
876
  | `schemaVersion` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:682-688` |
877
877
  | `schemaVersion` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1068-1094` |
878
- | `schemaVersion` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1332-1371` |
878
+ | `schemaVersion` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1333-1372` |
879
879
  | `scope` | property | `EscalationRecipient` | `dist/case/case-sdk.d.ts:121` |
880
880
  | `scopes` | property | `GuardrailSelector` | `dist/core/actions.d.ts:1339` |
881
881
  | `script` | property | `ScriptTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:846-862` |
@@ -950,11 +950,11 @@ not find it either.
950
950
  | `steps` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:692` |
951
951
  | `steps` | property | `StepList` | `dist/flow-sdk.d.ts:714` |
952
952
  | `stepSwitch` | method | `StepList` | `dist/flow-sdk.d.ts:757-799` |
953
- | `stepToList` | method | `StepList` | `dist/flow-sdk.d.ts:875-899` |
954
- | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1075-1103` |
955
- | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1104-1123` |
953
+ | `stepToList` | method | `StepList` | `dist/flow-sdk.d.ts:876-900` |
954
+ | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1076-1104` |
955
+ | `stepToRef` | method | `StepList` | `dist/flow-sdk.d.ts:1105-1124` |
956
956
  | `stickyNotes` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:700-701` |
957
- | `stickyNotes` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1202-1227` |
957
+ | `stickyNotes` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1203-1228` |
958
958
  | `storageBucket` | property | `DocValidationInputs` | `dist/core/actions.d.ts:456-457` |
959
959
  | `strategy` | property | `LookupSpec` | `dist/core/lookups.d.ts:33` |
960
960
  | `style` | property | `CaseNodeLayout` | `dist/case/case-sdk.d.ts:597-598` |
@@ -966,7 +966,7 @@ not find it either.
966
966
  | `subType` | property | `VarOpts` | `dist/bpmn/bpmn-sdk.d.ts:1709-1714` |
967
967
  | `subType` | property | `VarSpec` | `dist/flow-sdk.d.ts:72-73` |
968
968
  | `summary` | property | `CaseAppConfig` | `dist/case/case-sdk.d.ts:585-586` |
969
- | `switch` | method | `StepList` | `dist/flow-sdk.d.ts:927-960` |
969
+ | `switch` | method | `StepList` | `dist/flow-sdk.d.ts:928-961` |
970
970
  | `systemPrompt` | property | `ConversationalAgentInputs` | `dist/core/actions.d.ts:686-691` |
971
971
  | `systemPrompt` | property | `InlineAgentInputs` | `dist/core/actions.d.ts:1452-1501` |
972
972
  | `systemPrompt` | property | `VoiceAgentInputs` | `dist/core/actions.d.ts:773-778` |
@@ -991,7 +991,7 @@ not find it either.
991
991
  | `temperature` | property | `InlineAgentInputs` | `dist/core/actions.d.ts:1562-1563` |
992
992
  | `temperature` | property | `VoiceSettings` | `dist/core/actions.d.ts:765-766` |
993
993
  | `terminate` | property | `EndOpts` | `dist/bpmn/bpmn-sdk.d.ts:692-693` |
994
- | `terminate` | method | `StepList` | `dist/flow-sdk.d.ts:1044-1074` |
994
+ | `terminate` | method | `StepList` | `dist/flow-sdk.d.ts:1045-1075` |
995
995
  | `threshold` | property | `ContextIndexRef` | `dist/core/actions.d.ts:2076-2077` |
996
996
  | `timeCycle` | property | `BuiltTrigger` | `dist/case/case-sdk.d.ts:201-202` |
997
997
  | `timeout` | property | `HttpInputsBase` | `dist/core/actions.d.ts:97-114` |
@@ -1014,11 +1014,11 @@ not find it either.
1014
1014
  | `trigger` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:693-695` |
1015
1015
  | `trigger` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1224-1232` |
1016
1016
  | `trigger` | property | `EscalationOpts` | `dist/case/case-sdk.d.ts:128-129` |
1017
- | `trigger` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1228-1246` |
1017
+ | `trigger` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1229-1247` |
1018
1018
  | `trigger` | property | `StartOpts` | `dist/bpmn/bpmn-sdk.d.ts:624-671` |
1019
1019
  | `triggeredByEvent` | property | `SubProcessOpts` | `dist/bpmn/bpmn-sdk.d.ts:976-977` |
1020
1020
  | `triggerId` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:704-710` |
1021
- | `triggerId` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1298-1317` |
1021
+ | `triggerId` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1299-1318` |
1022
1022
  | `triggerOptions` | property | `BuiltFlow` | `dist/flow-sdk.d.ts:696-697` |
1023
1023
  | `triggers` | property | `BuiltCase` | `dist/case/case-sdk.d.ts:644-645` |
1024
1024
  | `triggers` | property | `CaseLayout` | `dist/case/case-sdk.d.ts:620-621` |
@@ -1074,7 +1074,7 @@ not find it either.
1074
1074
  | `value` | property | `TypedInputRow` | `dist/bpmn/typed-node.d.ts:205-206` |
1075
1075
  | `values` | property | `DataFabricCreateInputs` | `dist/core/actions.d.ts:2280-2285` |
1076
1076
  | `var` | method | `CaseBuilder` | `dist/case/case-sdk.d.ts:1199-1223` |
1077
- | `var` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1411-1420` |
1077
+ | `var` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1412-1421` |
1078
1078
  | `var` | method | `ScopeBuilder` | `dist/bpmn/bpmn-sdk.d.ts:3059-3067` |
1079
1079
  | `var` | property | `TaskOutputBinding` | `dist/case/case-sdk.d.ts:494-495` |
1080
1080
  | `var` | property | `TypedOutputRow` | `dist/bpmn/typed-node.d.ts:251-252` |
@@ -1097,7 +1097,7 @@ not find it either.
1097
1097
  | `version` | property | `ConnectorToolRef` | `dist/core/actions.d.ts:1870-1871` |
1098
1098
  | `version` | property | `EventSubscription` | `dist/core/actions.d.ts:3566` |
1099
1099
  | `version` | property | `ExternalTaskOpts` | `dist/bpmn/bpmn-sdk.d.ts:1507-1508` |
1100
- | `version` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1318-1331` |
1100
+ | `version` | method | `FlowBuilder` | `dist/flow-sdk.d.ts:1319-1332` |
1101
1101
  | `version` | property | `NodeOptions` | `dist/flow-sdk.d.ts:354-361` |
1102
1102
  | `version` | property | `TriggerMeta` | `dist/core/connectors.d.ts:126` |
1103
1103
  | `version` | property | `TriggerOptions` | `dist/core/actions.d.ts:3523-3524` |
package/dist/check-cli.js CHANGED
@@ -9,9 +9,8 @@ import { reportDiagnostics } from './cli-result.js';
9
9
  import { defaultBindingsFile } from './workdir.js';
10
10
  import { resolveFlowFile, loadBuiltFlow } from './load.js';
11
11
  import { check } from './check.js';
12
- import { connectorCheckOpts, openCliLibrary } from './core/cli-library.js';
12
+ import { flowCheckOpts, openCliLibrary } from './cli-library.js';
13
13
  import { Bindings } from './bindings.js';
14
- import { connectorInputErrors } from './serialize.js';
15
14
  import { runWhenInvokedDirectly } from './cli-run.js';
16
15
  import { ensureTypeScriptRuntime } from './node-runtime.js';
17
16
  /** Flags that take a value, so the value is never read as the source argument. */
@@ -36,34 +35,7 @@ function checkOpts(argv) {
36
35
  // The overlay matters here as much as it does for compile: `resolutions.json`
37
36
  // lives in it, and without it every already-resolved lookup would be reported
38
37
  // as still owed — telling the author to re-run a `prepare` they already ran.
39
- const library = openCliLibrary(argv);
40
- // The connector and event hooks are the shared bag every family fills
41
- // (`core/cli-library.ts`); what Flow adds is the one hook only it has a site for.
42
- const shared = connectorCheckOpts(library, bindings);
43
- if (!library)
44
- return shared;
45
- return {
46
- ...shared,
47
- listEnvelope: (connector, operation, version, object) => {
48
- try {
49
- return library.resolve(connector, operation, version, object).listEnvelope;
50
- }
51
- catch {
52
- return undefined;
53
- }
54
- },
55
- // The field contract compile enforces, from the same validator: an operation
56
- // the library cannot resolve is compile's business (it names the entry).
57
- connectorInputs: (spec, inputs) => {
58
- try {
59
- const rc = library.resolve(spec.key, spec.action, spec.version, spec.object);
60
- return connectorInputErrors(rc, inputs, library.lookupResolutions ?? {}, library.lookupSpecs(spec.key, spec.action, spec.version, spec.object) ?? {});
61
- }
62
- catch {
63
- return undefined;
64
- }
65
- },
66
- };
38
+ return flowCheckOpts(openCliLibrary(argv), bindings);
67
39
  }
68
40
  export async function run(argv) {
69
41
  const arg = argv.find((a, i) => !a.startsWith('--') && !VALUE_FLAGS.has(argv[i - 1])) ?? argv[0];
package/dist/check.js CHANGED
@@ -8,6 +8,7 @@
8
8
  import { Expr, SCHEDULE_PRESETS, DELAY_PRESETS, VARIANT_OPERATION, parseIxpProjectType, flatNameOf, flatNameSegmentsOf, FLAT_SEP } from './flow-sdk.js';
9
9
  import { FlowNode } from './core/node-classes.js';
10
10
  import { planContributionBindings } from './core/contribution-bindings.js';
11
+ import { definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
11
12
  import { resolveContributionDefinition } from './serialize.js';
12
13
  import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
13
14
  import { AGENTIC_PROCESS_FORMS } from './core/agentic-process-forms.js';
@@ -257,7 +258,7 @@ function checkFlow(built, ancestors, opts = {}) {
257
258
  stepNames.add(s.name);
258
259
  declared.add(s.name); // a step's output is referenceable by name
259
260
  }
260
- if (s.kind === 'stepToList' && s.port === 'error')
261
+ if ((s.kind === 'stepToList' || s.kind === 'stepToRef') && s.port === 'error')
261
262
  checkOnError(s, prevPortSource, diags);
262
263
  if ((s.kind === 'stepToList' || s.kind === 'stepToRef') && s.port.startsWith('branch-')) {
263
264
  const want = s.port.slice('branch-'.length);
@@ -5341,7 +5342,7 @@ function checkOnError(_handler, step, diags) {
5341
5342
  // A `.loop()` CONTAINER is fine: `core.logic.loop` declares the error handle at
5342
5343
  // both bundled versions, and a measured run routed a body failure to it — the
5343
5344
  // container's envelope carried the body's message in `detail` and the failing
5344
- // body step's id in `element`.
5345
+ // body step's label in `element`.
5345
5346
  if (step.kind === 'loop')
5346
5347
  return;
5347
5348
  // `.doWhile()` is not. `core.logic.dowhile@1.0` declares an error VARIABLE and
@@ -5350,12 +5351,38 @@ function checkOnError(_handler, step, diags) {
5350
5351
  // declare that handle". The builder refuses this too; this catches a
5351
5352
  // hand-built flow and says the same thing.
5352
5353
  if (step.kind === 'doWhile') {
5354
+ diags.push(doWhileOnErrorRefusal(step.name));
5355
+ return;
5356
+ }
5357
+ // A custom FlowAction or rawNode has no `kind`: ask its DEFINITION, with the
5358
+ // product's own rule (definitionHasErrorPort), not the kind list (#943).
5359
+ const maybeCustom = step.spec;
5360
+ if (!('kind' in maybeCustom) && maybeCustom instanceof FlowNode) {
5361
+ let def;
5362
+ try {
5363
+ const requestedVersion = step.options?.version;
5364
+ def = resolveContributionDefinition(maybeCustom.contribute(requestedVersion !== undefined ? { requestedVersion } : {}).definition, requestedVersion, `step "${step.name}"`);
5365
+ }
5366
+ catch {
5367
+ // checkContribution already reports a contribution compile cannot lower.
5368
+ return;
5369
+ }
5370
+ // A custom node backed by a typed family's bundled definition gets that
5371
+ // family's refusals: the rules are about the node type, not the SDK kind.
5372
+ if (def?.nodeType === 'core.logic.dowhile') {
5373
+ diags.push(doWhileOnErrorRefusal(step.name));
5374
+ return;
5375
+ }
5376
+ if (def?.nodeType === 'core.action.http') {
5377
+ diags.push(plainHttpOnErrorRefusal(step.name));
5378
+ return;
5379
+ }
5380
+ if (definitionHasErrorPort(def))
5381
+ return;
5353
5382
  diags.push({
5354
5383
  level: 'error',
5355
5384
  code: 'ONERROR_NO_ERROR_PORT',
5356
- message: `Step "${step.name}" is a .doWhile() container. It declares an error variable but no error HANDLE `
5357
- + `(core.logic.dowhile@1.0: input, success, start, continue, break), so the edge would leave a handle the `
5358
- + `node does not have. Handle the failure inside the body, on the step that can fail.`,
5385
+ message: errorPortRefusal(step.name, def),
5359
5386
  step: step.name,
5360
5387
  });
5361
5388
  return;
@@ -5386,19 +5413,33 @@ function checkOnError(_handler, step, diags) {
5386
5413
  // So this stays an error, and says the second part too: an author who reads
5387
5414
  // the old message ("use the managed node if statuses must route") could
5388
5415
  // reasonably conclude a transport-failure handler is fine as it is.
5389
- if (spec.kind === 'http' && !spec.inputs?.managed) {
5390
- diags.push({
5391
- level: 'error',
5392
- code: 'HTTP_ONERROR_V1',
5393
- message: `Step "${step.name}" handles errors on a plain http() request. A 4xx/5xx does NOT fail that node — it `
5394
- + `completes with out('${step.name}', 'statusCode') set — so the handler runs only on a transport failure, `
5395
- + `and when it does the node publishes no failure envelope at all (measured: "<step>.error" is the boolean `
5396
- + `true and "<step>.output" is null, in 1.0.0 and in the 1.3 flow migrate produces), so err() has nothing `
5397
- + `to read. The managed node is the one whose failures route AND carry the envelope.`,
5398
- step: step.name,
5399
- suggestion: `http({ url: …, managed: true })`,
5400
- });
5401
- }
5416
+ if (spec.kind === 'http' && !spec.inputs?.managed)
5417
+ diags.push(plainHttpOnErrorRefusal(step.name));
5418
+ }
5419
+ /** `.onError` after a `core.logic.dowhile` container: it declares no error handle. */
5420
+ function doWhileOnErrorRefusal(stepName) {
5421
+ return {
5422
+ level: 'error',
5423
+ code: 'ONERROR_NO_ERROR_PORT',
5424
+ message: `Step "${stepName}" is a .doWhile() container. It declares an error variable but no error HANDLE `
5425
+ + `(core.logic.dowhile@1.0: input, success, start, continue, break), so the edge would leave a handle the `
5426
+ + `node does not have. Handle the failure inside the body, on the step that can fail.`,
5427
+ step: stepName,
5428
+ };
5429
+ }
5430
+ /** `.onError` after a plain `core.action.http` node (see the two measured facts in {@link checkOnError}). */
5431
+ function plainHttpOnErrorRefusal(stepName) {
5432
+ return {
5433
+ level: 'error',
5434
+ code: 'HTTP_ONERROR_V1',
5435
+ message: `Step "${stepName}" handles errors on a plain http() request. A 4xx/5xx does NOT fail that node — it `
5436
+ + `completes with out('${stepName}', 'statusCode') set — so the handler runs only on a transport failure, `
5437
+ + `and when it does the node publishes no failure envelope at all (measured: "<step>.error" is the boolean `
5438
+ + `true and "<step>.output" is null, in 1.0.0 and in the 1.3 flow migrate produces), so err() has nothing `
5439
+ + `to read. The managed node is the one whose failures route AND carry the envelope.`,
5440
+ step: stepName,
5441
+ suggestion: `http({ url: …, managed: true })`,
5442
+ };
5402
5443
  }
5403
5444
  /**
5404
5445
  * Reading a value that only ONE arm produces (flow-builder-sdk#200).
@@ -1,9 +1,23 @@
1
1
  /**
2
- * cli-library — compatibility re-export.
2
+ * cli-library — Flow's check options, plus the historical re-exports.
3
3
  *
4
4
  * How a CLI opens the connector library and its `connectors-local/` overlay, and
5
- * the event verdicts `check` shares with `compile`, all moved to
6
- * `core/cli-library.ts` when BPMN's `compile` and `check` needed the same things.
7
- * This shim preserves the historical `./cli-library.js` import path.
5
+ * the connector and event verdicts every family's `check` shares with its
6
+ * `compile`, live in `core/cli-library.ts`. This module keeps the historical
7
+ * `./cli-library.js` import path and adds the one thing that is Flow's own:
8
+ * {@link flowCheckOpts}, the options both `flow check` and `flow compile`'s check
9
+ * pass run on.
8
10
  */
11
+ import type { CheckOpts } from './check.js';
12
+ import type { BindingsView } from './core/binding-messages.js';
13
+ import type { Library } from './core/library.js';
9
14
  export { openCliLibrary, connectorCheckOpts, eventResolveErrorFor, byoaCheckOpts } from './core/cli-library.js';
15
+ /**
16
+ * Flow's check options from a library the CLI already opened: the shared
17
+ * connector and event hooks, Flow's own field validator (it renders Flow
18
+ * expressions, as `serialize` does), and the measured list envelopes.
19
+ *
20
+ * One builder for `flow check` and `flow compile`'s check pass, so the two
21
+ * cannot disagree.
22
+ */
23
+ export declare function flowCheckOpts(library: Library | undefined, bindings?: BindingsView): CheckOpts;
@@ -1,9 +1,27 @@
1
+ import { connectorCheckOpts } from './core/cli-library.js';
2
+ import { connectorInputErrors } from './serialize.js';
3
+ export { openCliLibrary, connectorCheckOpts, eventResolveErrorFor, byoaCheckOpts } from './core/cli-library.js';
1
4
  /**
2
- * cli-library — compatibility re-export.
5
+ * Flow's check options from a library the CLI already opened: the shared
6
+ * connector and event hooks, Flow's own field validator (it renders Flow
7
+ * expressions, as `serialize` does), and the measured list envelopes.
3
8
  *
4
- * How a CLI opens the connector library and its `connectors-local/` overlay, and
5
- * the event verdicts `check` shares with `compile`, all moved to
6
- * `core/cli-library.ts` when BPMN's `compile` and `check` needed the same things.
7
- * This shim preserves the historical `./cli-library.js` import path.
9
+ * One builder for `flow check` and `flow compile`'s check pass, so the two
10
+ * cannot disagree.
8
11
  */
9
- export { openCliLibrary, connectorCheckOpts, eventResolveErrorFor, byoaCheckOpts } from './core/cli-library.js';
12
+ export function flowCheckOpts(library, bindings) {
13
+ const shared = connectorCheckOpts(library, bindings, connectorInputErrors);
14
+ if (!library)
15
+ return shared;
16
+ return {
17
+ ...shared,
18
+ listEnvelope: (connector, operation, version, object) => {
19
+ try {
20
+ return library.resolve(connector, operation, version, object).listEnvelope;
21
+ }
22
+ catch {
23
+ return undefined; // an unresolvable operation is connectorResolveError's to report
24
+ }
25
+ },
26
+ };
27
+ }
@@ -22,9 +22,9 @@ import { writeJsonFile } from './core/json-file.js';
22
22
  import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync } from 'node:fs';
23
23
  import { basename, dirname, join, resolve } from 'node:path';
24
24
  import { resolveFlowFile, loadBuiltFlow } from './load.js';
25
- import { serializeWithSidecars, connectorInputErrors, compileOwnsResource } from './serialize.js';
25
+ import { serializeWithSidecars, compileOwnsResource } from './serialize.js';
26
26
  import { check } from './check.js';
27
- import { byoaCheckOpts, eventResolveErrorFor, openCliLibrary } from './cli-library.js';
27
+ import { flowCheckOpts, openCliLibrary } from './cli-library.js';
28
28
  import { Bindings } from './bindings.js';
29
29
  import { flagValue, runWhenInvokedDirectly } from './cli-run.js';
30
30
  import { connectionResources, inlineAgentResources, mergeBindingsV2, mergeInlineAgentResources, readBindingsV2, readInlineAgentFiles, } from './bindings-v2.js';
@@ -70,37 +70,8 @@ export async function run(argv) {
70
70
  // One list per run; every exit path reports it (reportResult overwrites keys).
71
71
  const diagnostics = [];
72
72
  if (!noCheck) {
73
- const diags = check(built, library
74
- ? {
75
- // The refusal serialize() would throw for an event it cannot resolve,
76
- // printed as `✗ [EVENT_UNKNOWN]` before stopping instead of hiding
77
- // behind "1 error(s); not emitting".
78
- eventResolveError: eventResolveErrorFor(library),
79
- ...byoaCheckOpts(library),
80
- eventParams: (connector, event) => {
81
- try {
82
- return library.eventParameterFields(connector, event);
83
- }
84
- catch {
85
- return undefined; // unresolvable: serialize() reports it properly
86
- }
87
- },
88
- lookups: (connector, action, version, object) => library.lookupSpecs(connector, action, version, object),
89
- resolutions: library.lookupResolutions,
90
- // Same validator serialize() runs below, so the check pass names the
91
- // refusal (and stops) instead of printing `0 error(s)` first.
92
- connectorInputs: (spec, inputs) => {
93
- try {
94
- const rc = library.resolve(spec.key, spec.action, spec.version, spec.object);
95
- return connectorInputErrors(rc, inputs, library.lookupResolutions ?? {}, library.lookupSpecs(spec.key, spec.action, spec.version, spec.object) ?? {});
96
- }
97
- catch {
98
- return undefined;
99
- }
100
- },
101
- bindings,
102
- }
103
- : { bindings });
73
+ // Same options as `flow check`, so the two cannot disagree.
74
+ const diags = check(built, flowCheckOpts(library, bindings));
104
75
  const errors = diags.filter((d) => d.level === 'error');
105
76
  for (const d of diags)
106
77
  console.error(` ${d.level === 'error' ? '✗' : '⚠'} [${d.code}] ${d.message}${d.suggestion ? ` (did you mean "${d.suggestion}"?)` : ''}`);
@@ -58,7 +58,7 @@ interface HttpInputsBase {
58
58
  * an error port only makes sense here (`check` says so: HTTP_ONERROR_V1).
59
59
  * The handler can answer the flow (`.return`), stop the run
60
60
  * (`.terminate`), or compensate and continue at a step the success path
61
- * also reaches (`h.rejoin('<step>')` — see `references/error-handling.md`);
61
+ * also reaches (`h.stepToRef('<step>')` — see `references/error-handling.md`);
62
62
  * - both nodes expose JSON responses as parsed values in the live product;
63
63
  * use `returns` to declare fields before reading them. The node choice does
64
64
  * not decide whether application/json is parsed.
@@ -1,6 +1,7 @@
1
- import { Library } from './library.js';
1
+ import { Library, type ResolvedConnector } from './library.js';
2
2
  import type { BindingsView } from './binding-messages.js';
3
3
  import { type ConnectorCheckOpts } from './connector-checks.js';
4
+ import type { LookupResolutions, LookupSpec } from './lookups.js';
4
5
  import type { EventCheckOpts } from './event-checks.js';
5
6
  /**
6
7
  * The library for this invocation, or `undefined` when there is none.
@@ -15,17 +16,25 @@ export declare function openCliLibrary(argv: readonly string[]): Library | undef
15
16
  * The connector half of a family's check options, from a library the CLI already
16
17
  * opened.
17
18
  *
18
- * Every callback fails OPEN: an entry the library cannot resolve, or no library
19
- * at all, means "unknown", and an unknown fact fires no rule. That is what lets
20
- * `check` stay the fast inner-loop rung — a process with no connectors needs no
21
- * library, and one whose connector is absent from the library is `compile`'s
22
- * business to name, not this pass's to guess at.
19
+ * Every fact callback fails OPEN: no library at all, or an entry the library
20
+ * cannot resolve, means "unknown", and an unknown fact fires no rule. That is
21
+ * what lets `check` stay the fast inner-loop rung — a process with no
22
+ * connectors needs no library. The one exception is the resolution itself:
23
+ * `connectorResolveError` reports the refusal `compile` would throw for an
24
+ * action, the way `eventResolveError` does for an event, so `check` never
25
+ * passes a connector step `compile` refuses (#948).
26
+ *
27
+ * `inputErrors` is the family's field-contract validator. The default speaks
28
+ * the `=`-expression dialect BPMN uses; Flow passes its own, which renders its
29
+ * expressions (see `flowCheckOpts` in `../cli-library.ts`).
23
30
  *
24
31
  * The `resolutions` are the overlay's: without them every lookup already
25
32
  * recorded by `registry prepare --resolve` would be reported as still owed,
26
33
  * telling the author to re-run a prepare they already ran.
27
34
  */
28
- export declare function connectorCheckOpts(library: Library | undefined, bindings?: BindingsView): ConnectorCheckOpts & EventCheckOpts;
35
+ export declare function connectorCheckOpts(library: Library | undefined, bindings?: BindingsView, inputErrors?: ConnectorInputValidator): ConnectorCheckOpts & EventCheckOpts;
36
+ /** A family's field-contract validator: `compile`'s refusal for these inputs, or `undefined`. */
37
+ export type ConnectorInputValidator = (rc: ResolvedConnector, inputs: Record<string, unknown>, resolutions: LookupResolutions, lookups: Readonly<Record<string, LookupSpec>>) => string | undefined;
29
38
  /**
30
39
  * `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
31
40
  * for a subscription, or `undefined` when it resolves.
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import { existsSync } from 'node:fs';
18
18
  import { join } from 'node:path';
19
- import { Library } from './library.js';
19
+ import { ConnectorResolveError, Library } from './library.js';
20
20
  import { resolveLibraryDir } from './library-cache.js';
21
21
  import { flagValue } from '../cli-run.js';
22
22
  import { defaultOverlayDir } from '../workdir.js';
@@ -41,19 +41,28 @@ export function openCliLibrary(argv) {
41
41
  * The connector half of a family's check options, from a library the CLI already
42
42
  * opened.
43
43
  *
44
- * Every callback fails OPEN: an entry the library cannot resolve, or no library
45
- * at all, means "unknown", and an unknown fact fires no rule. That is what lets
46
- * `check` stay the fast inner-loop rung — a process with no connectors needs no
47
- * library, and one whose connector is absent from the library is `compile`'s
48
- * business to name, not this pass's to guess at.
44
+ * Every fact callback fails OPEN: no library at all, or an entry the library
45
+ * cannot resolve, means "unknown", and an unknown fact fires no rule. That is
46
+ * what lets `check` stay the fast inner-loop rung — a process with no
47
+ * connectors needs no library. The one exception is the resolution itself:
48
+ * `connectorResolveError` reports the refusal `compile` would throw for an
49
+ * action, the way `eventResolveError` does for an event, so `check` never
50
+ * passes a connector step `compile` refuses (#948).
51
+ *
52
+ * `inputErrors` is the family's field-contract validator. The default speaks
53
+ * the `=`-expression dialect BPMN uses; Flow passes its own, which renders its
54
+ * expressions (see `flowCheckOpts` in `../cli-library.ts`).
49
55
  *
50
56
  * The `resolutions` are the overlay's: without them every lookup already
51
57
  * recorded by `registry prepare --resolve` would be reported as still owed,
52
58
  * telling the author to re-run a prepare they already ran.
53
59
  */
54
- export function connectorCheckOpts(library, bindings) {
60
+ export function connectorCheckOpts(library, bindings, inputErrors = (rc, inputs, resolutions, lookups) => connectorInputErrors(rc, inputs, resolutions, lookups, { dialect: EQUALS_EXPR_DIALECT })) {
55
61
  if (!library)
56
62
  return bindings ? { bindings } : {};
63
+ // One memoized resolve per connector step, shared by `connectorResolveError`
64
+ // and `connectorInputs`, so the second hook does not resolve again.
65
+ const resolve = connectorResolver(library);
57
66
  return {
58
67
  eventResolveError: eventResolveErrorFor(library),
59
68
  ...byoaCheckOpts(library),
@@ -85,26 +94,51 @@ export function connectorCheckOpts(library, bindings) {
85
94
  return undefined;
86
95
  }
87
96
  },
97
+ // The refusal compile throws for an operation it cannot resolve, with its
98
+ // code and text: CONNECTOR_NOT_IN_LIBRARY, CONNECTOR_OBJECT_REQUIRED,
99
+ // CONNECTOR_OBJECT_NOT_GENERIC.
100
+ connectorResolveError: (spec) => {
101
+ const r = resolve(spec);
102
+ return 'error' in r ? r.error : undefined;
103
+ },
88
104
  // The field contract compile enforces, from the same validator, so the inner
89
105
  // loop and the emit rung cannot disagree about a missing required field, an
90
- // unknown key or a mistyped value. An operation the library cannot resolve is
91
- // compile's business to name — here it just means "unknown".
92
- //
93
- // The `=`-expression dialect, because this bag serves the families that spell
94
- // an expression that way. Flow binds its own `connectorInputErrors` in
95
- // `serialize.ts`, which carries `renderDeep` with it, and overrides this.
106
+ // unknown key or a mistyped value. An unresolvable operation is
107
+ // `connectorResolveError`'s to report; here it just means "unknown".
96
108
  connectorInputs: (spec, inputs) => {
97
- try {
98
- const rc = library.resolve(spec.key, spec.action, spec.version, spec.object);
99
- return connectorInputErrors(rc, inputs, library.lookupResolutions ?? {}, library.lookupSpecs(spec.key, spec.action, spec.version, spec.object) ?? {}, { dialect: EQUALS_EXPR_DIALECT });
100
- }
101
- catch {
109
+ const r = resolve(spec);
110
+ if (!('rc' in r))
102
111
  return undefined;
103
- }
112
+ return inputErrors(r.rc, inputs, library.lookupResolutions ?? {}, library.lookupSpecs(spec.key, spec.action, spec.version, spec.object) ?? {});
104
113
  },
105
114
  ...(bindings ? { bindings } : {}),
106
115
  };
107
116
  }
117
+ /**
118
+ * `library.resolve` for one connector step, memoized per step for the life of
119
+ * one check's options. A {@link ConnectorResolveError} is the refusal compile
120
+ * throws and becomes `error`; anything else thrown is not a verdict about the
121
+ * author's source and stays "unknown", as before.
122
+ */
123
+ function connectorResolver(library) {
124
+ const memo = new Map();
125
+ return (spec) => {
126
+ const id = JSON.stringify([spec.key, spec.action, spec.version ?? null, spec.object ?? null]);
127
+ let r = memo.get(id);
128
+ if (!r) {
129
+ try {
130
+ r = { rc: library.resolve(spec.key, spec.action, spec.version, spec.object) };
131
+ }
132
+ catch (error) {
133
+ r = error instanceof ConnectorResolveError
134
+ ? { error: { code: error.code, message: error.message } }
135
+ : { unknown: true };
136
+ }
137
+ memo.set(id, r);
138
+ }
139
+ return r;
140
+ };
141
+ }
108
142
  /**
109
143
  * `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
110
144
  * for a subscription, or `undefined` when it resolves.
@@ -113,6 +113,21 @@ export interface ConnectorCheckOpts {
113
113
  resolutions?: LookupResolutions;
114
114
  /** Whether a connector step's schema is materialized locally. */
115
115
  schemaReadiness?: (connector: string, action: string, version?: string, object?: string) => SchemaReadiness | undefined;
116
+ /**
117
+ * Why `compile` could not resolve this operation at all (`library.resolve`
118
+ * throws), or `undefined` when it resolves. Checked before
119
+ * {@link ConnectorCheckOpts.connectorInputs}, which answers `undefined` for an
120
+ * unresolvable operation and so cannot tell "not in the library" from "no facts".
121
+ */
122
+ connectorResolveError?: (spec: {
123
+ key: string;
124
+ action: string;
125
+ version?: string;
126
+ object?: string;
127
+ }) => {
128
+ code: string;
129
+ message: string;
130
+ } | undefined;
116
131
  /** What `compile` would refuse these inputs with, or `undefined` when it would accept them. */
117
132
  connectorInputs?: (spec: {
118
133
  key: string;
@@ -157,9 +172,10 @@ export declare function checkConnectorLookups(where: string, spec: ConnectorSpec
157
172
  */
158
173
  export declare function checkConnectorSchema(where: string, spec: ConnectorSpec, opts: ConnectorCheckOpts, dialect: ExprDialect, report: ReportConnector): void;
159
174
  /**
160
- * The field contract and the binding names `compile` enforces, reported here first.
175
+ * The operation, its field contract and the binding names `compile` enforces,
176
+ * reported here first.
161
177
  *
162
- * Both rules run only with the facts in hand (a library for the fields, a
178
+ * Each rule runs only with the facts in hand (a library for the operation and its fields, a
163
179
  * bindings.json for the names); without them `check` stays a pure function of the
164
180
  * built model and says nothing, as before.
165
181
  */
@@ -321,18 +321,28 @@ export function checkConnectorSchema(where, spec, opts, dialect, report) {
321
321
  }
322
322
  }
323
323
  /**
324
- * The field contract and the binding names `compile` enforces, reported here first.
324
+ * The operation, its field contract and the binding names `compile` enforces,
325
+ * reported here first.
325
326
  *
326
- * Both rules run only with the facts in hand (a library for the fields, a
327
+ * Each rule runs only with the facts in hand (a library for the operation and its fields, a
327
328
  * bindings.json for the names); without them `check` stays a pure function of the
328
329
  * built model and says nothing, as before.
329
330
  */
330
331
  export function checkConnectorContract(where, spec, opts, report,
331
332
  /** The activity's own id, for {@link connectionConnectorConflicts}; omit to record nothing. */
332
333
  id) {
333
- const inputErr = opts.connectorInputs?.({ key: spec.key, action: spec.action, version: spec.version, object: spec.object }, spec.inputs ?? {});
334
- if (inputErr) {
335
- report({ level: 'error', code: 'CONNECTOR_INPUT', message: `${where}: ${inputErr}` });
334
+ const target = { key: spec.key, action: spec.action, version: spec.version, object: spec.object };
335
+ // The operation itself first: an operation compile cannot resolve has no field
336
+ // contract to check, and `connectorInputs` answers "unknown" for it.
337
+ const unresolved = opts.connectorResolveError?.(target);
338
+ if (unresolved) {
339
+ report({ level: 'error', code: unresolved.code, message: `${where}: ${unresolved.message}` });
340
+ }
341
+ else {
342
+ const inputErr = opts.connectorInputs?.(target, spec.inputs ?? {});
343
+ if (inputErr) {
344
+ report({ level: 'error', code: 'CONNECTOR_INPUT', message: `${where}: ${inputErr}` });
345
+ }
336
346
  }
337
347
  checkBindingLabels(where, spec, opts, (code, message) => report({ level: 'error', code, message }), { key: spec.key, action: spec.action }, id === undefined ? undefined : { id, connector: spec.key });
338
348
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Does a node definition have an `error` port? One answer for `check` and
3
+ * `serialize` (flow-builder-sdk#943).
4
+ *
5
+ * The product's rule, read from @uipath/flow-core and @uipath/flow-tool:
6
+ *
7
+ * - the manifest client injects an `error` source handle into every served
8
+ * definition with `supportsErrorHandling: true` that does not declare one
9
+ * (`withErrorHandles` / `nodeSupportsErrorHandling`);
10
+ * - `uip maestro flow validate` does the same when it checks edge handles
11
+ * (`validateEdgeHandlesAgainstCurrentManifests`: `supportsErrorHandling ===
12
+ * true` adds `error` to the node's source handles).
13
+ *
14
+ * So the flag alone grants the port. For instance, the manifest
15
+ * `registry get --local` returns for a sibling Flow or RPA project
16
+ * (`buildNodeManifest`) has `supportsErrorHandling: true` and only `input` +
17
+ * `output` handles, and an `error` edge from it is valid. A definition that
18
+ * declares an `error` source handle without the flag counts too.
19
+ */
20
+ export declare function definitionHasErrorPort(def: any): boolean;
21
+ /**
22
+ * The ONERROR_NO_ERROR_PORT sentence for a definition-backed node, naming its
23
+ * node type. Shared with serialize, which throws it for the same node.
24
+ */
25
+ export declare function errorPortRefusal(stepName: string, def: any): string;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Does a node definition have an `error` port? One answer for `check` and
3
+ * `serialize` (flow-builder-sdk#943).
4
+ *
5
+ * The product's rule, read from @uipath/flow-core and @uipath/flow-tool:
6
+ *
7
+ * - the manifest client injects an `error` source handle into every served
8
+ * definition with `supportsErrorHandling: true` that does not declare one
9
+ * (`withErrorHandles` / `nodeSupportsErrorHandling`);
10
+ * - `uip maestro flow validate` does the same when it checks edge handles
11
+ * (`validateEdgeHandlesAgainstCurrentManifests`: `supportsErrorHandling ===
12
+ * true` adds `error` to the node's source handles).
13
+ *
14
+ * So the flag alone grants the port. For instance, the manifest
15
+ * `registry get --local` returns for a sibling Flow or RPA project
16
+ * (`buildNodeManifest`) has `supportsErrorHandling: true` and only `input` +
17
+ * `output` handles, and an `error` edge from it is valid. A definition that
18
+ * declares an `error` source handle without the flag counts too.
19
+ */
20
+ export function definitionHasErrorPort(def) {
21
+ if (def?.supportsErrorHandling === true)
22
+ return true;
23
+ const groups = Array.isArray(def?.handleConfiguration) ? def.handleConfiguration : [];
24
+ return groups.some((g) => (Array.isArray(g?.handles) ? g.handles : [])
25
+ .some((h) => h?.id === 'error' && h?.type === 'source'));
26
+ }
27
+ /**
28
+ * The ONERROR_NO_ERROR_PORT sentence for a definition-backed node, naming its
29
+ * node type. Shared with serialize, which throws it for the same node.
30
+ */
31
+ export function errorPortRefusal(stepName, def) {
32
+ return `Step "${stepName}" is a ${def?.nodeType}@${def?.version} node, and its definition has no error port: `
33
+ + `it does not set supportsErrorHandling: true and declares no "error" source handle, so the edge would leave a `
34
+ + `handle the node does not have. Handle the failure downstream instead, or pass the definition exactly as `
35
+ + `\`uip maestro flow registry get\` returns it.`;
36
+ }
@@ -145,8 +145,8 @@ export declare function ran(step: string): Expr;
145
145
  * The first five are what every error-capable node's definition declares
146
146
  * (`outputDefinition.error.schema`, `required`, `additionalProperties: false`).
147
147
  * `response` and `element` are NOT declared and are present at run time anyway —
148
- * measured on every family probed (2026-09-10), `element` carrying the id of the
149
- * step that failed. They are typed here because a field that exists should be
148
+ * measured on every family probed (2026-09-10), `element` carrying the label of
149
+ * the step that failed. They are typed here because a field that exists should be
150
150
  * readable; the declared five stay first because those are the contract.
151
151
  */
152
152
  export type ErrorEnvelopeField = 'code' | 'message' | 'detail' | 'category' | 'status' | 'response' | 'element';
@@ -166,15 +166,21 @@ export type ErrorEnvelopeField = 'code' | 'message' | 'detail' | 'category' | 's
166
166
  * | `category` | string | `'User'` |
167
167
  * | `status` | number | `404` |
168
168
  * | `response` | unknown | undeclared; `null` in every probe |
169
- * | `element` | string | undeclared; the id of the step that failed |
169
+ * | `element` | string | undeclared; the failing step's label |
170
170
  *
171
171
  * The last two resolve at run time — measured, a container handler reading
172
- * `element` came back with the failing body step's id — but they are absent from
173
- * the declared schema, so `uip maestro flow validate` reports
172
+ * `element` came back with the failing body step's label — but they are absent
173
+ * from the declared schema, so `uip maestro flow validate` reports
174
174
  * `EXPRESSION_DIAGNOSTIC: Property 'element' does not exist on type
175
175
  * '<Step>_Error'` for them. Valid, and noisy: prefer the declared five unless you
176
176
  * specifically need one of these.
177
177
  *
178
+ * **`element` is the step's canvas label (`display.label`), not its node id.** The
179
+ * label defaults to the step name, so it matches the name (not always the node
180
+ * id) only while no `label` is set: `.step('failA', …, { label: 'Fail A' })`
181
+ * failing gives `element: 'Fail A'`. Route on `code` / `message`, never on
182
+ * `element`.
183
+ *
178
184
  * **Which VARIABLE holds it is per node family, and this helper owns that.**
179
185
  * Measured on the product (2026-09-10), one debug run per family:
180
186
  *
package/dist/core/expr.js CHANGED
@@ -179,15 +179,21 @@ export function ran(step) {
179
179
  * | `category` | string | `'User'` |
180
180
  * | `status` | number | `404` |
181
181
  * | `response` | unknown | undeclared; `null` in every probe |
182
- * | `element` | string | undeclared; the id of the step that failed |
182
+ * | `element` | string | undeclared; the failing step's label |
183
183
  *
184
184
  * The last two resolve at run time — measured, a container handler reading
185
- * `element` came back with the failing body step's id — but they are absent from
186
- * the declared schema, so `uip maestro flow validate` reports
185
+ * `element` came back with the failing body step's label — but they are absent
186
+ * from the declared schema, so `uip maestro flow validate` reports
187
187
  * `EXPRESSION_DIAGNOSTIC: Property 'element' does not exist on type
188
188
  * '<Step>_Error'` for them. Valid, and noisy: prefer the declared five unless you
189
189
  * specifically need one of these.
190
190
  *
191
+ * **`element` is the step's canvas label (`display.label`), not its node id.** The
192
+ * label defaults to the step name, so it matches the name (not always the node
193
+ * id) only while no `label` is set: `.step('failA', …, { label: 'Fail A' })`
194
+ * failing gives `element: 'Fail A'`. Route on `code` / `message`, never on
195
+ * `element`.
196
+ *
191
197
  * **Which VARIABLE holds it is per node family, and this helper owns that.**
192
198
  * Measured on the product (2026-09-10), one debug run per family:
193
199
  *
@@ -218,6 +218,25 @@ export interface LibraryOpts {
218
218
  */
219
219
  overlayDir?: string;
220
220
  }
221
+ /** Why {@link Library.resolve} refused a connector action. */
222
+ export type ConnectorResolveCode =
223
+ /** The library carries no such operation (or no such connector, or not at that version). */
224
+ 'CONNECTOR_NOT_IN_LIBRARY'
225
+ /** A GENERIC operation (one entry per object) named without an `object`. */
226
+ | 'CONNECTOR_OBJECT_REQUIRED'
227
+ /** An `object` on a single, non-generic operation. */
228
+ | 'CONNECTOR_OBJECT_NOT_GENERIC';
229
+ /**
230
+ * The refusal {@link Library.resolve} throws, with a `code` for each reason.
231
+ *
232
+ * Typed so a caller can tell a refusal from a bug without matching on message
233
+ * text: `check` reports it under this code with this message, and a compile
234
+ * that throws it carries the same code into its `--json` diagnostics (#948).
235
+ */
236
+ export declare class ConnectorResolveError extends Error {
237
+ readonly code: ConnectorResolveCode;
238
+ constructor(code: ConnectorResolveCode, message: string);
239
+ }
221
240
  export declare class Library {
222
241
  private layers;
223
242
  /** The LIST-ENVELOPE LEDGER, overlay first so a prepared entry can add a row. */
@@ -9,10 +9,26 @@
9
9
  import { readFileSync, existsSync } from 'node:fs';
10
10
  import { join } from 'node:path';
11
11
  import { prepareCommand } from './cli-spelling.js';
12
+ import { PULL_COMMAND } from './library-cache.js';
12
13
  import { editDistance } from './edit-distance.js';
13
14
  import { loadListEnvelopes, lookupListEnvelope } from './list-envelope.js';
14
15
  import { lookupSpecOf } from './lookups.js';
15
16
  import { loadByoaLedger, loadInvariantCollections, loadLookupResolutions } from './lookup-store.js';
17
+ /**
18
+ * The refusal {@link Library.resolve} throws, with a `code` for each reason.
19
+ *
20
+ * Typed so a caller can tell a refusal from a bug without matching on message
21
+ * text: `check` reports it under this code with this message, and a compile
22
+ * that throws it carries the same code into its `--json` diagnostics (#948).
23
+ */
24
+ export class ConnectorResolveError extends Error {
25
+ code;
26
+ constructor(code, message) {
27
+ super(message);
28
+ this.name = 'ConnectorResolveError';
29
+ this.code = code;
30
+ }
31
+ }
16
32
  export class Library {
17
33
  layers = [];
18
34
  /** The LIST-ENVELOPE LEDGER, overlay first so a prepared entry can add a row. */
@@ -582,7 +598,7 @@ export class Library {
582
598
  + `the library index (\`index.json\`), and remember the two namespaces: `
583
599
  + `\`…connector.trigger.…\` starts a flow, \`…connector.event.…\` waits mid-flow.`
584
600
  : '';
585
- throw new Error(`connector not in library: ${nodeType}${version ? '@' + version : ''}.${hint}`
601
+ throw new ConnectorResolveError('CONNECTOR_NOT_IN_LIBRARY', `connector not in library: ${nodeType}${version ? '@' + version : ''}.${hint}`
586
602
  + this.describeMiss(nodeType, version, objectName));
587
603
  }
588
604
  /**
@@ -622,7 +638,7 @@ export class Library {
622
638
  + where
623
639
  + ' Note the operation slug is the nodeType segment, NOT the tenant\'s `objectName`'
624
640
  + ' — `uip maestro case spec` reports the latter, and the two can differ.'
625
- + ' If the operation is newer than the library, refresh it with `uip maestro flow registry pull --force`.';
641
+ + ` If the operation is newer than the library, refresh it with \`${PULL_COMMAND}\`.`;
626
642
  }
627
643
  /** Every direct operation id under `prefix` (no further dot), across layers, sorted and de-duplicated. */
628
644
  opsUnder(prefix) {
@@ -646,7 +662,7 @@ export class Library {
646
662
  return ` No connector "${key}" in the library (${keys.length} indexed).`
647
663
  + (near && near !== key ? ` Closest: ${near}.` : '')
648
664
  + where
649
- + ' If the connector is newer than the library, refresh it with `uip maestro flow registry pull --force`.';
665
+ + ` If the connector is newer than the library, refresh it with \`${PULL_COMMAND}\`.`;
650
666
  }
651
667
  /**
652
668
  * The event half of {@link describeMiss}: which of the connector's EVENTS the
@@ -666,7 +682,7 @@ export class Library {
666
682
  const waits = this.opsUnder(`uipath.connector.event.${key}.`);
667
683
  // A start trigger resolves from either form; a mid-flow wait needs the `.event.` form itself.
668
684
  const usable = kind === 'trigger' ? [...new Set([...starts, ...waits])].sort() : waits;
669
- const refresh = ' If the event is newer than the library, refresh it with `uip maestro flow registry pull --force`.';
685
+ const refresh = ` If the event is newer than the library, refresh it with \`${PULL_COMMAND}\`.`;
670
686
  if (usable.length) {
671
687
  if (usable.includes(asked)) {
672
688
  // Only a version can make a carried event miss here: every other refusal
@@ -755,7 +771,7 @@ export class Library {
755
771
  + `dispatch. If it is a typo, compile will not catch it.\n`);
756
772
  return this.build(layer.dir, { ...only, objectName }, nodeType, { objectNameUnverified: true });
757
773
  }
758
- throw new Error(`connector ${nodeType} does not have an object "${objectName}": it is a single, `
774
+ throw new ConnectorResolveError('CONNECTOR_OBJECT_NOT_GENERIC', `connector ${nodeType} does not have an object "${objectName}": it is a single, `
759
775
  + `non-generic operation addressing ${only.objectName ? `"${only.objectName}"` : 'no object'}. `
760
776
  + `Drop the \`object\` option (it is only for generic operations, whose node type covers many objects).`);
761
777
  }
@@ -769,7 +785,7 @@ export class Library {
769
785
  .filter((o) => typeof o === 'string' && o.length > 0)
770
786
  .sort();
771
787
  if (objectName === undefined) {
772
- throw new Error(`connector ${nodeType} is a GENERIC operation covering ${matches.length} objects — `
788
+ throw new ConnectorResolveError('CONNECTOR_OBJECT_REQUIRED', `connector ${nodeType} is a GENERIC operation covering ${matches.length} objects — `
773
789
  + `say which one with the \`object\` option, e.g. `
774
790
  + `connector('${nodeType.split('.').slice(2, 3)[0]}', '${nodeType.split('.').slice(3).join('.')}', `
775
791
  + `{ … }, { object: '${objects[0] ?? '<object>'}' }). ${describeObjects(objects)}`);
@@ -824,7 +824,7 @@ declare class StepList {
824
824
  * even a legal call: `out(step, path?)` takes two arguments.
825
825
  *
826
826
  * **Three ways the handler can end**: `.return(...)` answers the flow,
827
- * `.terminate(...)` stops the run, and `h.rejoin('<step>')` compensates and
827
+ * `.terminate(...)` stops the run, and `h.stepToRef('<step>')` compensates and
828
828
  * hands control back to a step the success path also reaches — the shape most
829
829
  * deployed flows use. A handler that just runs out of steps still gets its own
830
830
  * End: rejoining is something the author SAYS, never something wiring infers.
@@ -838,8 +838,9 @@ declare class StepList {
838
838
  *
839
839
  * **A `.loop()` container takes one too.** `core.logic.loop` declares the
840
840
  * handle, and a body step's failure routes to it: the container's envelope
841
- * carries the body's message in `detail` and the failing body step's id in
842
- * `element`, and the instance completes rather than faulting. `.doWhile()` does
841
+ * carries the body's message in `detail` and the failing body step's label
842
+ * (`display.label`, which defaults to the step name) in `element`, and the
843
+ * instance completes rather than faulting. `.doWhile()` does
843
844
  * NOT — it declares an error variable and no error handle — so that one is
844
845
  * refused by name, and its failures belong to the body step that can fail.
845
846
  *
package/dist/flow-sdk.js CHANGED
@@ -402,7 +402,7 @@ class StepList {
402
402
  * even a legal call: `out(step, path?)` takes two arguments.
403
403
  *
404
404
  * **Three ways the handler can end**: `.return(...)` answers the flow,
405
- * `.terminate(...)` stops the run, and `h.rejoin('<step>')` compensates and
405
+ * `.terminate(...)` stops the run, and `h.stepToRef('<step>')` compensates and
406
406
  * hands control back to a step the success path also reaches — the shape most
407
407
  * deployed flows use. A handler that just runs out of steps still gets its own
408
408
  * End: rejoining is something the author SAYS, never something wiring infers.
@@ -416,8 +416,9 @@ class StepList {
416
416
  *
417
417
  * **A `.loop()` container takes one too.** `core.logic.loop` declares the
418
418
  * handle, and a body step's failure routes to it: the container's envelope
419
- * carries the body's message in `detail` and the failing body step's id in
420
- * `element`, and the instance completes rather than faulting. `.doWhile()` does
419
+ * carries the body's message in `detail` and the failing body step's label
420
+ * (`display.label`, which defaults to the step name) in `element`, and the
421
+ * instance completes rather than faulting. `.doWhile()` does
421
422
  * NOT — it declares an error variable and no error handle — so that one is
422
423
  * refused by name, and its failures belong to the body step that can fail.
423
424
  *
@@ -464,7 +465,7 @@ class StepList {
464
465
  // `@2.4`, gated on `errorHandlingEnabled` like every other error handle), and
465
466
  // the platform routes it: a body step throwing inside a measured run left the
466
467
  // instance Completed with the container's envelope published — `detail` the
467
- // body's own message, `element` the id of the body step that failed.
468
+ // body's own message, `element` the label of the body step that failed.
468
469
  //
469
470
  // `.doWhile()` is NOT: `core.logic.dowhile@1.0` declares an error VARIABLE
470
471
  // and no error HANDLE, so an edge would leave a handle the node does not
package/dist/serialize.js CHANGED
@@ -15,6 +15,7 @@ import { FlowAction, FlowTrigger } from './core/node-classes.js';
15
15
  import { connectorRawNodeRefusal } from './core/connector-raw-node.js';
16
16
  import { dataFabricUnknownInputs } from './core/typed-raw-node.js';
17
17
  import { planContributionBindings } from './core/contribution-bindings.js';
18
+ import { definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
18
19
  import { isAnswerField } from './core/hitl-answers.js';
19
20
  import { connectionConnectors } from './bindings-v2.js';
20
21
  import { BindingRefusal, GUID_RE, bindingMissingMessage, bindingSelfNameMessage, bindingUndeclaredMessage, missingBindingLabels, undeclaredBinding } from './core/binding-messages.js';
@@ -4375,9 +4376,9 @@ function newScope(outputs, vars = []) {
4375
4376
  * note at `uipath.ts:118-123`, MST-9544).
4376
4377
  */
4377
4378
  /**
4378
- * Wire every parked `.rejoin('<step>')` edge, now that the whole scope exists.
4379
+ * Wire every parked `.stepToRef('<step>')` edge, now that the whole scope exists.
4379
4380
  *
4380
- * An unresolved target should be impossible — `check`'s REJOIN_UNKNOWN_TARGET
4381
+ * An unresolved target should be impossible — `check`'s REF_UNKNOWN_TARGET
4381
4382
  * runs first and names the steps that do exist — but a serializer that silently
4382
4383
  * dropped the edge would emit a flow whose handler goes nowhere, which is the
4383
4384
  * exact class of failure `.onError` used to have (an error path that vanishes in
@@ -4636,8 +4637,8 @@ function renameRefs(text, rename) {
4636
4637
  /** Every step name a flow declares in its own scope (not its children's). */
4637
4638
  function stepNamesOf(steps, out = []) {
4638
4639
  for (const s of steps) {
4639
- // `return` and `rejoin` carry a synthetic `name` and create no node named
4640
- // after it (an End id is claimed as `end`; a rejoin is one edge).
4640
+ // `return` carries a synthetic `name` but creates no node named after it (an
4641
+ // End id is claimed as `end`); `stepToRef` has no `name` at all (it is one edge).
4641
4642
  if ('name' in s && s.kind !== 'return')
4642
4643
  out.push(s.name);
4643
4644
  if (s.kind === 'branch') {
@@ -4679,6 +4680,18 @@ export function serialize(built, opts = {}) {
4679
4680
  * A bindings entry the node does not reference is not a bound resource.
4680
4681
  */
4681
4682
  const resourceBindings = new Map();
4683
+ /**
4684
+ * The resolved definition of every contribution-lowered node, by node id, so an
4685
+ * `error` edge from one can be checked against its definition (#943). Typed
4686
+ * families are not recorded: their definitions are the SDK's own.
4687
+ */
4688
+ const contributionDefs = new Map();
4689
+ /** Refuse an `error` edge from a contribution-lowered node whose definition has no error port. */
4690
+ function refuseErrorEdgeWithoutPort(nodeId, stepName) {
4691
+ const def = contributionDefs.get(nodeId);
4692
+ if (def !== undefined && !definitionHasErrorPort(def))
4693
+ throw new Error(errorPortRefusal(stepName, def));
4694
+ }
4682
4695
  /**
4683
4696
  * Hoist a contribution's own bindings, then close every `<bindings.NAME>` its
4684
4697
  * definition references and it did not supply, from the definition's own
@@ -4785,7 +4798,7 @@ export function serialize(built, opts = {}) {
4785
4798
  /**
4786
4799
  * `uid` for a node that IS an author's step, recording which id that step got.
4787
4800
  *
4788
- * `.rejoin('<step>')` names a step, and the id it was emitted under is not
4801
+ * `.stepToRef('<step>')` names a step, and the id it was emitted under is not
4789
4802
  * derivable from the name: `uid` sanitizes, de-duplicates against every id in
4790
4803
  * the file, and hands a subflow COPY a prefixed one from the rename map. So
4791
4804
  * the mapping is recorded where it is decided rather than reconstructed later
@@ -5120,6 +5133,7 @@ export function serialize(built, opts = {}) {
5120
5133
  node.outputs = { ...(node.outputs ?? {}), ...subNodeId(clone(contribution.outputs), id) };
5121
5134
  }
5122
5135
  hoistContributionBindings(def, contribution.bindings, where);
5136
+ contributionDefs.set(id, def);
5123
5137
  scope.nodes.push(node);
5124
5138
  for (const t of tails)
5125
5139
  addEdge(scope, t, id);
@@ -6457,7 +6471,7 @@ export function serialize(built, opts = {}) {
6457
6471
  * The handler is its OWN path, and it still is: its leftover tails get their
6458
6472
  * own End rather than rejoining the chain, because `.onError` must not
6459
6473
  * SILENTLY change what runs after the step. What changed is that an author can
6460
- * now ASK — `h.rejoin('<step>')` emits an edge into a step the success path
6474
+ * now ASK — `h.stepToRef('<step>')` emits an edge into a step the success path
6461
6475
  * also reaches, and returns no tail, so nothing is capped. Never inferred:
6462
6476
  * a handler that just runs out of steps ends exactly as it always did.
6463
6477
  *
@@ -6522,8 +6536,10 @@ export function serialize(built, opts = {}) {
6522
6536
  throw new Error(`.stepToList('${step.port}', …) after step "${source}": emitted node "${nodeId}" not found in scope`);
6523
6537
  // Only the error port carries this: without it the platform routes but Studio
6524
6538
  // Web HIDES the handle, so no human can see the handler.
6525
- if (step.port === 'error')
6539
+ if (step.port === 'error') {
6540
+ refuseErrorEdgeWithoutPort(nodeId, source);
6526
6541
  node.inputs = { ...(node.inputs ?? {}), errorHandlingEnabled: true };
6542
+ }
6527
6543
  const handlerTails = emit(handler, [{ node: nodeId, port: step.port }], scope, parentId, breakTarget);
6528
6544
  if (handlerTails.length) {
6529
6545
  const endId = uid(scope, `${source}${step.port === 'error' ? 'Error' : step.port.charAt(0).toUpperCase() + step.port.slice(1)}End`);
@@ -6924,6 +6940,7 @@ export function serialize(built, opts = {}) {
6924
6940
  throw new Error(`.stepToRef('${step.port}', '${step.target}') has no step to leave from.`);
6925
6941
  refuseRewire('.stepToRef', step.port, lastAction ?? '?', tails);
6926
6942
  if (step.port === 'error') {
6943
+ refuseErrorEdgeWithoutPort(from.node, lastAction ?? from.node);
6927
6944
  const node = scope.nodes.find((n) => n.id === from.node);
6928
6945
  if (node)
6929
6946
  node.inputs = { ...(node.inputs ?? {}), errorHandlingEnabled: true };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.17.0",
3
+ "version": "6.17.1",
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": "c6e35983af98d4dc81b45aaee8a9bb0419bc1cc2"
95
+ "gitref": "16311a1f95f57ac9799d42eca556b25e4879fb5d"
96
96
  }