@uipath/maestro-builder-sdk 6.14.4 → 6.15.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.
- package/dist/api-index.md +129 -129
- package/dist/api-members.md +420 -416
- package/dist/bpmn/bpmn-sdk.d.ts +16 -0
- package/dist/bpmn/bpmn-sdk.js +2 -0
- package/dist/bpmn/check-cli.js +22 -5
- package/dist/bpmn/check.d.ts +15 -1
- package/dist/bpmn/check.js +69 -2
- package/dist/bpmn/compile-cli.js +24 -14
- package/dist/bpmn/connector.js +29 -14
- package/dist/bpmn/intsvc.js +5 -2
- package/dist/bpmn/serialize.d.ts +2 -0
- package/dist/bpmn/serialize.js +1 -1
- package/dist/case/compile-cli.js +6 -9
- package/dist/case/serialize.js +1 -1
- package/dist/check-cli.js +6 -35
- package/dist/check.d.ts +16 -148
- package/dist/check.js +53 -711
- package/dist/cli/commands/bpmn.js +15 -0
- package/dist/cli-library.d.ts +6 -25
- package/dist/cli-library.js +6 -73
- package/dist/compile-cli.js +14 -8
- package/dist/core/actions.d.ts +19 -0
- package/dist/core/cli-library.d.ts +47 -0
- package/dist/core/cli-library.js +150 -0
- package/dist/core/connector-checks.d.ts +226 -0
- package/dist/core/connector-checks.js +518 -0
- package/dist/core/connector-inputs.d.ts +80 -0
- package/dist/core/connector-inputs.js +453 -0
- package/dist/core/event-checks.d.ts +137 -0
- package/dist/core/event-checks.js +321 -0
- package/dist/decompile.js +1 -1
- package/dist/registry/generators/markdown/sections/example.d.ts +7 -1
- package/dist/registry/generators/markdown/sections/example.js +70 -5
- package/dist/registry/generators/markdown/sections/lookups.js +29 -8
- package/dist/registry/prepare/messages.js +6 -1
- package/dist/registry/prepare/source-import.d.ts +3 -3
- package/dist/registry/prepare/source-import.js +15 -4
- package/dist/registry/prepare/source-labels.js +31 -4
- package/dist/serialize.d.ts +11 -11
- package/dist/serialize.js +285 -428
- package/lib/README.md +1 -0
- package/lib/library-json.samples/index.json +9 -0
- package/lib/library-json.samples/uipath-uipath-airdk/web-search@1.0.0.json +118 -0
- package/lib/library-json.samples/uipath-uipath-airdk/web-search@1.0.0.v1def.json +258 -0
- package/package.json +2 -2
- /package/dist/{event-filters.d.ts → core/event-filters.d.ts} +0 -0
- /package/dist/{event-filters.js → core/event-filters.js} +0 -0
|
@@ -7,11 +7,17 @@ export function registerBpmnCommands(program) {
|
|
|
7
7
|
.option('-o, --output <file>', 'output .bpmn path')
|
|
8
8
|
.option('--library <dir>', 'connector library directory')
|
|
9
9
|
.option('--bindings <file>', 'bindings.json path')
|
|
10
|
+
// The overlay `registry prepare` writes, as Flow's compile takes it. This
|
|
11
|
+
// CLI parses with Commander and `exitOverride()`s, so an option it does not
|
|
12
|
+
// declare is an `unknown option` BEFORE compile-cli sees argv — reading the
|
|
13
|
+
// flag in compile-cli is necessary and not sufficient.
|
|
14
|
+
.option('--connectors-local <dir>', 'connection-resolved connector overlay')
|
|
10
15
|
.action(async (source, options) => {
|
|
11
16
|
const argv = [source];
|
|
12
17
|
addValue(argv, '-o', options.output);
|
|
13
18
|
addValue(argv, '--library', options.library);
|
|
14
19
|
addValue(argv, '--bindings', options.bindings);
|
|
20
|
+
addValue(argv, '--connectors-local', options.connectorsLocal);
|
|
15
21
|
await invoke('bpmn compile', () => loadTool(import.meta.url, '../../bpmn/compile-cli.js'), argv);
|
|
16
22
|
});
|
|
17
23
|
family.command('check')
|
|
@@ -19,6 +25,12 @@ export function registerBpmnCommands(program) {
|
|
|
19
25
|
.argument('<input>', 'a .bpmn.ts path or bare name')
|
|
20
26
|
.option('--source', 'check authored TypeScript')
|
|
21
27
|
.option('--graph', 'also print the resolved wiring: every element with the flows leaving it, implied edges marked ~>')
|
|
28
|
+
// The library and its overlay, as Flow's check takes them: `check` reads
|
|
29
|
+
// the connector corpus now, and an option this parser does not declare is
|
|
30
|
+
// `unknown option` before check-cli sees argv.
|
|
31
|
+
.option('--library <dir>', 'connector library directory')
|
|
32
|
+
.option('--connectors-local <dir>', 'connection-resolved connector overlay')
|
|
33
|
+
.option('--bindings <file>', 'bindings.json path')
|
|
22
34
|
.addOption(retiredCompiledOption())
|
|
23
35
|
.action(async (input, options) => {
|
|
24
36
|
let mode;
|
|
@@ -36,6 +48,9 @@ export function registerBpmnCommands(program) {
|
|
|
36
48
|
const argv = [input];
|
|
37
49
|
if (options.graph)
|
|
38
50
|
argv.push('--graph');
|
|
51
|
+
addValue(argv, '--library', options.library);
|
|
52
|
+
addValue(argv, '--connectors-local', options.connectorsLocal);
|
|
53
|
+
addValue(argv, '--bindings', options.bindings);
|
|
39
54
|
await invoke('bpmn check', () => loadTool(import.meta.url, '../../bpmn/check-cli.js'), argv);
|
|
40
55
|
});
|
|
41
56
|
family.command('tidy')
|
package/dist/cli-library.d.ts
CHANGED
|
@@ -1,28 +1,9 @@
|
|
|
1
|
-
import type { CheckOpts } from './check.js';
|
|
2
|
-
import { Library } from './library.js';
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
2
|
+
* cli-library — compatibility re-export.
|
|
5
3
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* How a CLI opens the connector library and its `connectors-local/` overlay, and
|
|
5
|
+
* the event verdicts `check` shares with `compile`, all moved to
|
|
6
|
+
* `core/cli-library.ts` when BPMN's `compile` and `check` needed the same things.
|
|
7
|
+
* This shim preserves the historical `./cli-library.js` import path.
|
|
10
8
|
*/
|
|
11
|
-
export
|
|
12
|
-
/**
|
|
13
|
-
* `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
|
|
14
|
-
* for a subscription, or `undefined` when it resolves.
|
|
15
|
-
*
|
|
16
|
-
* This is the call `serialize` makes for `onEvent` (kind `trigger`, for the
|
|
17
|
-
* flow's trigger and each entry point) and for `waitForEvent` (kind `event`),
|
|
18
|
-
* with the subscription's own `version` and `object`, so check reports an error
|
|
19
|
-
* exactly when compile would throw, with the same text.
|
|
20
|
-
*/
|
|
21
|
-
export declare function eventResolveErrorFor(library: Library): NonNullable<CheckOpts['eventResolveError']>;
|
|
22
|
-
/**
|
|
23
|
-
* `check`'s EVENT_BYOA_UNVERIFIED inputs: the event facts and the recorded BYOA
|
|
24
|
-
* checks, from the same `library.eventFacts` / `library.byoaVerifications` that
|
|
25
|
-
* `serialize` reads for the same refusal. Both CLIs spread this into their
|
|
26
|
-
* check options, so the inner loop and the emit rung refuse the same flows.
|
|
27
|
-
*/
|
|
28
|
-
export declare function byoaCheckOpts(library: Library): Pick<CheckOpts, 'eventFacts' | 'byoa'>;
|
|
9
|
+
export { openCliLibrary, flagValue, connectorCheckOpts, eventResolveErrorFor, byoaCheckOpts } from './core/cli-library.js';
|
package/dist/cli-library.js
CHANGED
|
@@ -1,76 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* cli-library —
|
|
3
|
-
* `check` shares with `compile`.
|
|
2
|
+
* cli-library — compatibility re-export.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the library cannot resolve an event, so a different library would make check
|
|
10
|
-
* refuse a source compile accepts. Both CLIs open it here instead.
|
|
4
|
+
* How a CLI opens the connector library and its `connectors-local/` overlay, and
|
|
5
|
+
* the event verdicts `check` shares with `compile`, all moved to
|
|
6
|
+
* `core/cli-library.ts` when BPMN's `compile` and `check` needed the same things.
|
|
7
|
+
* This shim preserves the historical `./cli-library.js` import path.
|
|
11
8
|
*/
|
|
12
|
-
|
|
13
|
-
import { join } from 'node:path';
|
|
14
|
-
import { Library } from './library.js';
|
|
15
|
-
import { resolveLibraryDir } from './registry/cache.js';
|
|
16
|
-
import { defaultOverlayDir } from './workdir.js';
|
|
17
|
-
/** The value after `name` in `argv`, or `undefined`. */
|
|
18
|
-
function flagValue(argv, name) {
|
|
19
|
-
const i = argv.indexOf(name);
|
|
20
|
-
return i >= 0 ? argv[i + 1] : undefined;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* The library for this invocation, or `undefined` when there is none.
|
|
24
|
-
*
|
|
25
|
-
* `--library <dir>`, else `$FLOW_SDK_LIBRARY_JSON`, else the cache `registry
|
|
26
|
-
* pull` filled (`resolveLibraryDir`). The overlay is `--connectors-local <dir>`,
|
|
27
|
-
* else `.flow-sdk/connectors-local` (or a legacy `./connectors-local`) when it has an `index.json` — the directory
|
|
28
|
-
* `registry prepare` writes by default.
|
|
29
|
-
*/
|
|
30
|
-
export function openCliLibrary(argv) {
|
|
31
|
-
const libDir = resolveLibraryDir(flagValue(argv, '--library'));
|
|
32
|
-
if (!libDir || !existsSync(join(libDir, 'index.json')))
|
|
33
|
-
return undefined;
|
|
34
|
-
const overlayDir = flagValue(argv, '--connectors-local')
|
|
35
|
-
?? defaultOverlayDir();
|
|
36
|
-
return new Library(libDir, { overlayDir });
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
|
|
40
|
-
* for a subscription, or `undefined` when it resolves.
|
|
41
|
-
*
|
|
42
|
-
* This is the call `serialize` makes for `onEvent` (kind `trigger`, for the
|
|
43
|
-
* flow's trigger and each entry point) and for `waitForEvent` (kind `event`),
|
|
44
|
-
* with the subscription's own `version` and `object`, so check reports an error
|
|
45
|
-
* exactly when compile would throw, with the same text.
|
|
46
|
-
*/
|
|
47
|
-
export function eventResolveErrorFor(library) {
|
|
48
|
-
return (kind, sub) => {
|
|
49
|
-
try {
|
|
50
|
-
library.resolveEvent(kind, sub.connector, sub.event, sub.version, sub.object);
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
return error instanceof Error ? error.message : String(error);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* `check`'s EVENT_BYOA_UNVERIFIED inputs: the event facts and the recorded BYOA
|
|
60
|
-
* checks, from the same `library.eventFacts` / `library.byoaVerifications` that
|
|
61
|
-
* `serialize` reads for the same refusal. Both CLIs spread this into their
|
|
62
|
-
* check options, so the inner loop and the emit rung refuse the same flows.
|
|
63
|
-
*/
|
|
64
|
-
export function byoaCheckOpts(library) {
|
|
65
|
-
return {
|
|
66
|
-
eventFacts: (connector, event, object) => {
|
|
67
|
-
try {
|
|
68
|
-
return library.eventFacts(connector, event, object);
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return undefined; // unknown fails open, same as every library callback
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
byoa: library.byoaVerifications,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
9
|
+
export { openCliLibrary, flagValue, connectorCheckOpts, eventResolveErrorFor, byoaCheckOpts } from './core/cli-library.js';
|
package/dist/compile-cli.js
CHANGED
|
@@ -36,20 +36,24 @@ function opt(argv, name) {
|
|
|
36
36
|
return i >= 0 ? argv[i + 1] : undefined;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
* The
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
39
|
+
* The tool `type` values `compile` writes. NOT every `$resourceType: 'tool'`:
|
|
40
|
+
* the designer writes kinds the SDK cannot derive into the same directory, so
|
|
41
|
+
* pruning by `$resourceType` alone would delete theirs.
|
|
42
|
+
*
|
|
43
|
+
* `integration` (connector tools) is compile's since #867: compile writes the
|
|
44
|
+
* file under the tool node's own `source` id, the same id and content `uip agent
|
|
45
|
+
* refresh --inline-in-flow` derives from that node, so a file under any other id
|
|
46
|
+
* belongs to a tool node the flow no longer has.
|
|
43
47
|
*/
|
|
44
48
|
const COMPILE_OWNED_TOOL_TYPES = new Set([
|
|
45
|
-
'process', 'api', 'processOrchestration', 'flow', 'agent', 'function',
|
|
49
|
+
'process', 'api', 'processOrchestration', 'flow', 'agent', 'function', 'integration',
|
|
46
50
|
]);
|
|
47
51
|
/**
|
|
48
52
|
* Does `compile` own this resource file — i.e. would this run have written it,
|
|
49
53
|
* so an unwritten one is stale rather than someone else's?
|
|
50
54
|
*
|
|
51
|
-
* Everything it says no to belongs to
|
|
52
|
-
*
|
|
55
|
+
* Everything it says no to belongs to the designer (escalation, mcp, and the
|
|
56
|
+
* kinds the SDK cannot derive).
|
|
53
57
|
*/
|
|
54
58
|
function compileOwnsResource(body) {
|
|
55
59
|
const kind = body?.$resourceType;
|
|
@@ -236,7 +240,9 @@ export async function run(argv) {
|
|
|
236
240
|
// fail on it. Keyed the way refresh keys it — an index by its name.
|
|
237
241
|
const named = body?.indexName ?? body?.name;
|
|
238
242
|
const key = typeof named === 'string' && named !== '' ? named : undefined;
|
|
239
|
-
|
|
243
|
+
// A connector tool's binding is a `connection` row, and `mergeBindingsV2`
|
|
244
|
+
// re-derives every connection row from the flow below — nothing to retract.
|
|
245
|
+
if (key !== undefined && body?.type !== 'integration') {
|
|
240
246
|
// Keyed the way refresh keys it: an index by its name, a deployed-resource
|
|
241
247
|
// tool under `process` whatever its own type says.
|
|
242
248
|
staleBindings.push({ resource: resourceType === 'context' ? 'index' : 'process', key });
|
package/dist/core/actions.d.ts
CHANGED
|
@@ -1806,6 +1806,25 @@ export interface ConnectorToolRef {
|
|
|
1806
1806
|
object?: string;
|
|
1807
1807
|
/** Display label; defaults to the library's own (e.g. `'Create Issue'`). */
|
|
1808
1808
|
name?: string;
|
|
1809
|
+
/**
|
|
1810
|
+
* What the agent is told the tool does — the runtime hands it to the MODEL.
|
|
1811
|
+
* Defaults to the library's own operation description.
|
|
1812
|
+
*/
|
|
1813
|
+
description?: string;
|
|
1814
|
+
/**
|
|
1815
|
+
* The connection's binding NAME in `bindings.json` — the same label
|
|
1816
|
+
* `connector()`'s `connection` option takes (e.g. `'genai'`), resolved to
|
|
1817
|
+
* the tenant connection id at compile. Required: a connector tool with no
|
|
1818
|
+
* connection has nothing to call Integration Service with, and `check`
|
|
1819
|
+
* reports `INLINE_AGENT_TOOL_CONNECTOR_NO_CONNECTION`.
|
|
1820
|
+
*/
|
|
1821
|
+
connection?: string;
|
|
1822
|
+
/**
|
|
1823
|
+
* The connection's folder binding NAME in `bindings.json` (a `FolderKey`
|
|
1824
|
+
* entry) — the same label `connector()`'s `folder` option takes. Required
|
|
1825
|
+
* with `connection`.
|
|
1826
|
+
*/
|
|
1827
|
+
folder?: string;
|
|
1809
1828
|
}
|
|
1810
1829
|
/**
|
|
1811
1830
|
* The tool kinds that wrap a DEPLOYED tenant resource. `kind` picks the
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Library } from './library.js';
|
|
2
|
+
import type { BindingsView } from './binding-messages.js';
|
|
3
|
+
import { type ConnectorCheckOpts } from './connector-checks.js';
|
|
4
|
+
import type { EventCheckOpts } from './event-checks.js';
|
|
5
|
+
/** The value after `name` in `argv`, or `undefined`. */
|
|
6
|
+
export declare function flagValue(argv: readonly string[], name: string): string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* The library for this invocation, or `undefined` when there is none.
|
|
9
|
+
*
|
|
10
|
+
* `--library <dir>`, else `$FLOW_SDK_LIBRARY_JSON`, else the cache `registry
|
|
11
|
+
* pull` filled (`resolveLibraryDir`). The overlay is `--connectors-local <dir>`,
|
|
12
|
+
* else `.flow-sdk/connectors-local` (or a legacy `./connectors-local`) when it
|
|
13
|
+
* has an `index.json` — the directory `registry prepare` writes by default.
|
|
14
|
+
*/
|
|
15
|
+
export declare function openCliLibrary(argv: readonly string[]): Library | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The connector half of a family's check options, from a library the CLI already
|
|
18
|
+
* opened.
|
|
19
|
+
*
|
|
20
|
+
* Every callback fails OPEN: an entry the library cannot resolve, or no library
|
|
21
|
+
* at all, means "unknown", and an unknown fact fires no rule. That is what lets
|
|
22
|
+
* `check` stay the fast inner-loop rung — a process with no connectors needs no
|
|
23
|
+
* library, and one whose connector is absent from the library is `compile`'s
|
|
24
|
+
* business to name, not this pass's to guess at.
|
|
25
|
+
*
|
|
26
|
+
* The `resolutions` are the overlay's: without them every lookup already
|
|
27
|
+
* recorded by `registry prepare --resolve` would be reported as still owed,
|
|
28
|
+
* telling the author to re-run a prepare they already ran.
|
|
29
|
+
*/
|
|
30
|
+
export declare function connectorCheckOpts(library: Library | undefined, bindings?: BindingsView): ConnectorCheckOpts & EventCheckOpts;
|
|
31
|
+
/**
|
|
32
|
+
* `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
|
|
33
|
+
* for a subscription, or `undefined` when it resolves.
|
|
34
|
+
*
|
|
35
|
+
* This is the call `serialize` makes for a START subscription (kind `trigger`)
|
|
36
|
+
* and for a mid-flow wait (kind `event`), with the subscription's own `version`
|
|
37
|
+
* and `object`, so check reports an error exactly when compile would throw, with
|
|
38
|
+
* the same text.
|
|
39
|
+
*/
|
|
40
|
+
export declare function eventResolveErrorFor(library: Library): NonNullable<EventCheckOpts['eventResolveError']>;
|
|
41
|
+
/**
|
|
42
|
+
* `check`'s EVENT_BYOA_UNVERIFIED inputs: the event facts and the recorded BYOA
|
|
43
|
+
* checks, from the same `library.eventFacts` / `library.byoaVerifications` that
|
|
44
|
+
* `serialize` reads for the same refusal, so the inner loop and the emit rung
|
|
45
|
+
* refuse the same subscriptions.
|
|
46
|
+
*/
|
|
47
|
+
export declare function byoaCheckOpts(library: Library): Pick<EventCheckOpts, 'eventFacts' | 'byoa'>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/cli-library — how every family's CLI opens the connector library.
|
|
3
|
+
*
|
|
4
|
+
* One function, because the families kept opening it differently and the
|
|
5
|
+
* differences were invisible until they bit. Flow's `check-cli` and `compile-cli`
|
|
6
|
+
* used to disagree about `--connectors-local` (compile honoured the flag, check
|
|
7
|
+
* only auto-detected the directory), which made `check` refuse a source `compile`
|
|
8
|
+
* accepted. BPMN had the opposite shape of the same bug: `bpmn/compile-cli`
|
|
9
|
+
* constructed `new Library(libDir)` with no overlay at all, so `uip maestro
|
|
10
|
+
* registry prepare` wrote `connectors-local/` and BPMN never read a byte of it —
|
|
11
|
+
* a prepare that looked like it worked and changed nothing.
|
|
12
|
+
*
|
|
13
|
+
* Nothing here is family-specific. The two Flow-typed helpers that used to sit
|
|
14
|
+
* beside it (`eventResolveErrorFor`, `byoaCheckOpts`) stay in `../cli-library.ts`
|
|
15
|
+
* until the BPMN check rung needs them too.
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync } from 'node:fs';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { Library } from './library.js';
|
|
20
|
+
import { resolveLibraryDir } from '../registry/cache.js';
|
|
21
|
+
import { defaultOverlayDir } from '../workdir.js';
|
|
22
|
+
import { EQUALS_EXPR_DIALECT } from './connector-checks.js';
|
|
23
|
+
import { connectorInputErrors } from './connector-inputs.js';
|
|
24
|
+
/** The value after `name` in `argv`, or `undefined`. */
|
|
25
|
+
export function flagValue(argv, name) {
|
|
26
|
+
const i = argv.indexOf(name);
|
|
27
|
+
return i >= 0 ? argv[i + 1] : undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The library for this invocation, or `undefined` when there is none.
|
|
31
|
+
*
|
|
32
|
+
* `--library <dir>`, else `$FLOW_SDK_LIBRARY_JSON`, else the cache `registry
|
|
33
|
+
* pull` filled (`resolveLibraryDir`). The overlay is `--connectors-local <dir>`,
|
|
34
|
+
* else `.flow-sdk/connectors-local` (or a legacy `./connectors-local`) when it
|
|
35
|
+
* has an `index.json` — the directory `registry prepare` writes by default.
|
|
36
|
+
*/
|
|
37
|
+
export function openCliLibrary(argv) {
|
|
38
|
+
const libDir = resolveLibraryDir(flagValue(argv, '--library'));
|
|
39
|
+
if (!libDir || !existsSync(join(libDir, 'index.json')))
|
|
40
|
+
return undefined;
|
|
41
|
+
const overlayDir = flagValue(argv, '--connectors-local') ?? defaultOverlayDir();
|
|
42
|
+
return new Library(libDir, { overlayDir });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The connector half of a family's check options, from a library the CLI already
|
|
46
|
+
* opened.
|
|
47
|
+
*
|
|
48
|
+
* Every callback fails OPEN: an entry the library cannot resolve, or no library
|
|
49
|
+
* at all, means "unknown", and an unknown fact fires no rule. That is what lets
|
|
50
|
+
* `check` stay the fast inner-loop rung — a process with no connectors needs no
|
|
51
|
+
* library, and one whose connector is absent from the library is `compile`'s
|
|
52
|
+
* business to name, not this pass's to guess at.
|
|
53
|
+
*
|
|
54
|
+
* The `resolutions` are the overlay's: without them every lookup already
|
|
55
|
+
* recorded by `registry prepare --resolve` would be reported as still owed,
|
|
56
|
+
* telling the author to re-run a prepare they already ran.
|
|
57
|
+
*/
|
|
58
|
+
export function connectorCheckOpts(library, bindings) {
|
|
59
|
+
if (!library)
|
|
60
|
+
return bindings ? { bindings } : {};
|
|
61
|
+
return {
|
|
62
|
+
eventResolveError: eventResolveErrorFor(library),
|
|
63
|
+
...byoaCheckOpts(library),
|
|
64
|
+
eventParams: (connector, event, object) => {
|
|
65
|
+
try {
|
|
66
|
+
return library.eventParameterFields(connector, event, object);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// An unresolvable operation is EVENT_UNKNOWN's business, reported from
|
|
70
|
+
// `eventResolveError` above; here it just means "unknown".
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
eventFilterFields: (connector, event, object) => {
|
|
75
|
+
try {
|
|
76
|
+
return library.eventFilterFields(connector, event, object);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
lookups: (connector, action, version, object) => library.lookupSpecs(connector, action, version, object),
|
|
83
|
+
resolutions: library.lookupResolutions,
|
|
84
|
+
schemaReadiness: (connector, action, version, object) => {
|
|
85
|
+
try {
|
|
86
|
+
return library.schemaReadiness(connector, action, version, object);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
// The field contract compile enforces, from the same validator, so the inner
|
|
93
|
+
// loop and the emit rung cannot disagree about a missing required field, an
|
|
94
|
+
// unknown key or a mistyped value. An operation the library cannot resolve is
|
|
95
|
+
// compile's business to name — here it just means "unknown".
|
|
96
|
+
//
|
|
97
|
+
// The `=`-expression dialect, because this bag serves the families that spell
|
|
98
|
+
// an expression that way. Flow binds its own `connectorInputErrors` in
|
|
99
|
+
// `serialize.ts`, which carries `renderDeep` with it, and overrides this.
|
|
100
|
+
connectorInputs: (spec, inputs) => {
|
|
101
|
+
try {
|
|
102
|
+
const rc = library.resolve(spec.key, spec.action, spec.version, spec.object);
|
|
103
|
+
return connectorInputErrors(rc, inputs, library.lookupResolutions ?? {}, library.lookupSpecs(spec.key, spec.action, spec.version, spec.object) ?? {}, { dialect: EQUALS_EXPR_DIALECT });
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
...(bindings ? { bindings } : {}),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* `check`'s EVENT_UNKNOWN verdict: the message `library.resolveEvent` throws
|
|
114
|
+
* for a subscription, or `undefined` when it resolves.
|
|
115
|
+
*
|
|
116
|
+
* This is the call `serialize` makes for a START subscription (kind `trigger`)
|
|
117
|
+
* and for a mid-flow wait (kind `event`), with the subscription's own `version`
|
|
118
|
+
* and `object`, so check reports an error exactly when compile would throw, with
|
|
119
|
+
* the same text.
|
|
120
|
+
*/
|
|
121
|
+
export function eventResolveErrorFor(library) {
|
|
122
|
+
return (kind, sub) => {
|
|
123
|
+
try {
|
|
124
|
+
library.resolveEvent(kind, sub.connector, sub.event, sub.version, sub.object);
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return error instanceof Error ? error.message : String(error);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* `check`'s EVENT_BYOA_UNVERIFIED inputs: the event facts and the recorded BYOA
|
|
134
|
+
* checks, from the same `library.eventFacts` / `library.byoaVerifications` that
|
|
135
|
+
* `serialize` reads for the same refusal, so the inner loop and the emit rung
|
|
136
|
+
* refuse the same subscriptions.
|
|
137
|
+
*/
|
|
138
|
+
export function byoaCheckOpts(library) {
|
|
139
|
+
return {
|
|
140
|
+
eventFacts: (connector, event, object) => {
|
|
141
|
+
try {
|
|
142
|
+
return library.eventFacts(connector, event, object);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return undefined; // unknown fails open, same as every library callback
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
byoa: library.byoaVerifications,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/connector-checks — the check rules whose facts live in the connector
|
|
3
|
+
* library, shared by every family that authors a connector activity.
|
|
4
|
+
*
|
|
5
|
+
* These were Flow's, and they are the reason Flow's `check` can say "run THIS
|
|
6
|
+
* prepare" in the loop the author is already in. BPMN had none of them: its
|
|
7
|
+
* `check` took no options at all, so a BPMN connector node reached `compile`
|
|
8
|
+
* with an unresolved lookup, an unprepared object or a self-naming binding and
|
|
9
|
+
* learned about it from `uip maestro bpmn validate`, a tenant, or a faulted run.
|
|
10
|
+
* (`flow-v2-run-8`: `skill-bpmn-e2e-customer-escalation-triage` packed
|
|
11
|
+
* `bindings_v2.json` carrying the literal strings `jiraConnection` and
|
|
12
|
+
* `slackConnection` where connection ids belong.)
|
|
13
|
+
*
|
|
14
|
+
* Nothing here knows what a step or a task is. A caller supplies:
|
|
15
|
+
*
|
|
16
|
+
* - `where` — how the message opens (`Connector step "post"`,
|
|
17
|
+
* `Connector task "post"`), so each family keeps its own vocabulary;
|
|
18
|
+
* - `report` — where the diagnostic goes, so each family adds its own locator
|
|
19
|
+
* field (Flow's `step`, BPMN's `where`);
|
|
20
|
+
* - `dialect` — how an authored value reads, because Flow writes expressions as
|
|
21
|
+
* `Expr` objects over `$vars` and BPMN writes them as `=`-prefixed strings
|
|
22
|
+
* over `vars`. Without this a BPMN `'=vars.channelId'` would read as a pasted
|
|
23
|
+
* literal id and warn about itself.
|
|
24
|
+
*/
|
|
25
|
+
import { type LookupResolutions, type LookupSpec } from './lookups.js';
|
|
26
|
+
import type { SchemaReadiness } from './library.js';
|
|
27
|
+
import { type BindingsView, type PrepareTarget } from './binding-messages.js';
|
|
28
|
+
/** One connector activity, as every family already models it. */
|
|
29
|
+
export interface ConnectorSpec {
|
|
30
|
+
/** Connector library key, e.g. `uipath-atlassian-jira`. */
|
|
31
|
+
key: string;
|
|
32
|
+
/** The operation, e.g. `create-issue`. */
|
|
33
|
+
action: string;
|
|
34
|
+
/** Pinned operation version, when the author pinned one. */
|
|
35
|
+
version?: string;
|
|
36
|
+
/** Which OBJECT a generic operation addresses. */
|
|
37
|
+
object?: string;
|
|
38
|
+
/** The author's activity inputs, by the connector's own field names. */
|
|
39
|
+
inputs?: Record<string, unknown>;
|
|
40
|
+
/** Symbolic binding names, resolved through `bindings.json`. */
|
|
41
|
+
connection?: unknown;
|
|
42
|
+
folder?: unknown;
|
|
43
|
+
}
|
|
44
|
+
/** A diagnostic with no locator — the caller attaches its family's. */
|
|
45
|
+
export interface ConnectorDiagnostic {
|
|
46
|
+
level: 'error' | 'warning';
|
|
47
|
+
code: string;
|
|
48
|
+
message: string;
|
|
49
|
+
suggestion?: string;
|
|
50
|
+
}
|
|
51
|
+
/** Where a diagnostic goes. */
|
|
52
|
+
export type ReportConnector = (diagnostic: ConnectorDiagnostic) => void;
|
|
53
|
+
/**
|
|
54
|
+
* How one authored input value reads.
|
|
55
|
+
*
|
|
56
|
+
* `container` means "descend into it" — an array or a plain object. A lookup
|
|
57
|
+
* token is recognized before `classify` is consulted, so a dialect never sees one.
|
|
58
|
+
*/
|
|
59
|
+
export type ValueReading = {
|
|
60
|
+
kind: 'runtime';
|
|
61
|
+
js: string;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'literal';
|
|
64
|
+
value: unknown;
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'container';
|
|
67
|
+
};
|
|
68
|
+
/** How a family spells expressions. */
|
|
69
|
+
export interface ExprDialect {
|
|
70
|
+
/** The reference namespace `extractRefs` reads: `$vars` for Flow, `vars` for BPMN. */
|
|
71
|
+
namespace: string;
|
|
72
|
+
classify(value: unknown): ValueReading;
|
|
73
|
+
/**
|
|
74
|
+
* Is this value one the family cannot evaluate here — a Flow `Expr`, a BPMN
|
|
75
|
+
* `=`-expression?
|
|
76
|
+
*
|
|
77
|
+
* Separate from `classify` because the two questions differ for a Flow
|
|
78
|
+
* `lit(…)`: it classifies as a LITERAL (the lookup rules read its constant)
|
|
79
|
+
* but is still opaque to the input validator, which must not type-check the
|
|
80
|
+
* `Expr` wrapper against the field's declared type.
|
|
81
|
+
*/
|
|
82
|
+
isOpaque(value: unknown): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Does this family import GENERATED CONNECTOR DESCRIPTORS?
|
|
85
|
+
*
|
|
86
|
+
* Flow's `connector(SendMessageToUser, …)` does, and the `.byName()` aliases
|
|
87
|
+
* exist only on one. BPMN's `.connector()` takes the key and action as
|
|
88
|
+
* strings, so a remedy naming a descriptor there sends the reader after a
|
|
89
|
+
* module nothing generates. It is a family fact rather than an expression
|
|
90
|
+
* one, but the dialect is the family token every one of these rules already
|
|
91
|
+
* has in hand.
|
|
92
|
+
*/
|
|
93
|
+
descriptors: boolean;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Flow: an input is an {@link Expr} object. A non-literal one is runtime; a
|
|
97
|
+
* literal one (`lit(…)`) carries the constant it was built from.
|
|
98
|
+
*/
|
|
99
|
+
export declare const FLOW_EXPR_DIALECT: ExprDialect;
|
|
100
|
+
/**
|
|
101
|
+
* BPMN and Case: an expression is a string that starts with `=`.
|
|
102
|
+
*
|
|
103
|
+
* `=js:…` is the same thing with an evaluator prefix; both reduce to the source
|
|
104
|
+
* `extractRefs` reads. A string that does NOT start with `=` is a constant, which
|
|
105
|
+
* is exactly what `LOOKUP_LITERAL_ID` is about.
|
|
106
|
+
*/
|
|
107
|
+
export declare const EQUALS_EXPR_DIALECT: ExprDialect;
|
|
108
|
+
/** The library-backed facts these rules need, or `undefined` for "no library". */
|
|
109
|
+
export interface ConnectorCheckOpts {
|
|
110
|
+
/** One connector operation's generated lookup table, keyed by field. */
|
|
111
|
+
lookups?: (connector: string, action: string, version?: string, object?: string) => Readonly<Record<string, LookupSpec>> | undefined;
|
|
112
|
+
/** Everything `registry prepare --resolve` has recorded in the local overlay. */
|
|
113
|
+
resolutions?: LookupResolutions;
|
|
114
|
+
/** Whether a connector step's schema is materialized locally. */
|
|
115
|
+
schemaReadiness?: (connector: string, action: string, version?: string, object?: string) => SchemaReadiness | undefined;
|
|
116
|
+
/** What `compile` would refuse these inputs with, or `undefined` when it would accept them. */
|
|
117
|
+
connectorInputs?: (spec: {
|
|
118
|
+
key: string;
|
|
119
|
+
action: string;
|
|
120
|
+
version?: string;
|
|
121
|
+
object?: string;
|
|
122
|
+
}, inputs: Record<string, unknown>) => string | undefined;
|
|
123
|
+
/** The project's `bindings.json`, for the label rules. */
|
|
124
|
+
bindings?: BindingsView;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The lookup rules: a pasted id, and an unresolved token.
|
|
128
|
+
*
|
|
129
|
+
* These are the strongest discoverability route in the design, because they
|
|
130
|
+
* need no prior knowledge and arrive in the loop the author is already in. An
|
|
131
|
+
* author who pastes `WT9RC72KU` into a lookup field is not being careless, they
|
|
132
|
+
* are being uninformed — nothing anywhere told them the field was resolvable —
|
|
133
|
+
* and the fix is to tell them at the point of the mistake.
|
|
134
|
+
*
|
|
135
|
+
* Both are WARNINGS, not errors. A literal id is legal and sometimes correct
|
|
136
|
+
* (a value that genuinely does not move), and the unresolved case is already a
|
|
137
|
+
* hard failure at compile, where the same message is repeated. Making it an
|
|
138
|
+
* error here would stop a `check` that is otherwise clean from telling the
|
|
139
|
+
* author about everything ELSE that is wrong, which is the whole point of
|
|
140
|
+
* running the cheap pass first.
|
|
141
|
+
*/
|
|
142
|
+
export declare function checkConnectorLookups(where: string, spec: ConnectorSpec, opts: ConnectorCheckOpts, dialect: ExprDialect, report: ReportConnector): void;
|
|
143
|
+
/**
|
|
144
|
+
* The schema rules: an unprepared object, and unprepared custom fields.
|
|
145
|
+
*
|
|
146
|
+
* Same reasoning as the lookup rules above — the author needs no prior
|
|
147
|
+
* knowledge, and the diagnostic arrives in the loop they are already in, with
|
|
148
|
+
* the one command that discharges it. Both are WARNINGS: compile accepts a
|
|
149
|
+
* connection-scoped object (stamped `objectNameUnverified`) and passes the
|
|
150
|
+
* inputs through, so `check` is the one place the gap is visible BEFORE a
|
|
151
|
+
* process dispatches against a schema nothing validated.
|
|
152
|
+
*
|
|
153
|
+
* The custom-fields rule is deliberately narrower than "unprepared op": a step
|
|
154
|
+
* that uses only baked fields owes nothing, and warning on it anyway teaches
|
|
155
|
+
* the author that the warning is noise. It fires only for inputs OUTSIDE the
|
|
156
|
+
* tenant-agnostic snapshot — the moment hand-guessing actually starts.
|
|
157
|
+
*/
|
|
158
|
+
export declare function checkConnectorSchema(where: string, spec: ConnectorSpec, opts: ConnectorCheckOpts, dialect: ExprDialect, report: ReportConnector): void;
|
|
159
|
+
/**
|
|
160
|
+
* The field contract and the binding names `compile` enforces, reported here first.
|
|
161
|
+
*
|
|
162
|
+
* Both rules run only with the facts in hand (a library for the fields, a
|
|
163
|
+
* bindings.json for the names); without them `check` stays a pure function of the
|
|
164
|
+
* built model and says nothing, as before.
|
|
165
|
+
*/
|
|
166
|
+
export declare function checkConnectorContract(where: string, spec: ConnectorSpec, opts: ConnectorCheckOpts, report: ReportConnector,
|
|
167
|
+
/** The activity's own id, for {@link connectionConnectorConflicts}; omit to record nothing. */
|
|
168
|
+
id?: string): void;
|
|
169
|
+
/**
|
|
170
|
+
* The binding-label rules `serialize`'s `resolveBinding` enforces, for one
|
|
171
|
+
* `{ connection, folder }` pair — reported at every site that resolves one
|
|
172
|
+
* (connector step, event trigger and `.entryPoint` onEvent, waitForEvent, managed
|
|
173
|
+
* HTTP), with the sentence compile throws. Without this at the event and HTTP
|
|
174
|
+
* sites `check` printed `✓ no issues` for a source `compile` then refused.
|
|
175
|
+
*
|
|
176
|
+
* Silent without a bindings.json, and for a label that resolves to anything
|
|
177
|
+
* other than its own name (stub values are compile's CONNECTION_STUB warning).
|
|
178
|
+
*/
|
|
179
|
+
export declare function checkBindingLabels(where: string, labels: {
|
|
180
|
+
connection?: unknown;
|
|
181
|
+
folder?: unknown;
|
|
182
|
+
} | undefined, opts: ConnectorCheckOpts, report: (code: 'BINDING_SELF_NAME' | 'BINDING_UNDECLARED', message: string) => void, target?: PrepareTarget,
|
|
183
|
+
/** The activity, and the connector its connection must belong to, for {@link connectionConnectorConflicts}. */
|
|
184
|
+
use?: {
|
|
185
|
+
id: string;
|
|
186
|
+
connector: string | undefined;
|
|
187
|
+
}): void;
|
|
188
|
+
/**
|
|
189
|
+
* The two phrases every lookup diagnostic needs: what the field sends, and how
|
|
190
|
+
* to resolve it.
|
|
191
|
+
*
|
|
192
|
+
* The `call` names BOTH authoring forms, and names which one the alias belongs
|
|
193
|
+
* to. Printing `lookup(<Descriptor>, 'entityName').byDisplayName('<value>')`
|
|
194
|
+
* alone — the old text — was a remedy with an unstated precondition: aliases
|
|
195
|
+
* are generated onto the descriptor, and `<Descriptor>` is a placeholder the
|
|
196
|
+
* reader has to fill from somewhere. An author holding the connector key and
|
|
197
|
+
* action instead (the form the library's Generic CRUD half is authored in, and
|
|
198
|
+
* the majority of its lookup fields) substitutes those for the placeholder,
|
|
199
|
+
* keeps the alias, and gets `lookup(...).byDisplayName is not a function`. Six
|
|
200
|
+
* flow-eval tasks did precisely that, each losing a check-edit-check round to
|
|
201
|
+
* a message that had told them to.
|
|
202
|
+
*/
|
|
203
|
+
export declare function lookupPhrases(field: string, lookup: LookupSpec, spec: ConnectorSpec, descriptors?: boolean): {
|
|
204
|
+
target: string;
|
|
205
|
+
call: string;
|
|
206
|
+
};
|
|
207
|
+
/** One activity's use of a connection label, as the connector the connection must belong to. */
|
|
208
|
+
export interface ConnectionUse {
|
|
209
|
+
/** The activity's own id — Flow's step name, BPMN's element id. */
|
|
210
|
+
id: string;
|
|
211
|
+
label: string;
|
|
212
|
+
connector: string;
|
|
213
|
+
}
|
|
214
|
+
/** Run `check`, and hand back the connection uses its binding-label rules saw. */
|
|
215
|
+
export declare function collectConnectionUses(check: () => void): ConnectionUse[];
|
|
216
|
+
/**
|
|
217
|
+
* CONNECTION_CONNECTOR_CONFLICT — the rule `serialize` enforces on the emitted
|
|
218
|
+
* document (`connectionConnectors`, bindings-v2.ts), reported here with the same
|
|
219
|
+
* sentence so `check` does not print `✓ no issues` for a source `compile` then
|
|
220
|
+
* refuses. Labels are grouped by what they resolve to, so two labels bound to
|
|
221
|
+
* one connection id are one connection, as they are in the artifact.
|
|
222
|
+
*/
|
|
223
|
+
export declare function connectionConnectorConflicts(uses: readonly ConnectionUse[], opts: ConnectorCheckOpts): {
|
|
224
|
+
id: string;
|
|
225
|
+
message: string;
|
|
226
|
+
}[];
|