@uipath/maestro-builder-sdk 6.25.1 → 6.27.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 +22 -21
- package/dist/api-members.md +87 -84
- package/dist/check.js +83 -18
- package/dist/core/carried-definitions.d.ts +33 -0
- package/dist/core/carried-definitions.js +63 -0
- package/dist/core/nodes/versioned.d.ts +35 -0
- package/dist/core/nodes/versioned.js +35 -0
- package/dist/decompile.js +152 -57
- package/dist/flow-expr-check.js +6 -1
- package/dist/flow-node-type.d.ts +8 -3
- package/dist/flow-sdk.d.ts +91 -12
- package/dist/flow-sdk.js +74 -6
- package/dist/merge.js +2 -1
- package/dist/serialize.js +76 -28
- package/package.json +2 -2
package/dist/serialize.js
CHANGED
|
@@ -19,7 +19,8 @@ import { planContributionBindings } from './core/contribution-bindings.js';
|
|
|
19
19
|
import { declaredErrorPortRefusal, definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
|
|
20
20
|
import { FLOW_NODE_TYPES } from './flow-node-registry.js';
|
|
21
21
|
import { stepExits } from './flow-step-exits.js';
|
|
22
|
-
import {
|
|
22
|
+
import { resolveVersionCarried } from './core/nodes/versioned.js';
|
|
23
|
+
import { indexCarriedDefinitions } from './core/carried-definitions.js';
|
|
23
24
|
import { FORM_FIELD_JSON_TYPE } from './core/form-field-type.js';
|
|
24
25
|
import { connectionConnectors } from './bindings-v2.js';
|
|
25
26
|
import { BindingRefusal, GUID_RE, bindingLabelRefusal, bindingMissingMessage, missingBindingLabels } from './core/binding-messages.js';
|
|
@@ -2271,8 +2272,8 @@ function declaresMemoryHandle(def) {
|
|
|
2271
2272
|
* compiles. The corpus also carries 1.1 and 1.3; `shared/sample-flows/
|
|
2272
2273
|
* inline-agent.flow` says 1.0, which appears in none of the 29.
|
|
2273
2274
|
*/
|
|
2274
|
-
function inlineAgentDef(version, withMemory) {
|
|
2275
|
-
const bundled =
|
|
2275
|
+
function inlineAgentDef(version, withMemory, resolve = (t, v) => DEFS[`${t}@${v}`]) {
|
|
2276
|
+
const bundled = resolve(INLINE_AGENT_TYPE, version);
|
|
2276
2277
|
if (!bundled)
|
|
2277
2278
|
return undefined;
|
|
2278
2279
|
const def = jsonClone(bundled);
|
|
@@ -4240,6 +4241,17 @@ function stepNamesOf(steps, out = []) {
|
|
|
4240
4241
|
return out;
|
|
4241
4242
|
}
|
|
4242
4243
|
export function serialize(built, opts = {}) {
|
|
4244
|
+
/**
|
|
4245
|
+
* Definitions the flow carries (`.definitions()`, #1128), by `type@version` —
|
|
4246
|
+
* the third source a pinned `{ version }` resolves from, after the bundle and
|
|
4247
|
+
* the node-type registry. A flow that carries nothing compiles exactly as
|
|
4248
|
+
* before. A subflow body sees its own carried definitions plus its
|
|
4249
|
+
* ancestors' (as `check` does), only while it is emitted.
|
|
4250
|
+
*/
|
|
4251
|
+
let carriedDefs = indexCarriedDefinitions(built.definitions ?? [], `flow "${built.id}" .definitions()`);
|
|
4252
|
+
const carriedFor = Object.assign((type, version) => carriedDefs.get(`${type}@${version}`), { versions: (type) => [...carriedDefs.keys()].filter((k) => k.startsWith(`${type}@`)).map((k) => k.slice(type.length + 1)) });
|
|
4253
|
+
/** The exact definition of `type@version`: bundled, else carried, else `undefined`. */
|
|
4254
|
+
const definitionFor = (type, version) => DEFS[`${type}@${version}`] ?? carriedFor(type, version);
|
|
4243
4255
|
/**
|
|
4244
4256
|
* The `definitions[]` a flow carries, keyed by `type@version` — NOT by type.
|
|
4245
4257
|
* One flow can legitimately hold two versions of the same family (a plain
|
|
@@ -4451,19 +4463,22 @@ export function serialize(built, opts = {}) {
|
|
|
4451
4463
|
function makeNode(type, id, label, o = {}) {
|
|
4452
4464
|
let def = o.def ?? defByType.get(type);
|
|
4453
4465
|
if (o.requestedVersion !== undefined && def?.version !== o.requestedVersion) {
|
|
4454
|
-
const exact = o.def ? undefined :
|
|
4466
|
+
const exact = o.def ? undefined : definitionFor(type, o.requestedVersion);
|
|
4455
4467
|
if (!exact) {
|
|
4456
|
-
// Name every version the SDK could have resolved: every bundled
|
|
4457
|
-
// version of the type, else (a type built per resource, a
|
|
4458
|
-
// the definition in hand. Naming only the default sent the
|
|
4459
|
-
// looking for a version that was shipped all along (#1128:
|
|
4468
|
+
// Name every version the SDK could have resolved: every bundled or
|
|
4469
|
+
// carried version of the type, else (a type built per resource, a
|
|
4470
|
+
// connector) the definition in hand. Naming only the default sent the
|
|
4471
|
+
// reader looking for a version that was shipped all along (#1128:
|
|
4460
4472
|
// quick-form bundles 1.0 AND 1.1, and the message said 1.0).
|
|
4461
|
-
const
|
|
4462
|
-
const
|
|
4473
|
+
const prefix = `${type}@`;
|
|
4474
|
+
const carriedVersions = [...carriedDefs.keys()].filter((k) => k.startsWith(prefix)).map((k) => k.slice(prefix.length));
|
|
4475
|
+
const known = o.def ? [] : [...bundledVersions(type), ...carriedVersions];
|
|
4476
|
+
const resolvable = known.length > 0 ? known
|
|
4463
4477
|
: [def?.version].filter((v) => typeof v === 'string');
|
|
4464
4478
|
throw new Error(`"${label ?? id}" requests ${type}@${o.requestedVersion}, but this SDK resolves only `
|
|
4465
4479
|
+ `${type}@${resolvable.join(', ') || '<none>'}. Versions are exact — omit { version } to use `
|
|
4466
|
-
+ `the pinned default,
|
|
4480
|
+
+ `the pinned default, request a version this SDK ships, or carry that version's definition `
|
|
4481
|
+
+ `(the .flow file's definitions[] entry) with .definitions([...]).`);
|
|
4467
4482
|
}
|
|
4468
4483
|
def = exact;
|
|
4469
4484
|
}
|
|
@@ -4532,6 +4547,16 @@ export function serialize(built, opts = {}) {
|
|
|
4532
4547
|
* a null. It is emitted here, always, so it cannot be forgotten.
|
|
4533
4548
|
*/
|
|
4534
4549
|
function emitSubflowBody(child, nodeId) {
|
|
4550
|
+
const outer = carriedDefs;
|
|
4551
|
+
carriedDefs = indexCarriedDefinitions(child.definitions ?? [], `subflow "${nodeId}" .definitions()`, new Map(outer));
|
|
4552
|
+
try {
|
|
4553
|
+
return emitSubflowBodyIn(child, nodeId);
|
|
4554
|
+
}
|
|
4555
|
+
finally {
|
|
4556
|
+
carriedDefs = outer;
|
|
4557
|
+
}
|
|
4558
|
+
}
|
|
4559
|
+
function emitSubflowBodyIn(child, nodeId) {
|
|
4535
4560
|
const childGlobals = emittableGlobals(child, `subflow "${nodeId}"`, 'subflow');
|
|
4536
4561
|
const scope = newScope(childGlobals.outputs, childGlobals.vars, childGlobals.backing, childGlobals.backingReads);
|
|
4537
4562
|
// Claim this copy's node ids UP FRONT, so the rename map is complete before
|
|
@@ -4807,7 +4832,11 @@ export function serialize(built, opts = {}) {
|
|
|
4807
4832
|
function emitRegistered(entry, step, tails, scope, parentId) {
|
|
4808
4833
|
const where = `step "${step.name}"`;
|
|
4809
4834
|
const spec = step.spec;
|
|
4810
|
-
|
|
4835
|
+
// A pin the registry has no implementation for, but the flow carries, is
|
|
4836
|
+
// emitted at that version with the carried definition (#1128).
|
|
4837
|
+
const resolved = resolveVersionCarried(entry.type, spec, step.options?.version, where, carriedFor);
|
|
4838
|
+
const impl = resolved.impl;
|
|
4839
|
+
const version = resolved.version;
|
|
4811
4840
|
const id = stepUid(scope, step.name);
|
|
4812
4841
|
// As for every typed family: record the failure-envelope boundary before any
|
|
4813
4842
|
// expression renders, so a handler reading this step resolves correctly.
|
|
@@ -4817,14 +4846,19 @@ export function serialize(built, opts = {}) {
|
|
|
4817
4846
|
step: step.name,
|
|
4818
4847
|
nodeId: id,
|
|
4819
4848
|
flowId: built.id,
|
|
4820
|
-
version
|
|
4849
|
+
version,
|
|
4821
4850
|
pinnedVersion: step.options?.version,
|
|
4822
4851
|
render: (value) => renderValue(value, scope.rename),
|
|
4823
4852
|
renameRefs: (js) => renameRefs(js, scope.rename),
|
|
4824
4853
|
stepNodeId: (name) => scope.stepNodeId.get(name) ?? name,
|
|
4825
4854
|
mint: (seed) => stableId(`${built.id}:${id}:${seed}`),
|
|
4826
4855
|
bind: (b) => { bound.push(b); },
|
|
4827
|
-
|
|
4856
|
+
// At a carried version the node's own definition IS the carried one,
|
|
4857
|
+
// whatever version the implementation asks for (it was written for a
|
|
4858
|
+
// bundled one), so its defaults and outputs come from the file's entry.
|
|
4859
|
+
definition: (typeName, v) => (resolved.carried !== undefined && typeName === impl.typeName
|
|
4860
|
+
? resolved.carried
|
|
4861
|
+
: bundledDefinition(typeName, v) ?? carriedFor(typeName, v)),
|
|
4828
4862
|
bindings: resourceBindings,
|
|
4829
4863
|
resolveBinding: (name, attribute, at) => resolveBinding(opts, name, attribute, at),
|
|
4830
4864
|
bindConnection: (c) => {
|
|
@@ -4843,26 +4877,31 @@ export function serialize(built, opts = {}) {
|
|
|
4843
4877
|
// The definition contract, both halves: a per-tenant type supplies its
|
|
4844
4878
|
// definition, and a bundled type does not (its definition is the bundle's, and
|
|
4845
4879
|
// makeNode records it, so the error-edge refusal and check ask the same one).
|
|
4846
|
-
let def;
|
|
4880
|
+
let def = resolved.carried;
|
|
4847
4881
|
if (impl.definition === 'bundled' && contribution.definition !== undefined) {
|
|
4848
|
-
throw new Error(`internal SDK error: ${where}: bundled node type ${impl.typeName}@${
|
|
4882
|
+
throw new Error(`internal SDK error: ${where}: bundled node type ${impl.typeName}@${version} returned a definition; `
|
|
4849
4883
|
+ 'the bundle owns it — omit `definition`, or declare the type per-tenant.');
|
|
4850
4884
|
}
|
|
4885
|
+
// A per-tenant type builds its definition from `ctx.definition(type, version)`,
|
|
4886
|
+
// which answers with the carried definition at a carried version, so the
|
|
4887
|
+
// contribution's own definition wins: it is the carried template plus this
|
|
4888
|
+
// instance's edits (a queue step's own resourceKey, for instance). Only a type
|
|
4889
|
+
// that supplies none at a carried version takes the carried definition as is.
|
|
4851
4890
|
if (contribution.definition !== undefined) {
|
|
4852
|
-
def = resolveContributionDefinition(contribution.definition,
|
|
4891
|
+
def = resolveContributionDefinition(contribution.definition, version, where);
|
|
4853
4892
|
}
|
|
4854
|
-
else if (impl.definition === 'per-tenant') {
|
|
4855
|
-
throw new Error(`internal SDK error: ${where}: per-tenant node type ${impl.typeName}@${
|
|
4893
|
+
else if (impl.definition === 'per-tenant' && resolved.carried === undefined) {
|
|
4894
|
+
throw new Error(`internal SDK error: ${where}: per-tenant node type ${impl.typeName}@${version} returned no definition.`);
|
|
4856
4895
|
}
|
|
4857
4896
|
if (impl.definition === 'per-tenant') {
|
|
4858
4897
|
const port = typeof impl.errorPort === 'function' ? impl.errorPort(spec) : impl.errorPort === true;
|
|
4859
4898
|
// The declaration answers for check, which has no definition; here the
|
|
4860
4899
|
// definition is in hand, and the two must agree (#1011).
|
|
4861
4900
|
if (port && def !== undefined && !definitionHasErrorPort(def)) {
|
|
4862
|
-
throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${
|
|
4901
|
+
throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${version} declares an error port, `
|
|
4863
4902
|
+ 'but the definition it supplied has no error handle and no supportsErrorHandling.');
|
|
4864
4903
|
}
|
|
4865
|
-
declaredErrorPorts.set(id, { port, typeName: impl.typeName, version
|
|
4904
|
+
declaredErrorPorts.set(id, { port, typeName: impl.typeName, version });
|
|
4866
4905
|
}
|
|
4867
4906
|
// A forward port is a handle the definition declares, one of the type's
|
|
4868
4907
|
// author-named exits, or one the product derives (`derivesPort`: a human
|
|
@@ -4871,13 +4910,17 @@ export function serialize(built, opts = {}) {
|
|
|
4871
4910
|
const exitPorts = new Set(exits && hasExits(exits) ? exits.map((e) => e.port) : []);
|
|
4872
4911
|
for (const p of [...(contribution.port !== undefined ? [contribution.port] : []), ...(contribution.fanOut ?? []).map((f) => f.port)]) {
|
|
4873
4912
|
if (exitPorts.has(p) || impl.derivesPort?.(spec, p)
|
|
4874
|
-
|| declaresForwardPort(def ?? bundledDefinition(impl.typeName,
|
|
4913
|
+
|| declaresForwardPort(def ?? bundledDefinition(impl.typeName, version), p))
|
|
4875
4914
|
continue;
|
|
4876
|
-
throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${
|
|
4915
|
+
throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${version} leaves by port "${p}", `
|
|
4877
4916
|
+ 'which its definition declares no source handle for, and the type neither lists as an exit nor derives.');
|
|
4878
4917
|
}
|
|
4918
|
+
// A carried definition answers the error-edge refusal as a bundled one does
|
|
4919
|
+
// (makeNode records only the definitions it resolved itself).
|
|
4920
|
+
if (resolved.carried !== undefined)
|
|
4921
|
+
bundledNodeDefs.set(id, def ?? resolved.carried);
|
|
4879
4922
|
return placeStepNode({
|
|
4880
|
-
where, stepName: step.name, id, typeName: impl.typeName, requestedVersion:
|
|
4923
|
+
where, stepName: step.name, id, typeName: impl.typeName, requestedVersion: version, def, contribution, bound, tails, scope, parentId,
|
|
4881
4924
|
trackOutcomes: true,
|
|
4882
4925
|
});
|
|
4883
4926
|
}
|
|
@@ -5041,11 +5084,12 @@ export function serialize(built, opts = {}) {
|
|
|
5041
5084
|
// agent attaches memory keeps the handle for all of them.
|
|
5042
5085
|
const withMemory = s.memory !== undefined
|
|
5043
5086
|
|| declaresMemoryHandle(emittedDefs.get(`${INLINE_AGENT_TYPE}@${version}`));
|
|
5044
|
-
const def = inlineAgentDef(version, withMemory);
|
|
5087
|
+
const def = inlineAgentDef(version, withMemory, definitionFor);
|
|
5045
5088
|
if (!def) {
|
|
5046
5089
|
throw new Error(`"${step.name}" requests ${INLINE_AGENT_TYPE}@${version}, but this SDK resolves only `
|
|
5047
5090
|
+ `${INLINE_AGENT_VERSIONS.map((v) => `${INLINE_AGENT_TYPE}@${v}`).join(', ')}. Versions are exact — `
|
|
5048
|
-
+ `omit { version } to use the default (${INLINE_AGENT_DEFAULT_VERSION}),
|
|
5091
|
+
+ `omit { version } to use the default (${INLINE_AGENT_DEFAULT_VERSION}), request a version this SDK ships, `
|
|
5092
|
+
+ `or carry that version's definition with .definitions([...]).`);
|
|
5049
5093
|
}
|
|
5050
5094
|
if (s.memory !== undefined && !declaresMemoryHandle(def)) {
|
|
5051
5095
|
throw new Error(`"${step.name}" attaches \`memory\`, but ${INLINE_AGENT_TYPE}@${version} declares no \`memory\` handle. `
|
|
@@ -6127,8 +6171,12 @@ export function serialize(built, opts = {}) {
|
|
|
6127
6171
|
// must leave from ITS handles), else positional (#1130).
|
|
6128
6172
|
const cases = step.cases.map((c, i) => ({
|
|
6129
6173
|
id: c.id ?? `case_${i + 1}`,
|
|
6130
|
-
|
|
6131
|
-
|
|
6174
|
+
// A `when` case writes its own condition — the product's per-case form,
|
|
6175
|
+
// first truthy case wins (#1131). A `value` case compares with `on`.
|
|
6176
|
+
label: c.label ?? (c.when !== undefined ? `Case ${i + 1}` : `Case ${caseLiteral(c.value)}`),
|
|
6177
|
+
expression: c.when !== undefined
|
|
6178
|
+
? renameRefs(c.when.js, scope.rename)
|
|
6179
|
+
: `${renameRefs(step.on?.js ?? 'undefined', scope.rename)} === ${caseLiteral(c.value)}`,
|
|
6132
6180
|
}));
|
|
6133
6181
|
node.inputs = { cases, hasDefault: step.default !== undefined };
|
|
6134
6182
|
scope.nodes.push(node);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.27.0",
|
|
4
4
|
"description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://docs.uipath.com/maestro",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"@types/node": "^22.7.0",
|
|
93
93
|
"esbuild": "^0.28.1"
|
|
94
94
|
},
|
|
95
|
-
"gitref": "
|
|
95
|
+
"gitref": "69352e3f5c7c379e0e70b3c7b6fb2fba91255f84"
|
|
96
96
|
}
|