@uipath/maestro-builder-sdk 6.60.0 → 6.61.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 (50) hide show
  1. package/README.md +10 -12
  2. package/dist/api-index.md +5 -4
  3. package/dist/check-cli.js +8 -7
  4. package/dist/check.d.ts +11 -0
  5. package/dist/check.js +192 -783
  6. package/dist/cli-library.d.ts +2 -1
  7. package/dist/cli-library.js +7 -2
  8. package/dist/cli-result.d.ts +14 -0
  9. package/dist/cli-result.js +18 -1
  10. package/dist/compile-cli.js +2 -2
  11. package/dist/core/compile-refusal.d.ts +7 -1
  12. package/dist/core/compile-refusal.js +9 -1
  13. package/dist/core/connector-checks.d.ts +8 -30
  14. package/dist/core/connector-checks.js +11 -60
  15. package/dist/core/connector-inputs.js +9 -1
  16. package/dist/core/event-checks.d.ts +15 -2
  17. package/dist/core/event-checks.js +28 -13
  18. package/dist/core/hitl-routing.d.ts +10 -1
  19. package/dist/core/hitl-routing.js +20 -5
  20. package/dist/core/lookups.d.ts +13 -0
  21. package/dist/core/lookups.js +26 -0
  22. package/dist/core/refusals.d.ts +2 -0
  23. package/dist/core/refusals.js +5 -1
  24. package/dist/flow-node-type.d.ts +35 -21
  25. package/dist/flow-parallel-hitl.d.ts +105 -0
  26. package/dist/flow-parallel-hitl.js +214 -0
  27. package/dist/flow-sdk.d.ts +4 -4
  28. package/dist/flow-sdk.js +2 -2
  29. package/dist/flow-terminate-names.d.ts +2 -2
  30. package/dist/flow-terminate-names.js +2 -2
  31. package/dist/merge-compile.js +2 -1
  32. package/dist/nodes/agent/flow/check.js +13 -88
  33. package/dist/nodes/agent/flow/inline-agent.js +41 -14
  34. package/dist/nodes/connector/flow/node-type.js +45 -18
  35. package/dist/nodes/document/flow/ixp.d.ts +1 -1
  36. package/dist/nodes/document/flow/ixp.js +22 -26
  37. package/dist/nodes/hitl/flow/check.js +4 -11
  38. package/dist/nodes/hitl/flow/node-type.js +16 -7
  39. package/dist/nodes/http/flow/check.js +5 -31
  40. package/dist/nodes/http/flow/node-type.js +7 -4
  41. package/dist/nodes/queue/flow/check.d.ts +4 -3
  42. package/dist/nodes/queue/flow/check.js +7 -6
  43. package/dist/nodes/queue/flow/node-type.js +1 -1
  44. package/dist/nodes/transform/flow/check.d.ts +2 -0
  45. package/dist/nodes/transform/flow/check.js +3 -6
  46. package/dist/nodes/transform/flow/node-type.js +6 -6
  47. package/dist/raw-node.js +8 -8
  48. package/dist/serialize.d.ts +38 -3
  49. package/dist/serialize.js +757 -322
  50. package/package.json +2 -2
