@uipath/maestro-builder-sdk 6.51.3 → 6.52.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/case/decompile.js +5 -1
- package/dist/case/serialize.js +24 -29
- package/dist/check.d.ts +8 -0
- package/dist/check.js +33 -2
- package/dist/cli/commands/flow.js +6 -0
- package/dist/cli-run.d.ts +2 -0
- package/dist/cli-run.js +8 -0
- package/dist/core/connector-configuration.d.ts +29 -2
- package/dist/core/connector-configuration.js +45 -3
- package/dist/core/connector-inputs.d.ts +10 -0
- package/dist/core/connector-inputs.js +16 -0
- package/dist/core/nodes/extensions.d.ts +23 -0
- package/dist/core/nodes/extensions.js +18 -0
- package/dist/core/nodes/family.d.ts +13 -0
- package/dist/core/nodes/node-type.d.ts +19 -1
- package/dist/core/nodes/package-definition.d.ts +82 -0
- package/dist/core/nodes/package-definition.js +162 -0
- package/dist/core/nodes/registry.d.ts +14 -2
- package/dist/core/nodes/registry.js +68 -25
- package/dist/decompile-cli.d.ts +1 -1
- package/dist/decompile-cli.js +14 -4
- package/dist/decompile.d.ts +14 -0
- package/dist/decompile.js +77 -9
- package/dist/extend.d.ts +81 -0
- package/dist/extend.js +56 -0
- package/dist/flow-node-registry.d.ts +7 -0
- package/dist/flow-node-registry.js +14 -0
- package/dist/merge-cli.js +12 -2
- package/dist/merge-compile.js +14 -1
- package/dist/node-packages.d.ts +68 -0
- package/dist/node-packages.js +279 -0
- package/dist/nodes/connector/flow/node-type.js +2 -6
- package/dist/serialize.d.ts +2 -1
- package/dist/serialize.js +10 -3
- package/package.json +6 -2
package/dist/case/decompile.js
CHANGED
|
@@ -506,7 +506,11 @@ function connectorVersion(context) {
|
|
|
506
506
|
const encoded = metadata?.activityPropertyConfiguration?.configuration;
|
|
507
507
|
if (typeof encoded === 'string' && encoded.startsWith('=jsonString:')) {
|
|
508
508
|
try {
|
|
509
|
-
|
|
509
|
+
// The activity's version is `instanceParameters.version`. `packageVersion`
|
|
510
|
+
// is what the platform writes as "1.0.0" on every activity; an SDK plan
|
|
511
|
+
// once wrote the library version there, so it stays the fallback.
|
|
512
|
+
const essential = JSON.parse(encoded.slice('=jsonString:'.length))?.essentialConfiguration;
|
|
513
|
+
return essential?.instanceParameters?.version ?? essential?.packageVersion;
|
|
510
514
|
}
|
|
511
515
|
catch {
|
|
512
516
|
throw new Error('connector task has malformed activity metadata configuration JSON.');
|
package/dist/case/serialize.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
import { IdGen, offlineBindingSeed } from './ids.js';
|
|
12
12
|
import { isUnrestorableSlotId } from './preserve.js';
|
|
13
13
|
import { v31TaskSets } from './task-sets.js';
|
|
14
|
-
import { buildConnectorInputs, nestConnectorBody, transportHttpMethod } from '../core/connector-inputs.js';
|
|
14
|
+
import { buildConnectorInputs, nestConnectorBody, replayInputsOf, transportHttpMethod } from '../core/connector-inputs.js';
|
|
15
|
+
import { buildEssentialConfiguration } from '../core/connector-configuration.js';
|
|
15
16
|
import { EQUALS_EXPR_DIALECT } from '../core/connector-checks.js';
|
|
16
17
|
import { bindingLabelRefusal } from '../core/binding-messages.js';
|
|
17
18
|
import { resolveEventWhere } from '../core/lookups.js';
|
|
@@ -1444,7 +1445,7 @@ function connectorTaskData(spec, resolver, elementId, where, executionType) {
|
|
|
1444
1445
|
// from the `body` slot. This used to drop the whole wire and push a filled
|
|
1445
1446
|
// file part into the body, where the runtime does not look for it (#1420).
|
|
1446
1447
|
const fileParts = (slots.multipartParameters ?? []).filter((part) => part.dataType.toLowerCase() === 'file');
|
|
1447
|
-
context.push(io('metadata', 'json', { body: connectorMetadata(rc, op, slots, executionType) }));
|
|
1448
|
+
context.push(io('metadata', 'json', { body: connectorMetadata(rc, op, slots, elementId, executionType) }));
|
|
1448
1449
|
const inputs = [
|
|
1449
1450
|
ioSlot('pathParameters', pathParameters, `${elementId}`),
|
|
1450
1451
|
ioSlot('queryParameters', queryParameters, `${elementId}`),
|
|
@@ -1601,45 +1602,39 @@ function folderBindingRef(resolver, name, connection, site) {
|
|
|
1601
1602
|
}
|
|
1602
1603
|
return { id };
|
|
1603
1604
|
}
|
|
1604
|
-
/**
|
|
1605
|
+
/**
|
|
1606
|
+
* The connector `metadata` json blob: the FUNCTIONAL essentialConfiguration +
|
|
1605
1607
|
* activityTypeId, and the multipart wire of a multipart operation. Designer
|
|
1606
1608
|
* cosmetics (packageId/activityColor/…) are omitted — the caseplan
|
|
1607
|
-
* schema-validates without them (see design §C).
|
|
1608
|
-
|
|
1609
|
+
* schema-validates without them (see design §C).
|
|
1610
|
+
*
|
|
1611
|
+
* The configuration is the one Flow writes, from the shared
|
|
1612
|
+
* {@link buildEssentialConfiguration}. Case used to build its own, thinner copy:
|
|
1613
|
+
* no `operation` verb, `customFieldsRequestDetails`, `connectorVersion` or
|
|
1614
|
+
* `unifiedTypesCompatible`, a curated-only `instanceParameters` even for a
|
|
1615
|
+
* Generic activity, and the library version where the platform writes
|
|
1616
|
+
* `packageVersion: "1.0.0"` (#1420).
|
|
1617
|
+
*/
|
|
1618
|
+
function connectorMetadata(rc, op, slots, seed, executionType) {
|
|
1609
1619
|
// The part DECLARATIONS only: a file part's value rides on its `file` input.
|
|
1610
1620
|
const multipartParameters = (slots.multipartParameters ?? []).map(({ name, dataType }) => ({ name, dataType }));
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
supportsStreaming: op.supportsStreaming ?? false,
|
|
1618
|
-
subType: op.subType ?? 'standard',
|
|
1619
|
-
};
|
|
1620
|
-
const configuration = {
|
|
1621
|
-
essentialConfiguration: {
|
|
1622
|
-
instanceParameters,
|
|
1623
|
-
objectName: instanceParameters.objectName,
|
|
1624
|
-
httpMethod: transportHttpMethod(rc.httpMethod),
|
|
1625
|
-
path: rc.endpoint,
|
|
1626
|
-
packageVersion: rc.version,
|
|
1627
|
-
// An external task's object states how it runs; the Designer saves it here
|
|
1628
|
-
// and beside the configuration. A plain connector activity has none.
|
|
1629
|
-
...(executionType ? { executionType } : {}),
|
|
1630
|
-
},
|
|
1631
|
-
};
|
|
1621
|
+
// The configuration replays the authored values (a schema action's parent
|
|
1622
|
+
// fields, a CEQL filter's tree), keyed by the library's own names, as Flow's.
|
|
1623
|
+
const essential = buildEssentialConfiguration(rc.entry, rc.version, replayInputsOf(slots), seed, executionType ?? null);
|
|
1624
|
+
const configuration = `=jsonString:${JSON.stringify({ essentialConfiguration: essential })}`;
|
|
1625
|
+
const instanceParameters = essential.instanceParameters;
|
|
1626
|
+
const objectName = String(op.objectName ?? rc.nodeType.split('.').pop());
|
|
1632
1627
|
return {
|
|
1633
1628
|
activityPropertyConfiguration: {
|
|
1634
1629
|
...(multipartParameters.length ? { multipartParameters } : {}),
|
|
1635
|
-
configuration
|
|
1630
|
+
configuration,
|
|
1636
1631
|
uiPathActivityTypeId: rc.activityTypeId ?? '',
|
|
1637
1632
|
errorState: { issues: [] },
|
|
1638
1633
|
...(executionType ? { executionType } : {}),
|
|
1639
1634
|
},
|
|
1640
1635
|
activityMetadata: {
|
|
1641
1636
|
activity: {
|
|
1642
|
-
displayName: rc.entry.display?.label ??
|
|
1637
|
+
displayName: rc.entry.display?.label ?? objectName,
|
|
1643
1638
|
description: rc.entry.display?.description ?? '',
|
|
1644
1639
|
category: rc.connectorName,
|
|
1645
1640
|
configuration: JSON.stringify(instanceParameters),
|
|
@@ -1653,7 +1648,7 @@ function connectorMetadata(rc, op, slots, executionType) {
|
|
|
1653
1648
|
telemetryData: {
|
|
1654
1649
|
connectorKey: rc.connectorKey,
|
|
1655
1650
|
connectorName: rc.connectorName,
|
|
1656
|
-
objectName
|
|
1651
|
+
objectName,
|
|
1657
1652
|
objectDisplayName: op.objectDisplayName ?? rc.entry.display?.operationLabel ?? '',
|
|
1658
1653
|
},
|
|
1659
1654
|
};
|
package/dist/check.d.ts
CHANGED
|
@@ -52,3 +52,11 @@ export declare const SCHEDULE_PATTERN: string;
|
|
|
52
52
|
* and day names, and the Quartz specials `L W LW ? * #`.
|
|
53
53
|
*/
|
|
54
54
|
export declare const SCHEDULE_CRON_PATTERN: string;
|
|
55
|
+
/**
|
|
56
|
+
* The one thing `check` says about runtimes: a flow with a node from a node-type
|
|
57
|
+
* package does not run on the UiPath platform, which runs exactly its registry.
|
|
58
|
+
* Reported once per flow, naming the steps and their packages, as a WARNING: the
|
|
59
|
+
* flow is still a correct workflow for a runtime that loads the package (the
|
|
60
|
+
* local engine), it just cannot be validated or published through `uip`.
|
|
61
|
+
*/
|
|
62
|
+
export declare const PACKAGE_NODES_NOT_PLATFORM = "PACKAGE_NODES_NOT_PLATFORM";
|
package/dist/check.js
CHANGED
|
@@ -892,6 +892,7 @@ function checkFlow(built, ancestors, opts = {}, ledger = newResourceIdLedger())
|
|
|
892
892
|
}
|
|
893
893
|
reportUnreachableHitlOutcomes(hitlChoiceNoPorts, exprs, diags);
|
|
894
894
|
checkRegisteredFamilies(registeredSteps, unresolvedSteps, stepNames, diags);
|
|
895
|
+
checkPackageNodes(registeredSteps, diags);
|
|
895
896
|
// The ids this scope's other nodes get, for the file-wide nodeId check in `check`.
|
|
896
897
|
for (const n of stepNames)
|
|
897
898
|
if (!ledger.taken.has(n))
|
|
@@ -2819,6 +2820,36 @@ function catalogued(entry, step, code, message, suggestion) {
|
|
|
2819
2820
|
// Key order as the per-family rules always wrote it — `check --json` prints it.
|
|
2820
2821
|
return { level: known.severity, code, step, message, ...(suggestion !== undefined ? { suggestion } : {}) };
|
|
2821
2822
|
}
|
|
2823
|
+
/**
|
|
2824
|
+
* The one thing `check` says about runtimes: a flow with a node from a node-type
|
|
2825
|
+
* package does not run on the UiPath platform, which runs exactly its registry.
|
|
2826
|
+
* Reported once per flow, naming the steps and their packages, as a WARNING: the
|
|
2827
|
+
* flow is still a correct workflow for a runtime that loads the package (the
|
|
2828
|
+
* local engine), it just cannot be validated or published through `uip`.
|
|
2829
|
+
*/
|
|
2830
|
+
export const PACKAGE_NODES_NOT_PLATFORM = 'PACKAGE_NODES_NOT_PLATFORM';
|
|
2831
|
+
function checkPackageNodes(steps, diags) {
|
|
2832
|
+
const byPackage = new Map();
|
|
2833
|
+
let first;
|
|
2834
|
+
for (const [name, placed] of steps) {
|
|
2835
|
+
const origin = placed.entry.family.package;
|
|
2836
|
+
if (origin === undefined)
|
|
2837
|
+
continue;
|
|
2838
|
+
first ??= name;
|
|
2839
|
+
const list = byPackage.get(origin.name) ?? [];
|
|
2840
|
+
list.push(`"${name}" (${placed.impl.typeName})`);
|
|
2841
|
+
byPackage.set(origin.name, list);
|
|
2842
|
+
}
|
|
2843
|
+
if (first === undefined)
|
|
2844
|
+
return;
|
|
2845
|
+
const packages = [...byPackage].map(([pkg, names]) => `${pkg}: ${names.join(', ')}`).join('; ');
|
|
2846
|
+
diags.push({
|
|
2847
|
+
level: 'warning', code: PACKAGE_NODES_NOT_PLATFORM, step: first,
|
|
2848
|
+
message: `This flow uses node types from a node-type package (${packages}). The UiPath platform runs only its own registry, `
|
|
2849
|
+
+ 'so `uip maestro flow validate` refuses the file and it cannot be published; it runs on a runtime that loads the package, '
|
|
2850
|
+
+ 'such as the local engine (`flow-debug`).',
|
|
2851
|
+
});
|
|
2852
|
+
}
|
|
2822
2853
|
/** Run each registered family's own rules over all of its placements in this flow. */
|
|
2823
2854
|
function checkRegisteredFamilies(steps, unresolved, stepNames, diags) {
|
|
2824
2855
|
const byFamily = new Map();
|
|
@@ -2969,7 +3000,7 @@ placed, opts, carried) {
|
|
|
2969
3000
|
if (!placed)
|
|
2970
3001
|
return;
|
|
2971
3002
|
const { impl } = placed;
|
|
2972
|
-
if (impl.definition
|
|
3003
|
+
if (impl.definition !== 'bundled' && placed.carried !== undefined) {
|
|
2973
3004
|
// At a carried version the carried definition answers, as serialize asks
|
|
2974
3005
|
// it: the type's declaration covers only the versions it registers.
|
|
2975
3006
|
if (!definitionHasErrorPort(placed.carried)) {
|
|
@@ -2977,7 +3008,7 @@ placed, opts, carried) {
|
|
|
2977
3008
|
return;
|
|
2978
3009
|
}
|
|
2979
3010
|
}
|
|
2980
|
-
else if (impl.definition
|
|
3011
|
+
else if (impl.definition !== 'bundled') {
|
|
2981
3012
|
// The definition serialize will be supplied, when check's options can name
|
|
2982
3013
|
// it (a connector's, from the library); the type answers without it otherwise.
|
|
2983
3014
|
const def = impl.checkDefinition?.(placed.spec, opts);
|
|
@@ -92,6 +92,7 @@ export function registerFlowCommands(program) {
|
|
|
92
92
|
.option('--import <specifier>', 'SDK import specifier in generated source')
|
|
93
93
|
.option('--strict', 'fail on unsupported constructs')
|
|
94
94
|
.option('--no-pipeline', 'do not emit a brownfield pipeline helper')
|
|
95
|
+
.option('--package <name...>', 'trust and load this node-type package (repeatable); otherwise package.json "maestroBuilderSdk".nodePackages decides')
|
|
95
96
|
.action(async (input, options) => {
|
|
96
97
|
const argv = [input];
|
|
97
98
|
addValue(argv, '-o', options.output);
|
|
@@ -100,6 +101,8 @@ export function registerFlowCommands(program) {
|
|
|
100
101
|
argv.push('--strict');
|
|
101
102
|
if (options.pipeline === false)
|
|
102
103
|
argv.push('--no-pipeline');
|
|
104
|
+
for (const name of options.package ?? [])
|
|
105
|
+
argv.push('--package', name);
|
|
103
106
|
await invoke('flow decompile', () => import('../../decompile-cli.js'), argv);
|
|
104
107
|
});
|
|
105
108
|
flow.command('merge')
|
|
@@ -112,6 +115,7 @@ export function registerFlowCommands(program) {
|
|
|
112
115
|
.option('--library <dir>', 'connector library, for compiling with --baseline-from or a .flow.ts edited source')
|
|
113
116
|
.option('--bindings <file>', 'bindings.json, for the same compiles')
|
|
114
117
|
.option('--strict', 'refuse when the no-edit round trip (the baseline) differs from the original')
|
|
118
|
+
.option('--package <name...>', 'trust and load this node-type package for --baseline-from (repeatable)')
|
|
115
119
|
.allowExcessArguments()
|
|
116
120
|
.action(async (_edited, options, command) => {
|
|
117
121
|
const pair = namedOrLegacySecond(command, {
|
|
@@ -129,6 +133,8 @@ export function registerFlowCommands(program) {
|
|
|
129
133
|
addValue(argv, '--bindings', options.bindings);
|
|
130
134
|
if (options.strict)
|
|
131
135
|
argv.push('--strict');
|
|
136
|
+
for (const name of options.package ?? [])
|
|
137
|
+
argv.push('--package', name);
|
|
132
138
|
await invoke('flow merge', () => import('../../merge-cli.js'), argv);
|
|
133
139
|
});
|
|
134
140
|
}
|
package/dist/cli-run.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type CliExitCode = 0 | 1 | 2;
|
|
2
2
|
export declare function runWhenInvokedDirectly(moduleUrl: string, label: string, run: (argv: string[]) => Promise<CliExitCode> | CliExitCode): void;
|
|
3
3
|
/** The value after `name` in `argv`, or `undefined`. */
|
|
4
|
+
/** Every value of a repeatable flag, in order: `--package a --package b` → `['a', 'b']`. */
|
|
5
|
+
export declare function flagValues(argv: readonly string[], flag: string): string[];
|
|
4
6
|
export declare function flagValue(argv: readonly string[], name: string): string | undefined;
|
package/dist/cli-run.js
CHANGED
|
@@ -51,6 +51,14 @@ export function runWhenInvokedDirectly(moduleUrl, label, run) {
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
/** The value after `name` in `argv`, or `undefined`. */
|
|
54
|
+
/** Every value of a repeatable flag, in order: `--package a --package b` → `['a', 'b']`. */
|
|
55
|
+
export function flagValues(argv, flag) {
|
|
56
|
+
const out = [];
|
|
57
|
+
for (let i = 0; i < argv.length - 1; i++)
|
|
58
|
+
if (argv[i] === flag)
|
|
59
|
+
out.push(argv[i + 1]);
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
54
62
|
export function flagValue(argv, name) {
|
|
55
63
|
const i = argv.indexOf(name);
|
|
56
64
|
return i >= 0 ? argv[i + 1] : undefined;
|
|
@@ -63,6 +63,33 @@
|
|
|
63
63
|
*
|
|
64
64
|
* Neither is cosmetic for a generic node: v1's own `check_generic_dynamic_node.py`
|
|
65
65
|
* identifies the activity semantically, by `activityType == 'generic'` **and
|
|
66
|
-
* `operation == 'list'`**, read from these very keys.
|
|
66
|
+
* `operation == 'list'`**, read from these very keys. *
|
|
67
|
+
* ## `savedJitInputFieldId` is not written, because the library cannot say when
|
|
68
|
+
*
|
|
69
|
+
* The CLI writes `savedJitInputFieldId: "in_<objectName>"` for a create /
|
|
70
|
+
* update / replace whose IS metadata declares a `body` PARAMETER (a
|
|
71
|
+
* just-in-time body). The offline library does not carry that parameter: its
|
|
72
|
+
* `operation.parameters` hold only `query` · `path` · `multipart`. Its body
|
|
73
|
+
* FIELDS do not stand in for it. Measured over the Designer- and CLI-saved
|
|
74
|
+
* create/update/replace nodes in the eval corpus: Slack `create-channel` (2
|
|
75
|
+
* body fields) carries the key, while `join-channel` (1 body field, 0/2) and
|
|
76
|
+
* `create-group-direct-message` (1 body field, 0/89) do not, and Data Service
|
|
77
|
+
* `create-entity-record` (no body fields) does (336/405). Writing it on a
|
|
78
|
+
* guess would be wrong on hundreds of nodes, so it stays out until the library
|
|
79
|
+
* records the body parameter.
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildConfiguration(entry: any, version: string, inputValues?: Record<string, unknown>, seed?: string, executionType?: string | null): string;
|
|
82
|
+
/**
|
|
83
|
+
* The `essentialConfiguration` object that {@link buildConfiguration} wraps in
|
|
84
|
+
* its `=jsonString:` envelope. For a caller that also needs a field of it (Case
|
|
85
|
+
* copies its `instanceParameters` into the activity metadata), so it does not
|
|
86
|
+
* parse the string back.
|
|
87
|
+
*
|
|
88
|
+
* @param entry - The connector library entry.
|
|
89
|
+
* @param version - The connector version.
|
|
90
|
+
* @param inputValues - The authored inputs to replay, keyed by the library's names.
|
|
91
|
+
* @param seed - Seed for the saved filter tree ids.
|
|
92
|
+
* @param executionType - An External Agent / Workflow object's run mode, or `null`.
|
|
93
|
+
* @returns The essential configuration, with only Studio Web's essential keys.
|
|
67
94
|
*/
|
|
68
|
-
export declare function
|
|
95
|
+
export declare function buildEssentialConfiguration(entry: any, version: string, inputValues?: Record<string, unknown>, seed?: string, executionType?: string | null): Record<string, unknown>;
|
|
@@ -20,6 +20,14 @@ const ESSENTIAL_DEFAULTS = {
|
|
|
20
20
|
executionType: null,
|
|
21
21
|
operation: 'create',
|
|
22
22
|
packageVersion: '1.0.0',
|
|
23
|
+
// The CLI's offline builder writes these two on every activity
|
|
24
|
+
// (`buildActivityEssentialConfiguration`, uipath-cli
|
|
25
|
+
// `integrationservice-sdk/src/dap/essential-config.ts`), and so does every
|
|
26
|
+
// Designer save in the eval corpus. `connectorVersion` is a request header
|
|
27
|
+
// the library does not carry; Studio Web fills it from its type cache on
|
|
28
|
+
// open, so offline it is `null`, as the CLI and the Case fixture write it.
|
|
29
|
+
connectorVersion: null,
|
|
30
|
+
unifiedTypesCompatible: true,
|
|
23
31
|
};
|
|
24
32
|
/**
|
|
25
33
|
* Which of an operation's parameters carries a CEQL filter.
|
|
@@ -161,9 +169,40 @@ function envelope(flat) {
|
|
|
161
169
|
*
|
|
162
170
|
* Neither is cosmetic for a generic node: v1's own `check_generic_dynamic_node.py`
|
|
163
171
|
* identifies the activity semantically, by `activityType == 'generic'` **and
|
|
164
|
-
* `operation == 'list'`**, read from these very keys.
|
|
172
|
+
* `operation == 'list'`**, read from these very keys. *
|
|
173
|
+
* ## `savedJitInputFieldId` is not written, because the library cannot say when
|
|
174
|
+
*
|
|
175
|
+
* The CLI writes `savedJitInputFieldId: "in_<objectName>"` for a create /
|
|
176
|
+
* update / replace whose IS metadata declares a `body` PARAMETER (a
|
|
177
|
+
* just-in-time body). The offline library does not carry that parameter: its
|
|
178
|
+
* `operation.parameters` hold only `query` · `path` · `multipart`. Its body
|
|
179
|
+
* FIELDS do not stand in for it. Measured over the Designer- and CLI-saved
|
|
180
|
+
* create/update/replace nodes in the eval corpus: Slack `create-channel` (2
|
|
181
|
+
* body fields) carries the key, while `join-channel` (1 body field, 0/2) and
|
|
182
|
+
* `create-group-direct-message` (1 body field, 0/89) do not, and Data Service
|
|
183
|
+
* `create-entity-record` (no body fields) does (336/405). Writing it on a
|
|
184
|
+
* guess would be wrong on hundreds of nodes, so it stays out until the library
|
|
185
|
+
* records the body parameter.
|
|
186
|
+
*/
|
|
187
|
+
export function buildConfiguration(entry, version, inputValues, seed = 'node', executionType = null) {
|
|
188
|
+
return '=jsonString:' + JSON.stringify({
|
|
189
|
+
essentialConfiguration: buildEssentialConfiguration(entry, version, inputValues, seed, executionType),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The `essentialConfiguration` object that {@link buildConfiguration} wraps in
|
|
194
|
+
* its `=jsonString:` envelope. For a caller that also needs a field of it (Case
|
|
195
|
+
* copies its `instanceParameters` into the activity metadata), so it does not
|
|
196
|
+
* parse the string back.
|
|
197
|
+
*
|
|
198
|
+
* @param entry - The connector library entry.
|
|
199
|
+
* @param version - The connector version.
|
|
200
|
+
* @param inputValues - The authored inputs to replay, keyed by the library's names.
|
|
201
|
+
* @param seed - Seed for the saved filter tree ids.
|
|
202
|
+
* @param executionType - An External Agent / Workflow object's run mode, or `null`.
|
|
203
|
+
* @returns The essential configuration, with only Studio Web's essential keys.
|
|
165
204
|
*/
|
|
166
|
-
export function
|
|
205
|
+
export function buildEssentialConfiguration(entry, version, inputValues, seed = 'node', executionType = null) {
|
|
167
206
|
const op = entry.operation ?? {};
|
|
168
207
|
const conn = entry.connector ?? {};
|
|
169
208
|
const at = op.activityType;
|
|
@@ -177,6 +216,9 @@ export function buildConfiguration(entry, version, inputValues, seed = 'node') {
|
|
|
177
216
|
: ESSENTIAL_DEFAULTS.operation;
|
|
178
217
|
const composed = {
|
|
179
218
|
...ESSENTIAL_DEFAULTS,
|
|
219
|
+
// An External Agent / Workflow object states how it runs; a connector
|
|
220
|
+
// activity has none (`null`, the default).
|
|
221
|
+
executionType,
|
|
180
222
|
operation: verb,
|
|
181
223
|
customFieldsRequestDetails: schemaReplayDetails(op, inputValues),
|
|
182
224
|
savedFilterTrees: savedFilterTrees(op, inputValues, seed),
|
|
@@ -202,5 +244,5 @@ export function buildConfiguration(entry, version, inputValues, seed = 'node') {
|
|
|
202
244
|
},
|
|
203
245
|
...(op.pathTemplate || op.path ? { path: op.pathTemplate || op.path } : {}),
|
|
204
246
|
};
|
|
205
|
-
return
|
|
247
|
+
return envelope(composed).essentialConfiguration;
|
|
206
248
|
}
|
|
@@ -58,6 +58,16 @@ export declare const CONNECTOR_INPUT_MISSING = "CONNECTOR_INPUT_MISSING";
|
|
|
58
58
|
*/
|
|
59
59
|
export declare function connectorInputErrors(rc: ResolvedConnector, inputs: Record<string, unknown>, resolutions?: LookupResolutions, lookups?: Readonly<Record<string, LookupSpec>>, wire?: Pick<ConnectorInputOpts, 'dialect' | 'render'>): string | undefined;
|
|
60
60
|
export declare function buildConnectorInputs(rc: any, inputs: Record<string, unknown>, opts: ConnectorInputOpts): ConnectorSlots;
|
|
61
|
+
/**
|
|
62
|
+
* The authored values a connector's `configuration` replays (a schema action's
|
|
63
|
+
* parent fields, a CEQL filter's tree), keyed by the library's own names: the
|
|
64
|
+
* body, path and query slots, merged. Flow and Case both write the
|
|
65
|
+
* configuration from this, so the two cannot drift.
|
|
66
|
+
*
|
|
67
|
+
* @param slots - The slots {@link buildConnectorInputs} returned.
|
|
68
|
+
* @returns The merged body, path and query values.
|
|
69
|
+
*/
|
|
70
|
+
export declare function replayInputsOf(slots: ConnectorSlots): Record<string, unknown>;
|
|
61
71
|
/**
|
|
62
72
|
* `inputMetadata.multipart.bodyFieldName` names the CONTAINER part — the one the
|
|
63
73
|
* runtime composes from `bodyParameters`. Measured on the designer's own nodes in
|
|
@@ -253,6 +253,22 @@ function swapLookupTokens(value, resolutions, unresolved) {
|
|
|
253
253
|
return value.map((item) => swapLookupTokens(item, resolutions, unresolved));
|
|
254
254
|
return value;
|
|
255
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* The authored values a connector's `configuration` replays (a schema action's
|
|
258
|
+
* parent fields, a CEQL filter's tree), keyed by the library's own names: the
|
|
259
|
+
* body, path and query slots, merged. Flow and Case both write the
|
|
260
|
+
* configuration from this, so the two cannot drift.
|
|
261
|
+
*
|
|
262
|
+
* @param slots - The slots {@link buildConnectorInputs} returned.
|
|
263
|
+
* @returns The merged body, path and query values.
|
|
264
|
+
*/
|
|
265
|
+
export function replayInputsOf(slots) {
|
|
266
|
+
return {
|
|
267
|
+
...(slots.bodyParameters ?? {}),
|
|
268
|
+
...(slots.pathParameters ?? {}),
|
|
269
|
+
...(slots.queryParameters ?? {}),
|
|
270
|
+
};
|
|
271
|
+
}
|
|
256
272
|
/**
|
|
257
273
|
* `inputMetadata.multipart.bodyFieldName` names the CONTAINER part — the one the
|
|
258
274
|
* runtime composes from `bodyParameters`. Measured on the designer's own nodes in
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hand-off between a node-type package and the artifact's registry.
|
|
3
|
+
*
|
|
4
|
+
* `@uipath/maestro-builder-sdk/extend` is a builder entry and stays light at
|
|
5
|
+
* import (FB009): it must not load the Flow registry, which pulls the bundled
|
|
6
|
+
* definitions in. So a package's family is CONTRIBUTED here, and the registry
|
|
7
|
+
* ADOPTS whatever was contributed when it loads — at compile time, before any
|
|
8
|
+
* flow is built — and installs itself as the sink for every later contribution,
|
|
9
|
+
* which it then registers at once. A refusal (a kind a built-in family owns, a
|
|
10
|
+
* type that is not `definition: 'package'`) surfaces at adoption, still before
|
|
11
|
+
* the first node is serialized.
|
|
12
|
+
*/
|
|
13
|
+
import type { ArtifactContexts } from './node-type.js';
|
|
14
|
+
import type { NodeFamily } from './family.js';
|
|
15
|
+
type Sink = (family: NodeFamily<ArtifactContexts>) => void;
|
|
16
|
+
/** Hand a package's family to the artifact's registry, now or when it loads. */
|
|
17
|
+
export declare function contributeFamily(family: NodeFamily<ArtifactContexts>): void;
|
|
18
|
+
/**
|
|
19
|
+
* The registry calls this once at load: it receives every family contributed so
|
|
20
|
+
* far and every one contributed after. Families are adopted in contribution order.
|
|
21
|
+
*/
|
|
22
|
+
export declare function adoptContributedFamilies(adopt: Sink): void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const pending = [];
|
|
2
|
+
let sink;
|
|
3
|
+
/** Hand a package's family to the artifact's registry, now or when it loads. */
|
|
4
|
+
export function contributeFamily(family) {
|
|
5
|
+
if (sink !== undefined)
|
|
6
|
+
sink(family);
|
|
7
|
+
else
|
|
8
|
+
pending.push(family);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The registry calls this once at load: it receives every family contributed so
|
|
12
|
+
* far and every one contributed after. Families are adopted in contribution order.
|
|
13
|
+
*/
|
|
14
|
+
export function adoptContributedFamilies(adopt) {
|
|
15
|
+
sink = adopt;
|
|
16
|
+
for (const family of pending.splice(0))
|
|
17
|
+
adopt(family);
|
|
18
|
+
}
|
|
@@ -25,12 +25,25 @@ export interface Placement<Spec = unknown> {
|
|
|
25
25
|
/** The version the node will be emitted at. */
|
|
26
26
|
readonly version: string;
|
|
27
27
|
}
|
|
28
|
+
/** The npm package a node family comes from, when it is not built into the SDK. */
|
|
29
|
+
export interface PackageOrigin {
|
|
30
|
+
/** The package name an author imports, e.g. `'@uipath/flow-local-nodes'`. */
|
|
31
|
+
readonly name: string;
|
|
32
|
+
/** The package's version, when it knows it; written into each definition's provenance. */
|
|
33
|
+
readonly version?: string;
|
|
34
|
+
}
|
|
28
35
|
export interface NodeFamily<Ctx extends ArtifactContexts> {
|
|
29
36
|
/** Stable id, e.g. `'data-fabric'`. Unique within the artifact's registry. */
|
|
30
37
|
readonly id: string;
|
|
31
38
|
readonly title: string;
|
|
32
39
|
readonly types: readonly AnyNodeType<Ctx>[];
|
|
33
40
|
readonly diagnostics: DiagnosticCatalog;
|
|
41
|
+
/**
|
|
42
|
+
* Set on a family registered from a node-type package. Every type of such a
|
|
43
|
+
* family declares `definition: 'package'`, and only such a family may; a
|
|
44
|
+
* built-in family never sets this.
|
|
45
|
+
*/
|
|
46
|
+
readonly package?: PackageOrigin;
|
|
34
47
|
/** Rules over every placement of this family's types, after the per-node checks. */
|
|
35
48
|
check?(placements: readonly Placement[], ctx: Ctx['familyCheck']): void;
|
|
36
49
|
}
|
|
@@ -25,7 +25,19 @@ import type { TypeDesc } from '../expr.js';
|
|
|
25
25
|
* its declared inputs) is read from. `per-tenant`: built per tenant or per call —
|
|
26
26
|
* there is no bundled entry to ask, so the node type declares those answers itself.
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Where a node type's definition comes from.
|
|
30
|
+
*
|
|
31
|
+
* - `bundled`: the SDK's bundled registry snapshot has it, so the node carries no
|
|
32
|
+
* definition and the bundle answers `errorPort`.
|
|
33
|
+
* - `per-tenant`: a connector-shaped type the tenant defines; the type supplies its
|
|
34
|
+
* definition at serialize time and declares `errorPort`.
|
|
35
|
+
* - `package`: a type from a node-type package (`@uipath/maestro-builder-sdk/extend`);
|
|
36
|
+
* the package ships the definition, the type writes it into the file with its
|
|
37
|
+
* provenance, and the UiPath platform does not run it. A built-in family may not
|
|
38
|
+
* declare one — the registry refuses it (see `NodeTypeRegistry`).
|
|
39
|
+
*/
|
|
40
|
+
export type DefinitionSource = 'bundled' | 'per-tenant' | 'package';
|
|
29
41
|
/**
|
|
30
42
|
* One place a spec carries a value the artifact evaluates against its scope.
|
|
31
43
|
* `value` is walked deeply for expressions; `code` is a script body whose
|
|
@@ -104,6 +116,12 @@ export type OutputContract = {
|
|
|
104
116
|
*/
|
|
105
117
|
export interface FactoryCall {
|
|
106
118
|
readonly factory: string;
|
|
119
|
+
/**
|
|
120
|
+
* The module the factory is imported from, when it is not the SDK: a node-type
|
|
121
|
+
* package's own name. Decompile defaults it to the type's family `package.name`,
|
|
122
|
+
* so a `print` implementation sets it only to import from somewhere else.
|
|
123
|
+
*/
|
|
124
|
+
readonly module?: string;
|
|
107
125
|
readonly positional?: readonly string[];
|
|
108
126
|
readonly options?: ReadonlyArray<readonly [name: string, source: string | undefined]>;
|
|
109
127
|
/** A note for the reader, written as a block comment after the call (the artifact escapes it). */
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The node definition a node-type package writes into a compiled `.flow`.
|
|
3
|
+
*
|
|
4
|
+
* A package type has no platform definition — neither the SDK's bundled snapshot
|
|
5
|
+
* nor the tenant has one — so the file has to carry everything a reader needs:
|
|
6
|
+
* the designer's display and handles, the input and output schemas, and the
|
|
7
|
+
* `model.expansion` template the `.flow` → BPMN converter expands.
|
|
8
|
+
*
|
|
9
|
+
* ## Why one-node expansion
|
|
10
|
+
*
|
|
11
|
+
* The product's converter (vendored in `local-engine`) resolves a node's
|
|
12
|
+
* definition as `manifestDef ?? fileDef` and reads a node's per-instance input
|
|
13
|
+
* VALUES only through a definition's `model.expansion`: a `context` entry's
|
|
14
|
+
* `source: 'node.data.inputs.<name>'` is read off each placed node while the
|
|
15
|
+
* template is expanded. So every package definition expands to exactly one
|
|
16
|
+
* `bpmn:ServiceTask` that REPLACES the node under its own id, carries
|
|
17
|
+
* `<uipath:type value="<serviceType>">`, its inputs as context, and its
|
|
18
|
+
* `=response` / `=Error` output rows — the element shape a runtime's dispatch
|
|
19
|
+
* lane reads for a connector. Expansion drops the node's original edges, so the
|
|
20
|
+
* template re-creates the `success` edge and, when the author wired `.onError`,
|
|
21
|
+
* an error boundary with the `error` edge.
|
|
22
|
+
*
|
|
23
|
+
* The input NAMES are the contract with the runtime half of the package: a
|
|
24
|
+
* handler reads them off `TaskContext.inputs`. A `string` context entry is
|
|
25
|
+
* emitted as `value` and a `json` one as a JSON `body`; the converter turns a
|
|
26
|
+
* falsy `string` into `""` and a falsy `json` into `{}`, so a package encodes
|
|
27
|
+
* booleans and numbers as `=js:` expressions rather than relying on either.
|
|
28
|
+
*/
|
|
29
|
+
/** One authored input of a package node. */
|
|
30
|
+
export interface PackageInputField {
|
|
31
|
+
readonly type: 'string' | 'boolean' | 'number' | 'array' | 'object';
|
|
32
|
+
readonly description: string;
|
|
33
|
+
readonly required?: boolean;
|
|
34
|
+
readonly enum?: readonly string[];
|
|
35
|
+
readonly default?: unknown;
|
|
36
|
+
}
|
|
37
|
+
/** One field of a package node's `output`. */
|
|
38
|
+
export interface PackageOutputField {
|
|
39
|
+
readonly type: 'string' | 'boolean' | 'number' | 'array' | 'object';
|
|
40
|
+
readonly description: string;
|
|
41
|
+
}
|
|
42
|
+
/** What a package declares about one node; `defineNodeDefinition` does the rest. */
|
|
43
|
+
export interface PackageNodeShape {
|
|
44
|
+
/** The `.flow` node type, e.g. `acme.ledger.post`. */
|
|
45
|
+
readonly nodeType: string;
|
|
46
|
+
/** The BPMN service type a runtime dispatches on, e.g. `Acme.Ledger.Post`. */
|
|
47
|
+
readonly serviceType: string;
|
|
48
|
+
/** The definition version; the node's `typeVersion`. Default `1.0`. */
|
|
49
|
+
readonly version?: string;
|
|
50
|
+
readonly label: string;
|
|
51
|
+
readonly description: string;
|
|
52
|
+
/** A Lucide icon name the designer draws, e.g. `file-text`. */
|
|
53
|
+
readonly icon: string;
|
|
54
|
+
/** The designer's category for the add-node panel. Default `package`. */
|
|
55
|
+
readonly category?: string;
|
|
56
|
+
readonly tags?: readonly string[];
|
|
57
|
+
readonly inputs: Readonly<Record<string, PackageInputField>>;
|
|
58
|
+
readonly outputs: Readonly<Record<string, PackageOutputField>>;
|
|
59
|
+
}
|
|
60
|
+
export declare const DEFAULT_PACKAGE_DEFINITION_VERSION = "1.0";
|
|
61
|
+
/**
|
|
62
|
+
* The definition `defineNodeDefinition` returns: the complete manifest, with the
|
|
63
|
+
* fields a package's node type reads back typed — `version` is the type's
|
|
64
|
+
* `version` and the snapshot reference's, `model.serviceType` is what the runtime
|
|
65
|
+
* half claims.
|
|
66
|
+
*/
|
|
67
|
+
export interface PackageNodeDefinition extends Record<string, unknown> {
|
|
68
|
+
readonly nodeType: string;
|
|
69
|
+
readonly version: string;
|
|
70
|
+
readonly model: Record<string, unknown> & {
|
|
71
|
+
readonly type: 'bpmn:ServiceTask';
|
|
72
|
+
readonly serviceType: string;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build a package node's definition from its shape: the complete manifest a
|
|
77
|
+
* compiled flow carries as a `snapshot` reference, with the one-node expansion
|
|
78
|
+
* described above. Provenance (`source.package`) is stamped at serialize time
|
|
79
|
+
* from the family's `package`, not here, so a shape stays free of the package's
|
|
80
|
+
* own name.
|
|
81
|
+
*/
|
|
82
|
+
export declare function defineNodeDefinition(shape: PackageNodeShape): PackageNodeDefinition;
|