@uipath/maestro-builder-sdk 6.29.0 → 6.29.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/dist/core/definition-handles.d.ts +38 -0
- package/dist/core/definition-handles.js +74 -0
- package/dist/core/raw-node-exits.d.ts +28 -0
- package/dist/core/raw-node-exits.js +10 -0
- package/dist/decompile.js +32 -1
- package/dist/flow-step-exits.js +5 -0
- package/dist/merge-roundtrip.js +3 -26
- package/dist/raw-node.js +7 -0
- package/package.json +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
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
|
+
}
|
|
@@ -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 { 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';
|
|
@@ -2534,7 +2535,9 @@ function declaredExitsOfNode(node) {
|
|
|
2534
2535
|
// A registered type that declares exits answers from its own spec, lifted off
|
|
2535
2536
|
// this node; one that declares none is not lifted at all (this runs per edge).
|
|
2536
2537
|
const impl = registeredImpl(node);
|
|
2537
|
-
if (!impl
|
|
2538
|
+
if (!impl)
|
|
2539
|
+
return rawNodeExits(node);
|
|
2540
|
+
if (!impl.exits)
|
|
2538
2541
|
return undefined;
|
|
2539
2542
|
const lifted = liftRegistered(node, impl);
|
|
2540
2543
|
const exits = lifted && impl.exits(lifted.spec);
|
|
@@ -2542,6 +2545,34 @@ function declaredExitsOfNode(node) {
|
|
|
2542
2545
|
return undefined;
|
|
2543
2546
|
return exits.map((e) => ({ value: e.value, port: e.port }));
|
|
2544
2547
|
}
|
|
2548
|
+
/**
|
|
2549
|
+
* The exits of a node that decompiles to a `rawNode` (a type this SDK has no
|
|
2550
|
+
* factory for, carried with the file's own definition): that definition's
|
|
2551
|
+
* forward source handles, `repeat` ones expanded over the node's inputs, when it
|
|
2552
|
+
* has more than one. `core.logic.agentic-switch` declares `case-{item.id}` over
|
|
2553
|
+
* `inputs.criteria` plus `default`, so a node with choices `returns` and
|
|
2554
|
+
* `billing` has the exits `case-returns`, `case-billing`, `default`. Each exit's
|
|
2555
|
+
* value is its port, which is what `.stepSwitch` over a `rawNode` matches
|
|
2556
|
+
* (`rawNodeExits` in raw-node.ts reads the same handles off the manifest).
|
|
2557
|
+
*
|
|
2558
|
+
* Without this, a fully wired multi-exit raw node had ONE exit to the walker:
|
|
2559
|
+
* it emitted `.step(...)` with a TODO and dropped every arm (#1141).
|
|
2560
|
+
*
|
|
2561
|
+
* `undefined` for every node the decompiler names some other way (the walker's
|
|
2562
|
+
* structural types, triggers, connectors, agents, published resources, IxP):
|
|
2563
|
+
* their exits are not a raw node's, and an agent's artifact handles (`tool`,
|
|
2564
|
+
* `context`, …) are not exits at all.
|
|
2565
|
+
*/
|
|
2566
|
+
function rawNodeExits(node) {
|
|
2567
|
+
const type = String(node.type);
|
|
2568
|
+
if (Object.values(T).includes(type) || isTrigger(type))
|
|
2569
|
+
return undefined;
|
|
2570
|
+
if (['uipath.connector.', 'uipath.core.', 'uipath.ixp.', 'uipath.agent.', 'uipath.conversational.']
|
|
2571
|
+
.some((p) => type.startsWith(p)))
|
|
2572
|
+
return undefined;
|
|
2573
|
+
const def = runDefs.get(`${type}@${node.typeVersion}`) ?? runDefs.get(type);
|
|
2574
|
+
return forwardFanOut(def, node.inputs)?.map((port) => ({ value: port, port }));
|
|
2575
|
+
}
|
|
2545
2576
|
/**
|
|
2546
2577
|
* Split a switch case expression into `<discriminant> === <literal>`, the only
|
|
2547
2578
|
* 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.29.
|
|
3
|
+
"version": "6.29.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": "
|
|
95
|
+
"gitref": "5dee9e0ebdef1bca6c586f4802285a0f429ae432"
|
|
96
96
|
}
|