@uipath/maestro-builder-sdk 6.18.10 → 6.20.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 +185 -184
- package/dist/api-members.md +506 -473
- package/dist/check.js +358 -695
- package/dist/cli/commands/flow.js +3 -0
- package/dist/compile-cli.js +51 -0
- package/dist/core/actions.d.ts +132 -765
- package/dist/core/actions.js +1 -307
- package/dist/core/binding-identity.d.ts +22 -0
- package/dist/core/binding-identity.js +28 -0
- package/dist/core/context-index.d.ts +34 -0
- package/dist/core/context-index.js +38 -0
- package/dist/core/definitionless-node-types.d.ts +16 -0
- package/dist/core/definitionless-node-types.js +16 -0
- package/dist/core/error-port.d.ts +6 -0
- package/dist/core/error-port.js +9 -0
- package/dist/core/form-field-type.d.ts +33 -0
- package/dist/core/form-field-type.js +30 -0
- package/dist/core/hitl-routing.d.ts +8 -0
- package/dist/core/hitl-routing.js +17 -1
- package/dist/core/node-classes.d.ts +4 -63
- package/dist/core/node-classes.js +0 -112
- package/dist/core/nodes/family.d.ts +36 -0
- package/dist/core/nodes/family.js +1 -0
- package/dist/core/nodes/node-type.d.ts +136 -0
- package/dist/core/nodes/node-type.js +1 -0
- package/dist/core/nodes/registry.d.ts +57 -0
- package/dist/core/nodes/registry.js +122 -0
- package/dist/core/nodes/versioned.d.ts +50 -0
- package/dist/core/nodes/versioned.js +46 -0
- package/dist/core/process-resource-sort-order.d.ts +40 -0
- package/dist/core/process-resource-sort-order.js +44 -0
- package/dist/core/typed-raw-node.d.ts +13 -62
- package/dist/core/typed-raw-node.js +40 -154
- package/dist/core/wire-expr.d.ts +27 -0
- package/dist/core/wire-expr.js +34 -0
- package/dist/decompile-cli.js +11 -1
- package/dist/decompile.d.ts +8 -3
- package/dist/decompile.js +665 -354
- package/dist/flow-definitions.d.ts +10 -0
- package/dist/flow-definitions.js +35 -0
- package/dist/flow-expr-check.js +1 -1
- package/dist/flow-node-registry.d.ts +13 -0
- package/dist/flow-node-registry.js +19 -0
- package/dist/flow-node-type.d.ts +192 -0
- package/dist/flow-node-type.js +1 -0
- package/dist/flow-sdk.d.ts +40 -1
- package/dist/flow-sdk.js +29 -2
- package/dist/flow-step-tree.js +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/merge-cli.js +25 -8
- package/dist/merge-roundtrip.d.ts +81 -0
- package/dist/merge-roundtrip.js +404 -0
- package/dist/merge.d.ts +35 -6
- package/dist/merge.js +124 -24
- package/dist/node-placement.d.ts +93 -0
- package/dist/node-placement.js +163 -0
- package/dist/nodes/data-fabric/flow/check.d.ts +13 -0
- package/dist/nodes/data-fabric/flow/check.js +164 -0
- package/dist/nodes/data-fabric/flow/factories.d.ts +113 -0
- package/dist/nodes/data-fabric/flow/factories.js +134 -0
- package/dist/nodes/data-fabric/flow/family.d.ts +7 -0
- package/dist/nodes/data-fabric/flow/family.js +9 -0
- package/dist/nodes/data-fabric/flow/index.d.ts +8 -0
- package/dist/nodes/data-fabric/flow/index.js +8 -0
- package/dist/nodes/data-fabric/flow/raw.d.ts +32 -0
- package/dist/nodes/data-fabric/flow/raw.js +100 -0
- package/dist/nodes/data-fabric/flow/shared.d.ts +77 -0
- package/dist/nodes/data-fabric/flow/shared.js +174 -0
- package/dist/nodes/data-fabric/flow/spec.d.ts +238 -0
- package/dist/nodes/data-fabric/flow/spec.js +1 -0
- package/dist/nodes/data-fabric/flow/verbs.d.ts +29 -0
- package/dist/nodes/data-fabric/flow/verbs.js +239 -0
- package/dist/nodes/delay/flow/check.d.ts +16 -0
- package/dist/nodes/delay/flow/check.js +86 -0
- package/dist/nodes/delay/flow/factories.d.ts +28 -0
- package/dist/nodes/delay/flow/factories.js +38 -0
- package/dist/nodes/delay/flow/family.d.ts +3 -0
- package/dist/nodes/delay/flow/family.js +8 -0
- package/dist/nodes/delay/flow/index.d.ts +3 -0
- package/dist/nodes/delay/flow/index.js +3 -0
- package/dist/nodes/delay/flow/node-type.d.ts +13 -0
- package/dist/nodes/delay/flow/node-type.js +71 -0
- package/dist/nodes/delay/flow/spec.d.ts +43 -0
- package/dist/nodes/delay/flow/spec.js +16 -0
- package/dist/nodes/document/flow/factories.d.ts +27 -0
- package/dist/nodes/document/flow/factories.js +30 -0
- package/dist/nodes/document/flow/family.d.ts +3 -0
- package/dist/nodes/document/flow/family.js +7 -0
- package/dist/nodes/document/flow/index.d.ts +3 -0
- package/dist/nodes/document/flow/index.js +3 -0
- package/dist/nodes/document/flow/node-type.d.ts +14 -0
- package/dist/nodes/document/flow/node-type.js +150 -0
- package/dist/nodes/document/flow/spec.d.ts +65 -0
- package/dist/nodes/document/flow/spec.js +1 -0
- package/dist/nodes/mock/flow/factories.d.ts +51 -0
- package/dist/nodes/mock/flow/factories.js +47 -0
- package/dist/nodes/mock/flow/family.d.ts +3 -0
- package/dist/nodes/mock/flow/family.js +7 -0
- package/dist/nodes/mock/flow/index.d.ts +2 -0
- package/dist/nodes/mock/flow/index.js +2 -0
- package/dist/nodes/mock/flow/node-type.d.ts +11 -0
- package/dist/nodes/mock/flow/node-type.js +51 -0
- package/dist/nodes/script/flow/check.d.ts +19 -0
- package/dist/nodes/script/flow/check.js +49 -0
- package/dist/nodes/script/flow/factories.d.ts +14 -0
- package/dist/nodes/script/flow/factories.js +15 -0
- package/dist/nodes/script/flow/family.d.ts +3 -0
- package/dist/nodes/script/flow/family.js +8 -0
- package/dist/nodes/script/flow/index.d.ts +3 -0
- package/dist/nodes/script/flow/index.js +3 -0
- package/dist/nodes/script/flow/node-type.d.ts +7 -0
- package/dist/nodes/script/flow/node-type.js +125 -0
- package/dist/nodes/script/flow/spec.d.ts +52 -0
- package/dist/nodes/script/flow/spec.js +1 -0
- package/dist/nodes/transform/flow/check.d.ts +6 -0
- package/dist/nodes/transform/flow/check.js +229 -0
- package/dist/nodes/transform/flow/factories.d.ts +52 -0
- package/dist/nodes/transform/flow/factories.js +53 -0
- package/dist/nodes/transform/flow/family.d.ts +3 -0
- package/dist/nodes/transform/flow/family.js +8 -0
- package/dist/nodes/transform/flow/index.d.ts +3 -0
- package/dist/nodes/transform/flow/index.js +3 -0
- package/dist/nodes/transform/flow/node-type.d.ts +7 -0
- package/dist/nodes/transform/flow/node-type.js +245 -0
- package/dist/nodes/transform/flow/spec.d.ts +116 -0
- package/dist/nodes/transform/flow/spec.js +10 -0
- package/dist/raw-node-advice.d.ts +16 -0
- package/dist/raw-node-advice.js +36 -0
- package/dist/raw-node.d.ts +71 -0
- package/dist/raw-node.js +116 -0
- package/dist/registry/uip/pipeline-front-door.js +5 -3
- package/dist/serialize.js +246 -549
- package/package.json +2 -2
package/dist/core/actions.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
import { splitConnectorNodeType, isTriggerDescriptor, } from './connectors.js';
|
|
2
2
|
import { FlowAction, FlowTrigger } from './node-classes.js';
|
|
3
|
-
/**
|
|
4
|
-
* The operation `type` each variant node must carry — one of, and only.
|
|
5
|
-
*
|
|
6
|
-
* @internal Serializer plumbing; an author states the variant, not the mapping.
|
|
7
|
-
*/
|
|
8
|
-
export const VARIANT_OPERATION = {
|
|
9
|
-
map: 'map',
|
|
10
|
-
filter: 'filter',
|
|
11
|
-
'group-by': 'groupBy',
|
|
12
|
-
};
|
|
13
3
|
// ─── Document extraction (uipath.ixp.*) ──────────────────────────────────────
|
|
14
4
|
//
|
|
15
5
|
// The platform's *Extract* node (that is its `display.canvasLabel`): it hands a
|
|
@@ -49,18 +39,6 @@ export function parseIxpProjectType(nodeType) {
|
|
|
49
39
|
return undefined;
|
|
50
40
|
return { slug, versionId: m[1], folderKey: m[2] };
|
|
51
41
|
}
|
|
52
|
-
// ─── Delay (core.logic.delay) ────────────────────────────────────────────────
|
|
53
|
-
/**
|
|
54
|
-
* The twelve durations the designer's dropdown offers. Purely an ENCODING
|
|
55
|
-
* detail: a duration in this list ships as `timerPreset: '<duration>'` and any
|
|
56
|
-
* other ships as `timerPreset: 'custom'` + `timerValue: '<duration>'`. Both
|
|
57
|
-
* deploy and both wait the same length of time — the author never picks.
|
|
58
|
-
* `core-definitions.test.ts` pins this list against the definition's own form.
|
|
59
|
-
*/
|
|
60
|
-
export const DELAY_PRESETS = [
|
|
61
|
-
'PT5S', 'PT15S', 'PT30S', 'PT1M', 'PT5M', 'PT15M', 'PT30M',
|
|
62
|
-
'PT1H', 'PT6H', 'PT12H', 'P1D', 'P1W',
|
|
63
|
-
];
|
|
64
42
|
// ── Built-in spec adapters ──────────────────────────────────────────────────
|
|
65
43
|
// Every factory result IS a FlowAction/FlowTrigger instance (design §4.4 pass
|
|
66
44
|
// 1), so `instanceof` can tell an SDK-owned construct from a raw literal. The
|
|
@@ -125,64 +103,6 @@ export function http(inputs) {
|
|
|
125
103
|
}
|
|
126
104
|
return builtinActionSpec({ kind: 'http', inputs });
|
|
127
105
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Declare an inline script action.
|
|
130
|
-
*
|
|
131
|
-
* @param inputs - The JavaScript body (`code`, which must `return`) and what it
|
|
132
|
-
* returns (`returns`).
|
|
133
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
134
|
-
*/
|
|
135
|
-
export function script(inputs) {
|
|
136
|
-
return builtinActionSpec({ kind: 'script', inputs });
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Declare a Transform action — a chain of declarative operations over a
|
|
140
|
-
* collection. Read the result downstream with `out('<step>')`.
|
|
141
|
-
*
|
|
142
|
-
* @remarks
|
|
143
|
-
* For a node that does ONE thing, name the variant — the emitted `.flow` then
|
|
144
|
-
* carries `core.action.transform.filter` and reads as `Filter` in the designer
|
|
145
|
-
* instead of a generic `Transform`:
|
|
146
|
-
*
|
|
147
|
-
* ```ts
|
|
148
|
-
* .step('bigOrders', transform({
|
|
149
|
-
* variant: 'filter',
|
|
150
|
-
* collection: v('orders'),
|
|
151
|
-
* operations: [
|
|
152
|
-
* { type: 'filter', filters: [{ field: 'amount', condition: 'greater_equal', value: 100 }] },
|
|
153
|
-
* ],
|
|
154
|
-
* }))
|
|
155
|
-
* ```
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* **Filter a collection, then reshape what survives**
|
|
159
|
-
* ```ts
|
|
160
|
-
* .var('catalog', types.array, [
|
|
161
|
-
* { title: 'Deep Learning', author: 'Goodfellow', difficulty: 9, pages: 800 },
|
|
162
|
-
* { title: 'Information Theory', author: 'MacKay', difficulty: 7, pages: 540 },
|
|
163
|
-
* ])
|
|
164
|
-
* .step('curate', transform({
|
|
165
|
-
* collection: v('catalog'),
|
|
166
|
-
* operations: [
|
|
167
|
-
* { type: 'filter', operation: 'and', filters: [
|
|
168
|
-
* { field: 'difficulty', condition: 'greater_than', value: 5 },
|
|
169
|
-
* { field: 'pages', condition: 'less_than', value: 600 },
|
|
170
|
-
* ] },
|
|
171
|
-
* { type: 'map', keepOriginalFields: false, mappings: [
|
|
172
|
-
* { field: 'title', transformation: 'uppercase' },
|
|
173
|
-
* { field: 'author' },
|
|
174
|
-
* ] },
|
|
175
|
-
* ],
|
|
176
|
-
* }))
|
|
177
|
-
* ```
|
|
178
|
-
*
|
|
179
|
-
* @param inputs - The `collection` to transform and the chain of `operations` to
|
|
180
|
-
* run over it.
|
|
181
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
182
|
-
*/
|
|
183
|
-
export function transform(inputs) {
|
|
184
|
-
return builtinActionSpec({ kind: 'transform', inputs });
|
|
185
|
-
}
|
|
186
106
|
/**
|
|
187
107
|
* Declare a human task — a step that pauses for a person to read some values,
|
|
188
108
|
* fill others in, and press one of the outcome buttons.
|
|
@@ -374,81 +294,6 @@ export function batchTransform(inputs) {
|
|
|
374
294
|
export function ixpExtract(inputs) {
|
|
375
295
|
return builtinActionSpec({ kind: 'ixpExtract', inputs });
|
|
376
296
|
}
|
|
377
|
-
/**
|
|
378
|
-
* Declare a delay — a step that pauses the flow for a fixed length of time and
|
|
379
|
-
* then carries on.
|
|
380
|
-
*
|
|
381
|
-
* @remarks
|
|
382
|
-
* A delay produces nothing: there is no `out('settle')` to read. It is a wait,
|
|
383
|
-
* not a value.
|
|
384
|
-
*
|
|
385
|
-
* The node itself splits that one duration across two fields (`timerPreset`
|
|
386
|
-
* holds it directly, or the literal `"custom"` with the real value in
|
|
387
|
-
* `timerValue`); the serializer picks the encoding, so you state the wait once.
|
|
388
|
-
*
|
|
389
|
-
* @example
|
|
390
|
-
* **Wait thirty seconds before carrying on**
|
|
391
|
-
* ```ts
|
|
392
|
-
* .step('settle', delay({ duration: 'PT30S' }))
|
|
393
|
-
* ```
|
|
394
|
-
*
|
|
395
|
-
* @param inputs - How long to wait (`duration`), as an ISO-8601 duration.
|
|
396
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
397
|
-
*/
|
|
398
|
-
export function delay(inputs) {
|
|
399
|
-
// Key presence, not value shape: `{ duration: undefined }` picks the
|
|
400
|
-
// duration arm and flows to check()'s DELAY_NO_DURATION diagnostic — the
|
|
401
|
-
// factory only rejects picking BOTH arms or NEITHER.
|
|
402
|
-
const hasDuration = 'duration' in inputs;
|
|
403
|
-
const hasUntil = 'until' in inputs;
|
|
404
|
-
if (hasDuration === hasUntil) {
|
|
405
|
-
throw new Error("delay() takes exactly ONE of { duration } (an ISO-8601 duration, e.g. 'PT15M') or "
|
|
406
|
-
+ "{ until } (an ISO-8601 date-time, e.g. '2026-09-01T09:00:00Z').");
|
|
407
|
-
}
|
|
408
|
-
return builtinActionSpec({ kind: 'delay', inputs });
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Declare a PLACEHOLDER step — "a real node goes here later".
|
|
412
|
-
*
|
|
413
|
-
* @remarks
|
|
414
|
-
* A mock takes **no inputs and publishes nothing**. It is a marker on the canvas
|
|
415
|
-
* that keeps the graph wired and the flow deployable while one step is still
|
|
416
|
-
* missing — not a stub that returns test data. `out('extractInvoice')` is
|
|
417
|
-
* refused at compile time (`MOCK_HAS_NO_OUTPUT`) because it would read `null` at
|
|
418
|
-
* run time, always.
|
|
419
|
-
*
|
|
420
|
-
* Say what belongs there in the step's own name and in the label the canvas
|
|
421
|
-
* shows; the corpus's placeholders read like
|
|
422
|
-
* `"Extract Invoice Fields (mock — IxP model not yet published)"`.
|
|
423
|
-
*
|
|
424
|
-
* ### Why there are no arguments (convention #191 — the family contract)
|
|
425
|
-
*
|
|
426
|
-
* The platform's `core.logic.mock@1.0.0` declares **no `inputDefinition`** and one
|
|
427
|
-
* output whose `source` is the literal `"null"`. Measured over the 4,033 distinct
|
|
428
|
-
* archived `.flow` artifacts: **74 mock instances in 62 flows, and 0 carrying a
|
|
429
|
-
* fixture anywhere in the node** — 71 of them with `inputs: {}` or no `inputs`
|
|
430
|
-
* key. The 3 exceptions carry free-text `placeholder` / `_placeholder` keys the
|
|
431
|
-
* definition never declares, invented by agents on runs that scored 0.9 and 0.4.
|
|
432
|
-
*
|
|
433
|
-
* **This is NOT a local runner's `kind: 'mock'` test construct**, which returns a
|
|
434
|
-
* baked fixture. They are different things that share
|
|
435
|
-
* a name, and a `mock({ fixture })` surface would emit a node whose local
|
|
436
|
-
* behaviour and deployed behaviour disagree silently — see
|
|
437
|
-
* [#125](https://github.com/UiPath/flow-builder-sdk/issues/125). Nothing this SDK
|
|
438
|
-
* emits opens that channel: an SDK-authored mock publishes `null` locally,
|
|
439
|
-
* exactly as the platform does.
|
|
440
|
-
*
|
|
441
|
-
* @example
|
|
442
|
-
* **Hold a step's place until the real node exists**
|
|
443
|
-
* ```ts
|
|
444
|
-
* .step('extractInvoice', mock()) // ← swap for the IxP node once the project exists
|
|
445
|
-
* ```
|
|
446
|
-
*
|
|
447
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
448
|
-
*/
|
|
449
|
-
export function mock() {
|
|
450
|
-
return builtinActionSpec({ kind: 'mock' });
|
|
451
|
-
}
|
|
452
297
|
/**
|
|
453
298
|
* Invoke a deployed RPA (robotic process automation) workflow — a classic
|
|
454
299
|
* UI-automation process, published to Orchestrator, run by a robot.
|
|
@@ -764,7 +609,7 @@ export function agenticProcess(inputs) {
|
|
|
764
609
|
* @remarks
|
|
765
610
|
* **Coded and low-code agents are the same node.** This one factory authors both.
|
|
766
611
|
* `registry get` on a coded agent and on a low-code one returns the same node type,
|
|
767
|
-
* the same service type, the same `sortOrder
|
|
612
|
+
* the same service type, the same `sortOrder` and the same bindings shape; the
|
|
768
613
|
* only difference is the icon, which is what `flavour` sets. Which kind a resource
|
|
769
614
|
* is a property of what somebody published, not of the flow — so if a task asks for
|
|
770
615
|
* "a coded agent", what it is asking you to get right is the RESOURCE you point at.
|
|
@@ -866,157 +711,6 @@ export function agent(inputs) {
|
|
|
866
711
|
export function inlineAgent(inputs) {
|
|
867
712
|
return builtinActionSpec({ kind: 'inlineAgent', inputs });
|
|
868
713
|
}
|
|
869
|
-
/**
|
|
870
|
-
* Classify a document into a document type (`uipath.document.classify`). The
|
|
871
|
-
* result publishes `ClassificationResult` — an array of typed classifications
|
|
872
|
-
* with page ranges and confidences.
|
|
873
|
-
*
|
|
874
|
-
* @param inputs - The file reference and optional page range / split / model settings.
|
|
875
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
876
|
-
*/
|
|
877
|
-
export function documentClassify(inputs) {
|
|
878
|
-
return builtinActionSpec({ kind: 'documentClassify', inputs });
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* Extract fields from a document with an INLINE schema — Dynamic Extract
|
|
882
|
-
* (`uipath.ixp.extract-document-builder`), the newer of the two extraction
|
|
883
|
-
* shapes. No deployed IXP project is referenced: the extraction schema rides
|
|
884
|
-
* the node. The result publishes `ExtractionResult` (and `Taxonomy`).
|
|
885
|
-
*
|
|
886
|
-
* @param inputs - The file reference, the inline extraction schema, and
|
|
887
|
-
* optional page range / model settings.
|
|
888
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
889
|
-
*/
|
|
890
|
-
export function dynamicExtract(inputs) {
|
|
891
|
-
return builtinActionSpec({ kind: 'dynamicExtract', inputs });
|
|
892
|
-
}
|
|
893
|
-
/**
|
|
894
|
-
* Query entity records from Data Fabric (`core.datafabric.read`). The result
|
|
895
|
-
* publishes to the step's `output`; downstream references re-fetch fresh data
|
|
896
|
-
* at activation time (the engine re-runs the query rather than caching).
|
|
897
|
-
*
|
|
898
|
-
* @remarks
|
|
899
|
-
* This node is **read-one AND query-many**, on its 1.4 definition: `resultMode:
|
|
900
|
-
* 'multiple'` publishes the matching records under `output.results`, and the
|
|
901
|
-
* platform renames the node "Query entity records" to say so. The SDK still
|
|
902
|
-
* pins 1.0 — read-one — as the no-`{ version }` default, so passing
|
|
903
|
-
* `resultMode` is what selects 1.4; see {@link DataFabricReadInputs.resultMode}.
|
|
904
|
-
*
|
|
905
|
-
* The native family covers all four CRUD verbs: this one,
|
|
906
|
-
* {@link dataFabricCreate}, {@link dataFabricUpdate} and
|
|
907
|
-
* {@link dataFabricDelete}. What it does NOT cover is get-by-id, a query row
|
|
908
|
-
* limit, file record fields, and entity events — those are operations on the
|
|
909
|
-
* SAME product reached through its Integration Service connector,
|
|
910
|
-
* `uipath-uipath-dataservice` (the tenant displays it as **UiPath Data
|
|
911
|
-
* Fabric**). So a flow that needs one of those still straddles two surfaces,
|
|
912
|
-
* and the connector remains the one surface that covers everything:
|
|
913
|
-
*
|
|
914
|
-
* ```ts
|
|
915
|
-
* .step('byId', connector('uipath-uipath-dataservice', 'get-entity-record-by-id',
|
|
916
|
-
* { entityName: 'Contracts', recordId: input('id') }, { connection: 'df' }))
|
|
917
|
-
* ```
|
|
918
|
-
*
|
|
919
|
-
* Get-by-id matters for long text. This node is a query even when it reads one
|
|
920
|
-
* record by an `Id` filter, and a Data Service query returns a PREVIEW of a
|
|
921
|
-
* long-text (`MULTILINE_MAX`) field: the first 10,000 characters plus
|
|
922
|
-
* `...[Truncated]`, with no flag in the output. A 15,551-character value comes
|
|
923
|
-
* back as 10,014 characters. When a field may exceed 10,000 characters, read
|
|
924
|
-
* it with `get-entity-record-by-id`, which returns the whole value
|
|
925
|
-
* (flow-builder-sdk#954).
|
|
926
|
-
*
|
|
927
|
-
* A connector operation's body fields come from the entity, so the library
|
|
928
|
-
* cannot carry them: run `uip maestro registry prepare uipath-uipath-dataservice
|
|
929
|
-
* get-entity-record-by-id -f entityName=<Entity>` first.
|
|
930
|
-
* The routing table is in the `data-fabric.md` reference and the parent-field
|
|
931
|
-
* loop in `connector-params.md` — cited by name rather than linked, because this
|
|
932
|
-
* comment renders both into the flat corpus, where those files sit alongside
|
|
933
|
-
* it, and onto the site, where each symbol is its own page and a relative
|
|
934
|
-
* `./data-fabric` resolves to nothing.
|
|
935
|
-
*
|
|
936
|
-
* @param inputs - The entity, optional filter rows, result mode, and folder scope.
|
|
937
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
938
|
-
*/
|
|
939
|
-
export function dataFabricRead(inputs) {
|
|
940
|
-
return builtinActionSpec({ kind: 'dataFabricRead', inputs });
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* Create an entity record in Data Fabric (`core.datafabric.create`). The new
|
|
944
|
-
* record publishes to the step's `output`, so a following
|
|
945
|
-
* {@link dataFabricUpdate} or {@link dataFabricDelete} can read its id.
|
|
946
|
-
*
|
|
947
|
-
* @remarks
|
|
948
|
-
* `values` must name at least one column — the node's schema rejects an empty
|
|
949
|
-
* field list rather than inserting a blank row, and `check` says so before the
|
|
950
|
-
* platform does. Field names are the ENTITY's, so copy them from the scenario
|
|
951
|
-
* or the tenant; nothing offline can tell a real column from a typo.
|
|
952
|
-
*
|
|
953
|
-
* The published `output` is the record as a query returns it, so a long-text
|
|
954
|
-
* (`MULTILINE_MAX`) field longer than 10,000 characters comes back cut, with
|
|
955
|
-
* `...[Truncated]` appended, even though the whole value was stored. Use the
|
|
956
|
-
* value you passed in, or re-read the record with the connector's
|
|
957
|
-
* `get-entity-record-by-id`, when the whole text is needed (flow-builder-sdk#954).
|
|
958
|
-
*
|
|
959
|
-
* See {@link dataFabricRead} for what the native family still does not cover
|
|
960
|
-
* and which connector operation covers it.
|
|
961
|
-
*
|
|
962
|
-
* @param inputs - The entity, the columns the record starts with, and folder scope.
|
|
963
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
964
|
-
*/
|
|
965
|
-
export function dataFabricCreate(inputs) {
|
|
966
|
-
return builtinActionSpec({ kind: 'dataFabricCreate', inputs });
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
* Update an entity record in Data Fabric (`core.datafabric.update`). Target the
|
|
970
|
-
* record by id or through an earlier {@link dataFabricRead} step; downstream
|
|
971
|
-
* reads of this step observe the record AFTER the write.
|
|
972
|
-
*
|
|
973
|
-
* @remarks
|
|
974
|
-
* `set` must write at least one column: an empty `set` is a no-op the platform
|
|
975
|
-
* reports as success, so `check` rejects it.
|
|
976
|
-
*
|
|
977
|
-
* See {@link dataFabricRead} for what the native family still does not cover
|
|
978
|
-
* and which connector operation covers it.
|
|
979
|
-
*
|
|
980
|
-
* @param inputs - The entity, the record selector, and the columns to write.
|
|
981
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
982
|
-
*/
|
|
983
|
-
export function dataFabricUpdate(inputs) {
|
|
984
|
-
assertOneRecordRef(inputs.record, 'dataFabricUpdate');
|
|
985
|
-
return builtinActionSpec({ kind: 'dataFabricUpdate', inputs });
|
|
986
|
-
}
|
|
987
|
-
/**
|
|
988
|
-
* Delete an entity record from Data Fabric (`core.datafabric.delete`). Target
|
|
989
|
-
* the record by id or through an earlier {@link dataFabricRead} step, exactly
|
|
990
|
-
* as {@link dataFabricUpdate} does.
|
|
991
|
-
*
|
|
992
|
-
* @remarks
|
|
993
|
-
* A delete **publishes nothing** — its definition declares no output — so
|
|
994
|
-
* `$vars.<step>.output` is undefined at run time and `check` rejects a read of
|
|
995
|
-
* it. Take what you need off the read step that found the record, before the
|
|
996
|
-
* delete.
|
|
997
|
-
*
|
|
998
|
-
* See {@link dataFabricRead} for what the native family still does not cover
|
|
999
|
-
* and which connector operation covers it.
|
|
1000
|
-
*
|
|
1001
|
-
* @param inputs - The entity, the record selector, and folder scope.
|
|
1002
|
-
* @returns An action spec to pass to `.step(name, …)`.
|
|
1003
|
-
*/
|
|
1004
|
-
export function dataFabricDelete(inputs) {
|
|
1005
|
-
assertOneRecordRef(inputs.record, 'dataFabricDelete');
|
|
1006
|
-
return builtinActionSpec({ kind: 'dataFabricDelete', inputs });
|
|
1007
|
-
}
|
|
1008
|
-
/**
|
|
1009
|
-
* `record` names exactly ONE of `{ byId }` / `{ fromRead }`. Both forms are
|
|
1010
|
-
* optional properties on the same object type, so TypeScript alone cannot
|
|
1011
|
-
* refuse `{}` — and an empty selector compiles into a write with no target.
|
|
1012
|
-
*/
|
|
1013
|
-
function assertOneRecordRef(record, factory) {
|
|
1014
|
-
const byId = record?.byId !== undefined;
|
|
1015
|
-
const fromRead = typeof record?.fromRead === 'string';
|
|
1016
|
-
if (byId === fromRead) {
|
|
1017
|
-
throw new Error(`${factory}() targets exactly ONE of record: { byId } or record: { fromRead: '<step>' }.`);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
714
|
/**
|
|
1021
715
|
* Declare an Orchestrator QUEUE ITEM step.
|
|
1022
716
|
*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a `.flow` binding row binds, as one comparable key.
|
|
3
|
+
*
|
|
4
|
+
* The key is `(resource, resourceKey, resourceSubType, propertyAttribute, name)`.
|
|
5
|
+
* It is NOT the row `id`: nodes never reference a row by id, and the two
|
|
6
|
+
* producers name rows differently (compile writes `b<Name><Prop>`, the canvas a
|
|
7
|
+
* random 9-character id), so two rows for the same property never share an id.
|
|
8
|
+
*
|
|
9
|
+
* `name` is part of the key. For a connection row it is the definition's own
|
|
10
|
+
* `<bindings.NAME>` placeholder, and two definitions sharing one connection
|
|
11
|
+
* spell it differently (`uipath-uipath-http connection`, `uipath-salesforce-slack
|
|
12
|
+
* connection`); each needs its own row, which is how compile keys them
|
|
13
|
+
* (`serialize.ts`, flow-builder-sdk#865). Process and queue rows carry
|
|
14
|
+
* `name === propertyAttribute`, so the extra field does not split them.
|
|
15
|
+
*
|
|
16
|
+
* Example: `{ resource: 'process', resourceKey: 'e05d...', resourceSubType: 'Flow',
|
|
17
|
+
* propertyAttribute: 'name', name: 'name' }` has the same identity whether its
|
|
18
|
+
* id is `bCalleeName` or `b7CE8ALjn`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function bindingIdentity(b: {
|
|
21
|
+
readonly [k: string]: unknown;
|
|
22
|
+
}): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a `.flow` binding row binds, as one comparable key.
|
|
3
|
+
*
|
|
4
|
+
* The key is `(resource, resourceKey, resourceSubType, propertyAttribute, name)`.
|
|
5
|
+
* It is NOT the row `id`: nodes never reference a row by id, and the two
|
|
6
|
+
* producers name rows differently (compile writes `b<Name><Prop>`, the canvas a
|
|
7
|
+
* random 9-character id), so two rows for the same property never share an id.
|
|
8
|
+
*
|
|
9
|
+
* `name` is part of the key. For a connection row it is the definition's own
|
|
10
|
+
* `<bindings.NAME>` placeholder, and two definitions sharing one connection
|
|
11
|
+
* spell it differently (`uipath-uipath-http connection`, `uipath-salesforce-slack
|
|
12
|
+
* connection`); each needs its own row, which is how compile keys them
|
|
13
|
+
* (`serialize.ts`, flow-builder-sdk#865). Process and queue rows carry
|
|
14
|
+
* `name === propertyAttribute`, so the extra field does not split them.
|
|
15
|
+
*
|
|
16
|
+
* Example: `{ resource: 'process', resourceKey: 'e05d...', resourceSubType: 'Flow',
|
|
17
|
+
* propertyAttribute: 'name', name: 'name' }` has the same identity whether its
|
|
18
|
+
* id is `bCalleeName` or `b7CE8ALjn`.
|
|
19
|
+
*/
|
|
20
|
+
export function bindingIdentity(b) {
|
|
21
|
+
return JSON.stringify([
|
|
22
|
+
b.resource ?? null,
|
|
23
|
+
b.resourceKey ?? null,
|
|
24
|
+
b.resourceSubType ?? null,
|
|
25
|
+
b.propertyAttribute ?? null,
|
|
26
|
+
b.name ?? null,
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A context-grounding index's node type, both ways.
|
|
3
|
+
*
|
|
4
|
+
* The platform names an index's resource node
|
|
5
|
+
* `uipath.agent.resource.context.index.<slug>.<uuid>`: the slug is derived from
|
|
6
|
+
* the index's display name, and the uuid is the index's id. Serialize builds the
|
|
7
|
+
* type from an author's `{ name, id }`; decompile reads `{ slug, id }` back out
|
|
8
|
+
* of a file's type. Keeping both directions here is what keeps them inverses.
|
|
9
|
+
*/
|
|
10
|
+
/** The type prefix every context-index resource node shares. */
|
|
11
|
+
export declare const CONTEXT_INDEX_TYPE_PREFIX = "uipath.agent.resource.context.index.";
|
|
12
|
+
/**
|
|
13
|
+
* The slug for an index name: lower-cased, with every run of non-alphanumerics
|
|
14
|
+
* collapsed to a single `-`. Measured against the platform's own type for
|
|
15
|
+
* "Billing Dispute SOP Index" → `billing-dispute-sop-index`, and pinned by a
|
|
16
|
+
* test, because a derived identifier that disagrees with the registry's is a
|
|
17
|
+
* node type the tenant has never heard of. A slug never contains a `.`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function contextIndexSlug(name: string): string;
|
|
20
|
+
/** The node type for an index: `…context.index.<slug>.<uuid>`. */
|
|
21
|
+
export declare function contextIndexType(spec: {
|
|
22
|
+
name: string;
|
|
23
|
+
id: string;
|
|
24
|
+
}): string;
|
|
25
|
+
/**
|
|
26
|
+
* The `{ slug, id }` a context-index node type carries, or `undefined` when the
|
|
27
|
+
* type is not one. The id is everything after the LAST `.`, because a slug has
|
|
28
|
+
* no dot in it. Either part can be `''` (the SDK once wrote `…<slug>.` for an
|
|
29
|
+
* index with no id).
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseContextIndexType(type: string): {
|
|
32
|
+
slug: string;
|
|
33
|
+
id: string;
|
|
34
|
+
} | undefined;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A context-grounding index's node type, both ways.
|
|
3
|
+
*
|
|
4
|
+
* The platform names an index's resource node
|
|
5
|
+
* `uipath.agent.resource.context.index.<slug>.<uuid>`: the slug is derived from
|
|
6
|
+
* the index's display name, and the uuid is the index's id. Serialize builds the
|
|
7
|
+
* type from an author's `{ name, id }`; decompile reads `{ slug, id }` back out
|
|
8
|
+
* of a file's type. Keeping both directions here is what keeps them inverses.
|
|
9
|
+
*/
|
|
10
|
+
/** The type prefix every context-index resource node shares. */
|
|
11
|
+
export const CONTEXT_INDEX_TYPE_PREFIX = 'uipath.agent.resource.context.index.';
|
|
12
|
+
/**
|
|
13
|
+
* The slug for an index name: lower-cased, with every run of non-alphanumerics
|
|
14
|
+
* collapsed to a single `-`. Measured against the platform's own type for
|
|
15
|
+
* "Billing Dispute SOP Index" → `billing-dispute-sop-index`, and pinned by a
|
|
16
|
+
* test, because a derived identifier that disagrees with the registry's is a
|
|
17
|
+
* node type the tenant has never heard of. A slug never contains a `.`.
|
|
18
|
+
*/
|
|
19
|
+
export function contextIndexSlug(name) {
|
|
20
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
21
|
+
}
|
|
22
|
+
/** The node type for an index: `…context.index.<slug>.<uuid>`. */
|
|
23
|
+
export function contextIndexType(spec) {
|
|
24
|
+
return `${CONTEXT_INDEX_TYPE_PREFIX}${contextIndexSlug(spec.name)}.${spec.id}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The `{ slug, id }` a context-index node type carries, or `undefined` when the
|
|
28
|
+
* type is not one. The id is everything after the LAST `.`, because a slug has
|
|
29
|
+
* no dot in it. Either part can be `''` (the SDK once wrote `…<slug>.` for an
|
|
30
|
+
* index with no id).
|
|
31
|
+
*/
|
|
32
|
+
export function parseContextIndexType(type) {
|
|
33
|
+
if (!type.startsWith(CONTEXT_INDEX_TYPE_PREFIX))
|
|
34
|
+
return undefined;
|
|
35
|
+
const tail = type.slice(CONTEXT_INDEX_TYPE_PREFIX.length);
|
|
36
|
+
const dot = tail.lastIndexOf('.');
|
|
37
|
+
return dot < 0 ? { slug: tail, id: '' } : { slug: tail.slice(0, dot), id: tail.slice(dot + 1) };
|
|
38
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node types that never have a `definitions[]` row.
|
|
3
|
+
*
|
|
4
|
+
* A `.flow` file pairs every node's `(type, typeVersion)` with a definition —
|
|
5
|
+
* except these. The platform special-cases them ahead of definition resolution:
|
|
6
|
+
* a sticky note has no manifest, `flow validate` skips it, BPMN conversion skips
|
|
7
|
+
* it, and an edge that touches one is dropped. So "this node pins a pair no
|
|
8
|
+
* definition covers" is a real defect for every other type and the normal state
|
|
9
|
+
* for these.
|
|
10
|
+
*/
|
|
11
|
+
/** The wire type of a canvas sticky note. */
|
|
12
|
+
export declare const STICKY_NOTE_TYPE = "stickyNote";
|
|
13
|
+
/** The `typeVersion` Studio Web stamps on a sticky note. The type has no manifest to take it from. */
|
|
14
|
+
export declare const STICKY_NOTE_TYPE_VERSION = "1.0.0";
|
|
15
|
+
/** Node types that carry no definition by design. */
|
|
16
|
+
export declare const DEFINITIONLESS_NODE_TYPES: ReadonlySet<string>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node types that never have a `definitions[]` row.
|
|
3
|
+
*
|
|
4
|
+
* A `.flow` file pairs every node's `(type, typeVersion)` with a definition —
|
|
5
|
+
* except these. The platform special-cases them ahead of definition resolution:
|
|
6
|
+
* a sticky note has no manifest, `flow validate` skips it, BPMN conversion skips
|
|
7
|
+
* it, and an edge that touches one is dropped. So "this node pins a pair no
|
|
8
|
+
* definition covers" is a real defect for every other type and the normal state
|
|
9
|
+
* for these.
|
|
10
|
+
*/
|
|
11
|
+
/** The wire type of a canvas sticky note. */
|
|
12
|
+
export const STICKY_NOTE_TYPE = 'stickyNote';
|
|
13
|
+
/** The `typeVersion` Studio Web stamps on a sticky note. The type has no manifest to take it from. */
|
|
14
|
+
export const STICKY_NOTE_TYPE_VERSION = '1.0.0';
|
|
15
|
+
/** Node types that carry no definition by design. */
|
|
16
|
+
export const DEFINITIONLESS_NODE_TYPES = new Set([STICKY_NOTE_TYPE]);
|
|
@@ -25,3 +25,9 @@ export declare function definitionHasErrorPort(def: any): boolean;
|
|
|
25
25
|
export declare function errorPortRefusal(stepName: string, def: any, o?: {
|
|
26
26
|
bundled?: boolean;
|
|
27
27
|
}): string;
|
|
28
|
+
/**
|
|
29
|
+
* The ONERROR_NO_ERROR_PORT sentence for a registered node type whose definition is
|
|
30
|
+
* built per tenant and which declares no error port (`errorPort: false`), so there
|
|
31
|
+
* is no definition to name. Shared with serialize, which throws it for the same node.
|
|
32
|
+
*/
|
|
33
|
+
export declare function declaredErrorPortRefusal(stepName: string, typeName: string, version: string): string;
|
package/dist/core/error-port.js
CHANGED
|
@@ -34,3 +34,12 @@ export function errorPortRefusal(stepName, def, o = {}) {
|
|
|
34
34
|
+ `handle the node does not have. Handle the failure downstream instead`
|
|
35
35
|
+ (o.bundled ? '.' : `, or pass the definition exactly as \`uip maestro flow registry get\` returns it.`);
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* The ONERROR_NO_ERROR_PORT sentence for a registered node type whose definition is
|
|
39
|
+
* built per tenant and which declares no error port (`errorPort: false`), so there
|
|
40
|
+
* is no definition to name. Shared with serialize, which throws it for the same node.
|
|
41
|
+
*/
|
|
42
|
+
export function declaredErrorPortRefusal(stepName, typeName, version) {
|
|
43
|
+
return `Step "${stepName}" is a ${typeName}@${version} node, which has no error port, so the edge would leave a `
|
|
44
|
+
+ 'handle the node does not have. Handle the failure downstream instead.';
|
|
45
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The product's spellings of the form-field types the SDK models.
|
|
3
|
+
*
|
|
4
|
+
* A quick form's field `type` is read by the product through
|
|
5
|
+
* `@uipath/hitl-schema-types` `normalizeFieldType`. Its canonical stored values
|
|
6
|
+
* are `string`, `number`, `boolean`, `datetime`, … and it accepts aliases for
|
|
7
|
+
* each: `text` is an alias of `string`, `date-time` of `datetime`, and .NET
|
|
8
|
+
* names such as `System.String` resolve too. The designer saves the canonical
|
|
9
|
+
* value, so a canvas-built form says `"string"`; the SDK (like flow-v1's
|
|
10
|
+
* serializer and `uip maestro flow hitl add`) writes `text`.
|
|
11
|
+
*
|
|
12
|
+
* So `"string"` and `"text"` are the same field on the wire. This table maps
|
|
13
|
+
* each product spelling of the four types {@link FormFieldType} models to the
|
|
14
|
+
* SDK's spelling, so decompile hands the author source `check` accepts.
|
|
15
|
+
* A type the SDK does not model (`integer`, `date`,
|
|
16
|
+
* `file`, …) has no entry: it stays as written, and `check` reports it.
|
|
17
|
+
*
|
|
18
|
+
* Mirrors `resolveFieldType` in `@uipath/hitl-schema-types` 1.1.6, restricted
|
|
19
|
+
* to the groups that resolve to `string`, `number`, `boolean` and `datetime`
|
|
20
|
+
* (minus `singleSelect` / `enum` / `union` / …, which resolve to `string` but
|
|
21
|
+
* are not a plain text box).
|
|
22
|
+
*/
|
|
23
|
+
import type { FormFieldType } from './actions.js';
|
|
24
|
+
/**
|
|
25
|
+
* The SDK's spelling of a wire form-field type, or `undefined` when the SDK
|
|
26
|
+
* does not model that type.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* sdkFormFieldType('string') // 'text'
|
|
30
|
+
* sdkFormFieldType('datetime') // 'date-time'
|
|
31
|
+
* sdkFormFieldType('integer') // undefined
|
|
32
|
+
*/
|
|
33
|
+
export declare function sdkFormFieldType(wire: unknown): FormFieldType | undefined;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const PRODUCT_SPELLINGS = {
|
|
2
|
+
text: 'text',
|
|
3
|
+
string: 'text',
|
|
4
|
+
String: 'text',
|
|
5
|
+
'System.String': 'text',
|
|
6
|
+
'System.Char': 'text',
|
|
7
|
+
Char: 'text',
|
|
8
|
+
number: 'number',
|
|
9
|
+
Number: 'number',
|
|
10
|
+
boolean: 'boolean',
|
|
11
|
+
Boolean: 'boolean',
|
|
12
|
+
'System.Boolean': 'boolean',
|
|
13
|
+
'date-time': 'date-time',
|
|
14
|
+
datetime: 'date-time',
|
|
15
|
+
dateTime: 'date-time',
|
|
16
|
+
DateTime: 'date-time',
|
|
17
|
+
'System.DateTime': 'date-time',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The SDK's spelling of a wire form-field type, or `undefined` when the SDK
|
|
21
|
+
* does not model that type.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* sdkFormFieldType('string') // 'text'
|
|
25
|
+
* sdkFormFieldType('datetime') // 'date-time'
|
|
26
|
+
* sdkFormFieldType('integer') // undefined
|
|
27
|
+
*/
|
|
28
|
+
export function sdkFormFieldType(wire) {
|
|
29
|
+
return typeof wire === 'string' && Object.hasOwn(PRODUCT_SPELLINGS, wire) ? PRODUCT_SPELLINGS[wire] : undefined;
|
|
30
|
+
}
|
|
@@ -79,6 +79,14 @@ import type { HitlInputs } from './actions.js';
|
|
|
79
79
|
* nothing else recognises.
|
|
80
80
|
*/
|
|
81
81
|
export declare function outcomeSlug(name: unknown, index: number): string;
|
|
82
|
+
/**
|
|
83
|
+
* The id an outcome is emitted with: the author's `id` when the object form
|
|
84
|
+
* carries one (a decompiled flow keeps the canvas's ids, for example
|
|
85
|
+
* `outcome-1778015958049`), else {@link outcomeSlug} of its name. Every reader
|
|
86
|
+
* of outcome ids goes through this, so the `outcome-<id>` port an edge leaves
|
|
87
|
+
* from and the id `schema.outcomes[]` declares cannot disagree (#1130).
|
|
88
|
+
*/
|
|
89
|
+
export declare function outcomeIdOf(outcome: unknown, index: number): string;
|
|
82
90
|
/** One outcome's exit. */
|
|
83
91
|
export interface HitlOutcomeExit {
|
|
84
92
|
/** The outcome NAME — what `.stepSwitch` arms and `out('<step>', 'Action')` compare against. */
|
|
@@ -14,6 +14,22 @@ export function outcomeSlug(name, index) {
|
|
|
14
14
|
.replace(/^-+|-+$/g, '');
|
|
15
15
|
return slug || `outcome-${index + 1}`;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* The id an outcome is emitted with: the author's `id` when the object form
|
|
19
|
+
* carries one (a decompiled flow keeps the canvas's ids, for example
|
|
20
|
+
* `outcome-1778015958049`), else {@link outcomeSlug} of its name. Every reader
|
|
21
|
+
* of outcome ids goes through this, so the `outcome-<id>` port an edge leaves
|
|
22
|
+
* from and the id `schema.outcomes[]` declares cannot disagree (#1130).
|
|
23
|
+
*/
|
|
24
|
+
export function outcomeIdOf(outcome, index) {
|
|
25
|
+
if (outcome !== null && typeof outcome === 'object') {
|
|
26
|
+
const { id, name } = outcome;
|
|
27
|
+
if (typeof id === 'string' && id !== '')
|
|
28
|
+
return id;
|
|
29
|
+
return outcomeSlug(name, index);
|
|
30
|
+
}
|
|
31
|
+
return outcomeSlug(outcome, index);
|
|
32
|
+
}
|
|
17
33
|
/**
|
|
18
34
|
* The two human-task node types whose exits the product derives from
|
|
19
35
|
* `inputs.schema.outcomes`. Keyed on TYPE, never on whether `schema.outcomes` is
|
|
@@ -33,7 +49,7 @@ export function hitlExitModel(inputs, pinnedVersion) {
|
|
|
33
49
|
const name = typeof o === 'string' ? o : o?.name;
|
|
34
50
|
return {
|
|
35
51
|
value: String(name ?? ''),
|
|
36
|
-
port: `outcome-${
|
|
52
|
+
port: `outcome-${outcomeIdOf(o, i)}`,
|
|
37
53
|
endsProcess: typeof o !== 'string' && o?.action === 'End',
|
|
38
54
|
};
|
|
39
55
|
});
|