@uipath/maestro-builder-sdk 6.17.5 → 6.18.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.
Files changed (61) hide show
  1. package/dist/bindings-v2.js +15 -17
  2. package/dist/bpmn/bpmn-sdk.js +3 -2
  3. package/dist/bpmn/check.js +3 -2
  4. package/dist/bpmn/decompile.js +123 -137
  5. package/dist/bpmn/intsvc.js +7 -2
  6. package/dist/bpmn/serialize.js +1 -1
  7. package/dist/bpmn/typed-node.js +5 -4
  8. package/dist/case/compile-cli.js +1 -3
  9. package/dist/case/decompile.js +103 -109
  10. package/dist/case/entry-points.js +2 -1
  11. package/dist/case/merge.js +3 -5
  12. package/dist/case/serialize.js +1 -1
  13. package/dist/check.js +26 -10
  14. package/dist/core/ceql.js +5 -2
  15. package/dist/core/connector-inputs.js +4 -4
  16. package/dist/core/event-checks.js +17 -2
  17. package/dist/core/event-filters.d.ts +38 -4
  18. package/dist/core/event-filters.js +63 -7
  19. package/dist/core/expr.d.ts +1 -1
  20. package/dist/core/expr.js +3 -3
  21. package/dist/core/json-file.d.ts +2 -0
  22. package/dist/core/json-file.js +4 -0
  23. package/dist/core/library.js +2 -1
  24. package/dist/core/node-envelope.d.ts +1 -0
  25. package/dist/core/node-envelope.js +1 -1
  26. package/dist/core/own-entry.d.ts +9 -0
  27. package/dist/core/own-entry.js +11 -0
  28. package/dist/core/ts-literal.d.ts +22 -0
  29. package/dist/core/ts-literal.js +37 -0
  30. package/dist/core/typed-raw-node.js +4 -3
  31. package/dist/decompile.js +272 -300
  32. package/dist/merge.js +10 -12
  33. package/dist/registry/compat/pystr.d.ts +2 -0
  34. package/dist/registry/compat/pystr.js +35 -0
  35. package/dist/registry/compat/pyvalue.d.ts +16 -0
  36. package/dist/registry/compat/pyvalue.js +35 -0
  37. package/dist/registry/generators/markdown/pyvalue.d.ts +1 -4
  38. package/dist/registry/generators/markdown/pyvalue.js +2 -30
  39. package/dist/registry/generators/markdown/sections/inputs.js +3 -2
  40. package/dist/registry/generators/type-tree.d.ts +1 -7
  41. package/dist/registry/generators/type-tree.js +5 -22
  42. package/dist/registry/library-build/build.js +6 -6
  43. package/dist/registry/library-build/canonical.js +25 -25
  44. package/dist/registry/library-build/context.js +5 -5
  45. package/dist/registry/library-build/enrich.js +18 -18
  46. package/dist/registry/library-build/events.js +25 -24
  47. package/dist/registry/library-build/generic-expand.js +21 -20
  48. package/dist/registry/library-build/plan.js +8 -8
  49. package/dist/registry/library-build/py.d.ts +3 -10
  50. package/dist/registry/library-build/py.js +9 -52
  51. package/dist/registry/library-build/schema-action.js +6 -6
  52. package/dist/registry/prepare/event.js +2 -2
  53. package/dist/registry/prepare/source-import.js +2 -9
  54. package/dist/registry/prepare/source-labels.js +2 -9
  55. package/dist/registry/prepare/support.d.ts +2 -6
  56. package/dist/registry/prepare/support.js +3 -58
  57. package/dist/registry/pull-cli.js +6 -14
  58. package/dist/registry/search-cli.js +2 -2
  59. package/dist/schema-version.js +0 -1
  60. package/dist/serialize.js +86 -76
  61. package/package.json +2 -2
package/dist/serialize.js CHANGED
@@ -26,7 +26,7 @@ import { stopsAtEnd } from './flow-step-tree.js';
26
26
  import { assertNodeEnvelope } from './core/node-envelope.js';
27
27
  import { buildConfiguration } from './config.js';
28
28
  import { fnv1aX4Uuid, stableId } from './core/stable-id.js';
29
- import { readEventFilter, eventFilterProblem, eventFilterJmes, eventFilterTreeLeaf } from './core/event-filters.js';
29
+ import { readEventFilter, eventFilterProblem, eventFilterJmes, eventFilterTreeLeaf, jmesString, jmesStringProblem } from './core/event-filters.js';
30
30
  import { FLOW_EXPR_DIALECT } from './core/connector-checks.js';
31
31
  import { buildConnectorInputs, connectorInputErrors as coreConnectorInputErrors, multipartBodyFieldName, transportHttpMethod } from './core/connector-inputs.js';
