@uipath/maestro-builder-sdk 6.68.6 → 6.69.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.
@@ -191,6 +191,16 @@ export function createExternalTask(ctx, n) {
191
191
  `${n.key}/${n.action} is "${String(op.subType ?? 'untyped')}". ` +
192
192
  `The shipped library has very few of these — ${wanted === 'AgentExecution' ? '2' : '1'} operation(s).`);
193
193
  }
194
+ // The object's execution type, when the library records it (#1369): a `mode`
195
+ // that contradicts it compiles the other contract, which validate accepts and
196
+ // the run gets wrong. Studio Web runs `hybrid` as `async`.
197
+ const recorded = op.executionType;
198
+ if (recorded === 'sync' || recorded === 'async' || recorded === 'hybrid') {
199
+ const runs = recorded === 'sync' ? 'sync' : 'async';
200
+ if (n.mode !== runs)
201
+ throw new CompileRefusal('EXTERNAL_TASK_MODE_MISMATCH', `external ${n.family} "${n.id}" has mode "${n.mode}", but the connector library records ${n.key}/${n.action}'s ` +
202
+ `executionType as "${recorded}", which runs ${runs}; the node would run the wrong contract. Use mode: "${runs}".`);
203
+ }
194
204
  const conn = connectorBindingRef(ctx, n.connection, 'Connection', 'ConnectionId', `${rc.connectorKey} connection`);
195
205
  const folder = connectorBindingRef(ctx, n.folder, 'Connection', 'folderKey', 'FolderKey', conn?.resourceKey);
