@uipath/maestro-builder-sdk 6.19.0 → 6.20.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/api-index.md +107 -107
- package/dist/api-members.md +358 -356
- package/dist/check.js +181 -45
- package/dist/cli/commands/flow.js +3 -0
- package/dist/compile-cli.js +51 -0
- package/dist/core/actions.d.ts +13 -5
- package/dist/core/actions.js +1 -1
- 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/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/process-resource-sort-order.d.ts +40 -0
- package/dist/core/process-resource-sort-order.js +44 -0
- 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 +680 -104
- package/dist/flow-expr-check.js +1 -1
- package/dist/flow-sdk.d.ts +33 -1
- package/dist/flow-sdk.js +21 -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/transform/flow/node-type.js +2 -1
- package/dist/registry/uip/pipeline-front-door.js +5 -3
- package/dist/serialize.js +112 -61
- package/package.json +2 -2
|
@@ -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]);
|
|
@@ -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
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The palette `sortOrder` of a process-resource node (an RPA workflow, API
|
|
3
|
+
* workflow, function, agent, or agentic process, published or in-solution),
|
|
4
|
+
* derived the way the platform derives it.
|
|
5
|
+
*
|
|
6
|
+
* flow-core's `buildNodeManifest` (`@uipath/flow-core/manifest`) does not keep a
|
|
7
|
+
* per-family number. It writes `categorySortOrders[baseCategory] +
|
|
8
|
+
* DYNAMIC_NODE_SORT_OFFSET`, where `baseCategory` is the resource type's category
|
|
9
|
+
* (`agent`, `flow`, …) before any `published` / `in-solution` listing suffix. So
|
|
10
|
+
* this module keeps the same two inputs and the same sum, not five literals.
|
|
11
|
+
*
|
|
12
|
+
* The base values are flow-core 0.115.4's `baseCategorySortOrders` for these
|
|
13
|
+
* categories (read 2026-10-08). They match what the platform writes today:
|
|
14
|
+
* `registry get` on alpha/codereval returns agent 510, flow 600, agentic-process
|
|
15
|
+
* 610, case-management 620, rpa-workflow 630, api-workflow 640, function 650, and
|
|
16
|
+
* 54 of 54 v1 in-solution agent `.flow` files (09-01 to 10-08) carry 510.
|
|
17
|
+
*
|
|
18
|
+
* flow-core renumbered these once already (agent was 5, api-workflow 10,
|
|
19
|
+
* rpa-workflow 30). `tests/process-resource-sort-order.test.ts` compares this
|
|
20
|
+
* table with a local flow-core when one is present, so the next renumber shows
|
|
21
|
+
* up as a red test rather than as a silent diff.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PROCESS_RESOURCE_CATEGORY_SORT_ORDERS: {
|
|
24
|
+
readonly agent: 10;
|
|
25
|
+
readonly flow: 100;
|
|
26
|
+
readonly 'agentic-process': 110;
|
|
27
|
+
readonly 'case-management': 120;
|
|
28
|
+
readonly 'rpa-workflow': 130;
|
|
29
|
+
readonly 'api-workflow': 140;
|
|
30
|
+
readonly function: 150;
|
|
31
|
+
};
|
|
32
|
+
/** flow-core's `DYNAMIC_NODE_SORT_OFFSET`: every tenant-built node sorts after every static one. */
|
|
33
|
+
export declare const DYNAMIC_NODE_SORT_OFFSET = 500;
|
|
34
|
+
/** A process-resource node category, e.g. `'agent'` or `'rpa-workflow'`. */
|
|
35
|
+
export type ProcessResourceCategory = keyof typeof PROCESS_RESOURCE_CATEGORY_SORT_ORDERS;
|
|
36
|
+
/**
|
|
37
|
+
* The `sortOrder` the platform writes for a process-resource node of this
|
|
38
|
+
* category. For instance `resourceNodeSortOrder('agent')` is 510.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resourceNodeSortOrder(category: ProcessResourceCategory): number;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ownEntry } from './own-entry.js';
|
|
2
|
+
/**
|
|
3
|
+
* The palette `sortOrder` of a process-resource node (an RPA workflow, API
|
|
4
|
+
* workflow, function, agent, or agentic process, published or in-solution),
|
|
5
|
+
* derived the way the platform derives it.
|
|
6
|
+
*
|
|
7
|
+
* flow-core's `buildNodeManifest` (`@uipath/flow-core/manifest`) does not keep a
|
|
8
|
+
* per-family number. It writes `categorySortOrders[baseCategory] +
|
|
9
|
+
* DYNAMIC_NODE_SORT_OFFSET`, where `baseCategory` is the resource type's category
|
|
10
|
+
* (`agent`, `flow`, …) before any `published` / `in-solution` listing suffix. So
|
|
11
|
+
* this module keeps the same two inputs and the same sum, not five literals.
|
|
12
|
+
*
|
|
13
|
+
* The base values are flow-core 0.115.4's `baseCategorySortOrders` for these
|
|
14
|
+
* categories (read 2026-10-08). They match what the platform writes today:
|
|
15
|
+
* `registry get` on alpha/codereval returns agent 510, flow 600, agentic-process
|
|
16
|
+
* 610, case-management 620, rpa-workflow 630, api-workflow 640, function 650, and
|
|
17
|
+
* 54 of 54 v1 in-solution agent `.flow` files (09-01 to 10-08) carry 510.
|
|
18
|
+
*
|
|
19
|
+
* flow-core renumbered these once already (agent was 5, api-workflow 10,
|
|
20
|
+
* rpa-workflow 30). `tests/process-resource-sort-order.test.ts` compares this
|
|
21
|
+
* table with a local flow-core when one is present, so the next renumber shows
|
|
22
|
+
* up as a red test rather than as a silent diff.
|
|
23
|
+
*/
|
|
24
|
+
export const PROCESS_RESOURCE_CATEGORY_SORT_ORDERS = {
|
|
25
|
+
agent: 10,
|
|
26
|
+
flow: 100,
|
|
27
|
+
'agentic-process': 110,
|
|
28
|
+
'case-management': 120,
|
|
29
|
+
'rpa-workflow': 130,
|
|
30
|
+
'api-workflow': 140,
|
|
31
|
+
function: 150,
|
|
32
|
+
};
|
|
33
|
+
/** flow-core's `DYNAMIC_NODE_SORT_OFFSET`: every tenant-built node sorts after every static one. */
|
|
34
|
+
export const DYNAMIC_NODE_SORT_OFFSET = 500;
|
|
35
|
+
/**
|
|
36
|
+
* The `sortOrder` the platform writes for a process-resource node of this
|
|
37
|
+
* category. For instance `resourceNodeSortOrder('agent')` is 510.
|
|
38
|
+
*/
|
|
39
|
+
export function resourceNodeSortOrder(category) {
|
|
40
|
+
const base = ownEntry(PROCESS_RESOURCE_CATEGORY_SORT_ORDERS, category);
|
|
41
|
+
if (base === undefined)
|
|
42
|
+
throw new Error(`no sortOrder for process-resource category '${category}'`);
|
|
43
|
+
return base + DYNAMIC_NODE_SORT_OFFSET;
|
|
44
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/wire-expr — reading an expression back out of the wire format.
|
|
3
|
+
*
|
|
4
|
+
* Shared by decompile and by every node family's deserializer, so the set of
|
|
5
|
+
* accepted spellings lives in one place.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The JS body of a value in an EXPRESSION SLOT: a field that always holds an
|
|
9
|
+
* expression and never literal text (a branch condition, a loop collection, an
|
|
10
|
+
* agent input binding, an app input binding, a field binding).
|
|
11
|
+
*
|
|
12
|
+
* The wire format has more than one spelling for one expression there, and this
|
|
13
|
+
* is the one place that knows them all:
|
|
14
|
+
*
|
|
15
|
+
* - `=js:<body>` -- what SDK compile writes.
|
|
16
|
+
* - `=<body>` (bare `=`) -- what the product writes for bindings: the CLI's
|
|
17
|
+
* agent-input encoder emits `=$vars.<node>.output.<field>` (uipath-cli
|
|
18
|
+
* `agent-input-encoding-utils.ts`), and `=$metadata.<key>` the same way.
|
|
19
|
+
* - `=vars.<path>` / `=metadata.<path>` -- the PATH form flow-v1 writes for app
|
|
20
|
+
* and field bindings. It names the same variable the SDK spells `$vars.<path>`.
|
|
21
|
+
* - no prefix -- the slot stores a bare JS body (decision/switch conditions).
|
|
22
|
+
*
|
|
23
|
+
* A VALUE slot (an ordinary node input) is different: there only `=js:` marks an
|
|
24
|
+
* expression and any other string is literal text, as the product reads it
|
|
25
|
+
* (flow-schema `coerceToExpressionValue`). Do not use this for one.
|
|
26
|
+
*/
|
|
27
|
+
export declare function wireExprBody(raw: string): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/wire-expr — reading an expression back out of the wire format.
|
|
3
|
+
*
|
|
4
|
+
* Shared by decompile and by every node family's deserializer, so the set of
|
|
5
|
+
* accepted spellings lives in one place.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The JS body of a value in an EXPRESSION SLOT: a field that always holds an
|
|
9
|
+
* expression and never literal text (a branch condition, a loop collection, an
|
|
10
|
+
* agent input binding, an app input binding, a field binding).
|
|
11
|
+
*
|
|
12
|
+
* The wire format has more than one spelling for one expression there, and this
|
|
13
|
+
* is the one place that knows them all:
|
|
14
|
+
*
|
|
15
|
+
* - `=js:<body>` -- what SDK compile writes.
|
|
16
|
+
* - `=<body>` (bare `=`) -- what the product writes for bindings: the CLI's
|
|
17
|
+
* agent-input encoder emits `=$vars.<node>.output.<field>` (uipath-cli
|
|
18
|
+
* `agent-input-encoding-utils.ts`), and `=$metadata.<key>` the same way.
|
|
19
|
+
* - `=vars.<path>` / `=metadata.<path>` -- the PATH form flow-v1 writes for app
|
|
20
|
+
* and field bindings. It names the same variable the SDK spells `$vars.<path>`.
|
|
21
|
+
* - no prefix -- the slot stores a bare JS body (decision/switch conditions).
|
|
22
|
+
*
|
|
23
|
+
* A VALUE slot (an ordinary node input) is different: there only `=js:` marks an
|
|
24
|
+
* expression and any other string is literal text, as the product reads it
|
|
25
|
+
* (flow-schema `coerceToExpressionValue`). Do not use this for one.
|
|
26
|
+
*/
|
|
27
|
+
export function wireExprBody(raw) {
|
|
28
|
+
if (raw.startsWith('=js:'))
|
|
29
|
+
return raw.slice(4);
|
|
30
|
+
if (!raw.startsWith('='))
|
|
31
|
+
return raw;
|
|
32
|
+
const body = raw.slice(1);
|
|
33
|
+
return /^(?:vars|metadata)(?:\.[A-Za-z_$][\w$]*|\[\d+\])*$/.test(body.trim()) ? `$${body.trim()}` : body;
|
|
34
|
+
}
|
package/dist/decompile-cli.js
CHANGED
|
@@ -129,7 +129,17 @@ if (!existsSync(BASELINE)) {
|
|
|
129
129
|
// ask for confirmation before the write. Left as a no-op for now.
|
|
130
130
|
// ---------------------------------------------------------------------------
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
// \`merge <edited> --original <original>\` is the grammar; the positional
|
|
133
|
+
// \`merge <original> <edited>\` pair is deprecated. A \`uip\` from before
|
|
134
|
+
// UiPath/cli#4526 knows only the pair, so ask its \`merge --help\` first.
|
|
135
|
+
// Key on the door, not the file name: on Windows \`uip\` resolves to node.exe
|
|
136
|
+
// or a full uip.exe path.
|
|
137
|
+
const mergeHelp = frontDoor.via === 'uip'
|
|
138
|
+
? spawnSync(frontDoor.file, [...frontDoor.prefix, 'merge', '--help'], { encoding: 'utf8' })
|
|
139
|
+
: undefined;
|
|
140
|
+
const namedOriginal = mergeHelp === undefined
|
|
141
|
+
|| \`\${mergeHelp.stdout ?? ''}\${mergeHelp.stderr ?? ''}\`.includes('--original');
|
|
142
|
+
const args = namedOriginal ? [EDITED, '--original', ORIGINAL, '-o', MERGED] : [ORIGINAL, EDITED, '-o', MERGED];
|
|
133
143
|
if (existsSync(BASELINE)) args.push('--baseline', BASELINE);
|
|
134
144
|
run('merge', args);
|
|
135
145
|
console.log('\\n>>> Wrote ' + ${JSON.stringify(base + '.merged.flow')});
|
package/dist/decompile.d.ts
CHANGED
|
@@ -128,9 +128,11 @@ export interface DecompileOptions {
|
|
|
128
128
|
/**
|
|
129
129
|
* Receives each non-fatal finding about the file, one message per finding:
|
|
130
130
|
* a node no trigger reaches (the builder cannot express a detached node, so
|
|
131
|
-
* the source omits it — strict mode throws instead), and a
|
|
132
|
-
* `(type, typeVersion)` pair this SDK
|
|
133
|
-
*
|
|
131
|
+
* the source omits it — strict mode throws instead), and a
|
|
132
|
+
* `(type, typeVersion)` pair this SDK cannot resolve for a type it ships at
|
|
133
|
+
* other versions (the source omits that `{ version }`, so the node compiles at
|
|
134
|
+
* the SDK's default; `merge` with a baseline keeps the untouched original
|
|
135
|
+
* node at its version — strict mode throws instead). The CLI prints these on stderr.
|
|
134
136
|
*/
|
|
135
137
|
warn?: (message: string) => void;
|
|
136
138
|
/**
|
|
@@ -142,6 +144,9 @@ export interface DecompileOptions {
|
|
|
142
144
|
* (`{{input.start__output__notes}}`), so the recovered source declares its
|
|
143
145
|
* inputs under those names — the same flow, not the same spelling. Without a
|
|
144
146
|
* reader, a shell agent decompiles with empty prompts and a warning.
|
|
147
|
+
* A context index placed by the canvas or the CLI keeps its real name and
|
|
148
|
+
* folder only in `<agent source>/resources/<inputs.source>/resource.json`,
|
|
149
|
+
* which is read the same way.
|
|
145
150
|
*/
|
|
146
151
|
readSidecar?: (relativePath: string) => string | undefined;
|
|
147
152
|
}
|