32
32
  /**
@@ -53,6 +53,8 @@ import { prepareCommand } from './core/cli-spelling.js';
53
53
  import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
54
54
  import { AGENTIC_PROCESS_FORMS } from './core/agentic-process-forms.js';
55
55
  import { types } from './core/expr.js';
56
+ import { ownEntry } from './core/own-entry.js';
57
+ import { jsonClone } from './core/json-file.js';
56
58
  const HERE = dirname(fileURLToPath(import.meta.url));
57
59
  // core-definitions.json is an object keyed by "<nodeType>@<version>".
58
60
  const DEFS = JSON.parse(readFileSync(join(HERE, 'core-definitions.json'), 'utf8'));
@@ -547,7 +549,7 @@ function publishedFunctionDef(spec) {
547
549
  * `agenticProcess`'s doc comment).
548
550
  */
549
551
  function agenticProcessDef(spec) {
550
- const form = AGENTIC_PROCESS_FORMS[spec.form ?? 'bpmn'];
552
+ const form = ownEntry(AGENTIC_PROCESS_FORMS, spec.form ?? 'bpmn') ?? AGENTIC_PROCESS_FORMS.bpmn;
551
553
  const loc = processResourceLocation(spec);
552
554
  const { resourceKey } = loc;
553
555
  const properties = {};
@@ -948,7 +950,7 @@ function contextResourceJson(cx, spec) {
948
950
  folderPathPrefix: { variant: 'static' },
949
951
  threshold: cx.threshold ?? 0,
950
952
  resultCount: cx.resultCount ?? 3,
951
- fileExtension: { value: cx.fileExtension ?? DEFAULT_FILE_EXTENSION[mode] ?? 'All' },
953
+ fileExtension: { value: cx.fileExtension ?? ownEntry(DEFAULT_FILE_EXTENSION, mode) ?? 'All' },
952
954
  // Mode-specific keys the schema REQUIRES of those two modes and rejects
953
955
  // nowhere else, carrying the node's own constants through the enum's
954
956
  // spelling (the node says `enabled`; the resource says `Enabled`/`Inline`).
@@ -1081,7 +1083,7 @@ function toolResourceJson(tr, spec) {
1081
1083
  settings: {},
1082
1084
  argumentProperties: {},
1083
1085
  };
1084
- const resourceType = TOOL_RESOURCE_TYPE[tr.kind];
1086
+ const resourceType = ownEntry(TOOL_RESOURCE_TYPE, tr.kind);
1085
1087
  if (resourceType !== undefined) {
1086
1088
  return {
1087
1089
  ...common,
@@ -1149,7 +1151,7 @@ const enumValue = (v) => {
1149
1151
  * configuration in `properties.settings`.
1150
1152
  */
1151
1153
  function builtinToolResourceJson(tool, label, inputs, spec) {
1152
- const toolType = BUILTIN_TOOL_TYPE[tool];
1154
+ const toolType = ownEntry(BUILTIN_TOOL_TYPE, tool);
1153
1155
  if (toolType === undefined)
1154
1156
  return undefined;
1155
1157
  const empty = { type: 'object', properties: {} };
@@ -1341,11 +1343,6 @@ const DOTNET_TYPE = {
1341
1343
  string: 'System.String', number: 'System.Double', integer: 'System.Int32',
1342
1344
  boolean: 'System.Boolean', object: 'System.Object', array: 'System.Object',
1343
1345
  };
1344
- /** A quick-form field's JSON Schema type (`FormFieldType` → resource schema). */
1345
- const QUICK_FORM_FIELD_SCHEMA = {
1346
- text: { type: 'string' }, number: { type: 'number' }, boolean: { type: 'boolean' },
1347
- 'date-time': { type: 'string', format: 'date-time' },
1348
- };
1349
1346
  /**
1350
1347
  * The folder an app escalation names: the author's `folderPath`, or
1351
1348
  * `solution_folder` when they gave none — an app that ships in this solution.
@@ -1411,7 +1408,7 @@ function escalationResourceJson(esc, spec) {
1411
1408
  const fields = esc.fields ?? [];
1412
1409
  const props = (dirs) => Object.fromEntries(fields
1413
1410
  .filter((f) => dirs.includes(f.direction))
1414
- .map((f) => [f.id, QUICK_FORM_FIELD_SCHEMA[f.type] ?? { type: 'string' }]));
1411
+ .map((f) => [f.id, ownEntry(FORM_FIELD_JSON_TYPE, String(f.type)) ?? { type: 'string' }]));
1415
1412
  channel = {
1416
1413
  ...common,
1417
1414
  type: 'actionCenterQuickForm',
@@ -1426,7 +1423,7 @@ function escalationResourceJson(esc, spec) {
1426
1423
  }
1427
1424
  else {
1428
1425
  const app = esc.app;
1429
- const mapping = (fields) => Object.fromEntries(Object.entries(fields ?? {}).map(([k, t]) => [k, DOTNET_TYPE[t] ?? 'System.Object']));
1426
+ const mapping = (fields) => Object.fromEntries(Object.entries(fields ?? {}).map(([k, t]) => [k, ownEntry(DOTNET_TYPE, t) ?? 'System.Object']));
1430
1427
  channel = {
1431
1428
  ...common,
1432
1429
  type: 'actionCenter',
@@ -1629,9 +1626,9 @@ function connectorToolDef(rc) {
1629
1626
  category: `agent.tool.${v1.category ?? 'connector'}`,
1630
1627
  tags: ['agent-tool', 'connector', 'activity'],
1631
1628
  sortOrder: 565,
1632
- display: { ...clone(v1.display ?? {}), shape: 'circle' },
1629
+ display: { ...jsonClone(v1.display ?? {}), shape: 'circle' },
1633
1630
  handleConfiguration: [toolInputHandle()],
1634
- model: { ...clone(v1.model ?? {}), source: true },
1631
+ model: { ...jsonClone(v1.model ?? {}), source: true },
1635
1632
  inputDefinition: { type: 'object', properties: {} },
1636
1633
  inputDefaults: {},
1637
1634
  };
@@ -1648,16 +1645,28 @@ function connectorToolDescription(rc) {
1648
1645
  const prefix = `(${rc.connectorName}) `;
1649
1646
  return rc.connectorName && text.startsWith(prefix) ? text.slice(prefix.length) : text;
1650
1647
  }
1651
- /** An agent-decided value: `{{prompt: "<what the model is told>"}}`. */
1648
+ /**
1649
+ * An agent-decided value: `{{prompt: "<what the model is told>"}}`, byte for byte
1650
+ * what the product writes — `uip maestro flow node configure` (UiPath/cli
1651
+ * `connector-service.ts`, `` `{{prompt: "${f.description || f.displayName || f.name}"}}` ``)
1652
+ * and the designer's `PROMPT_WRAPPER` (@uipath/maestro-sdk) both splice the text RAW.
1653
+ * The chip format has no escape: the product's reader (`PROMPT_UNWRAPPER`) slices
1654
+ * off the fixed `{{prompt:` / `}}` frame and strips one pair of outer quotes, so
1655
+ * any text — `"`, `\`, a newline, a `}}` — round-trips. Escaping it here made the
1656
+ * model read literal backslashes. FB011 registers this as the one raw chip splice.
1657
+ */
1652
1658
  function promptChip(f) {
1653
1659
  const text = f.description || f.displayName || f.name;
1654
- return `{{prompt: "${text.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"}}`;
1660
+ return `{{prompt: "${text}"}}`;
1655
1661
  }
1656
1662
  const isPromptChip = (v) => typeof v === 'string' && v.startsWith('{{prompt');
1657
- /** The text inside `{{prompt: "…"}}`, unescaped; `''` for a bare `{{prompt}}`. */
1663
+ /** The text inside `{{prompt: "…"}}`, read the way the product reads it (maestro-sdk PROMPT_UNWRAPPER); `''` when `value` is not a chip. */
1658
1664
  function chipText(value) {
1659
- const m = /\{\{\s*prompt:\s*"((?:[^"\\]|\\.)*)"/.exec(value);
1660
- return m ? m[1].replace(/\\(.)/g, '$1') : '';
1665
+ if (!(value.startsWith('{{prompt:') && value.endsWith('}}')))
1666
+ return '';
1667
+ const inner = value.slice(9, -2).trim();
1668
+ const quoted = (inner.startsWith('"') && inner.endsWith('"')) || (inner.startsWith("'") && inner.endsWith("'"));
1669
+ return quoted ? inner.slice(1, -1) : inner;
1661
1670
  }
1662
1671
  /** A field's enum as `{ name, value }` rows, the platform's spelling; `undefined` when it has none. */
1663
1672
  function enumRows(raw) {
@@ -2002,9 +2011,9 @@ function ixpToolDef(spec) {
2002
2011
  // other branch, taken here because — unlike the extractor's `description` —
2003
2012
  // these three are load-bearing rather than inert.
2004
2013
  inputDefinition: {
2005
- ...clone(IXP_DEF.toolInputDefinition),
2014
+ ...jsonClone(IXP_DEF.toolInputDefinition),
2006
2015
  properties: {
2007
- ...clone(IXP_DEF.toolInputDefinition.properties),
2016
+ ...jsonClone(IXP_DEF.toolInputDefinition.properties),
2008
2017
  source: { type: 'string' },
2009
2018
  name: { type: 'string' },
2010
2019
  description: { type: 'string' },
@@ -2293,7 +2302,7 @@ function inlineAgentDef(version, withMemory) {
2293
2302
  const bundled = DEFS[`${INLINE_AGENT_TYPE}@${version}`];
2294
2303
  if (!bundled)
2295
2304
  return undefined;
2296
- const def = clone(bundled);
2305
+ const def = jsonClone(bundled);
2297
2306
  const output = def.outputDefinition?.output;
2298
2307
  if (output)
2299
2308
  output.source = '=result.response';
@@ -2652,7 +2661,7 @@ function ixpExtractDef(spec) {
2652
2661
  nodeType: spec.project,
2653
2662
  version: IXP_DEF.version,
2654
2663
  category: IXP_DEF.category,
2655
- tags: clone(IXP_DEF.tags),
2664
+ tags: jsonClone(IXP_DEF.tags),
2656
2665
  // The platform's own definition describes an extractor by its FOLDER, and
2657
2666
  // the designer prints exactly this in the node's subtitle.
2658
2667
  description: `(${spec.folderName})`,
@@ -2664,11 +2673,11 @@ function ixpExtractDef(spec) {
2664
2673
  description: `(${spec.folderName})`,
2665
2674
  icon: IXP_DEF.icon,
2666
2675
  },
2667
- handleConfiguration: clone(IXP_DEF.handleConfiguration),
2676
+ handleConfiguration: jsonClone(IXP_DEF.handleConfiguration),
2668
2677
  model: {
2669
- ...clone(IXP_DEF.model),
2678
+ ...jsonClone(IXP_DEF.model),
2670
2679
  bindings: {
2671
- ...clone(IXP_DEF.bindingsFrame),
2680
+ ...jsonClone(IXP_DEF.bindingsFrame),
2672
2681
  resourceKey: versionId,
2673
2682
  name: spec.name,
2674
2683
  values: [
@@ -2677,7 +2686,7 @@ function ixpExtractDef(spec) {
2677
2686
  ],
2678
2687
  },
2679
2688
  },
2680
- form: clone(IXP_DEF.form),
2689
+ form: jsonClone(IXP_DEF.form),
2681
2690
  // A `description` the author asked for is DECLARED in the same write. The
2682
2691
  // registry's own copy carries `description` in `inputDefaults` and not in
2683
2692
  // `inputDefinition.properties` — lesson 42's gap, live on this family — so
@@ -2688,10 +2697,10 @@ function ixpExtractDef(spec) {
2688
2697
  // why this is conditional and the definition otherwise stays byte-identical
2689
2698
  // to the platform's.
2690
2699
  inputDefinition: spec.description === undefined
2691
- ? clone(IXP_DEF.inputDefinition)
2700
+ ? jsonClone(IXP_DEF.inputDefinition)
2692
2701
  : {
2693
- ...clone(IXP_DEF.inputDefinition),
2694
- properties: { ...clone(IXP_DEF.inputDefinition.properties), description: { type: 'string' } },
2702
+ ...jsonClone(IXP_DEF.inputDefinition),
2703
+ properties: { ...jsonClone(IXP_DEF.inputDefinition.properties), description: { type: 'string' } },
2695
2704
  },
2696
2705
  inputDefaults: {
2697
2706
  model,
@@ -2707,8 +2716,8 @@ function ixpExtractDef(spec) {
2707
2716
  fileRef: '',
2708
2717
  pageRange: '',
2709
2718
  },
2710
- outputDefinition: clone(IXP_DEF.outputDefinition),
2711
- debug: clone(IXP_DEF.debug),
2719
+ outputDefinition: jsonClone(IXP_DEF.outputDefinition),
2720
+ debug: jsonClone(IXP_DEF.debug),
2712
2721
  };
2713
2722
  }
2714
2723
  /**
@@ -2961,7 +2970,7 @@ function queueItemDef(spec, stepName, ids) {
2961
2970
  const base = defByType.get(nodeType);
2962
2971
  if (!base)
2963
2972
  throw new Error(`no bundled definition for "${nodeType}"`);
2964
- const def = clone(base);
2973
+ const def = jsonClone(base);
2965
2974
  def.model.bindings.resourceKey = spec.key;
2966
2975
  def.model.context = [
2967
2976
  { name: 'name', type: 'string', value: `=bindings.${ids.name}`, default: spec.queue },
@@ -2975,7 +2984,7 @@ function queueItemDef(spec, stepName, ids) {
2975
2984
  properties: Object.fromEntries(Object.entries(spec.returns).map(([k, t]) => [k, { type: t }])),
2976
2985
  }
2977
2986
  : undefined)
2978
- : clone(QUEUE_ITEM_RECORD_SCHEMA);
2987
+ : jsonClone(QUEUE_ITEM_RECORD_SCHEMA);
2979
2988
  if (schema)
2980
2989
  def.outputDefinition.output.schema = schema;
2981
2990
  return def;
@@ -3062,7 +3071,7 @@ function transformNodeType(inputs) {
3062
3071
  const variant = inputs?.variant;
3063
3072
  if (!variant)
3064
3073
  return NODE_TYPE.transform;
3065
- return TRANSFORM_VARIANT_TYPE[variant] ?? `core.action.transform.${String(variant)}`;
3074
+ return ownEntry(TRANSFORM_VARIANT_TYPE, variant) ?? `core.action.transform.${String(variant)}`;
3066
3075
  }
3067
3076
  /**
3068
3077
  * Encode a scheduled trigger's single `every` interval into the three inputs the
@@ -3272,7 +3281,7 @@ function delayInputs(inputs) {
3272
3281
  ...(isPreset ? {} : { timerValue: duration }),
3273
3282
  };
3274
3283
  }
3275
- /** JSON-Schema type per form-field type, as flow-v1's form serializer maps them. */
3284
+ /** JSON-Schema type per form-field type, as flow-v1's form serializer maps them (quick-form escalations and human tasks). */
3276
3285
  const FORM_FIELD_JSON_TYPE = {
3277
3286
  text: { type: 'string' },
3278
3287
  number: { type: 'number' },
@@ -3353,7 +3362,7 @@ function hitlInputs(inputs, nodeId, flowId, label, rename) {
3353
3362
  // inOut fields land in the answers too — their reviewed value flows back.
3354
3363
  if (!isAnswerField(f))
3355
3364
  continue;
3356
- properties[f.id] = { ...FORM_FIELD_JSON_TYPE[f.type] };
3365
+ properties[f.id] = { ...ownEntry(FORM_FIELD_JSON_TYPE, String(f.type)) };
3357
3366
  }
3358
3367
  const names = outcomes.map((o) => o.name).filter((n) => typeof n === 'string');
3359
3368
  if (names.length > 0) {
@@ -3371,7 +3380,7 @@ function hitlInputs(inputs, nodeId, flowId, label, rename) {
3371
3380
  }
3372
3381
  // The author's recipient when given; the definition's own default otherwise
3373
3382
  // (unchanged — that default is what 203 of 233 deployed v1 tasks carry).
3374
- const defaultRecipient = clone(defByType.get(nodeType)?.inputDefaults?.recipient ?? {});
3383
+ const defaultRecipient = jsonClone(defByType.get(nodeType)?.inputDefaults?.recipient ?? {});
3375
3384
  const r = inputs?.recipient;
3376
3385
  const recipient = r
3377
3386
  ? {
@@ -3458,7 +3467,7 @@ function hitlInputs(inputs, nodeId, flowId, label, rename) {
3458
3467
  var: 'status',
3459
3468
  ...(names.length > 0 ? { enum: names, default: names[0] } : {}),
3460
3469
  },
3461
- ...(errorOutput !== undefined ? { error: clone(errorOutput) } : {}),
3470
+ ...(errorOutput !== undefined ? { error: jsonClone(errorOutput) } : {}),
3462
3471
  },
3463
3472
  };
3464
3473
  }
@@ -3589,16 +3598,13 @@ function nodeVariables(nodes) {
3589
3598
  id: `${n.id}.${varName}`,
3590
3599
  type: typeof decl.type === 'string' ? decl.type : 'object',
3591
3600
  ...(typeof decl.description === 'string' ? { description: decl.description } : {}),
3592
- ...(decl.schema !== undefined ? { schema: clone(decl.schema) } : {}),
3601
+ ...(decl.schema !== undefined ? { schema: jsonClone(decl.schema) } : {}),
3593
3602
  binding: { nodeId: n.id, outputId: varName },
3594
3603
  });
3595
3604
  }
3596
3605
  }
3597
3606
  return out;
3598
3607
  }
3599
- function clone(x) {
3600
- return JSON.parse(JSON.stringify(x));
3601
- }
3602
3608
  /** Deep-substitute the `{nodeId}` placeholder used in definition model templates. */
3603
3609
  function subNodeId(obj, nodeId) {
3604
3610
  return JSON.parse(JSON.stringify(obj).split('{nodeId}').join(nodeId));
@@ -3618,14 +3624,13 @@ const NO_RENAME = { nodeIds: new Map(), errorEnvelopes: new Map() };
3618
3624
  * `core.action.http` (plain, 1.0.0 and the 1.3 `flow migrate` produces) is NOT
3619
3625
  * an entry: it publishes no envelope anywhere, so there is no variable to name.
3620
3626
  * `check` refuses an error handler on it instead (HTTP_ONERROR_V1).
3627
+ *
3628
+ * Read with `ownEntry`: the envelope variable for a node type, or undefined when
3629
+ * it is the default `error`.
3621
3630
  */
3622
3631
  const ERROR_ENVELOPE_VAR = {
3623
3632
  [NODE_TYPE.httpV2]: 'output',
3624
3633
  };
3625
- /** The envelope variable for a node type, or undefined when it is the default `error`. */
3626
- function errorEnvelopeVar(nodeType) {
3627
- return ERROR_ENVELOPE_VAR[nodeType];
3628
- }
3629
3634
  /** The `typeVersion` Studio Web stamps on a sticky note. The type has no manifest to take it from. */
3630
3635
  const STICKY_NOTE_TYPE_VERSION = '1.0.0';
3631
3636
  /**
@@ -4185,7 +4190,12 @@ function eventDetail(rc, sub, nodeId, opts, site) {
4185
4190
  // the subscription, not a property of the events it matches.
4186
4191
  const scopeClauses = Object.entries(eventParameters)
4187
4192
  .filter(([, v]) => v !== undefined && v !== null && String(v) !== '')
4188
- .map(([k, v]) => `${k} == '${String(v)}'`);
4193
+ .map(([k, v]) => {
4194
+ const problem = jmesStringProblem(String(v));
4195
+ if (problem)
4196
+ throw new Error(`event node "${nodeId}": \`where.${k}\`: ${problem}`);
4197
+ return `${k} == ${jmesString(String(v))}`;
4198
+ });
4189
4199
  // Each authored filter is read structurally (which operator, which value) and
4190
4200
  // lowered with the designer's own grammar — see `event-filters.ts` for the
4191
4201
  // measured table. `check` has already refused a malformed leaf; a leaf that
@@ -4941,9 +4951,9 @@ export function serialize(built, opts = {}) {
4941
4951
  // `outputs` stay: the canvas persists them (`source: '=response'`), and
4942
4952
  // `variables.nodes[]` is derived from them.
4943
4953
  if (def?.model && !type.startsWith('core.datafabric.'))
4944
- node.model = subNodeId(clone(def.model), id);
4954
+ node.model = subNodeId(jsonClone(def.model), id);
4945
4955
  if (def?.outputDefinition)
4946
- node.outputs = subNodeId(clone(def.outputDefinition), id);
4956
+ node.outputs = subNodeId(jsonClone(def.outputDefinition), id);
4947
4957
  if (o.parentId)
4948
4958
  node.parentId = o.parentId;
4949
4959
  return node;
@@ -5214,7 +5224,7 @@ export function serialize(built, opts = {}) {
5214
5224
  const node = makeNode(def.nodeType, id, stepName, { parentId, def, requestedVersion });
5215
5225
  node.inputs = renderDeep(contribution.inputs ?? {}, scope.rename);
5216
5226
  if (contribution.outputs) {
5217
- node.outputs = { ...(node.outputs ?? {}), ...subNodeId(clone(contribution.outputs), id) };
5227
+ node.outputs = { ...(node.outputs ?? {}), ...subNodeId(jsonClone(contribution.outputs), id) };
5218
5228
  }
5219
5229
  hoistContributionBindings(def, contribution.bindings, where);
5220
5230
  contributionDefs.set(id, def);
@@ -5241,7 +5251,7 @@ export function serialize(built, opts = {}) {
5241
5251
  node.inputs = renderMap(spec.inputs, scope.rename);
5242
5252
  // The definition supplies `error`; `output` is per-instance (see
5243
5253
  // SUBFLOW_OUTPUT) and goes first, matching the platform's own emission.
5244
- node.outputs = { output: clone(SUBFLOW_OUTPUT), ...(node.outputs ?? {}) };
5254
+ node.outputs = { output: jsonClone(SUBFLOW_OUTPUT), ...(node.outputs ?? {}) };
5245
5255
  scope.nodes.push(node);
5246
5256
  for (const t of tails)
5247
5257
  addEdge(scope, t, id);
@@ -5330,7 +5340,6 @@ export function serialize(built, opts = {}) {
5330
5340
  // because `inputs` is required here (the empty-input floor — see
5331
5341
  // `AgentInputs.inputs`) and because the emitted binding subtype is `Agent`.
5332
5342
  const s = spec.inputs;
5333
- const inSolution = s.location === 'in-solution';
5334
5343
  const def = agentDef({
5335
5344
  key: s.key, name: s.name, folderPath: s.folderPath, location: s.location, projectId: s.projectId,
5336
5345
  inputs: s.inputs, returns: s.returns, flavour: s.flavour,
@@ -5564,7 +5573,8 @@ export function serialize(built, opts = {}) {
5564
5573
  let extraInputs = {};
5565
5574
  let connectorTool;
5566
5575
  if (tr.kind === 'builtin') {
5567
- tdef = clone(BUILTIN_TOOL_DEFS[tr.tool]);
5576
+ const def = ownEntry(BUILTIN_TOOL_DEFS, tr.tool);
5577
+ tdef = def === undefined ? undefined : jsonClone(def);
5568
5578
  if (!tdef)
5569
5579
  throw new Error(`inline agent "${step.name}": unknown builtin tool "${tr.tool}" (analyzefiles | summarize | batchtransform).`);
5570
5580
  label = tdef.display.label;
@@ -5572,7 +5582,7 @@ export function serialize(built, opts = {}) {
5572
5582
  // author's values over them — CX's context rule, kept per builtin
5573
5583
  // (each def declares different fields, so overrides apply only where
5574
5584
  // the def has the field).
5575
- extraInputs = clone(tdef.inputDefaults);
5585
+ extraInputs = jsonClone(tdef.inputDefaults);
5576
5586
  // summarize/batchtransform declare `source` among their defaults (as
5577
5587
  // an empty string); the derived uuid below must win, not be clobbered.
5578
5588
  delete extraInputs.source;
@@ -5597,7 +5607,7 @@ export function serialize(built, opts = {}) {
5597
5607
  // family's configuration lives on the NODE rather than in a binding:
5598
5608
  // its def declares no `model` at all, so there is no resource identity
5599
5609
  // to bind and nothing to add to `bindings[]`.
5600
- extraInputs = clone(tdef.inputDefaults);
5610
+ extraInputs = jsonClone(tdef.inputDefaults);
5601
5611
  }
5602
5612
  else if (tr.kind === 'connector') {
5603
5613
  if (!opts.library)
@@ -5639,20 +5649,20 @@ export function serialize(built, opts = {}) {
5639
5649
  // configuration lives on the node, not in a binding.
5640
5650
  tdef = mcpToolDef(tr);
5641
5651
  label = tr.name;
5642
- extraInputs = clone(tdef.inputDefaults);
5652
+ extraInputs = jsonClone(tdef.inputDefaults);
5643
5653
  }
5644
5654
  else if (tr.kind === 'a2a') {
5645
5655
  tdef = a2aToolDef(tr);
5646
5656
  label = tr.name;
5647
- extraInputs = clone(tdef.inputDefaults);
5657
+ extraInputs = jsonClone(tdef.inputDefaults);
5648
5658
  }
5649
5659
  else if (tr.kind === 'clientside') {
5650
5660
  // A static bundled def: the flow declares only the CONTRACT — the
5651
5661
  // calling application owns the implementation.
5652
- tdef = clone(DEFS['uipath.agent.resource.tool.clientside@1.0']);
5662
+ tdef = jsonClone(DEFS['uipath.agent.resource.tool.clientside@1.0']);
5653
5663
  label = tr.name;
5654
5664
  extraInputs = {
5655
- ...clone(tdef.inputDefaults),
5665
+ ...jsonClone(tdef.inputDefaults),
5656
5666
  name: tr.name,
5657
5667
  ...(tr.description !== undefined ? { description: tr.description } : {}),
5658
5668
  ...(tr.inputs !== undefined ? { inputSchema: fieldSchema(tr.inputs) } : {}),
@@ -5664,9 +5674,9 @@ export function serialize(built, opts = {}) {
5664
5674
  // text-builder (headers/params as name/value rows, timeout numeric —
5665
5675
  // the storage layer's own normalization), an omitted one keeps the
5666
5676
  // definition's prompt-mode default so the MODEL fills it at call time.
5667
- tdef = clone(DEFS['uipath.agent.resource.tool.builtin.httprequest@1.0']);
5677
+ tdef = jsonClone(DEFS['uipath.agent.resource.tool.builtin.httprequest@1.0']);
5668
5678
  label = tr.name ?? tdef.display.label;
5669
- extraInputs = clone(tdef.inputDefaults);
5679
+ extraInputs = jsonClone(tdef.inputDefaults);
5670
5680
  const fix = (field, value) => {
5671
5681
  const row = extraInputs[field];
5672
5682
  extraInputs[field] = { ...row, mode: 'text-builder', textValue: value };
@@ -5689,7 +5699,7 @@ export function serialize(built, opts = {}) {
5689
5699
  extraInputs.description = tr.description ?? String(tdef.description ?? '');
5690
5700
  }
5691
5701
  else {
5692
- const meta = PROCESS_TOOL_META[tr.kind];
5702
+ const meta = ownEntry(PROCESS_TOOL_META, tr.kind);
5693
5703
  if (!meta)
5694
5704
  throw new Error(`inline agent "${step.name}": unknown tool kind "${tr.kind}".`);
5695
5705
  tdef = processToolDef(tr.kind, tr);
@@ -5760,7 +5770,7 @@ export function serialize(built, opts = {}) {
5760
5770
  // The INLINE-form escalation: the same schema rows a human task's
5761
5771
  // quick form carries, on the bundled `.quick-form` definition (the
5762
5772
  // tenant registry does not serve the family).
5763
- const qdef = clone(DEFS['uipath.agent.resource.escalation.quick-form@1.2']);
5773
+ const qdef = jsonClone(DEFS['uipath.agent.resource.escalation.quick-form@1.2']);
5764
5774
  const qid = uid(scope, `${step.name}Escalation`);
5765
5775
  const qnode = makeNode(qdef.nodeType, qid, esc.name, { parentId, def: qdef });
5766
5776
  qnode.display = { ...qnode.display, shape: 'circle' };
@@ -6058,7 +6068,7 @@ export function serialize(built, opts = {}) {
6058
6068
  const id = stepUid(scope, step.name);
6059
6069
  const node = makeNode(type, id, step.name, { parentId, requestedVersion: step.options?.version });
6060
6070
  delete node.model;
6061
- const defaults = clone(defByType.get(type)?.inputDefaults ?? {});
6071
+ const defaults = jsonClone(defByType.get(type)?.inputDefaults ?? {});
6062
6072
  node.inputs = spec.kind === 'createOutgoingCall'
6063
6073
  ? {
6064
6074
  ...defaults,
@@ -6151,7 +6161,7 @@ export function serialize(built, opts = {}) {
6151
6161
  // `bpmn:IntermediateCatchEvent` nodes whose serviceType the platform
6152
6162
  // resolves from `definitions[]`.
6153
6163
  delete node.model;
6154
- const defaults = clone(defByType.get(type)?.inputDefaults ?? {});
6164
+ const defaults = jsonClone(defByType.get(type)?.inputDefaults ?? {});
6155
6165
  node.inputs = spec.kind === 'sendMessage'
6156
6166
  ? {
6157
6167
  ...defaults,
@@ -6228,7 +6238,7 @@ export function serialize(built, opts = {}) {
6228
6238
  // The instance IS the definition's defaults, with the file the author
6229
6239
  // named. Every field the designer writes, in the platform's own order.
6230
6240
  node.inputs = {
6231
- ...clone(def.inputDefaults),
6241
+ ...jsonClone(def.inputDefaults),
6232
6242
  fileRef: renderValue(s.fileRef, scope.rename),
6233
6243
  ...(s.pageRange === undefined ? {} : { pageRange: s.pageRange }),
6234
6244
  };
@@ -6353,7 +6363,7 @@ export function serialize(built, opts = {}) {
6353
6363
  const id = stepUid(scope, step.name);
6354
6364
  const node = makeNode(type, id, step.name, { parentId, requestedVersion: step.options?.version });
6355
6365
  const def = defByType.get(type);
6356
- const defaults = clone(def?.inputDefaults ?? {});
6366
+ const defaults = jsonClone(def?.inputDefaults ?? {});
6357
6367
  // A `uipath.ixp.*` fileRef must stay a PLAIN `=js:` string — the platform
6358
6368
  // reads it unwrapped (see migrate's UNWRAPPED_INPUTS); classify follows
6359
6369
  // the default envelope rules.
@@ -6498,7 +6508,7 @@ export function serialize(built, opts = {}) {
6498
6508
  // a handler that reads this step resolves against the right variable. The
6499
6509
  // handler is emitted after the step it guards, so recording it here is early
6500
6510
  // enough.
6501
- const envelope = errorEnvelopeVar(type);
6511
+ const envelope = ownEntry(ERROR_ENVELOPE_VAR, type);
6502
6512
  if (envelope)
6503
6513
  scope.rename.errorEnvelopes.set(step.name, envelope);
6504
6514
  node.inputs = actionInputs(spec, scope.rename, opts, step.name);
@@ -7209,7 +7219,7 @@ export function serialize(built, opts = {}) {
7209
7219
  ...(built.description !== undefined ? { description: built.description } : {}),
7210
7220
  nodes: root.nodes,
7211
7221
  edges: root.edges,
7212
- definitions: [...emittedDefs.values()].map(clone),
7222
+ definitions: [...emittedDefs.values()].map(jsonClone),
7213
7223
  variables: { globals, nodes: nodeVariables(root.nodes), variableUpdates: root.variableUpdates },
7214
7224
  subflows,
7215
7225
  ...(rootLayoutEdges ? { layout: { nodes: {}, edges: rootLayoutEdges } } : {}),
@@ -7474,7 +7484,7 @@ function actionInputs(spec, rename = NO_RENAME, opts = {}, stepName = '') {
7474
7484
  || i.targetConnector !== undefined) {
7475
7485
  throw new Error('standalone http cannot use Integration Service connection settings; set managed: true');
7476
7486
  }
7477
- const defaults = clone(defByType.get(NODE_TYPE.http)?.inputDefaults ?? {});
7487
+ const defaults = jsonClone(defByType.get(NODE_TYPE.http)?.inputDefaults ?? {});
7478
7488
  return {
7479
7489
  ...defaults,
7480
7490
  method: i.method ?? 'GET',
@@ -7563,7 +7573,7 @@ function resolveManagedHttpBinding(i, opts, where) {
7563
7573
  };
7564
7574
  }
7565
7575
  function managedHttpInputs(i, rename, opts, stepName) {
7566
- const defaults = clone(defByType.get(NODE_TYPE.httpV2)?.inputDefaults ?? {});
7576
+ const defaults = jsonClone(defByType.get(NODE_TYPE.httpV2)?.inputDefaults ?? {});
7567
7577
  // Resolution is repeated by the caller that hoists the binding pair; only that
7568
7578
  // one carries the `warn` sink, so a stub is reported once, not twice.
7569
7579
  const binding = resolveManagedHttpBinding(i, { bindings: opts.bindings }, `managed http "${stepName}"`);
@@ -7649,7 +7659,7 @@ function managedHttpInputs(i, rename, opts, stepName) {
7649
7659
  function httpOutputs(base, returns, managed) {
7650
7660
  if (!returns || Object.keys(returns).length === 0)
7651
7661
  return base;
7652
- const out = clone(base);
7662
+ const out = jsonClone(base);
7653
7663
  if (!out.output)
7654
7664
  return out;
7655
7665
  // The whole `output` shape lives on the INSTANCE, not in the bundled
@@ -7690,11 +7700,11 @@ function httpOutputs(base, returns, managed) {
7690
7700
  */
7691
7701
  function transformOutputs(base) {
7692
7702
  // An unrecognized `variant` resolves to no definition at all, so there are no
7693
- // outputs to refine — and `clone(undefined)` throws ("undefined" is not valid
7703
+ // outputs to refine — and `jsonClone(undefined)` throws ("undefined" is not valid
7694
7704
  // JSON) rather than passing the node through.
7695
7705
  if (!base || typeof base !== 'object')
7696
7706
  return base;
7697
- const out = clone(base);
7707
+ const out = jsonClone(base);
7698
7708
  if (out.output)
7699
7709
  out.output.type = 'array';
7700
7710
  return out;
@@ -7721,7 +7731,7 @@ function scriptOutputs(base, returns, code) {
7721
7731
  return base;
7722
7732
  if (!base || typeof base !== 'object')
7723
7733
  return base;
7724
- const out = clone(base);
7734
+ const out = jsonClone(base);
7725
7735
  if (!out.output)
7726
7736
  return out;
7727
7737
  out.output.type = shape.type;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.17.5",
3
+ "version": "6.18.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": "5c050c27fe72360970e28b811ad581442140544f"
95
+ "gitref": "a27fd844612856f0bf93741403cb548ab7b22e97"
96
96
  }