196
206
  if (!conn || !folder) {
@@ -430,9 +430,12 @@ export type ConnectorSpecData = Extract<ActionSpec, {
430
430
  * reports it for the connector object.
431
431
  *
432
432
  * @remarks
433
- * This is a property of the connector object, not a choice about the case: copy
434
- * it from the activity's `case spec` result
435
- * (`Data.EssentialConfiguration.essentialConfiguration.executionType`). The Case
433
+ * This is a property of the connector object, not a choice about the case. The
434
+ * connector library records it for the object when it was built or prepared
435
+ * from Integration Service metadata that reports it, and compile then takes it
436
+ * from there: leave `mode` out. Otherwise copy it from the activity's `case spec`
437
+ * result (`Data.EssentialConfiguration.essentialConfiguration.executionType`).
438
+ * A `mode` the library contradicts is refused (EXTERNAL_TASK_MODE_MISMATCH). The Case
436
439
  * Designer saves `sync` as the `Sync…Execution` service type and both `async`
437
440
  * and `hybrid` as `Async…Execution`, and writes the value itself into the task's
438
441
  * `executionType` context.
@@ -457,10 +460,10 @@ export type ExternalExecutionMode = 'sync' | 'async' | 'hybrid';
457
460
  * the Case Designer reads it from the object's metadata (its first event mode
458
461
  * and that mode's first event type) and saves it as the task's `operation` and
459
462
  * `eventMode` context rows, and as `eventType` / `eventMode` in the metadata's
460
- * `activityPropertyConfiguration`. Copy it from the same two rows of the
461
- * activity's `case spec` result (`caseShape.context`). `decompile` lifts it from
462
- * a saved task. For
463
- * example, the Power Automate "Invoke a Flow" object (`hybrid`) answers with
463
+ * `activityPropertyConfiguration`. Like `mode`, compile takes it from the
464
+ * connector library when the library records it; otherwise copy it from the same
465
+ * two rows of the activity's `case spec` result (`caseShape.context`).
466
+ * `decompile` lifts it from a saved task. For example, the Power Automate "Invoke a Flow" object (`hybrid`) answers with
464
467
  * `{ operation: 'TRIGGER_CREATED', mode: 'polling' }`.
465
468
  */
466
469
  export interface ExternalEventPair {
@@ -476,16 +479,18 @@ export interface ExternalTaskOptions<I extends Record<string, unknown>> {
476
479
  /** Symbolic Orchestrator folder binding name declared in `bindings.json`. */
477
480
  folder: string;
478
481
  /**
479
- * The connector object's `executionType` from its `case spec` result. Required:
480
- * the connector library does not carry it yet (#1369), and a wrong value passes
481
- * `validate` but runs the wrong contract. Not whether the stage waits: that is
482
+ * The connector object's `executionType`. Leave it out when the connector
483
+ * library records it (compile reads it from there); otherwise copy it from the
484
+ * `case spec` result. Compile refuses a task with no mode from either
485
+ * (EXTERNAL_TASK_MODE), and one the library contradicts
486
+ * (EXTERNAL_TASK_MODE_MISMATCH). Not whether the stage waits: that is
482
487
  * `.required(false)`. See {@link ExternalExecutionMode}.
483
488
  */
484
- mode: ExternalExecutionMode;
489
+ mode?: ExternalExecutionMode;
485
490
  /**
486
- * The event an `async` or `hybrid` object answers with. Required for `hybrid`;
487
- * optional for `async`; refused for `sync`, which answers inline. See
488
- * {@link ExternalEventPair}.
491
+ * The event an `async` or `hybrid` object answers with. Leave it out when the
492
+ * connector library records it. A `hybrid` task needs one from either place;
493
+ * a `sync` one refuses it, since it answers inline. See {@link ExternalEventPair}.
489
494
  */
490
495
  event?: ExternalEventPair;
491
496
  /** Inputs statically checked by the generated connector descriptor. */
@@ -493,9 +498,9 @@ export interface ExternalTaskOptions<I extends Record<string, unknown>> {
493
498
  }
494
499
  /** Normalized descriptor and execution mode stored on a built external task. */
495
500
  export interface ExternalTaskSpecData {
496
- /** The connector object's `executionType`. */
497
- mode: ExternalExecutionMode;
498
- /** The event an `async` or `hybrid` object answers with, when given. */
501
+ /** The connector object's `executionType`, when authored (else the library's). */
502
+ mode?: ExternalExecutionMode;
503
+ /** The event an `async` or `hybrid` object answers with, when authored (else the library's). */
499
504
  event?: ExternalEventPair;
500
505
  /** Shared connector action identity, inputs, and symbolic bindings. */
501
506
  connector: ConnectorSpecData;
@@ -333,7 +333,7 @@ class TaskBuilder {
333
333
  external(kind, descriptor, opts) {
334
334
  this.setKind(kind);
335
335
  this._external = {
336
- mode: opts.mode,
336
+ ...(opts.mode !== undefined ? { mode: opts.mode } : {}),
337
337
  ...(opts.event !== undefined ? { event: { ...opts.event } } : {}),
338
338
  connector: makeConnector(descriptor, opts.inputs, {
339
339
  connection: opts.connection,
@@ -1,61 +1,48 @@
1
1
  /**
2
- * case/check — fast static validation of a BuiltCase before serialization.
2
+ * case/check — fast validation of a BuiltCase.
3
3
  *
4
4
  * Surfaces the common `uip maestro case validate` failures early (task without
5
5
  * an entry rule, case/stage without a completion rule, an unsatisfiable
6
- * `required-tasks-completed`, unresolved stage/task references, duplicate stage
7
- * labels) so authoring gets instant feedback. The authoritative gate is still
8
- * `uip maestro case validate` / `@uipath/case-schema` on the emitted file.
6
+ * `required-tasks-completed`) so authoring gets instant feedback, and runs the
7
+ * serializer in collect mode (`serializerRefusals`), so it also reports every
8
+ * refusal `compile` would raise (unresolved stage/task references, duplicate
9
+ * stage labels, a connector input the operation does not declare), each from
10
+ * its one implementation and placed on its task, stage or trigger
11
+ * (docs/CHECK_COMPILE_CONTRACT_DESIGN.md §3.5, phase 8). The authoritative gate
12
+ * is still `uip maestro case validate` / `@uipath/case-schema` on the emitted file.
9
13
  */
10
14
  import type { BuiltCase } from './case-sdk.js';
11
15
  import { type ConnectorCheckOpts } from '../core/connector-checks.js';
12
- import type { EventSubscription } from '../core/actions.js';
13
- import { type EventCheckOpts } from '../core/event-checks.js';
16
+ import type { Library } from '../core/library.js';
14
17
  export interface Diagnostic {
15
18
  level: 'error' | 'warning';
16
19
  code: string;
17
20
  message: string;
21
+ /** What the finding is about: a task's name, a stage's label, a trigger's label. */
18
22
  where?: string;
19
23
  suggestion?: string;
24
+ /** The id of the node `where` names, for a refusal the serializer placed on one (`serializerRefusals`). */
25
+ nodeId?: string;
20
26
  }
21
27
  /**
22
28
  * The connector-library facts Case `check` reads, from the same `Library`
23
29
  * instance `compile` serializes against (`caseCheckOpts` in `./cli-library.ts`).
24
30
  *
25
- * Deliberately NARROWER than Flow's bag. An error here must be a refusal Case
26
- * `compile` actually makes. Case `serialize` resolves the connector operation and
27
- * the event, and validates a connector task's inputs and resolves its lookups
28
- * through the shared `buildConnectorInputs` (`connectorInputs`, `lookups`,
29
- * `resolutions`), and refuses a connection/folder label bindings.json cannot
30
- * turn into a resource key (`bindings`, `bindingLabelRefusal`), and refuses an
31
- * event on an unverified BYOA connection (`eventFacts`, `byoa`).
31
+ * `check` runs the serializer in collect mode (`serializerRefusals`), with
32
+ * `library` and `bindings`, so every refusal `compile` makes (an operation or
33
+ * event the library cannot resolve, a connector input the operation does not
34
+ * declare, an unrecorded lookup, a binding label bindings.json cannot answer,
35
+ * an unverified BYOA connection, an external task's descriptor contract) is
36
+ * reported from its one implementation. The other hooks feed the warnings only
37
+ * `check` gives: the schema-readiness warnings and the lookup rules of
38
+ * `checkConnectorLookups`.
32
39
  *
33
- * Every hook fails open: without a library, `check` stays a pure function of the
34
- * built model.
40
+ * Every hook fails open: without a library, `check` judges a connector task up
41
+ * to the library, as `compile` would.
35
42
  */
36
- export type CaseCheckOpts = Pick<ConnectorCheckOpts, 'connectorResolveError' | 'connectorInputs' | 'lookups' | 'resolutions' | 'schemaReadiness' | 'bindings'> & Pick<EventCheckOpts, 'eventFacts' | 'byoa'> & {
37
- /**
38
- * What Case `compile` would refuse an event subscription with, or `undefined`
39
- * when it resolves: `EVENT_UNKNOWN` (the event is not in the library, or
40
- * refuses the `object`) or `EVENT_GENERIC_NO_OBJECT` (a GENERIC event with no
41
- * `object`). Built on `resolveCaseSubscription`, the call compile makes.
42
- */
43
- /**
44
- * What Case `compile` would refuse an External Agent / External Workflow
45
- * task's resolved descriptor with (`externalDescriptorRefusal`), or
46
- * `undefined`: also `undefined` when the descriptor does not resolve, which
47
- * `connectorResolveError` reports.
48
- */
49
- externalDescriptorError?: (kind: 'external-agent' | 'external-workflow', descriptor: {
50
- key: string;
51
- action: string;
52
- version?: string;
53
- object?: string;
54
- }) => string | undefined;
55
- subscriptionError?: (kind: 'trigger' | 'event', subscription: EventSubscription) => {
56
- code: string;
57
- message: string;
58
- } | undefined;
43
+ export type CaseCheckOpts = Pick<ConnectorCheckOpts, 'lookups' | 'resolutions' | 'schemaReadiness' | 'bindings'> & {
44
+ /** The library `compile` serializes against, for the serializer `check` runs. */
45
+ library?: Library;
59
46
  };
60
47
  /**
61
48
  * Validate a built case.