@uipath/maestro-builder-sdk 6.57.0 → 6.58.1
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/case/subscription.d.ts +4 -2
- package/dist/case/subscription.js +5 -2
- package/dist/core/actions.js +2 -2
- package/dist/core/binding-messages.d.ts +2 -1
- package/dist/core/binding-messages.js +3 -4
- package/dist/core/byoa.d.ts +3 -2
- package/dist/core/byoa.js +3 -3
- package/dist/core/carried-definitions.d.ts +0 -18
- package/dist/core/carried-definitions.js +3 -2
- package/dist/core/ceql.d.ts +2 -1
- package/dist/core/ceql.js +3 -2
- package/dist/core/compile-refusal.d.ts +21 -0
- package/dist/core/compile-refusal.js +26 -0
- package/dist/core/connector-inputs.js +2 -1
- package/dist/core/connector-resolve-error.d.ts +2 -1
- package/dist/core/connector-resolve-error.js +3 -4
- package/dist/core/connectors.js +2 -1
- package/dist/core/event-filters.js +2 -1
- package/dist/core/hitl-routing.d.ts +7 -82
- package/dist/core/hitl-routing.js +95 -6
- package/dist/core/library.js +4 -3
- package/dist/core/lookups.js +6 -5
- package/dist/core/nodes/registry.js +3 -2
- package/dist/core/nodes/versioned.js +3 -2
- package/dist/core/process-resource-sort-order.js +1 -1
- package/dist/core/read-text.d.ts +0 -28
- package/dist/core/read-text.js +3 -2
- package/dist/core/refusals.d.ts +465 -0
- package/dist/core/refusals.js +504 -0
- package/dist/core/script-function.js +2 -1
- package/dist/core/typescript-module.js +2 -1
- package/dist/edit-scope.d.ts +180 -0
- package/dist/edit-scope.js +251 -0
- package/dist/flow-expr-check.d.ts +2 -1
- package/dist/flow-expr-check.js +4 -2
- package/dist/flow-sdk.js +17 -16
- package/dist/flow-step-tree.js +1 -1
- package/dist/flow-variables.js +3 -2
- package/dist/load.js +7 -6
- package/dist/merge-cli.js +4 -2
- package/dist/merge-compile.d.ts +5 -88
- package/dist/merge-compile.js +8 -138
- package/dist/merge.d.ts +1 -61
- package/dist/merge.js +1 -112
- package/dist/nodes/agent/flow/inline-agent.js +7 -6
- package/dist/nodes/connector/flow/node-type.js +2 -1
- package/dist/nodes/data-fabric/flow/factories.js +2 -1
- package/dist/nodes/data-fabric/flow/verbs.js +2 -1
- package/dist/nodes/delay/flow/factories.js +2 -1
- package/dist/nodes/document/flow/ixp.js +5 -1
- package/dist/nodes/hitl/flow/check.js +4 -2
- package/dist/nodes/hitl/flow/node-type.js +6 -5
- package/dist/nodes/http/flow/factories.js +2 -1
- package/dist/nodes/http/flow/node-type.js +6 -5
- package/dist/nodes/process/flow/factories.js +2 -1
- package/dist/nodes/queue/flow/node-type.js +3 -2
- package/dist/nodes/transform/flow/node-type.js +2 -1
- package/dist/raw-node.js +3 -2
- package/dist/ref-resolve.d.ts +0 -36
- package/dist/ref-resolve.js +9 -8
- package/dist/schema-version.d.ts +0 -38
- package/dist/schema-version.js +3 -2
- package/dist/sdk-resolve.js +2 -1
- package/dist/serialize.d.ts +5 -2
- package/dist/serialize.js +115 -83
- package/package.json +2 -2
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { EventSubscription } from '../core/actions.js';
|
|
12
12
|
import type { Library, ResolvedConnector } from '../core/library.js';
|
|
13
|
+
import { CompileRefusal } from '../core/compile-refusal.js';
|
|
13
14
|
import type { BindingsView } from '../core/binding-messages.js';
|
|
14
15
|
/** Check's code for {@link GenericEventNoObjectError}; Flow and BPMN `check` use the same one. */
|
|
15
16
|
export declare const EVENT_GENERIC_NO_OBJECT = "EVENT_GENERIC_NO_OBJECT";
|
|
16
17
|
/** A GENERIC event subscription that names no object. */
|
|
17
|
-
export declare class GenericEventNoObjectError extends
|
|
18
|
-
readonly code
|
|
18
|
+
export declare class GenericEventNoObjectError extends CompileRefusal {
|
|
19
|
+
readonly code: typeof EVENT_GENERIC_NO_OBJECT;
|
|
20
|
+
constructor(message: string);
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Resolve a Case event subscription: `library.resolveEvent` with the
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { genericEventObjectRefusal } from '../core/event-checks.js';
|
|
2
2
|
import { ByoaRefusal, byoaUnverified } from '../core/byoa.js';
|
|
3
|
+
import { CompileRefusal } from '../core/compile-refusal.js';
|
|
3
4
|
/** Check's code for {@link GenericEventNoObjectError}; Flow and BPMN `check` use the same one. */
|
|
4
5
|
export const EVENT_GENERIC_NO_OBJECT = 'EVENT_GENERIC_NO_OBJECT';
|
|
5
6
|
/** A GENERIC event subscription that names no object. */
|
|
6
|
-
export class GenericEventNoObjectError extends
|
|
7
|
-
|
|
7
|
+
export class GenericEventNoObjectError extends CompileRefusal {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(EVENT_GENERIC_NO_OBJECT, message);
|
|
10
|
+
}
|
|
8
11
|
}
|
|
9
12
|
/** How a Case subscription spells the `object` of a GENERIC event, for the refusal text. */
|
|
10
13
|
function caseObjectOption(object) {
|
package/dist/core/actions.js
CHANGED
|
@@ -13,7 +13,7 @@ class BuiltinAction extends FlowAction {
|
|
|
13
13
|
Object.assign(this, spec);
|
|
14
14
|
}
|
|
15
15
|
contribute() {
|
|
16
|
-
throw new Error('built-in action specs are lowered by the serializer directly; contribute() is only called on custom FlowAction subclasses');
|
|
16
|
+
throw new Error('internal SDK error: built-in action specs are lowered by the serializer directly; contribute() is only called on custom FlowAction subclasses');
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
class BuiltinTrigger extends FlowTrigger {
|
|
@@ -22,7 +22,7 @@ class BuiltinTrigger extends FlowTrigger {
|
|
|
22
22
|
Object.assign(this, spec);
|
|
23
23
|
}
|
|
24
24
|
contribute() {
|
|
25
|
-
throw new Error('built-in trigger specs are lowered by the serializer directly; contribute() is only called on custom FlowTrigger subclasses');
|
|
25
|
+
throw new Error('internal SDK error: built-in trigger specs are lowered by the serializer directly; contribute() is only called on custom FlowTrigger subclasses');
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
1
2
|
/** A tenant resource key — an Integration Service connection id or an Orchestrator folder key — is a GUID. */
|
|
2
3
|
export declare const GUID_RE: RegExp;
|
|
3
4
|
/** The diagnostic codes a label refusal carries, in `check` and on the error `serialize` throws. */
|
|
@@ -18,7 +19,7 @@ export type BindingRefusalCode = 'BINDING_SELF_NAME' | 'BINDING_UNDECLARED'
|
|
|
18
19
|
* message is the sentence `check` prints; the `code` lets `compile --no-check`
|
|
19
20
|
* print it in the same `✗ [CODE]` shape as the check pass instead of a bare line.
|
|
20
21
|
*/
|
|
21
|
-
export declare class BindingRefusal extends
|
|
22
|
+
export declare class BindingRefusal extends CompileRefusal {
|
|
22
23
|
readonly code: BindingRefusalCode;
|
|
23
24
|
constructor(code: BindingRefusalCode, message: string);
|
|
24
25
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* for a source `compile` then refused (teams-decision, 2026-09-01, turn 22 → 23).
|
|
7
7
|
*/
|
|
8
8
|
import { prepareCommand } from './cli-spelling.js';
|
|
9
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
9
10
|
/** A tenant resource key — an Integration Service connection id or an Orchestrator folder key — is a GUID. */
|
|
10
11
|
export const GUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
11
12
|
/**
|
|
@@ -13,12 +14,10 @@ export const GUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f
|
|
|
13
14
|
* message is the sentence `check` prints; the `code` lets `compile --no-check`
|
|
14
15
|
* print it in the same `✗ [CODE]` shape as the check pass instead of a bare line.
|
|
15
16
|
*/
|
|
16
|
-
export class BindingRefusal extends
|
|
17
|
-
code;
|
|
17
|
+
export class BindingRefusal extends CompileRefusal {
|
|
18
18
|
constructor(code, message) {
|
|
19
|
-
super(message);
|
|
19
|
+
super(code, message);
|
|
20
20
|
this.name = 'BindingRefusal';
|
|
21
|
-
this.code = code;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
export function bindingSelfNameMessage(where, name, attribute, target) {
|
package/dist/core/byoa.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
1
2
|
/** The diagnostic code, in `check` and on the error `serialize` throws. */
|
|
2
3
|
export declare const EVENT_BYOA_UNVERIFIED = "EVENT_BYOA_UNVERIFIED";
|
|
3
4
|
/** One verification `prepare` recorded. Only a PASSING check is ever written. */
|
|
@@ -30,8 +31,8 @@ export declare function byoaLedgerKey(connectorKey: string, event: string): stri
|
|
|
30
31
|
/** The record for `connectionId` under `nodeType`, matching the id case-insensitively. */
|
|
31
32
|
export declare function byoaRecordFor(ledger: ByoaLedger | undefined, nodeType: string, connectionId: string): ByoaRecord | undefined;
|
|
32
33
|
/** What `compile` throws for the refusal; `code` lets the CLI print it as `✗ [CODE]`. */
|
|
33
|
-
export declare class ByoaRefusal extends
|
|
34
|
-
readonly code
|
|
34
|
+
export declare class ByoaRefusal extends CompileRefusal {
|
|
35
|
+
readonly code: typeof EVENT_BYOA_UNVERIFIED;
|
|
35
36
|
constructor(message: string);
|
|
36
37
|
}
|
|
37
38
|
/** One subscription, as the rule needs it. */
|
package/dist/core/byoa.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { GUID_RE } from './binding-messages.js';
|
|
24
24
|
import { prepareCommand } from './cli-spelling.js';
|
|
25
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
25
26
|
/** The diagnostic code, in `check` and on the error `serialize` throws. */
|
|
26
27
|
export const EVENT_BYOA_UNVERIFIED = 'EVENT_BYOA_UNVERIFIED';
|
|
27
28
|
/**
|
|
@@ -45,10 +46,9 @@ export function byoaRecordFor(ledger, nodeType, connectionId) {
|
|
|
45
46
|
return undefined;
|
|
46
47
|
}
|
|
47
48
|
/** What `compile` throws for the refusal; `code` lets the CLI print it as `✗ [CODE]`. */
|
|
48
|
-
export class ByoaRefusal extends
|
|
49
|
-
code = EVENT_BYOA_UNVERIFIED;
|
|
49
|
+
export class ByoaRefusal extends CompileRefusal {
|
|
50
50
|
constructor(message) {
|
|
51
|
-
super(message);
|
|
51
|
+
super(EVENT_BYOA_UNVERIFIED, message);
|
|
52
52
|
this.name = 'ByoaRefusal';
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Node definitions a flow CARRIES — the third source a pinned `{ version }`
|
|
3
|
-
* resolves from, after the SDK's bundle (#1128).
|
|
4
|
-
*
|
|
5
|
-
* Every `.flow` file holds the exact definition of every node it uses, in
|
|
6
|
-
* `definitions[]`. The SDK bundles only the versions it was released with, so
|
|
7
|
-
* a version the registry served later (`node add` writes
|
|
8
|
-
* `uipath.human-in-the-loop.quick-form@1.6`; the SDK ships 1.0 and 1.1) used
|
|
9
|
-
* to be refused, and the source decompile wrote for an untouched product flow
|
|
10
|
-
* did not compile. A carried definition closes that: decompile copies the
|
|
11
|
-
* file's own entry into `.definitions([...])`, and compile resolves the pin
|
|
12
|
-
* against it.
|
|
13
|
-
*
|
|
14
|
-
* A carried definition is an exact copy of a real one, never a way to invent a
|
|
15
|
-
* version. So it is validated the way a `rawNode` snapshot manifest is: it
|
|
16
|
-
* names its own `nodeType` and `version`, and it has the `display.label` every
|
|
17
|
-
* node manifest has.
|
|
18
|
-
*/
|
|
19
1
|
/** A carried definition, by its `<nodeType>@<version>` key. */
|
|
20
2
|
export type CarriedDefinitions = ReadonlyMap<string, Record<string, unknown>>;
|
|
21
3
|
/**
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* names its own `nodeType` and `version`, and it has the `display.label` every
|
|
17
17
|
* node manifest has.
|
|
18
18
|
*/
|
|
19
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
19
20
|
/**
|
|
20
21
|
* Why `manifest` cannot be carried, or `undefined` when it can.
|
|
21
22
|
*
|
|
@@ -44,12 +45,12 @@ export function indexCarriedDefinitions(manifests, where, into = new Map()) {
|
|
|
44
45
|
for (const m of manifests) {
|
|
45
46
|
const refusal = carriedDefinitionRefusal(m, where);
|
|
46
47
|
if (refusal)
|
|
47
|
-
throw new
|
|
48
|
+
throw new CompileRefusal('CARRIED_DEFINITION_INVALID', refusal);
|
|
48
49
|
const def = m;
|
|
49
50
|
const key = `${def.nodeType}@${def.version}`;
|
|
50
51
|
const prior = into.get(key);
|
|
51
52
|
if (prior !== undefined && stableJson(prior) !== stableJson(def)) {
|
|
52
|
-
throw new
|
|
53
|
+
throw new CompileRefusal('CARRIED_DEFINITION_CONFLICT', `${where}: two different carried definitions for ${key}. Keep the one the file holds.`);
|
|
53
54
|
}
|
|
54
55
|
into.set(key, def);
|
|
55
56
|
}
|
package/dist/core/ceql.d.ts
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
* its runtime half and gets no tree — the same state as before this existed,
|
|
33
33
|
* rather than a wrong one.
|
|
34
34
|
*/
|
|
35
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
35
36
|
/** A leaf's comparison operator, in the canonical PascalCase the canvas stores. */
|
|
36
37
|
export type CeqlOperator = 'Equals' | 'NotEquals' | 'LessThan' | 'LessThanOrEqual' | 'GreaterThan' | 'GreaterThanOrEqual' | 'Contains' | 'NotContains' | 'StartsWith' | 'NotStartsWith' | 'EndsWith' | 'NotEndsWith' | 'Like' | 'NotLike' | 'IsNull' | 'IsNotNull';
|
|
37
38
|
/** One comparison — `<field> <operator> <value>`. */
|
|
@@ -55,7 +56,7 @@ export interface CeqlTree {
|
|
|
55
56
|
uuId?: string;
|
|
56
57
|
}
|
|
57
58
|
/** Raised when an expression is not CEQL this parser can represent. */
|
|
58
|
-
export declare class CeqlParseError extends
|
|
59
|
+
export declare class CeqlParseError extends CompileRefusal {
|
|
59
60
|
readonly expression: string;
|
|
60
61
|
constructor(message: string, expression: string);
|
|
61
62
|
}
|
package/dist/core/ceql.js
CHANGED
|
@@ -34,11 +34,12 @@
|
|
|
34
34
|
*/
|
|
35
35
|
import { stableId } from './stable-id.js';
|
|
36
36
|
import { ownEntry } from './own-entry.js';
|
|
37
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
37
38
|
/** Raised when an expression is not CEQL this parser can represent. */
|
|
38
|
-
export class CeqlParseError extends
|
|
39
|
+
export class CeqlParseError extends CompileRefusal {
|
|
39
40
|
expression;
|
|
40
41
|
constructor(message, expression) {
|
|
41
|
-
super(message);
|
|
42
|
+
super('CEQL_UNPARSEABLE', message);
|
|
42
43
|
this.expression = expression;
|
|
43
44
|
this.name = 'CeqlParseError';
|
|
44
45
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error every build-time refusal throws: a sentence for the author plus a
|
|
3
|
+
* stable `code` (docs/CHECK_COMPILE_CONTRACT_DESIGN.md §3.1, #1440).
|
|
4
|
+
*
|
|
5
|
+
* The code is what tells a refusal from a bug without matching on message text:
|
|
6
|
+
* `thrownDiagnostic` (`cli-result.ts`) reports it under this code, so
|
|
7
|
+
* `compile --output json` prints `[DUP_STEP]` instead of `COMPILE_FAILED`, and
|
|
8
|
+
* `merge` can sort it by node. Every code is listed in `core/refusals.ts` with
|
|
9
|
+
* its class (lint, lowering, draft); FB017 keeps the two in step.
|
|
10
|
+
*
|
|
11
|
+
* Only an internal error — a broken SDK invariant the author cannot act on —
|
|
12
|
+
* stays a plain `Error`, and its message starts with `internal SDK error:`.
|
|
13
|
+
*
|
|
14
|
+
* For instance:
|
|
15
|
+
*
|
|
16
|
+
* throw new CompileRefusal('DUP_STEP', `two steps are named "notify". …`);
|
|
17
|
+
*/
|
|
18
|
+
export declare class CompileRefusal extends Error {
|
|
19
|
+
readonly code: string;
|
|
20
|
+
constructor(code: string, message: string);
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error every build-time refusal throws: a sentence for the author plus a
|
|
3
|
+
* stable `code` (docs/CHECK_COMPILE_CONTRACT_DESIGN.md §3.1, #1440).
|
|
4
|
+
*
|
|
5
|
+
* The code is what tells a refusal from a bug without matching on message text:
|
|
6
|
+
* `thrownDiagnostic` (`cli-result.ts`) reports it under this code, so
|
|
7
|
+
* `compile --output json` prints `[DUP_STEP]` instead of `COMPILE_FAILED`, and
|
|
8
|
+
* `merge` can sort it by node. Every code is listed in `core/refusals.ts` with
|
|
9
|
+
* its class (lint, lowering, draft); FB017 keeps the two in step.
|
|
10
|
+
*
|
|
11
|
+
* Only an internal error — a broken SDK invariant the author cannot act on —
|
|
12
|
+
* stays a plain `Error`, and its message starts with `internal SDK error:`.
|
|
13
|
+
*
|
|
14
|
+
* For instance:
|
|
15
|
+
*
|
|
16
|
+
* throw new CompileRefusal('DUP_STEP', `two steps are named "notify". …`);
|
|
17
|
+
*/
|
|
18
|
+
export class CompileRefusal extends Error {
|
|
19
|
+
code;
|
|
20
|
+
constructor(code, message) {
|
|
21
|
+
super(message);
|
|
22
|
+
// `name` stays `Error`, so a converted `throw new Error(…)` prints exactly as
|
|
23
|
+
// it did (`Error: …` in `String(e)` and stacks). A subclass names itself.
|
|
24
|
+
this.code = code;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -30,6 +30,7 @@ export { FLOW_EXPR_DIALECT } from './connector-checks.js';
|
|
|
30
30
|
import { FLOW_EXPR_DIALECT as FLOW_DIALECT } from './connector-checks.js';
|
|
31
31
|
import { ownEntry } from './own-entry.js';
|
|
32
32
|
import { isRecord } from './node-envelope.js';
|
|
33
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
33
34
|
/** A required connector input left empty — the one draft code with no error class of its own. */
|
|
34
35
|
export const CONNECTOR_INPUT_MISSING = 'CONNECTOR_INPUT_MISSING';
|
|
35
36
|
/**
|
|
@@ -204,7 +205,7 @@ export function buildConnectorInputs(rc, inputs, opts) {
|
|
|
204
205
|
`wrong value resolves back to just the parents. ` +
|
|
205
206
|
`See the connector guide's parent-field loop.`;
|
|
206
207
|
}
|
|
207
|
-
throw new
|
|
208
|
+
throw new CompileRefusal('CONNECTOR_INPUT', `connector ${rc.nodeType}: ${errs.join('; ')}. Required fields: ${req}.${hint}`);
|
|
208
209
|
}
|
|
209
210
|
// Every declared part, in declaration order, as the designer lists them: the
|
|
210
211
|
// container part valueless, a file part with the author's value when given. A
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* the connector library from disk, so `serialize` can recognise the refusal
|
|
4
4
|
* without loading `node:fs` (FB015). `core/library.ts` re-exports both.
|
|
5
5
|
*/
|
|
6
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
6
7
|
/** Why `Library.resolve` refused a connector action. */
|
|
7
8
|
export type ConnectorResolveCode =
|
|
8
9
|
/** The library carries no such operation (or no such connector, or not at that version). */
|
|
@@ -29,7 +30,7 @@ export type ConnectorResolveCode =
|
|
|
29
30
|
* text: `check` reports it under this code with this message, and a compile
|
|
30
31
|
* that throws it carries the same code into its `--json` diagnostics (#948).
|
|
31
32
|
*/
|
|
32
|
-
export declare class ConnectorResolveError extends
|
|
33
|
+
export declare class ConnectorResolveError extends CompileRefusal {
|
|
33
34
|
readonly code: ConnectorResolveCode;
|
|
34
35
|
constructor(code: ConnectorResolveCode, message: string);
|
|
35
36
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* the connector library from disk, so `serialize` can recognise the refusal
|
|
4
4
|
* without loading `node:fs` (FB015). `core/library.ts` re-exports both.
|
|
5
5
|
*/
|
|
6
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
6
7
|
/**
|
|
7
8
|
* The refusal `Library.resolve` throws, with a `code` for each reason.
|
|
8
9
|
*
|
|
@@ -10,11 +11,9 @@
|
|
|
10
11
|
* text: `check` reports it under this code with this message, and a compile
|
|
11
12
|
* that throws it carries the same code into its `--json` diagnostics (#948).
|
|
12
13
|
*/
|
|
13
|
-
export class ConnectorResolveError extends
|
|
14
|
-
code;
|
|
14
|
+
export class ConnectorResolveError extends CompileRefusal {
|
|
15
15
|
constructor(code, message) {
|
|
16
|
-
super(message);
|
|
16
|
+
super(code, message);
|
|
17
17
|
this.name = 'ConnectorResolveError';
|
|
18
|
-
this.code = code;
|
|
19
18
|
}
|
|
20
19
|
}
|
package/dist/core/connectors.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* arrays; `buildConnectorInputs` validates them and projects them back to the
|
|
22
22
|
* registry's flat field ids when emitting Flow JSON.
|
|
23
23
|
*/
|
|
24
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
24
25
|
/**
|
|
25
26
|
* Brand a descriptor literal with its input/output types (zero runtime cost).
|
|
26
27
|
* Used by codegen: `descriptor<CreateIssueInputs, CreateIssueOutputs>()({ … } as const)`.
|
|
@@ -49,7 +50,7 @@ export function splitConnectorNodeType(nodeType) {
|
|
|
49
50
|
const rest = nodeType.replace(/^uipath\.connector\./, '');
|
|
50
51
|
const dot = rest.lastIndexOf('.');
|
|
51
52
|
if (dot <= 0)
|
|
52
|
-
throw new
|
|
53
|
+
throw new CompileRefusal('CONNECTOR_NODE_TYPE_INVALID', `invalid connector nodeType "${nodeType}" (expected uipath.connector.<key>.<action>).`);
|
|
53
54
|
return { key: rest.slice(0, dot), action: rest.slice(dot + 1) };
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
* matches.
|
|
36
36
|
*/
|
|
37
37
|
import { ownEntry } from './own-entry.js';
|
|
38
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
38
39
|
/** The designer's operator vocabulary this SDK emits, keyed by the authored key. */
|
|
39
40
|
export const EVENT_FILTER_OPERATORS = {
|
|
40
41
|
contains: { designer: 'Contains', kind: 'function', jmes: 'contains' },
|
|
@@ -136,7 +137,7 @@ export function eventFilterProblem(read) {
|
|
|
136
137
|
export function jmesString(value) {
|
|
137
138
|
const problem = jmesStringProblem(value);
|
|
138
139
|
if (problem)
|
|
139
|
-
throw new
|
|
140
|
+
throw new CompileRefusal('EVENT_FILTER_BACKSLASH', `jmesString: ${problem}`);
|
|
140
141
|
return `'${value.replace(/'/g, "\\'")}'`;
|
|
141
142
|
}
|
|
142
143
|
/** A backslash whose raw-string reading depends on the engine: before `\` or `'`, or last. */
|
|
@@ -1,83 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* How a human task leaves its node — the one model `serialize`, `check` and
|
|
3
|
-
* `.stepSwitch` (`step-ports.ts`) all read, so the three cannot drift. They did
|
|
4
|
-
* drift once, in the direction that matters least visibly: `check` keyed on the
|
|
5
|
-
* `outcomePorts` FLAG while `serialize` was about to infer it, which would have
|
|
6
|
-
* made `check` refuse per-outcome wiring that `compile` then emitted.
|
|
7
|
-
*
|
|
8
|
-
* **The product's rule, which the model follows.** On the base node
|
|
9
|
-
* (`uipath.human-in-the-loop`, `type: 'quick'`) and on the quick-form variant,
|
|
10
|
-
* the designer draws ONE handle per entry in `inputs.schema.outcomes`, named
|
|
11
|
-
* `outcome-<id>`, whatever the node's `typeVersion` — and draws the manifest's
|
|
12
|
-
* static `completed` handle only when there are no outcomes
|
|
13
|
-
* (flow-workbench `build-handle-customization.ts:102-124`; it derives them on
|
|
14
|
-
* every render and deliberately never saves them). A leftover `completed` edge
|
|
15
|
-
* on such a node is a stale placeholder: since flow-workbench #3512 the load
|
|
16
|
-
* path and the converter remap it to the PRIMARY outcome
|
|
17
|
-
* (`hitl-edge-reconciliation.ts:52-63`), so every other outcome loses its path at
|
|
18
|
-
* run time. So a task with outcomes never leaves on `completed` here. The two
|
|
19
|
-
* app-backed variants are different: action-app and document-validation read
|
|
20
|
-
* their outcomes from `inputs.app`, and `completed` really is the only handle
|
|
21
|
-
* they render (`hitl-edge-reconciliation.ts:68-74`).
|
|
22
|
-
*
|
|
23
|
-
* (This replaces an older premise — "the definition VERSION selects the port
|
|
24
|
-
* shape, and the variants have no per-outcome version" (#729). The manifests do
|
|
25
|
-
* declare only `completed` statically; the designer just never reads that list
|
|
26
|
-
* for these two node types once outcomes exist.)
|
|
27
|
-
*
|
|
28
|
-
* **Three shapes**, and what `.step()` after the task means in each — ".step()
|
|
29
|
-
* continues from the task's tails":
|
|
30
|
-
*
|
|
31
|
-
* - `per-outcome`: the task ROUTES per outcome. One tail, the PRIMARY (first)
|
|
32
|
-
* outcome's `outcome-<id>`; the author routes the rest with `.stepToList` /
|
|
33
|
-
* `.stepToRef`, or all of them as `.stepSwitch` arms.
|
|
34
|
-
* - `every-outcome`: the task does NOT route per outcome. One tail PER outcome,
|
|
35
|
-
* so `.step()` continues every outcome to the next step ("fan-out") — the
|
|
36
|
-
* decision reaches the flow as data, `out('<step>', 'Action')`, in the handles
|
|
37
|
-
* the product draws. An `action: 'End'` outcome is the exception: the flow
|
|
38
|
-
* runtime never reads `action` (flow-workbench `hitl-serialization.ts` does
|
|
39
|
-
* not; only the agent storage projection does), so the graph is the only thing
|
|
40
|
-
* that can end the run there, and `serialize` gives it an End node.
|
|
41
|
-
* - `placeholder`: `completed` — action-app, document-validation, and a task
|
|
42
|
-
* with no outcomes.
|
|
43
|
-
*
|
|
44
|
-
* **More than one outcome infers `per-outcome`** on the base node (#739): a task
|
|
45
|
-
* that publishes a choice and then routes every button the same way was the
|
|
46
|
-
* modelling error behind flow-builder-sdk#735, and a warning alone did not
|
|
47
|
-
* change what agents emitted. Five things keep a base or quick-form task on
|
|
48
|
-
* `every-outcome` instead, in this order:
|
|
49
|
-
*
|
|
50
|
-
* 1. `outcomePorts: false` — the explicit "decision as data" choice.
|
|
51
|
-
* 2. `variant: 'quick-form'`. Not a product limit — quick-form draws the same
|
|
52
|
-
* per-outcome handles — but its authors write `.step()` or a `.switch` on the
|
|
53
|
-
* Action after it and mean "every outcome continues" (every quick-form source
|
|
54
|
-
* in the 09-23 baseline does), so inferring primary-only there would strand
|
|
55
|
-
* the other outcomes. It routes per outcome when asked: `outcomePorts: true`,
|
|
56
|
-
* or `.stepSwitch`. Its definition version never moves.
|
|
57
|
-
* 3. An explicit `{ version }` pin. `decompile` pins every node and writes
|
|
58
|
-
* `outcomePorts: true` whenever a task's outcomes lead to different places, so
|
|
59
|
-
* a pinned task that reaches `.step()` without the flag is a round-tripped
|
|
60
|
-
* artifact whose outcomes all go to one step, or a legacy lone `completed`
|
|
61
|
-
* edge, which meant "every outcome continues" before #3512. Both are this
|
|
62
|
-
* shape. The pin also wins the version: `outcomePorts: true` on a pinned 1.0
|
|
63
|
-
* routes per outcome on the 1.0 node, which `flow validate` accepts.
|
|
64
|
-
* 4. A single outcome — an acknowledgement, not a choice.
|
|
65
|
-
* 5. Every outcome carrying `action: 'End'` — there is no continuation to
|
|
66
|
-
* distinguish, and each outcome gets its End.
|
|
67
|
-
*
|
|
68
|
-
* `exposeError: true` or `outcomePorts: true` select `per-outcome` on every node
|
|
69
|
-
* type, including the two app-backed variants, so that `serialize` and `check`
|
|
70
|
-
* refuse them there with their own message rather than silently ignoring them.
|
|
71
|
-
*
|
|
72
|
-
* **`legacyCompleted: true`** is the one way to keep a task with outcomes on the
|
|
73
|
-
* `completed` handle: the `placeholder` shape, marked `legacyCompleted`. It
|
|
74
|
-
* exists so a file saved before flow-workbench #3512, whose task leaves on one
|
|
75
|
-
* `completed` edge, round-trips through decompile and compile unchanged
|
|
76
|
-
* (flow-builder-sdk#1197). It is the file's shape, not one to author: the
|
|
77
|
-
* product runs that edge as the PRIMARY outcome only, and `check` says so
|
|
78
|
-
* (HITL_LEGACY_COMPLETED). `serialize`'s edge guard below exempts exactly the
|
|
79
|
-
* nodes that asked for it.
|
|
80
|
-
*/
|
|
81
1
|
/**
|
|
82
2
|
* The fields of a human task's inputs the routing model reads — structural, so
|
|
83
3
|
* this module stays in `core/` while the authoring type (`HitlInputs`) belongs
|
|
@@ -155,7 +75,9 @@ type EdgeLike = {
|
|
|
155
75
|
sourcePort?: unknown;
|
|
156
76
|
};
|
|
157
77
|
/**
|
|
158
|
-
* Why an edge on `port` cannot leave `node
|
|
78
|
+
* Why an edge on `port` cannot leave `node` — the code and the sentence — or
|
|
79
|
+
* `undefined` when it can. The code is `check`'s for the same edge, so both
|
|
80
|
+
* call sites throw what this returns.
|
|
159
81
|
*
|
|
160
82
|
* Only the two node types whose handles the product derives from the outcomes
|
|
161
83
|
* are judged, and only once they HAVE outcomes: then `completed` is a handle
|
|
@@ -165,7 +87,10 @@ type EdgeLike = {
|
|
|
165
87
|
* bare `completed` never is, unless the task asked for it with
|
|
166
88
|
* `legacyCompleted: true` (`legacyCompleted` here).
|
|
167
89
|
*/
|
|
168
|
-
export declare function hitlExitViolation(node: NodeLike, port: string, legacyCompleted?: boolean):
|
|
90
|
+
export declare function hitlExitViolation(node: NodeLike, port: string, legacyCompleted?: boolean): {
|
|
91
|
+
code: 'HITL_COMPLETED_PORT_GONE' | 'HITL_OUTCOME_PORT_UNKNOWN';
|
|
92
|
+
message: string;
|
|
93
|
+
} | undefined;
|
|
169
94
|
/**
|
|
170
95
|
* The post-emit half of the guard: every edge of an emitted scope, whatever
|
|
171
96
|
* path produced it (a tail, a `.stepToList` seed, a parked `.stepToRef`), is held
|
|
@@ -1,3 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a human task leaves its node — the one model `serialize`, `check` and
|
|
3
|
+
* `.stepSwitch` (`step-ports.ts`) all read, so the three cannot drift. They did
|
|
4
|
+
* drift once, in the direction that matters least visibly: `check` keyed on the
|
|
5
|
+
* `outcomePorts` FLAG while `serialize` was about to infer it, which would have
|
|
6
|
+
* made `check` refuse per-outcome wiring that `compile` then emitted.
|
|
7
|
+
*
|
|
8
|
+
* **The product's rule, which the model follows.** On the base node
|
|
9
|
+
* (`uipath.human-in-the-loop`, `type: 'quick'`) and on the quick-form variant,
|
|
10
|
+
* the designer draws ONE handle per entry in `inputs.schema.outcomes`, named
|
|
11
|
+
* `outcome-<id>`, whatever the node's `typeVersion` — and draws the manifest's
|
|
12
|
+
* static `completed` handle only when there are no outcomes
|
|
13
|
+
* (flow-workbench `build-handle-customization.ts:102-124`; it derives them on
|
|
14
|
+
* every render and deliberately never saves them). A leftover `completed` edge
|
|
15
|
+
* on such a node is a stale placeholder: since flow-workbench #3512 the load
|
|
16
|
+
* path and the converter remap it to the PRIMARY outcome
|
|
17
|
+
* (`hitl-edge-reconciliation.ts:52-63`), so every other outcome loses its path at
|
|
18
|
+
* run time. So a task with outcomes never leaves on `completed` here. The two
|
|
19
|
+
* app-backed variants are different: action-app and document-validation read
|
|
20
|
+
* their outcomes from `inputs.app`, and `completed` really is the only handle
|
|
21
|
+
* they render (`hitl-edge-reconciliation.ts:68-74`).
|
|
22
|
+
*
|
|
23
|
+
* (This replaces an older premise — "the definition VERSION selects the port
|
|
24
|
+
* shape, and the variants have no per-outcome version" (#729). The manifests do
|
|
25
|
+
* declare only `completed` statically; the designer just never reads that list
|
|
26
|
+
* for these two node types once outcomes exist.)
|
|
27
|
+
*
|
|
28
|
+
* **Three shapes**, and what `.step()` after the task means in each — ".step()
|
|
29
|
+
* continues from the task's tails":
|
|
30
|
+
*
|
|
31
|
+
* - `per-outcome`: the task ROUTES per outcome. One tail, the PRIMARY (first)
|
|
32
|
+
* outcome's `outcome-<id>`; the author routes the rest with `.stepToList` /
|
|
33
|
+
* `.stepToRef`, or all of them as `.stepSwitch` arms.
|
|
34
|
+
* - `every-outcome`: the task does NOT route per outcome. One tail PER outcome,
|
|
35
|
+
* so `.step()` continues every outcome to the next step ("fan-out") — the
|
|
36
|
+
* decision reaches the flow as data, `out('<step>', 'Action')`, in the handles
|
|
37
|
+
* the product draws. An `action: 'End'` outcome is the exception: the flow
|
|
38
|
+
* runtime never reads `action` (flow-workbench `hitl-serialization.ts` does
|
|
39
|
+
* not; only the agent storage projection does), so the graph is the only thing
|
|
40
|
+
* that can end the run there, and `serialize` gives it an End node.
|
|
41
|
+
* - `placeholder`: `completed` — action-app, document-validation, and a task
|
|
42
|
+
* with no outcomes.
|
|
43
|
+
*
|
|
44
|
+
* **More than one outcome infers `per-outcome`** on the base node (#739): a task
|
|
45
|
+
* that publishes a choice and then routes every button the same way was the
|
|
46
|
+
* modelling error behind flow-builder-sdk#735, and a warning alone did not
|
|
47
|
+
* change what agents emitted. Five things keep a base or quick-form task on
|
|
48
|
+
* `every-outcome` instead, in this order:
|
|
49
|
+
*
|
|
50
|
+
* 1. `outcomePorts: false` — the explicit "decision as data" choice.
|
|
51
|
+
* 2. `variant: 'quick-form'`. Not a product limit — quick-form draws the same
|
|
52
|
+
* per-outcome handles — but its authors write `.step()` or a `.switch` on the
|
|
53
|
+
* Action after it and mean "every outcome continues" (every quick-form source
|
|
54
|
+
* in the 09-23 baseline does), so inferring primary-only there would strand
|
|
55
|
+
* the other outcomes. It routes per outcome when asked: `outcomePorts: true`,
|
|
56
|
+
* or `.stepSwitch`. Its definition version never moves.
|
|
57
|
+
* 3. An explicit `{ version }` pin. `decompile` pins every node and writes
|
|
58
|
+
* `outcomePorts: true` whenever a task's outcomes lead to different places, so
|
|
59
|
+
* a pinned task that reaches `.step()` without the flag is a round-tripped
|
|
60
|
+
* artifact whose outcomes all go to one step, or a legacy lone `completed`
|
|
61
|
+
* edge, which meant "every outcome continues" before #3512. Both are this
|
|
62
|
+
* shape. The pin also wins the version: `outcomePorts: true` on a pinned 1.0
|
|
63
|
+
* routes per outcome on the 1.0 node, which `flow validate` accepts.
|
|
64
|
+
* 4. A single outcome — an acknowledgement, not a choice.
|
|
65
|
+
* 5. Every outcome carrying `action: 'End'` — there is no continuation to
|
|
66
|
+
* distinguish, and each outcome gets its End.
|
|
67
|
+
*
|
|
68
|
+
* `exposeError: true` or `outcomePorts: true` select `per-outcome` on every node
|
|
69
|
+
* type, including the two app-backed variants, so that `serialize` and `check`
|
|
70
|
+
* refuse them there with their own message rather than silently ignoring them.
|
|
71
|
+
*
|
|
72
|
+
* **`legacyCompleted: true`** is the one way to keep a task with outcomes on the
|
|
73
|
+
* `completed` handle: the `placeholder` shape, marked `legacyCompleted`. It
|
|
74
|
+
* exists so a file saved before flow-workbench #3512, whose task leaves on one
|
|
75
|
+
* `completed` edge, round-trips through decompile and compile unchanged
|
|
76
|
+
* (flow-builder-sdk#1197). It is the file's shape, not one to author: the
|
|
77
|
+
* product runs that edge as the PRIMARY outcome only, and `check` says so
|
|
78
|
+
* (HITL_LEGACY_COMPLETED). `serialize`'s edge guard below exempts exactly the
|
|
79
|
+
* nodes that asked for it.
|
|
80
|
+
*/
|
|
81
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
1
82
|
/**
|
|
2
83
|
* An outcome's stable id — the slug that names its `outcome-<id>` port.
|
|
3
84
|
*
|
|
@@ -90,7 +171,9 @@ function outcomeIdsOf(node) {
|
|
|
90
171
|
return outcomes.map((o) => o?.id).filter((id) => typeof id === 'string' && id !== '');
|
|
91
172
|
}
|
|
92
173
|
/**
|
|
93
|
-
* Why an edge on `port` cannot leave `node
|
|
174
|
+
* Why an edge on `port` cannot leave `node` — the code and the sentence — or
|
|
175
|
+
* `undefined` when it can. The code is `check`'s for the same edge, so both
|
|
176
|
+
* call sites throw what this returns.
|
|
94
177
|
*
|
|
95
178
|
* Only the two node types whose handles the product derives from the outcomes
|
|
96
179
|
* are judged, and only once they HAVE outcomes: then `completed` is a handle
|
|
@@ -110,12 +193,18 @@ export function hitlExitViolation(node, port, legacyCompleted = false) {
|
|
|
110
193
|
if (port === 'completed') {
|
|
111
194
|
if (legacyCompleted)
|
|
112
195
|
return undefined;
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
|
|
196
|
+
return {
|
|
197
|
+
code: 'HITL_COMPLETED_PORT_GONE',
|
|
198
|
+
message: `human task "${String(node.id)}" has outcomes (${declared}), so the product draws no `
|
|
199
|
+
+ `'completed' handle on it — an edge there is remapped to the primary outcome and every other `
|
|
200
|
+
+ `outcome loses its path.`,
|
|
201
|
+
};
|
|
116
202
|
}
|
|
117
203
|
if (port.startsWith('outcome-') && !ids.includes(port.slice('outcome-'.length))) {
|
|
118
|
-
return
|
|
204
|
+
return {
|
|
205
|
+
code: 'HITL_OUTCOME_PORT_UNKNOWN',
|
|
206
|
+
message: `human task "${String(node.id)}" has no outcome for port "${port}" — it declares ${declared}.`,
|
|
207
|
+
};
|
|
119
208
|
}
|
|
120
209
|
return undefined;
|
|
121
210
|
}
|
|
@@ -135,6 +224,6 @@ export function assertHitlExitInvariant(nodes, edges, legacyCompleted = new Set(
|
|
|
135
224
|
continue;
|
|
136
225
|
const why = hitlExitViolation(node, String(e.sourcePort), legacyCompleted.has(String(e.sourceNodeId)));
|
|
137
226
|
if (why)
|
|
138
|
-
throw new
|
|
227
|
+
throw new CompileRefusal(why.code, `serialize: ${why.message}`);
|
|
139
228
|
}
|
|
140
229
|
}
|
package/dist/core/library.js
CHANGED
|
@@ -14,6 +14,7 @@ import { lookupSpecOf } from './lookups.js';
|
|
|
14
14
|
import { loadByoaLedger, loadInvariantCollections, loadLookupResolutions } from './lookup-store.js';
|
|
15
15
|
import { ownEntry } from './own-entry.js';
|
|
16
16
|
import { ConnectorResolveError } from './connector-resolve-error.js';
|
|
17
|
+
import { CompileRefusal } from './compile-refusal.js';
|
|
17
18
|
export { ConnectorResolveError } from './connector-resolve-error.js';
|
|
18
19
|
export class Library {
|
|
19
20
|
layers = [];
|
|
@@ -59,7 +60,7 @@ export class Library {
|
|
|
59
60
|
const idx = libraryPath(dir, 'index.json');
|
|
60
61
|
const entries = libraryEntries(read, idx);
|
|
61
62
|
if (entries === undefined)
|
|
62
|
-
throw new
|
|
63
|
+
throw new CompileRefusal('LIBRARY_NOT_FOUND', `connector library not found at ${idx}. `
|
|
63
64
|
+ (read === readTextFromDisk
|
|
64
65
|
? `Run \`${PULL_COMMAND}\`, or point --library / $FLOW_SDK_LIBRARY_JSON at a library-json dir.`
|
|
65
66
|
: 'The reader passed to Library has no such file.'));
|
|
@@ -292,7 +293,7 @@ export class Library {
|
|
|
292
293
|
};
|
|
293
294
|
}
|
|
294
295
|
}
|
|
295
|
-
throw new
|
|
296
|
+
throw new CompileRefusal('CONNECTOR_NOT_IN_LIBRARY', `connector activity not found in library: ${wire.connectorKey} ${wire.httpMethod ?? '?'} ${wire.endpoint ?? '?'}`);
|
|
296
297
|
}
|
|
297
298
|
/**
|
|
298
299
|
* Resolve a connector EVENT: the START trigger
|
|
@@ -393,7 +394,7 @@ export class Library {
|
|
|
393
394
|
};
|
|
394
395
|
}
|
|
395
396
|
}
|
|
396
|
-
throw new
|
|
397
|
+
throw new CompileRefusal('EVENT_UNKNOWN', `connector ${kind} event not found in library: ${wire.connectorKey} `
|
|
397
398
|
+ `${wire.eventOperation ?? '?'} ${wire.objectName ?? '?'}`);
|
|
398
399
|
}
|
|
399
400
|
/**
|