@uipath/maestro-builder-sdk 6.68.5 → 6.68.7
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 +33 -33
- package/dist/api-members.md +158 -158
- package/dist/bpmn/intsvc.js +10 -0
- package/dist/case/case-sdk.d.ts +50 -25
- package/dist/case/case-sdk.js +25 -6
- package/dist/case/check.d.ts +19 -0
- package/dist/case/check.js +26 -15
- package/dist/case/cli-library.js +12 -1
- package/dist/case/decompile.js +37 -7
- package/dist/case/external.d.ts +46 -0
- package/dist/case/external.js +79 -1
- package/dist/case/in-arg-binding.d.ts +58 -0
- package/dist/case/in-arg-binding.js +48 -0
- package/dist/case/serialize.js +44 -28
- package/dist/core/refusals.d.ts +2 -0
- package/dist/core/refusals.js +2 -0
- package/dist/registry/library-build/enrich.d.ts +20 -0
- package/dist/registry/library-build/enrich.js +40 -0
- package/dist/registry/model/library.d.ts +10 -0
- package/package.json +2 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which trigger a case In-arg (`.input()`) binds to — the rule `check` reports,
|
|
3
|
+
* `serialize` applies and `decompile` follows, kept in one place so they cannot
|
|
4
|
+
* drift (builder-sdk#1368).
|
|
5
|
+
*
|
|
6
|
+
* An In-arg's value arrives from a trigger: the caseplan carries a formal slot
|
|
7
|
+
* in `variables.inputs[]`, a same-name `variables.inputOutputs[]` companion
|
|
8
|
+
* keyed to the trigger node, and a bridge on that node. That is the only shape
|
|
9
|
+
* the Case Designer writes, and `uip maestro case validate --strict` refuses an
|
|
10
|
+
* In-arg with no companion (STRICT_INPUTOUTPUTS_COMPANION). So an In-arg always
|
|
11
|
+
* binds:
|
|
12
|
+
*
|
|
13
|
+
* - `.input(shape, { from: t })` binds to `t`;
|
|
14
|
+
* - with no `{ from }`, it binds to the PRIMARY trigger: the case's only
|
|
15
|
+
* trigger (the one `.trigger()` added, or the implicit manual trigger when
|
|
16
|
+
* none was added, whatever its kind); with several, the one trigger that is
|
|
17
|
+
* not a timer — the one a caller starts the case through;
|
|
18
|
+
* - with no `{ from }` and no single such trigger (several non-timer
|
|
19
|
+
* triggers, or only timers) there is no right guess, and the case is
|
|
20
|
+
* refused with CASE_IN_ARG_UNBOUND.
|
|
21
|
+
*
|
|
22
|
+
* This is the rule `uip maestro case sdd convert` applies to an `In` row with a
|
|
23
|
+
* blank `sourceTriggers` cell (cli `sdd-convert/variables.ts`,
|
|
24
|
+
* `boundTriggerFor`), and the one its `in_arg_trigger_bind` grader checks.
|
|
25
|
+
*/
|
|
26
|
+
import type { BuiltTrigger, CaseVarDecl } from './case-sdk.js';
|
|
27
|
+
/**
|
|
28
|
+
* The index, among the triggers the case emits, of the one an In-arg without
|
|
29
|
+
* `{ from }` binds to.
|
|
30
|
+
*
|
|
31
|
+
* @param isTimer - For each emitted trigger, in order, whether it is a timer.
|
|
32
|
+
* An empty list stands for the implicit manual trigger.
|
|
33
|
+
* @returns The trigger's index, or `undefined` when no single trigger qualifies.
|
|
34
|
+
*/
|
|
35
|
+
export declare function implicitInArgTrigger(isTimer: readonly boolean[]): number | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* {@link implicitInArgTrigger} over a built case's declared triggers.
|
|
38
|
+
*
|
|
39
|
+
* @param triggers - The case's `.trigger()` list.
|
|
40
|
+
* @returns The index of the trigger a `{ from }`-less In-arg binds to, or `undefined`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function implicitInArgBuiltTrigger(triggers: readonly BuiltTrigger[]): number | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Whether an In-arg declared without `{ from }` has no trigger to bind to.
|
|
45
|
+
*
|
|
46
|
+
* @param vd - The declared variable.
|
|
47
|
+
* @param triggers - The case's `.trigger()` list.
|
|
48
|
+
* @returns `true` when the In-arg must name its trigger with `{ from }`.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isUnboundInArg(vd: CaseVarDecl, triggers: readonly BuiltTrigger[]): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The CASE_IN_ARG_UNBOUND message.
|
|
53
|
+
*
|
|
54
|
+
* @param name - The In-arg's name.
|
|
55
|
+
* @param triggers - The case's `.trigger()` list.
|
|
56
|
+
* @returns The message both `check` and `serialize` report.
|
|
57
|
+
*/
|
|
58
|
+
export declare function unboundInArgMessage(name: string, triggers: readonly BuiltTrigger[]): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The index, among the triggers the case emits, of the one an In-arg without
|
|
3
|
+
* `{ from }` binds to.
|
|
4
|
+
*
|
|
5
|
+
* @param isTimer - For each emitted trigger, in order, whether it is a timer.
|
|
6
|
+
* An empty list stands for the implicit manual trigger.
|
|
7
|
+
* @returns The trigger's index, or `undefined` when no single trigger qualifies.
|
|
8
|
+
*/
|
|
9
|
+
export function implicitInArgTrigger(isTimer) {
|
|
10
|
+
if (isTimer.length <= 1)
|
|
11
|
+
return 0;
|
|
12
|
+
const callable = isTimer.flatMap((timer, i) => (timer ? [] : [i]));
|
|
13
|
+
return callable.length === 1 ? callable[0] : undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* {@link implicitInArgTrigger} over a built case's declared triggers.
|
|
17
|
+
*
|
|
18
|
+
* @param triggers - The case's `.trigger()` list.
|
|
19
|
+
* @returns The index of the trigger a `{ from }`-less In-arg binds to, or `undefined`.
|
|
20
|
+
*/
|
|
21
|
+
export function implicitInArgBuiltTrigger(triggers) {
|
|
22
|
+
return implicitInArgTrigger(triggers.map((t) => t.kind === 'timer'));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Whether an In-arg declared without `{ from }` has no trigger to bind to.
|
|
26
|
+
*
|
|
27
|
+
* @param vd - The declared variable.
|
|
28
|
+
* @param triggers - The case's `.trigger()` list.
|
|
29
|
+
* @returns `true` when the In-arg must name its trigger with `{ from }`.
|
|
30
|
+
*/
|
|
31
|
+
export function isUnboundInArg(vd, triggers) {
|
|
32
|
+
return vd.direction === 'in' && !vd.sourceTrigger && implicitInArgBuiltTrigger(triggers) === undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The CASE_IN_ARG_UNBOUND message.
|
|
36
|
+
*
|
|
37
|
+
* @param name - The In-arg's name.
|
|
38
|
+
* @param triggers - The case's `.trigger()` list.
|
|
39
|
+
* @returns The message both `check` and `serialize` report.
|
|
40
|
+
*/
|
|
41
|
+
export function unboundInArgMessage(name, triggers) {
|
|
42
|
+
const callable = triggers.filter((t) => t.kind !== 'timer').length;
|
|
43
|
+
const why = callable === 0
|
|
44
|
+
? `all ${triggers.length} of the case's triggers are timers`
|
|
45
|
+
: `${callable} of the case's ${triggers.length} triggers are not timers`;
|
|
46
|
+
return `In-arg "${name}" has no { from }, and ${why}, so there is no primary trigger to bind it to. `
|
|
47
|
+
+ `Pass .input({ ${name}: ... }, { from: <trigger> }) to name the trigger whose start supplies it, or declare it with .var() if no trigger supplies it.`;
|
|
48
|
+
}
|
package/dist/case/serialize.js
CHANGED
|
@@ -19,7 +19,7 @@ import { bindingLabelRefusal } from '../core/binding-messages.js';
|
|
|
19
19
|
import { resolveEventWhere } from '../core/lookups.js';
|
|
20
20
|
import { resolveCaseSubscription } from './subscription.js';
|
|
21
21
|
import { dedupeConditionNames } from './rule-names.js';
|
|
22
|
-
import { EXTERNAL_TASK_DESCRIPTOR_CONTRACT,
|
|
22
|
+
import { EXTERNAL_TASK_DESCRIPTOR_CONTRACT, externalDescriptorRefusal, externalExecution, externalServiceType, } from './external.js';
|
|
23
23
|
import { CASE_FORMAT_PROFILE, CASE_SCHEMA_VERSIONS, caseVersionMismatch } from './format-profile.js';
|
|
24
24
|
import { isResourceLabelRefusal, resolveResourceRef, resourceIdentity } from './resource-identity.js';
|
|
25
25
|
import { ownEntry } from '../core/own-entry.js';
|
|
@@ -31,6 +31,7 @@ import { readEventFilterLeaf, eventFilterTreeLeaf } from '../core/event-filters.
|
|
|
31
31
|
import { responseJsonSchema } from '../core/connector-response-schema.js';
|
|
32
32
|
import { ruleShapeProblems } from './rule-options.js';
|
|
33
33
|
import { CompileRefusal } from '../core/compile-refusal.js';
|
|
34
|
+
import { implicitInArgBuiltTrigger, unboundInArgMessage } from './in-arg-binding.js';
|
|
34
35
|
import { taskShapeProblems } from './task-shape.js';
|
|
35
36
|
import { connectorPlaceholderData, isConnectorPlaceholder } from './connector-placeholder.js';
|
|
36
37
|
/** The ids a serialize pass hashed from element ids, by the document it returned. */
|
|
@@ -258,7 +259,7 @@ export function serialize(built, opts = {}) {
|
|
|
258
259
|
// outputs bound (collected during stage emission above). A declared var wins
|
|
259
260
|
// on a name clash. An own-name output (`id == var`) writes no root entry: like
|
|
260
261
|
// the Designer, the output row is itself the variable `=vars.<id>` reads.
|
|
261
|
-
const variables = emitVariables(built.vars, ids, triggerNodeByRef);
|
|
262
|
+
const variables = emitVariables(built.vars, ids, triggerNodeByRef, triggerNodes, built.triggers);
|
|
262
263
|
const inputOutputs = variables.inputOutputs;
|
|
263
264
|
const declared = new Set(inputOutputs.map((e) => e.id));
|
|
264
265
|
for (const [name, companion] of resolver.varCompanions)
|
|
@@ -960,7 +961,8 @@ function reseed(value, ids) {
|
|
|
960
961
|
value[key] = next;
|
|
961
962
|
}
|
|
962
963
|
}
|
|
963
|
-
function emitVariables(vars, ids, triggerNodeByRef) {
|
|
964
|
+
function emitVariables(vars, ids, triggerNodeByRef, triggerNodes, triggers) {
|
|
965
|
+
const implicit = implicitInArgBuiltTrigger(triggers);
|
|
964
966
|
const inputs = [];
|
|
965
967
|
const outputs = [];
|
|
966
968
|
const inputOutputs = [];
|
|
@@ -1002,26 +1004,38 @@ function emitVariables(vars, ids, triggerNodeByRef) {
|
|
|
1002
1004
|
id: slotId,
|
|
1003
1005
|
name: vd.name,
|
|
1004
1006
|
type: vd.type,
|
|
1005
|
-
|
|
1007
|
+
// A trigger-bound In-arg always carries a default, `""` when none was
|
|
1008
|
+
// authored. It is written here, ahead of a structured var's schema, so
|
|
1009
|
+
// `{ type }` and `{ type, default: "" }` emit the same bytes and a
|
|
1010
|
+
// decompile (which reads the `""` back) recompiles byte-identically.
|
|
1011
|
+
...(vd.direction === 'in' ? { default: encodedDefault(vd).default ?? '' } : encodedDefault(vd)),
|
|
1012
|
+
...jsonSchemaFields(vd),
|
|
1006
1013
|
};
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
//
|
|
1010
|
-
//
|
|
1011
|
-
//
|
|
1012
|
-
//
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1014
|
+
if (vd.direction === 'in') {
|
|
1015
|
+
// An In-arg is always trigger-bound: formal slot + companion + a bridge on
|
|
1016
|
+
// the trigger node that copies the slot into the companion at fire (see the
|
|
1017
|
+
// skill's variables/io-binding + global-vars § In argument). Its companion
|
|
1018
|
+
// is keyed to the trigger node, so it does not also take a root companion.
|
|
1019
|
+
// The Designer writes no other In-arg shape, and `uip maestro case validate
|
|
1020
|
+
// --strict` refuses an In-arg without its companion
|
|
1021
|
+
// (STRICT_INPUTOUTPUTS_COMPANION). Without `{ from }` the arg binds to the
|
|
1022
|
+
// primary trigger (in-arg-binding.ts); when there is none it is refused
|
|
1023
|
+
// (`check` reports the same code first).
|
|
1024
|
+
let node;
|
|
1025
|
+
if (vd.sourceTrigger) {
|
|
1026
|
+
node = triggerNodeByRef.get(vd.sourceTrigger);
|
|
1027
|
+
if (!node)
|
|
1028
|
+
throw new CompileRefusal('CASE_IN_ARG_TRIGGER_NOT_ADDED', `In-arg "${vd.name}" is bound via { from } to a trigger that was not added with .trigger(...).`);
|
|
1029
|
+
}
|
|
1030
|
+
else if (implicit !== undefined)
|
|
1031
|
+
node = triggerNodes[implicit];
|
|
1032
|
+
else
|
|
1033
|
+
throw new CompileRefusal('CASE_IN_ARG_UNBOUND', unboundInArgMessage(vd.name, triggers));
|
|
1017
1034
|
entry.elementId = node.id;
|
|
1018
1035
|
inputs.push(entry);
|
|
1019
1036
|
inputOutputs.push({ id: vd.name, name: vd.name, type: vd.type, elementId: node.id, ...jsonSchemaFields(vd) });
|
|
1020
1037
|
appendTriggerBridge(node, { name: vd.name, type: vd.type, source: `=vars.${slotId}`, var: vd.name });
|
|
1021
1038
|
}
|
|
1022
|
-
else if (vd.direction === 'in') {
|
|
1023
|
-
inputs.push(entry); // bare declaration (unbound In-arg; readable only via a trigger)
|
|
1024
|
-
}
|
|
1025
1039
|
else if (vd.direction === 'out') {
|
|
1026
1040
|
outputs.push(entry); // formal declaration
|
|
1027
1041
|
inputOutputs.push(readableCompanion(vd)); // …made readable as `vars.<name>`
|
|
@@ -1814,24 +1828,26 @@ function externalTaskData(kind, spec, resolver, elementId, where) {
|
|
|
1814
1828
|
const refused = externalDescriptorRefusal(kind, rc);
|
|
1815
1829
|
if (refused)
|
|
1816
1830
|
throw new CompileRefusal(EXTERNAL_TASK_DESCRIPTOR_CONTRACT, refused);
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1831
|
+
// The authored mode and event, else the library's (#1369): the same call check makes.
|
|
1832
|
+
const execution = externalExecution(where, spec, rc.entry?.operation ?? {});
|
|
1833
|
+
if (!execution)
|
|
1834
|
+
throw new Error(`internal SDK error: ${where} was judged without its library operation.`);
|
|
1835
|
+
if (execution.code !== undefined)
|
|
1836
|
+
throw new CompileRefusal(execution.code, execution.message);
|
|
1837
|
+
const { mode, event } = execution;
|
|
1822
1838
|
if (!spec.connector.connection || !spec.connector.folder)
|
|
1823
1839
|
throw new CompileRefusal(spec.connector.connection ? 'EXTERNAL_TASK_FOLDER' : 'EXTERNAL_TASK_CONNECTION', `${kind} task requires non-empty connection and folder binding names.`);
|
|
1824
|
-
const data = connectorTaskData(spec.connector, resolver, elementId, where,
|
|
1840
|
+
const data = connectorTaskData(spec.connector, resolver, elementId, where, mode, event);
|
|
1825
1841
|
const context = data.context;
|
|
1826
1842
|
const metadataAt = context.findIndex((row) => row.name === 'metadata');
|
|
1827
1843
|
// The Designer's order: the event pair (when the object answers through one),
|
|
1828
1844
|
// then the execution type, just before `metadata`.
|
|
1829
|
-
context.splice(metadataAt, 0, ...(
|
|
1830
|
-
io('operation', 'string', { value:
|
|
1831
|
-
io('eventMode', 'string', { value:
|
|
1832
|
-
] : []), io('executionType', 'string', { value:
|
|
1845
|
+
context.splice(metadataAt, 0, ...(event ? [
|
|
1846
|
+
io('operation', 'string', { value: event.operation }),
|
|
1847
|
+
io('eventMode', 'string', { value: event.mode }),
|
|
1848
|
+
] : []), io('executionType', 'string', { value: mode }));
|
|
1833
1849
|
context.push(io('activityConfigurationVersion', 'string', { value: 'v2' }));
|
|
1834
|
-
return { ...data, serviceType: externalServiceType(kind,
|
|
1850
|
+
return { ...data, serviceType: externalServiceType(kind, mode) };
|
|
1835
1851
|
}
|
|
1836
1852
|
/** A context/output name/value entry (the caseplan `InputOutput` shape). */
|
|
1837
1853
|
function io(name, type, extra) {
|
package/dist/core/refusals.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ export declare const REFUSALS: {
|
|
|
151
151
|
readonly CASE_APP_DETAILS_TYPE: "lint";
|
|
152
152
|
readonly CASE_EXPORT_NOT_BUILT: "lowering";
|
|
153
153
|
readonly CASE_IN_ARG_TRIGGER_NOT_ADDED: "lowering";
|
|
154
|
+
readonly CASE_IN_ARG_UNBOUND: "lowering";
|
|
154
155
|
readonly CASE_LAYOUT_NODE_MATCH: "lowering";
|
|
155
156
|
readonly CASE_LAYOUT_UNKNOWN_FIELD: "lowering";
|
|
156
157
|
readonly CASE_NO_DEFAULT_EXPORT: "lowering";
|
|
@@ -277,6 +278,7 @@ export declare const REFUSALS: {
|
|
|
277
278
|
readonly EXTERNAL_TASK_EVENT: "lowering";
|
|
278
279
|
readonly EXTERNAL_TASK_FOLDER: "lowering";
|
|
279
280
|
readonly EXTERNAL_TASK_MODE: "lowering";
|
|
281
|
+
readonly EXTERNAL_TASK_MODE_MISMATCH: "lowering";
|
|
280
282
|
readonly EXTRACT_SCHEMA_SHAPE: "lint";
|
|
281
283
|
readonly FAKE_JOIN: "lint";
|
|
282
284
|
readonly FILE_NOT_FOUND: "lowering";
|
package/dist/core/refusals.js
CHANGED
|
@@ -199,6 +199,7 @@ export const REFUSALS = {
|
|
|
199
199
|
CASE_APP_DETAILS_TYPE: 'lint',
|
|
200
200
|
CASE_EXPORT_NOT_BUILT: 'lowering',
|
|
201
201
|
CASE_IN_ARG_TRIGGER_NOT_ADDED: 'lowering',
|
|
202
|
+
CASE_IN_ARG_UNBOUND: 'lowering',
|
|
202
203
|
CASE_LAYOUT_NODE_MATCH: 'lowering',
|
|
203
204
|
CASE_LAYOUT_UNKNOWN_FIELD: 'lowering',
|
|
204
205
|
CASE_NO_DEFAULT_EXPORT: 'lowering',
|
|
@@ -328,6 +329,7 @@ export const REFUSALS = {
|
|
|
328
329
|
EXTERNAL_TASK_EVENT: 'lowering',
|
|
329
330
|
EXTERNAL_TASK_FOLDER: 'lowering',
|
|
330
331
|
EXTERNAL_TASK_MODE: 'lowering',
|
|
332
|
+
EXTERNAL_TASK_MODE_MISMATCH: 'lowering',
|
|
331
333
|
EXTRACT_SCHEMA_SHAPE: 'lint',
|
|
332
334
|
FAKE_JOIN: 'lint',
|
|
333
335
|
FILE_NOT_FOUND: 'lowering',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { LibraryEntry } from "../model/library.js";
|
|
2
2
|
import { type BuildContext } from "./context.js";
|
|
3
|
+
import { type Dict } from "./py.js";
|
|
3
4
|
/**
|
|
4
5
|
* Registry `httpMethod` (e.g. `GETBYID`) → a guess at the `is resources`
|
|
5
6
|
* operation name, for an entry whose canonical `operation.name` is empty.
|
|
@@ -18,6 +19,25 @@ export declare function discoverOperationName(ctx: BuildContext, entry: LibraryE
|
|
|
18
19
|
* payload; `objectDisplayName` and `display.operationLabel` fill gaps only.
|
|
19
20
|
*/
|
|
20
21
|
export declare function applyDescribe(entry: LibraryEntry, data: unknown): LibraryEntry;
|
|
22
|
+
/**
|
|
23
|
+
* Record an external agent's or automation's execution facts on its operation,
|
|
24
|
+
* from the describe payload (#1369, #1387).
|
|
25
|
+
*
|
|
26
|
+
* Integration Service keeps them on the object's metadata, not in the registry
|
|
27
|
+
* node: `executionType` (`sync`, `async` or `hybrid`) and, for an `async` or
|
|
28
|
+
* `hybrid` object, the event it answers with. `uip is resources describe`
|
|
29
|
+
* reports them as `ExecutionType`, `EventType` and `EventMode` (uip#5702,
|
|
30
|
+
* read with the same `externalExecutionOf` as `case spec`). They become
|
|
31
|
+
* `operation.executionType` and `operation.executionEvent` (`{ operation, mode }`),
|
|
32
|
+
* which Case and BPMN derive the task's `mode` and `event` from. The event is
|
|
33
|
+
* kept apart from `eventOperation` / `eventMode`, which mark a connector EVENT
|
|
34
|
+
* entry (a trigger) and which `identifyEvent` matches on.
|
|
35
|
+
*
|
|
36
|
+
* Only an `AgentExecution` / `ProcessExecution` operation gets them, and only
|
|
37
|
+
* what the payload states (an execution type outside the three is not stored): a describe from a CLI that does not report them
|
|
38
|
+
* leaves the entry as it was, so an older build stays byte-identical.
|
|
39
|
+
*/
|
|
40
|
+
export declare function applyExternalExecution(operation: Dict, data: unknown): void;
|
|
21
41
|
/**
|
|
22
42
|
* `enrich_entry`: augment a canonical entry with `is resources describe` data.
|
|
23
43
|
* On any failure the entry is returned as it was, so the pipeline degrades
|
|
@@ -78,6 +78,7 @@ export function applyDescribe(entry, data) {
|
|
|
78
78
|
const opCurated = pick(opData, "Curated", "curated");
|
|
79
79
|
if (pyTruthy(opCurated) && !pyTruthy(get(display, "operationLabel")))
|
|
80
80
|
display.operationLabel = opCurated;
|
|
81
|
+
applyExternalExecution(operation, data);
|
|
81
82
|
// Parameters (path / query) — raw shape, camelCase keys.
|
|
82
83
|
const params = pyOr(pick(data, "Parameters", "parameters"), []);
|
|
83
84
|
if (pyTruthy(params))
|
|
@@ -92,6 +93,45 @@ export function applyDescribe(entry, data) {
|
|
|
92
93
|
e.outputSchema = { fields: normalizeFieldKeys(responseFields) };
|
|
93
94
|
return entry;
|
|
94
95
|
}
|
|
96
|
+
/** The operation subtypes Case's and BPMN's external agent / workflow tasks run. */
|
|
97
|
+
const EXTERNAL_SUBTYPES = new Set(["AgentExecution", "ProcessExecution"]);
|
|
98
|
+
/** The execution types Integration Service reports, as Case and BPMN read them. */
|
|
99
|
+
const EXECUTION_TYPES = new Set(["sync", "async", "hybrid"]);
|
|
100
|
+
/**
|
|
101
|
+
* Record an external agent's or automation's execution facts on its operation,
|
|
102
|
+
* from the describe payload (#1369, #1387).
|
|
103
|
+
*
|
|
104
|
+
* Integration Service keeps them on the object's metadata, not in the registry
|
|
105
|
+
* node: `executionType` (`sync`, `async` or `hybrid`) and, for an `async` or
|
|
106
|
+
* `hybrid` object, the event it answers with. `uip is resources describe`
|
|
107
|
+
* reports them as `ExecutionType`, `EventType` and `EventMode` (uip#5702,
|
|
108
|
+
* read with the same `externalExecutionOf` as `case spec`). They become
|
|
109
|
+
* `operation.executionType` and `operation.executionEvent` (`{ operation, mode }`),
|
|
110
|
+
* which Case and BPMN derive the task's `mode` and `event` from. The event is
|
|
111
|
+
* kept apart from `eventOperation` / `eventMode`, which mark a connector EVENT
|
|
112
|
+
* entry (a trigger) and which `identifyEvent` matches on.
|
|
113
|
+
*
|
|
114
|
+
* Only an `AgentExecution` / `ProcessExecution` operation gets them, and only
|
|
115
|
+
* what the payload states (an execution type outside the three is not stored): a describe from a CLI that does not report them
|
|
116
|
+
* leaves the entry as it was, so an older build stays byte-identical.
|
|
117
|
+
*/
|
|
118
|
+
export function applyExternalExecution(operation, data) {
|
|
119
|
+
if (!EXTERNAL_SUBTYPES.has(String(get(operation, "subType") ?? "")))
|
|
120
|
+
return;
|
|
121
|
+
// Stored only as one of the three values Case and BPMN read, lowercased: a
|
|
122
|
+
// `Hybrid` kept verbatim would be ignored downstream and read as "no record".
|
|
123
|
+
const reported = pick(data, "ExecutionType", "executionType");
|
|
124
|
+
const executionType = typeof reported === "string" ? reported.trim().toLowerCase() : "";
|
|
125
|
+
if (!EXECUTION_TYPES.has(executionType))
|
|
126
|
+
return;
|
|
127
|
+
operation.executionType = executionType;
|
|
128
|
+
if (executionType === "sync")
|
|
129
|
+
return;
|
|
130
|
+
const eventType = pick(data, "EventType", "eventType");
|
|
131
|
+
const eventMode = pick(data, "EventMode", "eventMode");
|
|
132
|
+
if (typeof eventType === "string" && eventType && typeof eventMode === "string" && eventMode)
|
|
133
|
+
operation.executionEvent = { operation: eventType, mode: eventMode };
|
|
134
|
+
}
|
|
95
135
|
/**
|
|
96
136
|
* `enrich_entry`: augment a canonical entry with `is resources describe` data.
|
|
97
137
|
* On any failure the entry is returned as it was, so the pipeline degrades
|
|
@@ -85,6 +85,16 @@ export interface EntryOperation {
|
|
|
85
85
|
objectFromDiscovery?: boolean;
|
|
86
86
|
eventOperation?: string;
|
|
87
87
|
eventMode?: string;
|
|
88
|
+
/**
|
|
89
|
+
* An external agent's or automation's `executionType` (`sync`, `async`,
|
|
90
|
+
* `hybrid`), on an `AgentExecution` / `ProcessExecution` operation only.
|
|
91
|
+
*/
|
|
92
|
+
executionType?: string;
|
|
93
|
+
/** The event an `async` / `hybrid` external object answers with. */
|
|
94
|
+
executionEvent?: {
|
|
95
|
+
operation: string;
|
|
96
|
+
mode: string;
|
|
97
|
+
};
|
|
88
98
|
schemaAction?: SchemaAction | null;
|
|
89
99
|
dispatchStyle?: string;
|
|
90
100
|
paramGrammars?: unknown;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.68.
|
|
3
|
+
"version": "6.68.7",
|
|
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",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"@types/node": "^22.7.0",
|
|
101
101
|
"esbuild": "^0.28.1"
|
|
102
102
|
},
|
|
103
|
-
"gitref": "
|
|
103
|
+
"gitref": "436dbc08c3130fcde3197adec572df61116f4ede"
|
|
104
104
|
}
|