@uipath/maestro-builder-sdk 6.29.0 → 6.29.2
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/core/definition-handles.d.ts +51 -0
- package/dist/core/definition-handles.js +95 -0
- package/dist/core/raw-node-exits.d.ts +28 -0
- package/dist/core/raw-node-exits.js +10 -0
- package/dist/decompile.js +74 -2
- package/dist/flow-step-exits.js +5 -0
- package/dist/merge-roundtrip.js +3 -26
- package/dist/raw-node.js +7 -0
- package/dist/serialize.js +1 -12
- package/package.json +2 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source handles a node's definition declares, read against the node's own
|
|
3
|
+
* inputs — one reader for every layer that has to know which ports a node can
|
|
4
|
+
* leave on (`merge-roundtrip.ts`'s handle checks, `decompile`'s arm recovery for
|
|
5
|
+
* a node with no typed factory, and `.stepSwitch` over a `rawNode`).
|
|
6
|
+
*
|
|
7
|
+
* A definition lists its handles in `handleConfiguration[].handles[]`. A static
|
|
8
|
+
* handle is its `id`; a REPEATED one is a template expanded once per item of an
|
|
9
|
+
* input array:
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* { id: 'case-{item.id}', type: 'source', repeat: 'inputs.criteria' }
|
|
13
|
+
* inputs.criteria = [{ id: 'returns' }, { id: 'billing' }]
|
|
14
|
+
* → case-returns, case-billing
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* This is how `core.logic.agentic-switch` (one exit per choice, plus `default`)
|
|
18
|
+
* and `core.logic.switch` (one per case) declare their exits.
|
|
19
|
+
*/
|
|
20
|
+
type Def = {
|
|
21
|
+
readonly [k: string]: unknown;
|
|
22
|
+
} | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Every source handle `def` declares for a node with `inputs`, in declaration
|
|
25
|
+
* order, templates expanded. `undefined` when `def` has no
|
|
26
|
+
* `handleConfiguration`, or has a template this cannot expand (a `repeat` that
|
|
27
|
+
* is not an `inputs.` path), so a caller can tell "no handles" from "cannot
|
|
28
|
+
* know".
|
|
29
|
+
*/
|
|
30
|
+
export declare function expandSourceHandles(def: Def, inputs: unknown): string[] | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The FORWARD exits a node's definition declares when it has more than one —
|
|
33
|
+
* every source handle except `error` and an agent's artifact handles, templates
|
|
34
|
+
* expanded. `undefined` for a definition with one forward exit or fewer, or one
|
|
35
|
+
* whose handles cannot be known: such a node has no fan-out to route.
|
|
36
|
+
*/
|
|
37
|
+
export declare function forwardFanOut(def: Def, inputs: unknown): string[] | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* The port a node's main path leaves on — the edge a plain `.step()` writes
|
|
40
|
+
* and a following step continues from: the first concrete forward source
|
|
41
|
+
* handle (`isDefaultForType` wins), else `output`. `undefined` when every
|
|
42
|
+
* forward source handle is templated (`case-{item.id}`), so no main path leaves
|
|
43
|
+
* the node.
|
|
44
|
+
*
|
|
45
|
+
* `serialize` writes the main-path edge on this port, and `decompile` reads the
|
|
46
|
+
* main path back off it, so the two must agree: a `core.logic.agentic-switch`
|
|
47
|
+
* (`case-{item.id}` + `default`) continues on `default`, and each other wired
|
|
48
|
+
* exit is a `.stepToList('case-<id>', …)` (#1214).
|
|
49
|
+
*/
|
|
50
|
+
export declare function contributionPort(def: Def): string | undefined;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source handles a node's definition declares, read against the node's own
|
|
3
|
+
* inputs — one reader for every layer that has to know which ports a node can
|
|
4
|
+
* leave on (`merge-roundtrip.ts`'s handle checks, `decompile`'s arm recovery for
|
|
5
|
+
* a node with no typed factory, and `.stepSwitch` over a `rawNode`).
|
|
6
|
+
*
|
|
7
|
+
* A definition lists its handles in `handleConfiguration[].handles[]`. A static
|
|
8
|
+
* handle is its `id`; a REPEATED one is a template expanded once per item of an
|
|
9
|
+
* input array:
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* { id: 'case-{item.id}', type: 'source', repeat: 'inputs.criteria' }
|
|
13
|
+
* inputs.criteria = [{ id: 'returns' }, { id: 'billing' }]
|
|
14
|
+
* → case-returns, case-billing
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* This is how `core.logic.agentic-switch` (one exit per choice, plus `default`)
|
|
18
|
+
* and `core.logic.switch` (one per case) declare their exits.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Every source handle `def` declares for a node with `inputs`, in declaration
|
|
22
|
+
* order, templates expanded. `undefined` when `def` has no
|
|
23
|
+
* `handleConfiguration`, or has a template this cannot expand (a `repeat` that
|
|
24
|
+
* is not an `inputs.` path), so a caller can tell "no handles" from "cannot
|
|
25
|
+
* know".
|
|
26
|
+
*/
|
|
27
|
+
export function expandSourceHandles(def, inputs) {
|
|
28
|
+
const groups = def?.handleConfiguration;
|
|
29
|
+
if (!Array.isArray(groups))
|
|
30
|
+
return undefined;
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const g of groups) {
|
|
33
|
+
for (const h of (g?.handles ?? [])) {
|
|
34
|
+
if (h?.type !== 'source' || typeof h.id !== 'string')
|
|
35
|
+
continue;
|
|
36
|
+
const template = /\{item\.([A-Za-z0-9_]+)\}/.exec(h.id);
|
|
37
|
+
if (!template) {
|
|
38
|
+
if (!out.includes(h.id))
|
|
39
|
+
out.push(h.id);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (typeof h.repeat !== 'string' || !h.repeat.startsWith('inputs.'))
|
|
43
|
+
return undefined;
|
|
44
|
+
let items = inputs;
|
|
45
|
+
for (const seg of h.repeat.slice('inputs.'.length).split('.'))
|
|
46
|
+
items = items?.[seg];
|
|
47
|
+
for (const item of Array.isArray(items) ? items : []) {
|
|
48
|
+
const v = item?.[template[1]];
|
|
49
|
+
if (typeof v !== 'string' && typeof v !== 'number')
|
|
50
|
+
continue;
|
|
51
|
+
const id = h.id.replace(template[0], String(v));
|
|
52
|
+
if (!out.includes(id))
|
|
53
|
+
out.push(id);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Source handles that are not exits: `error` (routed by `.onError()`) and an
|
|
61
|
+
* agent's artifact handles, which attach its tools, context, escalations and
|
|
62
|
+
* memory rather than continue the flow.
|
|
63
|
+
*/
|
|
64
|
+
const NOT_FORWARD = new Set(['error', 'tool', 'context', 'escalation', 'memory']);
|
|
65
|
+
/**
|
|
66
|
+
* The FORWARD exits a node's definition declares when it has more than one —
|
|
67
|
+
* every source handle except `error` and an agent's artifact handles, templates
|
|
68
|
+
* expanded. `undefined` for a definition with one forward exit or fewer, or one
|
|
69
|
+
* whose handles cannot be known: such a node has no fan-out to route.
|
|
70
|
+
*/
|
|
71
|
+
export function forwardFanOut(def, inputs) {
|
|
72
|
+
const handles = expandSourceHandles(def, inputs)?.filter((h) => !NOT_FORWARD.has(h));
|
|
73
|
+
return handles !== undefined && handles.length > 1 ? handles : undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The port a node's main path leaves on — the edge a plain `.step()` writes
|
|
77
|
+
* and a following step continues from: the first concrete forward source
|
|
78
|
+
* handle (`isDefaultForType` wins), else `output`. `undefined` when every
|
|
79
|
+
* forward source handle is templated (`case-{item.id}`), so no main path leaves
|
|
80
|
+
* the node.
|
|
81
|
+
*
|
|
82
|
+
* `serialize` writes the main-path edge on this port, and `decompile` reads the
|
|
83
|
+
* main path back off it, so the two must agree: a `core.logic.agentic-switch`
|
|
84
|
+
* (`case-{item.id}` + `default`) continues on `default`, and each other wired
|
|
85
|
+
* exit is a `.stepToList('case-<id>', …)` (#1214).
|
|
86
|
+
*/
|
|
87
|
+
export function contributionPort(def) {
|
|
88
|
+
const groups = Array.isArray(def?.handleConfiguration) ? def.handleConfiguration : [];
|
|
89
|
+
const handles = groups.flatMap((g) => (g?.handles ?? []));
|
|
90
|
+
const sources = handles.filter((h) => h?.type === 'source' && h?.id !== 'error');
|
|
91
|
+
const concrete = sources.filter((h) => typeof h?.id === 'string' && !h.id.includes('{'));
|
|
92
|
+
if (concrete.length === 0 && sources.length > 0)
|
|
93
|
+
return undefined;
|
|
94
|
+
return concrete.find((h) => h?.isDefaultForType)?.id ?? concrete[0]?.id ?? 'output';
|
|
95
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The exits `.stepSwitch` routes over when its step is a `rawNode`: the
|
|
3
|
+
* manifest's forward source handles, `repeat` ones expanded over the node's
|
|
4
|
+
* inputs, each arm's `value` being its port. A `core.logic.agentic-switch`
|
|
5
|
+
* with choices `returns` and `billing` has `case-returns`, `case-billing` and
|
|
6
|
+
* `default`:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* .stepSwitch('route', rawNode({ nodeType: 'core.logic.agentic-switch', … }), [
|
|
10
|
+
* { value: 'case-returns', body: (b) => b.step('returns', …) },
|
|
11
|
+
* { value: 'case-billing', body: (b) => b.step('billing', …) },
|
|
12
|
+
* { value: 'default', body: (b) => b.step('triage', …) },
|
|
13
|
+
* ])
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Internal, not package API: `raw-node.ts` (whose module the package
|
|
17
|
+
* re-exports) puts the answer on its node under this symbol, and
|
|
18
|
+
* `flow-step-exits.ts` reads it. `decompile` reads the same handles off the
|
|
19
|
+
* file's definition, so what it emits recompiles (#1141).
|
|
20
|
+
*/
|
|
21
|
+
import type { DeclaredExit } from './step-ports.js';
|
|
22
|
+
/** The method a raw node answers its exits under. */
|
|
23
|
+
export declare const RAW_NODE_EXITS: unique symbol;
|
|
24
|
+
/**
|
|
25
|
+
* `action`'s exits when it is a raw node whose manifest declares more than one
|
|
26
|
+
* forward exit; `undefined` otherwise (then it has nothing to route).
|
|
27
|
+
*/
|
|
28
|
+
export declare function rawNodeExits(action: unknown): DeclaredExit[] | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The method a raw node answers its exits under. */
|
|
2
|
+
export const RAW_NODE_EXITS = Symbol('rawNodeExits');
|
|
3
|
+
/**
|
|
4
|
+
* `action`'s exits when it is a raw node whose manifest declares more than one
|
|
5
|
+
* forward exit; `undefined` otherwise (then it has nothing to route).
|
|
6
|
+
*/
|
|
7
|
+
export function rawNodeExits(action) {
|
|
8
|
+
const own = action?.[RAW_NODE_EXITS];
|
|
9
|
+
return typeof own === 'function' ? own.call(action) : undefined;
|
|
10
|
+
}
|
package/dist/decompile.js
CHANGED
|
@@ -46,6 +46,7 @@ import { mapJsCode } from './core/js-code-spans.js';
|
|
|
46
46
|
import { missingBindingLabels } from './core/binding-messages.js';
|
|
47
47
|
import { prepareCommand } from './core/cli-spelling.js';
|
|
48
48
|
import { OUTCOME_HANDLE_NODE_TYPES } from './core/hitl-routing.js';
|
|
49
|
+
import { contributionPort, forwardFanOut } from './core/definition-handles.js';
|
|
49
50
|
import { STICKY_NOTE_TYPE } from './core/definitionless-node-types.js';
|
|
50
51
|
import { eventFilterFromTreeLeaf } from './core/event-filters.js';
|
|
51
52
|
import { sdkFormFieldType } from './core/form-field-type.js';
|
|
@@ -531,11 +532,34 @@ class Graph {
|
|
|
531
532
|
successorEdges(id) {
|
|
532
533
|
const primary = this.primaryOutcomePort(id);
|
|
533
534
|
const forked = this.fullyWiredExits(id);
|
|
535
|
+
const side = forked ? undefined : this.rawSidePorts(id);
|
|
534
536
|
return this.outEdges(id).filter((e) => e.sourcePort !== 'error'
|
|
535
537
|
&& !ARTIFACT_PORTS.has(e.sourcePort)
|
|
536
538
|
&& (forked?.has(e.sourcePort)
|
|
537
539
|
|| (!e.sourcePort.startsWith('branch-')
|
|
538
|
-
&& (!e.sourcePort.startsWith('outcome-') || e.sourcePort === primary)
|
|
540
|
+
&& (!e.sourcePort.startsWith('outcome-') || e.sourcePort === primary)
|
|
541
|
+
&& !side?.has(e.sourcePort))));
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* A multi-exit `rawNode`'s SIDE exits when not every exit is wired: each
|
|
545
|
+
* declared exit except the one its main path leaves on (`contributionPort`,
|
|
546
|
+
* the port serialize writes a plain `.step()`'s edge on — `default` for a
|
|
547
|
+
* `core.logic.agentic-switch`). Each is recovered as a
|
|
548
|
+
* `.stepToList('<port>', …)` after the `.step`, as `branch-*` and non-primary
|
|
549
|
+
* `outcome-*` exits are. `undefined` for every other node, and for a raw node
|
|
550
|
+
* whose exits are all wired (that one is a `.stepSwitch`).
|
|
551
|
+
*
|
|
552
|
+
* Without this, a partially wired agentic switch had two successors and no
|
|
553
|
+
* merge join, so the walk emitted an unstructured-fan-out TODO and dropped
|
|
554
|
+
* every arm (#1214).
|
|
555
|
+
*/
|
|
556
|
+
rawSidePorts(id) {
|
|
557
|
+
const node = this.byId.get(id);
|
|
558
|
+
const exits = node ? rawNodeExits(node) : undefined;
|
|
559
|
+
if (!node || exits === undefined || this.fullyWiredExits(id) !== undefined)
|
|
560
|
+
return undefined;
|
|
561
|
+
const main = contributionPort(rawNodeDefinition(node));
|
|
562
|
+
return new Set(exits.map((e) => e.port).filter((p) => p !== main));
|
|
539
563
|
}
|
|
540
564
|
}
|
|
541
565
|
// ─── Node → step-spec source ──────────────────────────────────────────────────
|
|
@@ -2396,6 +2420,17 @@ function region(cursor, stop, scope, ipdom, ctx, refInto) {
|
|
|
2396
2420
|
segs.push(`.stepToList(${tsLiteral(oe.sourcePort)}, ${armCb('p', outSegs)})`);
|
|
2397
2421
|
}
|
|
2398
2422
|
}
|
|
2423
|
+
// A partially wired multi-exit raw node (an agentic switch with one choice
|
|
2424
|
+
// unwired): every wired exit but the main path's is its own port list, and
|
|
2425
|
+
// an unwired one stays unwired (#1214).
|
|
2426
|
+
const rawSide = ctx.graph.rawSidePorts(node.id);
|
|
2427
|
+
for (const re of rawSide ? ctx.graph.outEdges(node.id).filter((e) => rawSide.has(e.sourcePort)) : []) {
|
|
2428
|
+
const mainReach = forwardReach(succ, scope, ctx.graph);
|
|
2429
|
+
const sideSegs = edgeRegion(re, EXIT, scope, ipdom, ctx, mainReach);
|
|
2430
|
+
if (sideSegs.length === 0)
|
|
2431
|
+
sideSegs.push('.return({})');
|
|
2432
|
+
segs.push(`.stepToList(${tsLiteral(re.sourcePort)}, ${armCb('p', sideSegs)})`);
|
|
2433
|
+
}
|
|
2399
2434
|
// A body edge into the enclosing container's break handle: the path exits
|
|
2400
2435
|
// the loop here. Emit `.break()` and end the region — recompiling recreates
|
|
2401
2436
|
// exactly this edge and adds no continue back-edge for the path.
|
|
@@ -2534,7 +2569,9 @@ function declaredExitsOfNode(node) {
|
|
|
2534
2569
|
// A registered type that declares exits answers from its own spec, lifted off
|
|
2535
2570
|
// this node; one that declares none is not lifted at all (this runs per edge).
|
|
2536
2571
|
const impl = registeredImpl(node);
|
|
2537
|
-
if (!impl
|
|
2572
|
+
if (!impl)
|
|
2573
|
+
return rawNodeExits(node);
|
|
2574
|
+
if (!impl.exits)
|
|
2538
2575
|
return undefined;
|
|
2539
2576
|
const lifted = liftRegistered(node, impl);
|
|
2540
2577
|
const exits = lifted && impl.exits(lifted.spec);
|
|
@@ -2542,6 +2579,41 @@ function declaredExitsOfNode(node) {
|
|
|
2542
2579
|
return undefined;
|
|
2543
2580
|
return exits.map((e) => ({ value: e.value, port: e.port }));
|
|
2544
2581
|
}
|
|
2582
|
+
/**
|
|
2583
|
+
* The exits of a node that decompiles to a `rawNode` (a type this SDK has no
|
|
2584
|
+
* factory for, carried with the file's own definition): that definition's
|
|
2585
|
+
* forward source handles, `repeat` ones expanded over the node's inputs, when it
|
|
2586
|
+
* has more than one. `core.logic.agentic-switch` declares `case-{item.id}` over
|
|
2587
|
+
* `inputs.criteria` plus `default`, so a node with choices `returns` and
|
|
2588
|
+
* `billing` has the exits `case-returns`, `case-billing`, `default`. Each exit's
|
|
2589
|
+
* value is its port, which is what `.stepSwitch` over a `rawNode` matches
|
|
2590
|
+
* (`rawNodeExits` in raw-node.ts reads the same handles off the manifest).
|
|
2591
|
+
*
|
|
2592
|
+
* Without this, a fully wired multi-exit raw node had ONE exit to the walker:
|
|
2593
|
+
* it emitted `.step(...)` with a TODO and dropped every arm (#1141).
|
|
2594
|
+
*
|
|
2595
|
+
* `undefined` for every node the decompiler names some other way (the walker's
|
|
2596
|
+
* structural types, triggers, connectors, agents, published resources, IxP):
|
|
2597
|
+
* their exits are not a raw node's, and an agent's artifact handles (`tool`,
|
|
2598
|
+
* `context`, …) are not exits at all.
|
|
2599
|
+
*/
|
|
2600
|
+
function rawNodeExits(node) {
|
|
2601
|
+
const type = String(node.type);
|
|
2602
|
+
// A registered type (an HTTP call, say) answers from its own `exits`.
|
|
2603
|
+
if (registeredImpl(node) !== undefined)
|
|
2604
|
+
return undefined;
|
|
2605
|
+
if (Object.values(T).includes(type) || isTrigger(type))
|
|
2606
|
+
return undefined;
|
|
2607
|
+
if (['uipath.connector.', 'uipath.core.', 'uipath.ixp.', 'uipath.agent.', 'uipath.conversational.']
|
|
2608
|
+
.some((p) => type.startsWith(p)))
|
|
2609
|
+
return undefined;
|
|
2610
|
+
return forwardFanOut(rawNodeDefinition(node), node.inputs)?.map((port) => ({ value: port, port }));
|
|
2611
|
+
}
|
|
2612
|
+
/** The definition the file carries for `node`'s type (its version's, else the type's). */
|
|
2613
|
+
function rawNodeDefinition(node) {
|
|
2614
|
+
const type = String(node.type);
|
|
2615
|
+
return runDefs.get(`${type}@${node.typeVersion}`) ?? runDefs.get(type);
|
|
2616
|
+
}
|
|
2545
2617
|
/**
|
|
2546
2618
|
* Split a switch case expression into `<discriminant> === <literal>`, the only
|
|
2547
2619
|
* form `.switch(on, [{ value }])` models. Returns `undefined` for any other
|
package/dist/flow-step-exits.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { resolveVersion } from './core/nodes/versioned.js';
|
|
9
9
|
import { declaredExits } from './core/step-ports.js';
|
|
10
10
|
import { FLOW_NODE_TYPES } from './flow-node-registry.js';
|
|
11
|
+
import { rawNodeExits } from './core/raw-node-exits.js';
|
|
11
12
|
/**
|
|
12
13
|
* The author-declared exits of a step's spec: a registered type's own `exits`,
|
|
13
14
|
* at the version the step resolves to (its pin, else the type's choice; an
|
|
@@ -16,6 +17,10 @@ import { FLOW_NODE_TYPES } from './flow-node-registry.js';
|
|
|
16
17
|
* here, so they agree on what a port means.
|
|
17
18
|
*/
|
|
18
19
|
export function stepExits(spec, pinnedVersion) {
|
|
20
|
+
// A `rawNode` declares its exits through the manifest it carries (#1141).
|
|
21
|
+
const raw = rawNodeExits(spec);
|
|
22
|
+
if (raw !== undefined)
|
|
23
|
+
return raw;
|
|
19
24
|
const entry = typeof spec?.kind === 'string' ? FLOW_NODE_TYPES.byKind(spec.kind, spec) : undefined;
|
|
20
25
|
if (!entry)
|
|
21
26
|
return declaredExits(spec, pinnedVersion);
|
package/dist/merge-roundtrip.js
CHANGED
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
* merged file still has it.
|
|
51
51
|
*/
|
|
52
52
|
import { bindingIdentity } from './core/binding-identity.js';
|
|
53
|
+
import { expandSourceHandles } from './core/definition-handles.js';
|
|
53
54
|
import { OUTCOME_HANDLE_NODE_TYPES } from './core/hitl-routing.js';
|
|
54
55
|
/** A file's definitions, keyed `nodeType@version`. */
|
|
55
56
|
function defsOf(f) {
|
|
@@ -279,32 +280,8 @@ export function roundTripFindings(original, baseline, merged) {
|
|
|
279
280
|
}
|
|
280
281
|
/** The source handles a node's definition declares, or `undefined` when they cannot be known. */
|
|
281
282
|
function declaredSourceHandles(node, def) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
return undefined;
|
|
285
|
-
const out = new Set();
|
|
286
|
-
for (const g of groups) {
|
|
287
|
-
for (const h of (g?.handles ?? [])) {
|
|
288
|
-
if (h?.type !== 'source' || typeof h.id !== 'string')
|
|
289
|
-
continue;
|
|
290
|
-
const template = /\{item\.([A-Za-z0-9_]+)\}/.exec(h.id);
|
|
291
|
-
if (!template) {
|
|
292
|
-
out.add(h.id);
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
if (typeof h.repeat !== 'string' || !h.repeat.startsWith('inputs.'))
|
|
296
|
-
return undefined; // a template this check cannot expand
|
|
297
|
-
let items = node.inputs;
|
|
298
|
-
for (const seg of h.repeat.slice('inputs.'.length).split('.'))
|
|
299
|
-
items = items?.[seg];
|
|
300
|
-
for (const item of Array.isArray(items) ? items : []) {
|
|
301
|
-
const v = item?.[template[1]];
|
|
302
|
-
if (typeof v === 'string' || typeof v === 'number')
|
|
303
|
-
out.add(h.id.replace(template[0], String(v)));
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return out;
|
|
283
|
+
const handles = expandSourceHandles(def, node.inputs);
|
|
284
|
+
return handles === undefined ? undefined : new Set(handles);
|
|
308
285
|
}
|
|
309
286
|
/**
|
|
310
287
|
* The handles a node derives from its own inputs, in order: a definition's
|
package/dist/raw-node.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import { FlowAction, } from './core/node-classes.js';
|
|
9
9
|
import { connectorRawNodeRefusal } from './core/connector-raw-node.js';
|
|
10
10
|
import { rawNodeInputProblem, rawNodeTypedFamilyWarning } from './raw-node-advice.js';
|
|
11
|
+
import { forwardFanOut } from './core/definition-handles.js';
|
|
12
|
+
import { RAW_NODE_EXITS } from './core/raw-node-exits.js';
|
|
11
13
|
/**
|
|
12
14
|
* Place a node this SDK has no factory for, carrying its definition verbatim
|
|
13
15
|
* (`uipath.exotic.thing@2.1` and the manifest the platform served for it).
|
|
@@ -88,6 +90,11 @@ class RawNode extends FlowAction {
|
|
|
88
90
|
out.push({ code: 'RAW_NODE_TYPED_FAMILY', severity: 'warning', message: typed });
|
|
89
91
|
return out;
|
|
90
92
|
}
|
|
93
|
+
/** Its exits, for `.stepSwitch` (core/raw-node-exits.ts). */
|
|
94
|
+
[RAW_NODE_EXITS]() {
|
|
95
|
+
const manifest = this.spec.manifest;
|
|
96
|
+
return forwardFanOut(manifest, this.spec.inputs ?? {})?.map((port) => ({ value: port, port }));
|
|
97
|
+
}
|
|
91
98
|
contribute(context) {
|
|
92
99
|
// compile does not run diagnostics(); refuse here too so the escape hatch
|
|
93
100
|
// cannot emit an unconfigured connector node. (An input a registered node
|
package/dist/serialize.js
CHANGED
|
@@ -57,6 +57,7 @@ import { resolveSchemaVersion } from './schema-version.js';
|
|
|
57
57
|
import { planFlowGlobals, planSharedInputs, sharedInputRoots } from './flow-variables.js';
|
|
58
58
|
import { outputBackingGlobal, planOutputBacking } from './flow-output-backing.js';
|
|
59
59
|
import { mapJsCode } from './core/js-code-spans.js';
|
|
60
|
+
import { contributionPort } from './core/definition-handles.js';
|
|
60
61
|
import { prepareCommand } from './core/cli-spelling.js';
|
|
61
62
|
import { AGENTIC_PROCESS_FORMS } from './core/agentic-process-forms.js';
|
|
62
63
|
import { resourceNodeSortOrder } from './core/process-resource-sort-order.js';
|
|
@@ -3531,18 +3532,6 @@ function declaresForwardPort(def, port) {
|
|
|
3531
3532
|
return port.length > head.length + tail.length && port.startsWith(head) && port.endsWith(tail);
|
|
3532
3533
|
});
|
|
3533
3534
|
}
|
|
3534
|
-
/**
|
|
3535
|
-
* Forward port: the first concrete source handle (`isDefaultForType` wins), else `output`;
|
|
3536
|
-
* `undefined` when every forward source handle is templated (`case-{item.id}`).
|
|
3537
|
-
*/
|
|
3538
|
-
function contributionPort(def) {
|
|
3539
|
-
const handles = (def?.handleConfiguration ?? []).flatMap((g) => g?.handles ?? []);
|
|
3540
|
-
const sources = handles.filter((h) => h?.type === 'source' && h?.id !== 'error');
|
|
3541
|
-
const concrete = sources.filter((h) => typeof h?.id === 'string' && !h.id.includes('{'));
|
|
3542
|
-
if (concrete.length === 0 && sources.length > 0)
|
|
3543
|
-
return undefined;
|
|
3544
|
-
return concrete.find((h) => h?.isDefaultForType)?.id ?? concrete[0]?.id ?? 'output';
|
|
3545
|
-
}
|
|
3546
3535
|
/**
|
|
3547
3536
|
* Render a switch case value as a JS literal for the case expression.
|
|
3548
3537
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.29.
|
|
3
|
+
"version": "6.29.2",
|
|
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": "
|
|
95
|
+
"gitref": "b0d822e147a21ef1051b36c474b303839e980b13"
|
|
96
96
|
}
|