@uipath/maestro-builder-sdk 6.16.14 → 6.17.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 +108 -107
- package/dist/api-members.md +295 -291
- package/dist/bindings-v2.d.ts +39 -1
- package/dist/bindings-v2.js +289 -9
- package/dist/bpmn/compile-cli.js +11 -2
- package/dist/bpmn/decompile.js +2 -1
- package/dist/bpmn/registry-fallback.js +9 -7
- package/dist/case/compile-cli.js +16 -6
- package/dist/case/decompile-cli.js +2 -1
- package/dist/case/decompile.js +3 -2
- package/dist/case/merge-cli.js +3 -2
- package/dist/check.js +219 -37
- package/dist/cli-result.d.ts +9 -0
- package/dist/cli-result.js +12 -0
- package/dist/compile-cli.js +78 -53
- package/dist/core/actions.d.ts +70 -16
- package/dist/core/agentic-process-forms.d.ts +51 -0
- package/dist/core/agentic-process-forms.js +49 -0
- package/dist/core/binding-messages.d.ts +5 -0
- package/dist/core/comment-text.d.ts +29 -0
- package/dist/core/comment-text.js +40 -0
- package/dist/core/contribution-bindings.d.ts +73 -0
- package/dist/core/contribution-bindings.js +105 -0
- package/dist/core/expr-check.js +7 -2
- package/dist/core/json-file.d.ts +1 -0
- package/dist/core/json-file.js +12 -0
- package/dist/core/script-return.js +4 -1
- package/dist/core/typed-raw-node.js +1 -0
- package/dist/core/typescript-module.d.ts +2 -0
- package/dist/core/typescript-module.js +18 -0
- package/dist/core-definitions.json +210 -0
- package/dist/decompile-cli.js +2 -1
- package/dist/decompile.js +64 -24
- package/dist/emit.js +4 -3
- package/dist/flow-sdk.d.ts +14 -9
- package/dist/flow-sdk.js +14 -4
- package/dist/flow-step-tree.d.ts +2 -3
- package/dist/flow-step-tree.js +2 -3
- package/dist/load.js +1 -1
- package/dist/merge-cli.js +3 -2
- package/dist/merge.d.ts +2 -1
- package/dist/merge.js +0 -0
- package/dist/path-within.d.ts +33 -0
- package/dist/path-within.js +41 -0
- package/dist/registry/archive/extract.js +2 -5
- package/dist/registry/curated-overlay.js +3 -2
- package/dist/registry/generators/descriptors.js +20 -18
- package/dist/registry/generators/triggers.js +4 -4
- package/dist/registry/prepare/messages.js +2 -1
- package/dist/registry/prepare/source-labels.js +60 -1
- package/dist/registry/prepare-cli.js +14 -4
- package/dist/registry/pull-cli.js +3 -2
- package/dist/registry/uip/client.d.ts +28 -3
- package/dist/registry/uip/client.js +95 -34
- package/dist/registry/uip/host.d.ts +41 -0
- package/dist/registry/uip/host.js +312 -0
- package/dist/serialize.d.ts +7 -0
- package/dist/serialize.js +390 -270
- package/dist/workdir.js +1 -1
- package/package.json +3 -3
package/dist/core/actions.d.ts
CHANGED
|
@@ -981,21 +981,48 @@ export type DelayInputs = {
|
|
|
981
981
|
/** Impossible together with `until` — a delay waits one way or the other. */
|
|
982
982
|
duration?: never;
|
|
983
983
|
};
|
|
984
|
+
/**
|
|
985
|
+
* Where a process resource lives: deployed to an Orchestrator folder
|
|
986
|
+
* (`'published'`, the default) or a sibling project of the SAME solution
|
|
987
|
+
* (`'in-solution'`). Shared by `rpaWorkflow`, `agenticProcess` and `agent`.
|
|
988
|
+
*/
|
|
989
|
+
export type ProcessLocation = 'published' | 'in-solution';
|
|
984
990
|
export interface RpaWorkflowInputs {
|
|
985
991
|
/**
|
|
986
992
|
* The published process's release key (a GUID). It becomes part of the node's
|
|
987
993
|
* type, `uipath.core.rpa-workflow.<key>`. Find it with
|
|
988
994
|
* `uip or processes list --all-folders --process-type Process` (the row's `Key`)
|
|
989
995
|
* or `uip maestro flow registry search "uipath.core.rpa-workflow"`.
|
|
996
|
+
*
|
|
997
|
+
* For an in-solution sibling it is `resource.key` from
|
|
998
|
+
* `resources/solution_folder/process/process/<project>.json` — the suffix of the
|
|
999
|
+
* node type `uip maestro flow registry list --local` shows.
|
|
990
1000
|
*/
|
|
991
1001
|
key: string;
|
|
992
1002
|
/** The process's name in Orchestrator — e.g. `'RPA Workflow'`. */
|
|
993
1003
|
name: string;
|
|
1004
|
+
/**
|
|
1005
|
+
* Where the process lives. `'published'` (the default) is a process deployed
|
|
1006
|
+
* to `folderPath`. `'in-solution'` is a sibling RPA project of the same
|
|
1007
|
+
* solution: it needs `projectId` and no `folderPath`.
|
|
1008
|
+
*/
|
|
1009
|
+
location?: ProcessLocation;
|
|
994
1010
|
/**
|
|
995
1011
|
* The Orchestrator folder holding the process — e.g.
|
|
996
|
-
* `'Shared/uipath-maestro-flow/ProjectEuler RPA'`.
|
|
1012
|
+
* `'Shared/uipath-maestro-flow/ProjectEuler RPA'`. Required for a published
|
|
1013
|
+
* process; omit it for an in-solution sibling.
|
|
1014
|
+
*
|
|
1015
|
+
* @enforcedBy RPA_NO_FOLDER A published process needs its folder.
|
|
997
1016
|
*/
|
|
998
|
-
folderPath
|
|
1017
|
+
folderPath?: string;
|
|
1018
|
+
/**
|
|
1019
|
+
* The sibling RPA project's `resource.projectKey`, read from
|
|
1020
|
+
* `resources/solution_folder/process/process/<project>.json`. Required only
|
|
1021
|
+
* when `location` is `'in-solution'`.
|
|
1022
|
+
*
|
|
1023
|
+
* @enforcedBy RPA_LOCAL_NO_PROJECT_ID An in-solution process needs its project id.
|
|
1024
|
+
*/
|
|
1025
|
+
projectId?: string;
|
|
999
1026
|
/**
|
|
1000
1027
|
* The PROCESS's own input arguments, by its own argument names (e.g.
|
|
1001
1028
|
* `{ problemId: 123 }`). Not a fixed schema — every process declares its own,
|
|
@@ -1101,11 +1128,33 @@ interface AgenticProcessInputsBase {
|
|
|
1101
1128
|
key: string;
|
|
1102
1129
|
/** The process's name in Orchestrator — e.g. `'ProcurementProcess'`. */
|
|
1103
1130
|
name: string;
|
|
1131
|
+
/**
|
|
1132
|
+
* Where the process lives. `'published'` (the default) is a process deployed
|
|
1133
|
+
* to `folderPath`. `'in-solution'` is a sibling Flow of the same solution, so
|
|
1134
|
+
* it needs `form: 'flow'`, `projectId` and no `folderPath`; `key` is the
|
|
1135
|
+
* sibling's `resource.key` from `resources/solution_folder/process/flow/<project>.json`.
|
|
1136
|
+
* Only the Flow form has been run in-solution; `'bpmn'` and `'case'` siblings
|
|
1137
|
+
* are refused until they are.
|
|
1138
|
+
*
|
|
1139
|
+
* @enforcedBy AGENTIC_LOCAL_FORM_UNVERIFIED In-solution is supported for `form: 'flow'` only.
|
|
1140
|
+
*/
|
|
1141
|
+
location?: ProcessLocation;
|
|
1104
1142
|
/**
|
|
1105
1143
|
* The Orchestrator folder holding it — e.g.
|
|
1106
|
-
* `'Shared/uipath-agents/ProcurementProcess'`.
|
|
1144
|
+
* `'Shared/uipath-agents/ProcurementProcess'`. Required for a published
|
|
1145
|
+
* process; omit it for an in-solution sibling.
|
|
1146
|
+
*
|
|
1147
|
+
* @enforcedBy AGENTIC_NO_FOLDER A published process needs its folder.
|
|
1107
1148
|
*/
|
|
1108
|
-
folderPath
|
|
1149
|
+
folderPath?: string;
|
|
1150
|
+
/**
|
|
1151
|
+
* The sibling project's `resource.projectKey`, read from the same resource
|
|
1152
|
+
* file as `key` (`resources/solution_folder/process/flow/<project>.json`).
|
|
1153
|
+
* Required only when `location` is `'in-solution'`.
|
|
1154
|
+
*
|
|
1155
|
+
* @enforcedBy AGENTIC_LOCAL_NO_PROJECT_ID An in-solution process needs its project id.
|
|
1156
|
+
*/
|
|
1157
|
+
projectId?: string;
|
|
1109
1158
|
/**
|
|
1110
1159
|
* The PROCESS's own input arguments, by its own argument names (e.g.
|
|
1111
1160
|
* `{ productId: 1 }`). Not a fixed schema — every agentic process declares its
|
|
@@ -1167,7 +1216,7 @@ export type AgenticProcessInputs = AgenticProcessInputsBase & AgenticProcessComp
|
|
|
1167
1216
|
* resource. Display-only — see {@link AgentInputs.flavour}.
|
|
1168
1217
|
*/
|
|
1169
1218
|
export type AgentFlavour = 'coded' | 'lowcode';
|
|
1170
|
-
export type AgentLocation =
|
|
1219
|
+
export type AgentLocation = ProcessLocation;
|
|
1171
1220
|
export interface AgentInputs {
|
|
1172
1221
|
/**
|
|
1173
1222
|
* The agent resource key (a GUID). It becomes the node's TYPE,
|
|
@@ -1526,15 +1575,15 @@ export interface InlineAgentInputs {
|
|
|
1526
1575
|
maxIterations?: number;
|
|
1527
1576
|
/**
|
|
1528
1577
|
* The harness the agent runs on — `'standard'` (the default) or
|
|
1529
|
-
* `'advanced'
|
|
1530
|
-
*
|
|
1531
|
-
* definition
|
|
1578
|
+
* `'advanced'`, written to the `agent.json`'s `settings.mode`. It does not
|
|
1579
|
+
* change the node's version: every inline agent emits the bundle's newest
|
|
1580
|
+
* `uipath.agent.autonomous` definition (1.4).
|
|
1532
1581
|
*/
|
|
1533
1582
|
mode?: 'standard' | 'advanced';
|
|
1534
1583
|
/**
|
|
1535
1584
|
* Safety rails over the agent's inputs, outputs, LLM calls and tools — the
|
|
1536
|
-
* platform's own array shape ({@link AgentGuardrail}), carried
|
|
1537
|
-
* (
|
|
1585
|
+
* platform's own array shape ({@link AgentGuardrail}), carried in the
|
|
1586
|
+
* `agent.json` (every bundled definition declares the input).
|
|
1538
1587
|
*
|
|
1539
1588
|
* ```ts
|
|
1540
1589
|
* guardrails: [{
|
|
@@ -1550,8 +1599,8 @@ export interface InlineAgentInputs {
|
|
|
1550
1599
|
guardrails?: AgentGuardrail[];
|
|
1551
1600
|
/**
|
|
1552
1601
|
* Attach an episodic memory so the agent learns from past runs — one
|
|
1553
|
-
* {@link AgentMemoryRef}, wired to the agent's `memory` handle (
|
|
1554
|
-
* definition
|
|
1602
|
+
* {@link AgentMemoryRef}, wired to the agent's `memory` handle (declared by
|
|
1603
|
+
* the bundled 1.4 definition, which every inline agent uses).
|
|
1555
1604
|
*/
|
|
1556
1605
|
memory?: AgentMemoryRef;
|
|
1557
1606
|
/**
|
|
@@ -1764,9 +1813,9 @@ export interface HttpRequestToolRef {
|
|
|
1764
1813
|
* An episodic memory the agent learns from across runs, wired to the agent's
|
|
1765
1814
|
* own `memory` handle. Node type
|
|
1766
1815
|
* `uipath.agent.resource.memory.<name-slug>.<id-slug>`, minted exactly as the
|
|
1767
|
-
* platform's mapper does.
|
|
1768
|
-
* (
|
|
1769
|
-
*
|
|
1816
|
+
* platform's mapper does. The handle is LOCAL content on the bundled
|
|
1817
|
+
* `uipath.agent.autonomous@1.4` (#431): the registry's own 1.4 declares no
|
|
1818
|
+
* `memory` handle, so `check` refuses this today (AGENT_MEMORY_NOT_AUTHORABLE).
|
|
1770
1819
|
*/
|
|
1771
1820
|
export interface AgentMemoryRef {
|
|
1772
1821
|
/** The memory's display name on the tenant. */
|
|
@@ -1960,7 +2009,12 @@ export interface EscalationRef {
|
|
|
1960
2009
|
key: string;
|
|
1961
2010
|
/** The app's name, e.g. `'ContentReviewApp'`. */
|
|
1962
2011
|
name: string;
|
|
1963
|
-
/**
|
|
2012
|
+
/**
|
|
2013
|
+
* The Orchestrator folder the app lives in, e.g. `'Shared/Approvals'`.
|
|
2014
|
+
* Omit it for an app that ships in this solution: compile then writes
|
|
2015
|
+
* `'solution_folder'`, the `Folder` `uip solution resources list` reports
|
|
2016
|
+
* for a solution-internal app.
|
|
2017
|
+
*/
|
|
1964
2018
|
folderPath?: string;
|
|
1965
2019
|
/** The fields the agent hands the reviewer — becomes the app's `inputSchema`. */
|
|
1966
2020
|
inputs?: Record<string, InlineAgentFieldType>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three published forms under the Agentic Process umbrella (design §2.1).
|
|
3
|
+
* One public factory, three wire identities — transcribed from flow-v1's
|
|
4
|
+
* `RESOURCE_TYPE_METADATA` (ProcessOrchestration / Flow / CaseManagement):
|
|
5
|
+
* node-type segment, category, icon, resource subtype, `orchestratorType`
|
|
6
|
+
* (`resourceType.toLowerCase()`, per `createModel`), and the sync/async
|
|
7
|
+
* service-type pair. All three declare the fire-and-forget switch.
|
|
8
|
+
*
|
|
9
|
+
* `solutionFolder` is the folder under `resources/solution_folder/process/`
|
|
10
|
+
* that holds an in-solution sibling's resource file (e.g. a sibling Flow lands in
|
|
11
|
+
* `process/flow/Notifier.json`). The solution writer names it
|
|
12
|
+
* `toLowerFirstChar(resource.type)`: `@uipath/resource-builder-sdk`
|
|
13
|
+
* `MultiFileSolutionDefinitionProvider.buildResourceRelativePath`, with the
|
|
14
|
+
* process types `flow`, `processOrchestration` and `caseManagement` from that
|
|
15
|
+
* package's resource-type catalog.
|
|
16
|
+
*
|
|
17
|
+
* Shared by the serializer (which emits the node) and `check` (which names the
|
|
18
|
+
* resource file in `AGENTIC_LOCAL_NO_PROJECT_ID`), so the two can never disagree
|
|
19
|
+
* about what a form is.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AGENTIC_PROCESS_FORMS: {
|
|
22
|
+
readonly bpmn: {
|
|
23
|
+
readonly prefix: "uipath.core.agentic-process.";
|
|
24
|
+
readonly category: "agentic-process";
|
|
25
|
+
readonly icon: "agentic-process";
|
|
26
|
+
readonly resourceSubType: "ProcessOrchestration";
|
|
27
|
+
readonly orchestratorType: "processorchestration";
|
|
28
|
+
readonly serviceType: "Orchestrator.StartAgenticProcess";
|
|
29
|
+
readonly solutionFolder: "processOrchestration";
|
|
30
|
+
};
|
|
31
|
+
readonly flow: {
|
|
32
|
+
readonly prefix: "uipath.core.flow.";
|
|
33
|
+
readonly category: "flow";
|
|
34
|
+
readonly icon: "flow-project";
|
|
35
|
+
readonly resourceSubType: "Flow";
|
|
36
|
+
readonly orchestratorType: "flow";
|
|
37
|
+
readonly serviceType: "Orchestrator.StartFlowProcess";
|
|
38
|
+
readonly solutionFolder: "flow";
|
|
39
|
+
};
|
|
40
|
+
readonly case: {
|
|
41
|
+
readonly prefix: "uipath.core.case-management.";
|
|
42
|
+
readonly category: "case-management";
|
|
43
|
+
readonly icon: "case-management";
|
|
44
|
+
readonly resourceSubType: "CaseManagement";
|
|
45
|
+
readonly orchestratorType: "casemanagement";
|
|
46
|
+
readonly serviceType: "Orchestrator.StartCaseMgmtProcess";
|
|
47
|
+
readonly solutionFolder: "caseManagement";
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
/** An `agenticProcess` form: `'bpmn' | 'flow' | 'case'`. */
|
|
51
|
+
export type AgenticProcessForm = keyof typeof AGENTIC_PROCESS_FORMS;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three published forms under the Agentic Process umbrella (design §2.1).
|
|
3
|
+
* One public factory, three wire identities — transcribed from flow-v1's
|
|
4
|
+
* `RESOURCE_TYPE_METADATA` (ProcessOrchestration / Flow / CaseManagement):
|
|
5
|
+
* node-type segment, category, icon, resource subtype, `orchestratorType`
|
|
6
|
+
* (`resourceType.toLowerCase()`, per `createModel`), and the sync/async
|
|
7
|
+
* service-type pair. All three declare the fire-and-forget switch.
|
|
8
|
+
*
|
|
9
|
+
* `solutionFolder` is the folder under `resources/solution_folder/process/`
|
|
10
|
+
* that holds an in-solution sibling's resource file (e.g. a sibling Flow lands in
|
|
11
|
+
* `process/flow/Notifier.json`). The solution writer names it
|
|
12
|
+
* `toLowerFirstChar(resource.type)`: `@uipath/resource-builder-sdk`
|
|
13
|
+
* `MultiFileSolutionDefinitionProvider.buildResourceRelativePath`, with the
|
|
14
|
+
* process types `flow`, `processOrchestration` and `caseManagement` from that
|
|
15
|
+
* package's resource-type catalog.
|
|
16
|
+
*
|
|
17
|
+
* Shared by the serializer (which emits the node) and `check` (which names the
|
|
18
|
+
* resource file in `AGENTIC_LOCAL_NO_PROJECT_ID`), so the two can never disagree
|
|
19
|
+
* about what a form is.
|
|
20
|
+
*/
|
|
21
|
+
export const AGENTIC_PROCESS_FORMS = {
|
|
22
|
+
bpmn: {
|
|
23
|
+
prefix: 'uipath.core.agentic-process.',
|
|
24
|
+
category: 'agentic-process',
|
|
25
|
+
icon: 'agentic-process',
|
|
26
|
+
resourceSubType: 'ProcessOrchestration',
|
|
27
|
+
orchestratorType: 'processorchestration',
|
|
28
|
+
serviceType: 'Orchestrator.StartAgenticProcess',
|
|
29
|
+
solutionFolder: 'processOrchestration',
|
|
30
|
+
},
|
|
31
|
+
flow: {
|
|
32
|
+
prefix: 'uipath.core.flow.',
|
|
33
|
+
category: 'flow',
|
|
34
|
+
icon: 'flow-project',
|
|
35
|
+
resourceSubType: 'Flow',
|
|
36
|
+
orchestratorType: 'flow',
|
|
37
|
+
serviceType: 'Orchestrator.StartFlowProcess',
|
|
38
|
+
solutionFolder: 'flow',
|
|
39
|
+
},
|
|
40
|
+
case: {
|
|
41
|
+
prefix: 'uipath.core.case-management.',
|
|
42
|
+
category: 'case-management',
|
|
43
|
+
icon: 'case-management',
|
|
44
|
+
resourceSubType: 'CaseManagement',
|
|
45
|
+
orchestratorType: 'casemanagement',
|
|
46
|
+
serviceType: 'Orchestrator.StartCaseMgmtProcess',
|
|
47
|
+
solutionFolder: 'caseManagement',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -4,6 +4,11 @@ export declare const GUID_RE: RegExp;
|
|
|
4
4
|
export type BindingRefusalCode = 'BINDING_SELF_NAME' | 'BINDING_UNDECLARED'
|
|
5
5
|
/** An emitted definition's `<bindings.NAME>` placeholder has no `bindings[]` entry named NAME (#865). */
|
|
6
6
|
| 'BINDING_PLACEHOLDER_UNRESOLVED'
|
|
7
|
+
/**
|
|
8
|
+
* A custom node's definition references a `<bindings.NAME>` the contribution did not
|
|
9
|
+
* supply and the definition cannot close (no `resourceKey`, or no `values` row) (#942).
|
|
10
|
+
*/
|
|
11
|
+
| 'CONTRIBUTION_BINDING_UNRESOLVED'
|
|
7
12
|
/** Two steps on one connection disagree on which connector it belongs to (#866). */
|
|
8
13
|
| 'CONNECTION_CONNECTOR_CONFLICT'
|
|
9
14
|
/** A connector-bound node names no `connection` or no `folder` label (#890). */
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text that is safe inside a generated `//` or `/* … *\/` comment.
|
|
3
|
+
*
|
|
4
|
+
* A decompiler or generator that splices an input string into a comment hands that
|
|
5
|
+
* string the rest of the comment: a line terminator ends a `//` comment, `*\/` ends a
|
|
6
|
+
* block, and whatever follows is CODE in a file `compile` later executes. Those are the
|
|
7
|
+
* only two ways out of a JavaScript comment, so replacing both (line terminators — LF,
|
|
8
|
+
* CR, U+2028, U+2029 — with one space, `*\/` with `* /`) is complete, not a denylist.
|
|
9
|
+
* The replacements are the ones registry/generators already used, so their output keeps
|
|
10
|
+
* its bytes. FB006 holds every comment interpolation to this function.
|
|
11
|
+
*
|
|
12
|
+
* The result is ONE line: a multi-line value is flattened, which is right for a `//`
|
|
13
|
+
* line or a single ` * ` body line. To keep a value's line breaks, use `commentLines`
|
|
14
|
+
* (one escaped, prefixed line per input line) or `docComment` (a whole `/** … *\/`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function commentText(value: string | number): string;
|
|
17
|
+
/**
|
|
18
|
+
* `value` split on its line terminators, each line escaped by `commentText` and
|
|
19
|
+
* given `prefix` (`'// '`, `' * '`), trailing whitespace trimmed so a blank line is
|
|
20
|
+
* a bare `//` or ` *`. The lines are joined with `\n` by the caller, so a value's
|
|
21
|
+
* paragraph breaks survive and none of them can end the comment.
|
|
22
|
+
*/
|
|
23
|
+
export declare function commentLines(value: string | number, prefix?: string): string[];
|
|
24
|
+
/**
|
|
25
|
+
* A JSDoc comment holding `value`, at `indent`. A one-line value keeps the
|
|
26
|
+
* one-line form, `/** value *\/`, so its bytes do not change; a multi-line value
|
|
27
|
+
* gets an open block with one ` * ` line per input line.
|
|
28
|
+
*/
|
|
29
|
+
export declare function docComment(value: string | number, indent?: string): string[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** The line terminators (LF, CR, CRLF, U+2028, U+2029): the one way out of a `//` comment. */
|
|
2
|
+
const LINE_BREAK = /\r\n?|[\n\u2028\u2029]/g;
|
|
3
|
+
/**
|
|
4
|
+
* Text that is safe inside a generated `//` or `/* … *\/` comment.
|
|
5
|
+
*
|
|
6
|
+
* A decompiler or generator that splices an input string into a comment hands that
|
|
7
|
+
* string the rest of the comment: a line terminator ends a `//` comment, `*\/` ends a
|
|
8
|
+
* block, and whatever follows is CODE in a file `compile` later executes. Those are the
|
|
9
|
+
* only two ways out of a JavaScript comment, so replacing both (line terminators — LF,
|
|
10
|
+
* CR, U+2028, U+2029 — with one space, `*\/` with `* /`) is complete, not a denylist.
|
|
11
|
+
* The replacements are the ones registry/generators already used, so their output keeps
|
|
12
|
+
* its bytes. FB006 holds every comment interpolation to this function.
|
|
13
|
+
*
|
|
14
|
+
* The result is ONE line: a multi-line value is flattened, which is right for a `//`
|
|
15
|
+
* line or a single ` * ` body line. To keep a value's line breaks, use `commentLines`
|
|
16
|
+
* (one escaped, prefixed line per input line) or `docComment` (a whole `/** … *\/`).
|
|
17
|
+
*/
|
|
18
|
+
export function commentText(value) {
|
|
19
|
+
return String(value).replace(LINE_BREAK, ' ').replaceAll('*/', '* /');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* `value` split on its line terminators, each line escaped by `commentText` and
|
|
23
|
+
* given `prefix` (`'// '`, `' * '`), trailing whitespace trimmed so a blank line is
|
|
24
|
+
* a bare `//` or ` *`. The lines are joined with `\n` by the caller, so a value's
|
|
25
|
+
* paragraph breaks survive and none of them can end the comment.
|
|
26
|
+
*/
|
|
27
|
+
export function commentLines(value, prefix = '') {
|
|
28
|
+
return String(value).split(LINE_BREAK).map((line) => `${prefix}${commentText(line)}`.trimEnd());
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A JSDoc comment holding `value`, at `indent`. A one-line value keeps the
|
|
32
|
+
* one-line form, `/** value *\/`, so its bytes do not change; a multi-line value
|
|
33
|
+
* gets an open block with one ` * ` line per input line.
|
|
34
|
+
*/
|
|
35
|
+
export function docComment(value, indent = '') {
|
|
36
|
+
const body = commentLines(value);
|
|
37
|
+
if (body.length === 1)
|
|
38
|
+
return [`${indent}/** ${commentText(value)} */`];
|
|
39
|
+
return [`${indent}/**`, ...body.map((line) => `${indent} * ${line}`.trimEnd()), `${indent} */`];
|
|
40
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `bindings[]` entries a contribution-lowered node needs and did not supply
|
|
3
|
+
* (flow-builder-sdk#942).
|
|
4
|
+
*
|
|
5
|
+
* A definition's `model.context` names its resource through `<bindings.NAME>`
|
|
6
|
+
* placeholders, and declares each NAME in `model.bindings.values`. The typed
|
|
7
|
+
* emitters (rpa, api-workflow, queue, ixp, connector) close those names by hand.
|
|
8
|
+
* A `rawNode` or a hand-written `FlowAction` returns a definition and inputs, and
|
|
9
|
+
* usually no `bindings` — so before this, nothing closed them, and compile failed
|
|
10
|
+
* at `BINDING_PLACEHOLDER_UNRESOLVED` while `check` passed.
|
|
11
|
+
*
|
|
12
|
+
* For instance, the manifest `registry get --local` returns for a sibling Flow:
|
|
13
|
+
*
|
|
14
|
+
* ```json
|
|
15
|
+
* "model": { "bindings": { "resource": "process", "resourceSubType": "Flow", "resourceKey": "k1",
|
|
16
|
+
* "values": [{ "name": "name", "default": "Notifier" }, { "name": "folderPath", "default": "" }] },
|
|
17
|
+
* "context": [{ "name": "name", "value": "<bindings.name>" }, { "name": "folderPath", "value": "<bindings.folderPath>" }] }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* needs two `process` entries keyed `k1`: `name` = "Notifier" and `folderPath` = "".
|
|
21
|
+
* {@link planContributionBindings} reads exactly those facts off the definition.
|
|
22
|
+
*
|
|
23
|
+
* `connection` resources are out of scope: a connector definition's entries are
|
|
24
|
+
* keyed by the tenant connection id, which the definition does not carry. A raw
|
|
25
|
+
* connector node is refused for that reason (`connector-raw-node.ts`).
|
|
26
|
+
*
|
|
27
|
+
* Pure: `serialize` lowers with it, and `check` runs it dry so the two agree.
|
|
28
|
+
*/
|
|
29
|
+
/** One `bindings[]` entry, as the flow file carries it. */
|
|
30
|
+
export interface PlannedBinding {
|
|
31
|
+
name: string;
|
|
32
|
+
type: string;
|
|
33
|
+
resource: string;
|
|
34
|
+
resourceKey: string;
|
|
35
|
+
default?: string;
|
|
36
|
+
propertyAttribute: string;
|
|
37
|
+
resourceSubType?: string;
|
|
38
|
+
}
|
|
39
|
+
/** What one definition needs: the entries to build, and the names it cannot close. */
|
|
40
|
+
export interface ContributionBindingPlan {
|
|
41
|
+
/** The resource kind (`model.bindings.resource`), when it is one this plan closes. */
|
|
42
|
+
resource?: string;
|
|
43
|
+
/** The resource key every entry carries (`model.bindings.resourceKey`). */
|
|
44
|
+
resourceKey?: string;
|
|
45
|
+
/** One entry per referenced name the contribution did not supply. */
|
|
46
|
+
entries: PlannedBinding[];
|
|
47
|
+
/** One sentence per referenced name that cannot be closed, and why. Empty when every name closes. */
|
|
48
|
+
problems: string[];
|
|
49
|
+
}
|
|
50
|
+
/** The `<bindings.NAME>` names a definition's `model.context` references, in order, once each. */
|
|
51
|
+
export declare function referencedBindingNames(model: any): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Plan the entries a contribution-lowered node needs: for each `<bindings.NAME>`
|
|
54
|
+
* its definition's `model.context` references and `supplied` does not cover, one
|
|
55
|
+
* entry built from the definition — `resource`, `resourceKey`, `resourceSubType`
|
|
56
|
+
* from `model.bindings`, and `name`, `default`, `propertyAttribute` from the
|
|
57
|
+
* matching `model.bindings.values` row.
|
|
58
|
+
*
|
|
59
|
+
* A supplied entry covers a name when it has the same `resource` and `name`: the
|
|
60
|
+
* contributor's own bindings win, as they always did.
|
|
61
|
+
*
|
|
62
|
+
* A name is a problem (not an entry) when the definition declares no
|
|
63
|
+
* `values` row for it, or carries no `resourceKey` — a per-tenant template such
|
|
64
|
+
* as the bundled `core.action.queue.create` (`resourceKey: ""`), which only a
|
|
65
|
+
* typed factory can fill.
|
|
66
|
+
*
|
|
67
|
+
* @param def - The resolved definition.
|
|
68
|
+
* @param supplied - The bindings the contribution returned.
|
|
69
|
+
*/
|
|
70
|
+
export declare function planContributionBindings(def: any, supplied?: readonly {
|
|
71
|
+
resource?: string;
|
|
72
|
+
name?: string;
|
|
73
|
+
}[]): ContributionBindingPlan;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `bindings[]` entries a contribution-lowered node needs and did not supply
|
|
3
|
+
* (flow-builder-sdk#942).
|
|
4
|
+
*
|
|
5
|
+
* A definition's `model.context` names its resource through `<bindings.NAME>`
|
|
6
|
+
* placeholders, and declares each NAME in `model.bindings.values`. The typed
|
|
7
|
+
* emitters (rpa, api-workflow, queue, ixp, connector) close those names by hand.
|
|
8
|
+
* A `rawNode` or a hand-written `FlowAction` returns a definition and inputs, and
|
|
9
|
+
* usually no `bindings` — so before this, nothing closed them, and compile failed
|
|
10
|
+
* at `BINDING_PLACEHOLDER_UNRESOLVED` while `check` passed.
|
|
11
|
+
*
|
|
12
|
+
* For instance, the manifest `registry get --local` returns for a sibling Flow:
|
|
13
|
+
*
|
|
14
|
+
* ```json
|
|
15
|
+
* "model": { "bindings": { "resource": "process", "resourceSubType": "Flow", "resourceKey": "k1",
|
|
16
|
+
* "values": [{ "name": "name", "default": "Notifier" }, { "name": "folderPath", "default": "" }] },
|
|
17
|
+
* "context": [{ "name": "name", "value": "<bindings.name>" }, { "name": "folderPath", "value": "<bindings.folderPath>" }] }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* needs two `process` entries keyed `k1`: `name` = "Notifier" and `folderPath` = "".
|
|
21
|
+
* {@link planContributionBindings} reads exactly those facts off the definition.
|
|
22
|
+
*
|
|
23
|
+
* `connection` resources are out of scope: a connector definition's entries are
|
|
24
|
+
* keyed by the tenant connection id, which the definition does not carry. A raw
|
|
25
|
+
* connector node is refused for that reason (`connector-raw-node.ts`).
|
|
26
|
+
*
|
|
27
|
+
* Pure: `serialize` lowers with it, and `check` runs it dry so the two agree.
|
|
28
|
+
*/
|
|
29
|
+
/** The `<bindings.NAME>` names a definition's `model.context` references, in order, once each. */
|
|
30
|
+
export function referencedBindingNames(model) {
|
|
31
|
+
const names = [];
|
|
32
|
+
for (const row of Array.isArray(model?.context) ? model.context : []) {
|
|
33
|
+
const name = typeof row?.value === 'string' ? /^<bindings\.(.+)>$/.exec(row.value)?.[1] : undefined;
|
|
34
|
+
if (name !== undefined && !names.includes(name))
|
|
35
|
+
names.push(name);
|
|
36
|
+
}
|
|
37
|
+
return names;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Plan the entries a contribution-lowered node needs: for each `<bindings.NAME>`
|
|
41
|
+
* its definition's `model.context` references and `supplied` does not cover, one
|
|
42
|
+
* entry built from the definition — `resource`, `resourceKey`, `resourceSubType`
|
|
43
|
+
* from `model.bindings`, and `name`, `default`, `propertyAttribute` from the
|
|
44
|
+
* matching `model.bindings.values` row.
|
|
45
|
+
*
|
|
46
|
+
* A supplied entry covers a name when it has the same `resource` and `name`: the
|
|
47
|
+
* contributor's own bindings win, as they always did.
|
|
48
|
+
*
|
|
49
|
+
* A name is a problem (not an entry) when the definition declares no
|
|
50
|
+
* `values` row for it, or carries no `resourceKey` — a per-tenant template such
|
|
51
|
+
* as the bundled `core.action.queue.create` (`resourceKey: ""`), which only a
|
|
52
|
+
* typed factory can fill.
|
|
53
|
+
*
|
|
54
|
+
* @param def - The resolved definition.
|
|
55
|
+
* @param supplied - The bindings the contribution returned.
|
|
56
|
+
*/
|
|
57
|
+
export function planContributionBindings(def, supplied = []) {
|
|
58
|
+
const model = def?.model;
|
|
59
|
+
const names = referencedBindingNames(model);
|
|
60
|
+
const resource = model?.bindings?.resource;
|
|
61
|
+
// Connection (or undeclared) resources are keyed by a tenant connection id the
|
|
62
|
+
// definition does not carry; the connector paths own them.
|
|
63
|
+
if (names.length === 0 || typeof resource !== 'string' || !resource || resource === 'connection') {
|
|
64
|
+
return { entries: [], problems: [] };
|
|
65
|
+
}
|
|
66
|
+
const open = names.filter((n) => !supplied.some((b) => b?.resource === resource && b?.name === n));
|
|
67
|
+
if (open.length === 0)
|
|
68
|
+
return { resource, entries: [], problems: [] };
|
|
69
|
+
const label = `${def?.nodeType}@${def?.version}`;
|
|
70
|
+
const resourceKey = model.bindings.resourceKey;
|
|
71
|
+
if (typeof resourceKey !== 'string' || !resourceKey) {
|
|
72
|
+
return {
|
|
73
|
+
resource,
|
|
74
|
+
entries: [],
|
|
75
|
+
problems: open.map((n) => `${label} references "<bindings.${n}>", and its model.bindings carries no resourceKey, so no `
|
|
76
|
+
+ `"${resource}" binding can be built for it. This definition is a per-tenant template, not a resolved `
|
|
77
|
+
+ `manifest: use the typed factory for the family, or the manifest \`uip maestro flow registry get `
|
|
78
|
+
+ `${def?.nodeType}\` returns for a real resource, or return the bindings from contribute().`),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const values = Array.isArray(model.bindings.values) ? model.bindings.values : [];
|
|
82
|
+
const subType = model.bindings.resourceSubType;
|
|
83
|
+
const entries = [];
|
|
84
|
+
const problems = [];
|
|
85
|
+
for (const n of open) {
|
|
86
|
+
const row = values.find((r) => r?.name === n);
|
|
87
|
+
if (!row) {
|
|
88
|
+
problems.push(`${label} references "<bindings.${n}>", but its model.bindings.values declares no "${n}" row, so `
|
|
89
|
+
+ `there is no default to bind it to. Pass the manifest exactly as \`uip maestro flow registry get\` `
|
|
90
|
+
+ `returns it, or return the "${n}" binding from contribute().`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
entries.push({
|
|
94
|
+
name: n,
|
|
95
|
+
type: typeof row.type === 'string' && row.type ? row.type : 'string',
|
|
96
|
+
resource,
|
|
97
|
+
resourceKey,
|
|
98
|
+
...(typeof row.default === 'string' ? { default: row.default } : {}),
|
|
99
|
+
propertyAttribute: typeof row.propertyAttribute === 'string' && row.propertyAttribute
|
|
100
|
+
? row.propertyAttribute : n,
|
|
101
|
+
...(typeof subType === 'string' && subType ? { resourceSubType: subType } : {}),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return { resource, resourceKey, entries, problems };
|
|
105
|
+
}
|
package/dist/core/expr-check.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* and gets back diagnostics with no location. The caller stamps the location
|
|
30
30
|
* (which node / task / field) it came from.
|
|
31
31
|
*/
|
|
32
|
-
import
|
|
32
|
+
import { typescript } from './typescript-module.js';
|
|
33
33
|
/**
|
|
34
34
|
* A JSONPath wildcard/filter step — the spelling that reaches for JavaScript and
|
|
35
35
|
* misses. Used only to add a suggestion; the parse decides.
|
|
@@ -47,15 +47,18 @@ const JSONPATH_WILDCARD = /\[\s*(?:\*|\?|'[^']*'|"[^"]*")\s*\]|\.\.[A-Za-z_$]/;
|
|
|
47
47
|
* `ts.createSourceFile` is a parse, not an evaluation — nothing in `expr` runs.
|
|
48
48
|
* TypeScript is already a runtime dependency of this package (see
|
|
49
49
|
* `core/script-return.ts`, which infers a script's return type the same way), so
|
|
50
|
-
* this adds no dependency.
|
|
50
|
+
* this adds no dependency. It is loaded on the first check, not at import
|
|
51
|
+
* (`core/typescript-module.ts`).
|
|
51
52
|
*/
|
|
52
53
|
function syntaxError(expr) {
|
|
54
|
+
const ts = typescript();
|
|
53
55
|
const problems = parseExpression(expr).problems;
|
|
54
56
|
if (problems.length === 0)
|
|
55
57
|
return undefined;
|
|
56
58
|
return ts.flattenDiagnosticMessageText(problems[0].messageText, ' ');
|
|
57
59
|
}
|
|
58
60
|
function parseExpression(expr) {
|
|
61
|
+
const ts = typescript();
|
|
59
62
|
const source = ts.createSourceFile('expression.ts', `(${expr}\n)`, ts.ScriptTarget.ES2020,
|
|
60
63
|
/* setParentNodes */ false);
|
|
61
64
|
// `parseDiagnostics` is where the scanner records syntax problems. It is not on
|
|
@@ -77,6 +80,7 @@ function retype(expr, escapes, keepCooked) {
|
|
|
77
80
|
}
|
|
78
81
|
/** The value a leaf denotes — a name, or a literal's value (a regular expression's is its source). */
|
|
79
82
|
function leafValue(node) {
|
|
83
|
+
const ts = typescript();
|
|
80
84
|
if (ts.isIdentifier(node) || ts.isPrivateIdentifier(node))
|
|
81
85
|
return node.text;
|
|
82
86
|
// NumericLiteral … TemplateTail: every literal and template piece carries `.text`.
|
|
@@ -86,6 +90,7 @@ function leafValue(node) {
|
|
|
86
90
|
return undefined;
|
|
87
91
|
}
|
|
88
92
|
function children(node) {
|
|
93
|
+
const ts = typescript();
|
|
89
94
|
const out = [];
|
|
90
95
|
ts.forEachChild(node, (c) => { out.push(c); });
|
|
91
96
|
return out;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function writeJsonFile(path: string, value: unknown): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write `value` as an emitted JSON artifact: 2-space indent and a trailing newline.
|
|
3
|
+
*
|
|
4
|
+
* Every emitted `.flow`, caseplan, entry-points, bindings_v2 and library file is
|
|
5
|
+
* byte-locked, and twelve call sites each spelled this out by hand; a copy that dropped
|
|
6
|
+
* the `'\n'` would break byte-lock on that one artifact only. FB007 holds pretty-printed
|
|
7
|
+
* JSON writes to this function. Creating the parent directory stays the caller's job.
|
|
8
|
+
*/
|
|
9
|
+
import { writeFileSync } from 'node:fs';
|
|
10
|
+
export function writeJsonFile(path, value) {
|
|
11
|
+
writeFileSync(path, JSON.stringify(value, null, 2) + '\n');
|
|
12
|
+
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* into a designer error — the exact defect this file exists to remove, pointed
|
|
29
29
|
* the other way.
|
|
30
30
|
*/
|
|
31
|
-
import
|
|
31
|
+
import { typescript } from './typescript-module.js';
|
|
32
32
|
/** Normalize whatever the author wrote into the emitted shape. */
|
|
33
33
|
export function declaredScriptShape(returns) {
|
|
34
34
|
if (typeof returns === 'string')
|
|
@@ -59,6 +59,7 @@ export function declaredScriptShape(returns) {
|
|
|
59
59
|
* fields written down says so with `returns: {…}`.
|
|
60
60
|
*/
|
|
61
61
|
export function inferScriptShape(code) {
|
|
62
|
+
const ts = typescript();
|
|
62
63
|
// Wrap so a top-level `return` parses — this is how the runtime executes it.
|
|
63
64
|
const sf = ts.createSourceFile('script.ts', `function __block() {\n${code}\n}`, ts.ScriptTarget.ES2020, true);
|
|
64
65
|
// `var d = Math.floor(...); return { days: d }` is how these bodies are
|
|
@@ -99,6 +100,7 @@ export function inferScriptShape(code) {
|
|
|
99
100
|
}
|
|
100
101
|
/** The type of one expression, or undefined when it is not written down. */
|
|
101
102
|
function typeOf(expr, locals, depth) {
|
|
103
|
+
const ts = typescript();
|
|
102
104
|
// Bounded: a local initialized from another local is followed, a cycle is not.
|
|
103
105
|
if (depth > 8)
|
|
104
106
|
return undefined;
|
|
@@ -163,6 +165,7 @@ function typeOf(expr, locals, depth) {
|
|
|
163
165
|
}
|
|
164
166
|
/** `a + b`, comparisons, and the short-circuit operators. */
|
|
165
167
|
function binaryShape(e, locals, depth) {
|
|
168
|
+
const ts = typescript();
|
|
166
169
|
const op = e.operatorToken.kind;
|
|
167
170
|
// A comparison is a boolean whatever its operands are.
|
|
168
171
|
if (op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsEqualsToken
|
|
@@ -55,6 +55,7 @@ export const TYPED_FACTORIES = {
|
|
|
55
55
|
'core.logic.switch': { factory: '.switch()', bundled: ['1.0.0', '1.1'] },
|
|
56
56
|
'core.logic.terminate': { factory: '.terminate()', bundled: ['1.0.0', '1.0'] },
|
|
57
57
|
'core.subflow': { factory: 'subflow(child, inputs)', bundled: ['1.0.0', '1.0'] },
|
|
58
|
+
'uipath.agent.autonomous': { factory: 'inlineAgent()', bundled: ['1.2', '1.3', '1.4'] },
|
|
58
59
|
'uipath.agent.conversational': { factory: 'conversationalAgent()', bundled: ['1.6', '1.7'] },
|
|
59
60
|
'uipath.agent.voice': { factory: 'voiceAgent()', bundled: ['1.0', '1.1'] },
|
|
60
61
|
'uipath.conversational.get-conversation-context': { factory: 'conversationContext()', bundled: ['1.0'] },
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/**
|
|
3
|
+
* The TypeScript compiler, loaded on first use.
|
|
4
|
+
*
|
|
5
|
+
* Every builder entry reaches the expression and script checkers, and loading the compiler
|
|
6
|
+
* costs ~120 ms that a flow which never runs those checks should not pay (FB009). The
|
|
7
|
+
* specifier stays a literal at the call so the architecture lint sees the edge (as a lazy
|
|
8
|
+
* one); FB005 keeps this the only definition.
|
|
9
|
+
*
|
|
10
|
+
* The triple-slash reference: tests type-check generated code against `flow-sdk.ts`'s
|
|
11
|
+
* import graph without `@types/node` in scope, and this is the one `node:` import in that
|
|
12
|
+
* graph. Without it they fail with TS2307 on 'node:module'. It is not emitted into the .d.ts.
|
|
13
|
+
*/
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
15
|
+
let typescriptModule;
|
|
16
|
+
export function typescript() {
|
|
17
|
+
return (typescriptModule ??= createRequire(import.meta.url)('typescript'));
|
|
18
|
+
}
|