@@ -68,7 +68,8 @@ function plainHttpInputs(i, ctx) {
68
68
  if (i.connection !== undefined
69
69
  || i.folder !== undefined
70
70
  || i.targetConnector !== undefined) {
71
- throw new CompileRefusal('HTTP_BINDING_REQUIRES_MANAGED', 'standalone http cannot use Integration Service connection settings; set managed: true');
71
+ throw new CompileRefusal('HTTP_BINDING_REQUIRES_MANAGED', `Step "${ctx.step}" supplies Integration Service connection settings to the standalone HTTP node. `
72
+ + 'Only the managed node can use connection, folder, or targetConnector.', 'managed: true');
72
73
  }
73
74
  return {
74
75
  ...defaults(ctx, PLAIN),
@@ -92,7 +93,8 @@ function managedHttpBinding(i, ctx) {
92
93
  return undefined;
93
94
  if (typeof i.connection !== 'string' || i.connection.trim() === ''
94
95
  || typeof i.folder !== 'string' || i.folder.trim() === '') {
95
- throw new CompileRefusal('HTTP_MANAGED_BINDING_INCOMPLETE', 'managed http connection mode requires both a non-empty connection and folder');
96
+ throw new CompileRefusal('HTTP_MANAGED_BINDING_INCOMPLETE', `Managed HTTP step "${ctx.step}" must name both a non-empty \`connection\` and \`folder\`. The platform `
97
+ + 'needs the pair to resolve the Integration Service connection at runtime.', `connection: 'http', folder: 'shared'`);
96
98
  }
97
99
  // The same resolution a connector step gets: a self-referential binding is an
98
100
  // error, a stub is a warning.
@@ -122,11 +124,12 @@ function managedHttpBinding(i, ctx) {
122
124
  */
123
125
  function managedHttpInputs(i, binding, ctx) {
124
126
  if (i.targetConnector !== undefined && !binding) {
125
- throw new CompileRefusal('HTTP_TARGET_CONNECTOR_REQUIRES_BINDING', 'managed http targetConnector requires both a non-empty connection and folder');
127
+ throw new CompileRefusal('HTTP_TARGET_CONNECTOR_REQUIRES_BINDING', `Managed HTTP step "${ctx.step}" sets \`targetConnector\` without a connection and folder. `
128
+ + 'A connector-specific fallback needs the binding pair whose authentication it reuses.', `connection: 'slack', folder: 'shared'`);
126
129
  }
127
130
  if (i.targetConnector !== undefined
128
131
  && (typeof i.targetConnector !== 'string' || i.targetConnector.trim() === '')) {
129
- throw new CompileRefusal('HTTP_TARGET_CONNECTOR_EMPTY', 'managed http targetConnector must be a non-empty connector key');
132
+ throw new CompileRefusal('HTTP_TARGET_CONNECTOR_EMPTY', `Managed HTTP step "${ctx.step}" sets an empty \`targetConnector\`; name its Integration Service connector key.`, `targetConnector: 'uipath-salesforce-slack'`);
130
133
  }
131
134
  const url = ctx.render(i.url);
132
135
  const bodyParameters = {
@@ -44,7 +44,8 @@ export declare function queueItemExprMessage(step: string, typeName: string, ver
44
44
  * - `returns` on a step that does not wait (there is nothing per-tenant to
45
45
  * declare), and a `wait: true` step whose result nothing can read.
46
46
  * - a non-ISO `dueDate` / `deferDate`.
47
- * - an expression in `item` when the definition stores the item as one JSON
48
- * string (1.0): the serializer refuses it, so `check` reports it first.
47
+ *
48
+ * An expression in `item` when the definition stores the item as one JSON
49
+ * string (1.0) is the serializer's QUEUE_ITEM_EXPR_UNSUPPORTED.
49
50
  */
50
- export declare function checkQueueItem(inputs: QueueItemInputs | undefined, ctx: FlowCheckContext, typeName: string): void;
51
+ export declare function checkQueueItem(inputs: QueueItemInputs | undefined, ctx: FlowCheckContext): void;
@@ -64,10 +64,11 @@ export function queueItemExprMessage(step, typeName, version, field) {
64
64
  * - `returns` on a step that does not wait (there is nothing per-tenant to
65
65
  * declare), and a `wait: true` step whose result nothing can read.
66
66
  * - a non-ISO `dueDate` / `deferDate`.
67
- * - an expression in `item` when the definition stores the item as one JSON
68
- * string (1.0): the serializer refuses it, so `check` reports it first.
67
+ *
68
+ * An expression in `item` when the definition stores the item as one JSON
69
+ * string (1.0) is the serializer's QUEUE_ITEM_EXPR_UNSUPPORTED.
69
70
  */
70
- export function checkQueueItem(inputs, ctx, typeName) {
71
+ export function checkQueueItem(inputs, ctx) {
71
72
  const step = ctx.step;
72
73
  // Severity is the catalog's (QUEUE_DIAGNOSTICS): `at` and `warn` name the intent.
73
74
  const at = (code, message, suggestion) => ctx.report(code, message, suggestion);
@@ -109,10 +110,10 @@ export function checkQueueItem(inputs, ctx, typeName) {
109
110
  else {
110
111
  const itemIsString = itemDataIsString(ctx.definition());
111
112
  for (const [k, v] of Object.entries(item)) {
112
- if (v instanceof Expr && itemIsString) {
113
- at('QUEUE_ITEM_EXPR_UNSUPPORTED', queueItemExprMessage(step, typeName, ctx.version, k));
113
+ // An expression where the pinned version stores one JSON string is the
114
+ // serializer's QUEUE_ITEM_EXPR_UNSUPPORTED.
115
+ if (v instanceof Expr && itemIsString)
114
116
  continue;
115
- }
116
117
  // An Expr is a reference the runtime resolves — its VALUE may be anything,
117
118
  // and nothing local can know, so it is not flagged here.
118
119
  if (v instanceof Expr)
@@ -338,7 +338,7 @@ function queueAt(typeName, wait) {
338
338
  ],
339
339
  };
340
340
  },
341
- check: ({ inputs }, ctx) => checkQueueItem(inputs, ctx, typeName),
341
+ check: ({ inputs }, ctx) => checkQueueItem(inputs, ctx),
342
342
  // check collected no expressions for a queue step before the port; unchanged by it.
343
343
  expressions: () => [],
344
344
  output: ({ inputs }) => queueOutput(inputs, wait),
@@ -4,3 +4,5 @@ import { type TransformInputs } from './spec.js';
4
4
  /** Every code the Transform rules emit; all are errors. */
5
5
  export declare const TRANSFORM_DIAGNOSTICS: DiagnosticCatalog;
6
6
  export declare function checkTransform(inputs: TransformInputs, ctx: FlowCheckContext): void;
7
+ /** Nearest member of a closed vocabulary, for a "did you mean" suggestion. */
8
+ export declare function nearestIn(value: unknown, vocab: string[]): string | undefined;
@@ -166,12 +166,9 @@ function checkVariant(step, inputs, ops, at) {
166
166
  if (variant === undefined || variant === null)
167
167
  return; // generic — chains freely
168
168
  const variants = Object.keys(VARIANT_OPERATION);
169
- if (typeof variant !== 'string' || !variants.includes(variant)) {
170
- at('TRANSFORM_VARIANT_UNKNOWN', `Transform "${step}" has variant ${JSON.stringify(variant)}, which is not a Transform node type. `
171
- + `The emitted node would be "core.action.transform.${String(variant)}", which no runtime resolves. `
172
- + `Valid: ${variants.join(', ')} — or omit \`variant\` for the generic chaining Transform.`, nearestIn(variant, variants));
169
+ // A variant that is not a Transform node type is the serializer's TRANSFORM_VARIANT_UNKNOWN.
170
+ if (typeof variant !== 'string' || !variants.includes(variant))
173
171
  return;
174
- }
175
172
  const expected = ownEntry(VARIANT_OPERATION, variant);
176
173
  if (ops.length !== 1) {
177
174
  at('TRANSFORM_VARIANT_ONE_OP', `Transform "${step}" is the "${variant}" variant but carries ${ops.length} operations. A variant node runs `
@@ -190,7 +187,7 @@ function checkVariant(step, inputs, ops, at) {
190
187
  }
191
188
  }
192
189
  /** Nearest member of a closed vocabulary, for a "did you mean" suggestion. */
193
- function nearestIn(value, vocab) {
190
+ export function nearestIn(value, vocab) {
194
191
  const v = typeof value === 'string' ? value.toLowerCase() : '';
195
192
  return vocab.find((c) => c.replace(/[-_]/g, '') === v.replace(/[^a-z]/g, ''))
196
193
  ?? vocab.find((c) => c.startsWith(v) || (v !== '' && v.startsWith(c)));
@@ -10,7 +10,7 @@ import { Expr } from '../../../core/expr.js';
10
10
  import { wireExprBody } from '../../../core/wire-expr.js';
11
11
  import { jsonClone } from '../../../core/json-clone.js';
12
12
  import { VARIANT_OPERATION } from './spec.js';
13
- import { checkTransform } from './check.js';
13
+ import { checkTransform, nearestIn } from './check.js';
14
14
  import { CompileRefusal } from '../../../core/compile-refusal.js';
15
15
  /**
16
16
  * Emit a transform's `inputs` in the canonical shape the node's runtime reads:
@@ -207,12 +207,12 @@ function transformAt(typeName, variant, version, factory) {
207
207
  kind: 'transform', typeName, version, factory: 'transform', definition: 'bundled',
208
208
  rawNode: { factory },
209
209
  serialize: ({ inputs }, ctx) => {
210
- // Only the generic type matches an UNKNOWN variant, so check reports it
211
- // (TRANSFORM_VARIANT_UNKNOWN). A compile that skipped check refuses here
212
- // rather than emit the generic node, which would run and be the wrong node.
210
+ // Only the generic type matches an UNKNOWN variant: refused here rather
211
+ // than emit the generic node, which would run and be the wrong node.
213
212
  if (variant === undefined && inputs?.variant !== undefined && inputs.variant !== null) {
214
- throw new CompileRefusal('TRANSFORM_VARIANT_UNKNOWN', `transform step "${ctx.step}": variant ${JSON.stringify(inputs.variant)} is not a Transform node type `
215
- + `(${VARIANTS.join(', ')}), so there is no node to emit. Fix the variant, or omit it for the generic Transform.`);
213
+ throw new CompileRefusal('TRANSFORM_VARIANT_UNKNOWN', `Transform "${ctx.step}" has variant ${JSON.stringify(inputs.variant)}, which is not a Transform node type. `
214
+ + `The emitted node would be "core.action.transform.${String(inputs.variant)}", which no runtime resolves. `
215
+ + `Valid: ${VARIANTS.join(', ')} — or omit \`variant\` for the generic chaining Transform.`, nearestIn(inputs.variant, VARIANTS));
216
216
  }
217
217
  const base = ctx.definition(typeName, version)?.outputDefinition;
218
218
  const typed = transformOutputs(base);
package/dist/raw-node.js CHANGED
@@ -73,18 +73,18 @@ class RawNode extends FlowAction {
73
73
  this.spec = spec;
74
74
  }
75
75
  /**
76
- * `check` surfaces the connector refusal as an error, a typed family as a
77
- * warning, and an input a registered node type never reads as an error at a
78
- * bundled version (a warning at any other); `compile` throws the errors
79
- * (see {@link contribute}).
76
+ * `check` surfaces a typed family as a warning, and an input a registered node
77
+ * type never reads as a warning at a version the SDK does not bundle. The
78
+ * errors (a connector operation, an unread input at a bundled version) are
79
+ * `compile`'s refusals, which `check` reports by running it (see
80
+ * {@link contribute} and the serializer's `emitContribution`).
80
81
  */
81
82
  diagnostics() {
82
- const refusal = connectorRawNodeRefusal(this.spec.nodeType);
83
- if (refusal)
84
- return [{ code: 'RAW_NODE_CONNECTOR', severity: 'error', message: refusal }];
83
+ if (connectorRawNodeRefusal(this.spec.nodeType))
84
+ return [];
85
85
  const out = [];
86
86
  const unknown = rawNodeInputProblem(this.spec.nodeType, this.spec.version, this.spec.inputs);
87
- if (unknown)
87
+ if (unknown?.severity === 'warning')
88
88
  out.push({ code: 'RAW_NODE_UNKNOWN_INPUT', ...unknown });
89
89
  const typed = rawNodeTypedFamilyWarning(this.spec.nodeType);
90
90
  if (typed)
@@ -1,8 +1,7 @@
1
1
  import type { DefinitionReference } from './core/node-classes.js';
2
2
  import type { BuiltFlow } from './flow-sdk.js';
3
3
  import type { Library } from './library.js';
4
- import { type BindingRefusalCode } from './core/binding-messages.js';
5
- import type { Bindings } from './bindings.js';
4
+ import { type BindingRefusalCode, type BindingsView } from './core/binding-messages.js';
6
5
  import { CONNECTOR_INPUT_MISSING, connectorInputErrors as coreConnectorInputErrors } from './core/connector-inputs.js';
7
6
  /**
8
7
  * What `compile` would refuse these connector inputs with, or `undefined` when it
@@ -35,9 +34,24 @@ export interface DraftFinding {
35
34
  /** The sentence the strict compile refuses with. */
36
35
  message: string;
37
36
  }
37
+ /** A refusal a collect-mode serialize reported instead of throwing (see {@link SerializeOpts.collect}). */
38
+ export interface CollectedRefusal {
39
+ code: string;
40
+ /** The sentence an ordinary compile refuses with. */
41
+ message: string;
42
+ /** What to write instead, when the refusal knows ({@link CompileRefusal.suggestion}). */
43
+ suggestion?: string;
44
+ /** The step whose emission threw; absent for a scope-level refusal. */
45
+ step?: string;
46
+ /** The node id claimed for `step`. */
47
+ nodeId?: string;
48
+ /** The calling steps of the subflows `step` sits in, outermost first; absent at the root. */
49
+ subflows?: string[];
50
+ }
38
51
  export interface SerializeOpts {
39
52
  library?: Library;
40
- bindings?: Bindings;
53
+ /** The project's bindings.json (`Bindings`), or any view that answers the label rules. */
54
+ bindings?: BindingsView;
41
55
  /**
42
56
  * Receives each {@link SerializeWarning}. `compile-cli` prints them as
43
57
  * `⚠ [CODE] …` after `check()`'s diagnostics; a caller that passes nothing
@@ -57,6 +71,27 @@ export interface SerializeOpts {
57
71
  * ordinary compile), behaviour is unchanged.
58
72
  */
59
73
  draft?: (finding: DraftFinding) => void;
74
+ /**
75
+ * Collect mode, for `check` (docs/CHECK_COMPILE_CONTRACT_DESIGN.md §3.5).
76
+ *
77
+ * When given, a {@link CompileRefusal} that escapes one step's emission (or a
78
+ * root trigger's) is reported here, with the step's name and its node id, and
79
+ * an opaque stand-in takes the node's place (see `standInNode`), so the edges
80
+ * to and from it still resolve and every later step is judged too. A throw
81
+ * that is no refusal is reported the same way, as COMPILE_FAILED. A refusal at
82
+ * a site past a step's own emission (an edge out of it, a port list on it, a
83
+ * join it feeds) is reported on that step and emission goes on (`refuseOn`).
84
+ * A refusal that names no one step (two steps with one name, a variable plan,
85
+ * a layout key) is scope-level: it is reported with no step, and collection
86
+ * stops there, so `serialize` returns `undefined`. An `internal SDK error:`
87
+ * throw is never caught. The output, stand-ins and all, is for nothing to
88
+ * read: no caller writes it.
89
+ *
90
+ * For instance, a flow whose `notify` step names an input its connector does
91
+ * not declare, and whose `ticket` step pins an unregistered version, reports
92
+ * both, each on its own step, where an ordinary compile stops at the first.
93
+ */
94
+ collect?: (refusal: CollectedRefusal) => void;
60
95
  /**
61
96
  * Filled in by `serialize` with the extra files the flow needs beside the
62
97
  * `.flow`, relative to it: one `<source>/agent.json` per inline agent, plus a