@uipath/maestro-builder-sdk 5.2.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/LICENSE +21 -0
- package/README.md +322 -0
- package/dist/bindings-v2.d.ts +37 -0
- package/dist/bindings-v2.js +155 -0
- package/dist/bindings.d.ts +6 -0
- package/dist/bindings.js +6 -0
- package/dist/bpmn/bpmn-expr-check.d.ts +41 -0
- package/dist/bpmn/bpmn-expr-check.js +218 -0
- package/dist/bpmn/bpmn-sdk.d.ts +2257 -0
- package/dist/bpmn/bpmn-sdk.js +1476 -0
- package/dist/bpmn/check-cli.d.ts +3 -0
- package/dist/bpmn/check-cli.js +32 -0
- package/dist/bpmn/check.d.ts +25 -0
- package/dist/bpmn/check.js +430 -0
- package/dist/bpmn/compile-cli.d.ts +3 -0
- package/dist/bpmn/compile-cli.js +60 -0
- package/dist/bpmn/connector.d.ts +56 -0
- package/dist/bpmn/connector.js +199 -0
- package/dist/bpmn/decompile-cli.d.ts +8 -0
- package/dist/bpmn/decompile-cli.js +54 -0
- package/dist/bpmn/decompile.d.ts +6 -0
- package/dist/bpmn/decompile.js +1108 -0
- package/dist/bpmn/format-profile.d.ts +27 -0
- package/dist/bpmn/format-profile.js +11 -0
- package/dist/bpmn/intsvc.d.ts +77 -0
- package/dist/bpmn/intsvc.js +155 -0
- package/dist/bpmn/load.d.ts +4 -0
- package/dist/bpmn/load.js +22 -0
- package/dist/bpmn/merge-cli.d.ts +3 -0
- package/dist/bpmn/merge-cli.js +45 -0
- package/dist/bpmn/merge.d.ts +19 -0
- package/dist/bpmn/merge.js +293 -0
- package/dist/bpmn/registry-types.json +1869 -0
- package/dist/bpmn/serialize.d.ts +28 -0
- package/dist/bpmn/serialize.js +757 -0
- package/dist/bpmn/tidy-cli.d.ts +2 -0
- package/dist/bpmn/tidy-cli.js +39 -0
- package/dist/bpmn/typed-node.d.ts +382 -0
- package/dist/bpmn/typed-node.js +551 -0
- package/dist/bpmn/uipath-moddle.v1.json +823 -0
- package/dist/bpmn/xml-ranges.d.ts +45 -0
- package/dist/bpmn/xml-ranges.js +151 -0
- package/dist/case/case-expr-check.d.ts +35 -0
- package/dist/case/case-expr-check.js +85 -0
- package/dist/case/case-sdk.d.ts +1282 -0
- package/dist/case/case-sdk.js +923 -0
- package/dist/case/check-cli.d.ts +3 -0
- package/dist/case/check-cli.js +31 -0
- package/dist/case/check.d.ts +18 -0
- package/dist/case/check.js +456 -0
- package/dist/case/compile-cli.d.ts +3 -0
- package/dist/case/compile-cli.js +291 -0
- package/dist/case/decompile-cli.d.ts +9 -0
- package/dist/case/decompile-cli.js +117 -0
- package/dist/case/decompile.d.ts +187 -0
- package/dist/case/decompile.js +1170 -0
- package/dist/case/entry-points.d.ts +79 -0
- package/dist/case/entry-points.js +118 -0
- package/dist/case/format-profile.d.ts +60 -0
- package/dist/case/format-profile.js +79 -0
- package/dist/case/ids.d.ts +24 -0
- package/dist/case/ids.js +76 -0
- package/dist/case/load.d.ts +12 -0
- package/dist/case/load.js +32 -0
- package/dist/case/preserve.d.ts +133 -0
- package/dist/case/preserve.js +105 -0
- package/dist/case/serialize.d.ts +10 -0
- package/dist/case/serialize.js +1414 -0
- package/dist/check-cli.d.ts +3 -0
- package/dist/check-cli.js +118 -0
- package/dist/check.d.ts +146 -0
- package/dist/check.js +4898 -0
- package/dist/cli/commands/bpmn.d.ts +2 -0
- package/dist/cli/commands/bpmn.js +73 -0
- package/dist/cli/commands/case.d.ts +2 -0
- package/dist/cli/commands/case.js +60 -0
- package/dist/cli/commands/flow.d.ts +2 -0
- package/dist/cli/commands/flow.js +99 -0
- package/dist/cli/commands/registry.d.ts +10 -0
- package/dist/cli/commands/registry.js +170 -0
- package/dist/cli/common.d.ts +30 -0
- package/dist/cli/common.js +92 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli-run.d.ts +2 -0
- package/dist/cli-run.js +42 -0
- package/dist/compile-cli.d.ts +3 -0
- package/dist/compile-cli.js +160 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.js +201 -0
- package/dist/core/actions.d.ts +3244 -0
- package/dist/core/actions.js +1062 -0
- package/dist/core/binding-messages.d.ts +1 -0
- package/dist/core/binding-messages.js +16 -0
- package/dist/core/bindings.d.ts +12 -0
- package/dist/core/bindings.js +67 -0
- package/dist/core/ceql.d.ts +73 -0
- package/dist/core/ceql.js +272 -0
- package/dist/core/cli-spelling.d.ts +39 -0
- package/dist/core/cli-spelling.js +62 -0
- package/dist/core/connector-raw-node.d.ts +21 -0
- package/dist/core/connector-raw-node.js +47 -0
- package/dist/core/connectors.d.ts +184 -0
- package/dist/core/connectors.js +128 -0
- package/dist/core/expr-check.d.ts +93 -0
- package/dist/core/expr-check.js +186 -0
- package/dist/core/expr.d.ts +323 -0
- package/dist/core/expr.js +400 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.js +10 -0
- package/dist/core/library.d.ts +440 -0
- package/dist/core/library.js +1183 -0
- package/dist/core/list-envelope.d.ts +45 -0
- package/dist/core/list-envelope.js +97 -0
- package/dist/core/lookup-store.d.ts +22 -0
- package/dist/core/lookup-store.js +85 -0
- package/dist/core/lookups.d.ts +227 -0
- package/dist/core/lookups.js +231 -0
- package/dist/core/node-classes.d.ts +234 -0
- package/dist/core/node-classes.js +158 -0
- package/dist/core/script-return.d.ts +68 -0
- package/dist/core/script-return.js +197 -0
- package/dist/core/stable-id.d.ts +28 -0
- package/dist/core/stable-id.js +37 -0
- package/dist/core-definitions.json +16249 -0
- package/dist/decompile-cli.d.ts +3 -0
- package/dist/decompile-cli.js +131 -0
- package/dist/decompile.d.ts +138 -0
- package/dist/decompile.js +2482 -0
- package/dist/emit.d.ts +10 -0
- package/dist/emit.js +60 -0
- package/dist/event-filters.d.ts +130 -0
- package/dist/event-filters.js +137 -0
- package/dist/flow-expr-check.d.ts +17 -0
- package/dist/flow-expr-check.js +193 -0
- package/dist/flow-sdk.d.ts +1341 -0
- package/dist/flow-sdk.js +1164 -0
- package/dist/flow-variables.d.ts +13 -0
- package/dist/flow-variables.js +42 -0
- package/dist/format-profile.d.ts +72 -0
- package/dist/format-profile.js +97 -0
- package/dist/generators/_connections.py +287 -0
- package/dist/generators/_events.py +355 -0
- package/dist/generators/_lookups.py +114 -0
- package/dist/generators/_naming.py +185 -0
- package/dist/generators/_objects.py +299 -0
- package/dist/generators/_resolve.py +273 -0
- package/dist/generators/convert_library_to_md.py +1441 -0
- package/dist/generators/extract_library.py +125 -0
- package/dist/generators/generate_connectors_ts.py +936 -0
- package/dist/generators/generate_library_json.py +2527 -0
- package/dist/generators/generate_triggers_ts.py +110 -0
- package/dist/generators/materialize_registry.py +155 -0
- package/dist/generators/prepare_connector.py +1688 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +35 -0
- package/dist/ixp-definition.json +1982 -0
- package/dist/library.d.ts +6 -0
- package/dist/library.js +6 -0
- package/dist/load.d.ts +16 -0
- package/dist/load.js +95 -0
- package/dist/merge-cli.d.ts +3 -0
- package/dist/merge-cli.js +47 -0
- package/dist/merge.d.ts +125 -0
- package/dist/merge.js +0 -0
- package/dist/migrate.d.ts +15 -0
- package/dist/migrate.js +245 -0
- package/dist/node-runtime.d.ts +3 -0
- package/dist/node-runtime.js +22 -0
- package/dist/package-name.d.ts +17 -0
- package/dist/package-name.js +17 -0
- package/dist/ref-resolve.d.ts +77 -0
- package/dist/ref-resolve.js +170 -0
- package/dist/registry/cache.d.ts +55 -0
- package/dist/registry/cache.js +134 -0
- package/dist/registry/curated-overlay.d.ts +16 -0
- package/dist/registry/curated-overlay.js +62 -0
- package/dist/registry/extractor.d.ts +22 -0
- package/dist/registry/extractor.js +18 -0
- package/dist/registry/materialize-bin.d.ts +2 -0
- package/dist/registry/materialize-bin.js +7 -0
- package/dist/registry/materialize-cli.d.ts +1 -0
- package/dist/registry/materialize-cli.js +46 -0
- package/dist/registry/materializer.d.ts +23 -0
- package/dist/registry/materializer.js +34 -0
- package/dist/registry/path-cli.d.ts +1 -0
- package/dist/registry/path-cli.js +56 -0
- package/dist/registry/prepare-cli.d.ts +62 -0
- package/dist/registry/prepare-cli.js +185 -0
- package/dist/registry/pull-cli.d.ts +1 -0
- package/dist/registry/pull-cli.js +274 -0
- package/dist/registry/python.d.ts +26 -0
- package/dist/registry/python.js +46 -0
- package/dist/registry/search-cli.d.ts +52 -0
- package/dist/registry/search-cli.js +159 -0
- package/dist/schema-version.d.ts +165 -0
- package/dist/schema-version.js +148 -0
- package/dist/serialize.d.ts +64 -0
- package/dist/serialize.js +6398 -0
- package/lib/README.md +112 -0
- package/lib/library-json.samples/index.json +158 -0
- package/lib/library-json.samples/invariant-collections.json +83 -0
- package/lib/library-json.samples/list-envelopes.json +123 -0
- package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.json +131 -0
- package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.v1def.json +306 -0
- package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.json +86 -0
- package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.v1def.json +208 -0
- package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.json +2040 -0
- package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.v1def.json +195 -0
- package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.json +169 -0
- package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.v1def.json +209 -0
- package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.json +63 -0
- package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.v1def.json +262 -0
- package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.json +63 -0
- package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.v1def.json +213 -0
- package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.json +227 -0
- package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.v1def.json +373 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.json +116 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.v1def.json +369 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.json +56 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.v1def.json +256 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.json +116 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.v1def.json +320 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.json +56 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.v1def.json +207 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.json +107 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.v1def.json +264 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.json +142 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.v1def.json +306 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.json +107 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.v1def.json +217 -0
- package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.json +85 -0
- package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.v1def.json +209 -0
- package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.json +755 -0
- package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.v1def.json +513 -0
- package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.json +122 -0
- package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.v1def.json +227 -0
- package/package.json +85 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/lookups — authoring a connector field whose value is an opaque id.
|
|
3
|
+
*
|
|
4
|
+
* Sending a Slack message to a person needs that person's Slack user id. The id
|
|
5
|
+
* is wrong to write down twice over: it is meaningless in review (nothing in a
|
|
6
|
+
* diff says which person `WT9RC72KU` is), and it is silently wrong after a move
|
|
7
|
+
* (deploy against another workspace and it resolves to nobody, or to somebody).
|
|
8
|
+
* An email is not immune — people leave — but it is reviewable, and it fails
|
|
9
|
+
* LOUDLY: resolution against the new workspace either finds the person or says
|
|
10
|
+
* it did not.
|
|
11
|
+
*
|
|
12
|
+
* So the author writes what they mean and resolution happens later:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* channel: lookup(SendMessageToUser, 'channel').byEmail('dustin@example.com')
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* That call returns an unresolved {@link LookupToken}, not a string. Each stage
|
|
19
|
+
* of the pipeline can then see it for what it is: `check` reports it as owed
|
|
20
|
+
* work and prints the command that discharges it, `registry prepare --resolve`
|
|
21
|
+
* performs the one network call and records the answer, and `compile` reads the
|
|
22
|
+
* recorded answer. Compile never resolves anything itself — it is offline by
|
|
23
|
+
* design, because the byte-lock gates require that the same source produces the
|
|
24
|
+
* same bytes regardless of tenant state.
|
|
25
|
+
*
|
|
26
|
+
* Not every `reference` block earns a helper. See `_lookups.py` for the two
|
|
27
|
+
* degenerate classes the generator excludes and why generating for them would
|
|
28
|
+
* make the surface worse rather than more complete.
|
|
29
|
+
*/
|
|
30
|
+
import { prepareCommand } from './cli-spelling.js';
|
|
31
|
+
/** True when `v` is an unresolved {@link LookupToken}. */
|
|
32
|
+
export function isLookupToken(v) {
|
|
33
|
+
return (typeof v === 'object' && v !== null &&
|
|
34
|
+
typeof v.__lookup === 'object' &&
|
|
35
|
+
v.__lookup !== null &&
|
|
36
|
+
typeof v.__lookup.field === 'string');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The identity of one resolution, as `prepare` records it and `compile` reads it.
|
|
40
|
+
*
|
|
41
|
+
* JSON-encoded rather than delimiter-joined because every component is
|
|
42
|
+
* author-supplied text: a real name containing the delimiter would collide two
|
|
43
|
+
* distinct resolutions onto one key, and the symptom would be a flow compiled
|
|
44
|
+
* with the wrong person's id.
|
|
45
|
+
*/
|
|
46
|
+
export function lookupKey(nodeType, field, by, value) {
|
|
47
|
+
return JSON.stringify([nodeType, field, by, value]);
|
|
48
|
+
}
|
|
49
|
+
function makeBuilder(nodeType, field, spec) {
|
|
50
|
+
const token = (by, value) => ({ __lookup: { nodeType, field, by, value } });
|
|
51
|
+
const builder = {
|
|
52
|
+
by(name, value) {
|
|
53
|
+
// A `by` the collection cannot be searched by is caught here rather than
|
|
54
|
+
// at `prepare` time. The alternative is spending the network call to be
|
|
55
|
+
// told the field does not exist, which is the expensive way to learn it.
|
|
56
|
+
if (spec && !spec.by.includes(name)) {
|
|
57
|
+
throw new Error(`lookup(${nodeType}, '${field}'): cannot search by "${name}". ` +
|
|
58
|
+
`This collection is searchable by ${spec.by.map((b) => `"${b}"`).join(', ')}.`);
|
|
59
|
+
}
|
|
60
|
+
return token(name, value);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
for (const [alias, byName] of Object.entries(spec?.aliases ?? {})) {
|
|
64
|
+
builder[alias] = (value) => token(byName, value);
|
|
65
|
+
}
|
|
66
|
+
return builder;
|
|
67
|
+
}
|
|
68
|
+
export function lookup(a, b, c) {
|
|
69
|
+
if (typeof a === 'string') {
|
|
70
|
+
if (typeof c !== 'string') {
|
|
71
|
+
throw new Error("lookup(key, action, field) needs all three arguments; " +
|
|
72
|
+
"did you mean lookup(descriptor, field)?");
|
|
73
|
+
}
|
|
74
|
+
return makeBuilder(`uipath.connector.${a}.${b}`, c);
|
|
75
|
+
}
|
|
76
|
+
if (!('nodeType' in a) || a.nodeType === undefined) {
|
|
77
|
+
const event = a;
|
|
78
|
+
if (typeof event.connector === 'string' && typeof event.event === 'string') {
|
|
79
|
+
// The spec, when the descriptor carries one. Dropping it here is what
|
|
80
|
+
// made `.byDisplayName` a `TypeError` on a trigger whose generated
|
|
81
|
+
// descriptor declared that very alias: the branch is chosen on the
|
|
82
|
+
// ABSENCE of `nodeType`, not on the absence of a lookup table.
|
|
83
|
+
return makeBuilder(`uipath.connector.event.${event.connector}.${event.event}`, b, event.lookups?.[b]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const bearing = a;
|
|
87
|
+
const spec = bearing.lookups?.[b];
|
|
88
|
+
if (!spec) {
|
|
89
|
+
const known = Object.keys(bearing.lookups ?? {});
|
|
90
|
+
// Naming the fields that DO have one matters: the commonest cause of this
|
|
91
|
+
// is a field whose `reference` is degenerate, where the right answer is a
|
|
92
|
+
// plain string and not a different helper call.
|
|
93
|
+
throw new Error(`lookup(${bearing.nodeType}, '${b}'): no lookup is generated for that field. ` +
|
|
94
|
+
(known.length
|
|
95
|
+
? `Fields with a lookup: ${known.map((k) => `"${k}"`).join(', ')}.`
|
|
96
|
+
: 'This operation has no lookup fields — author the value as a plain string.'));
|
|
97
|
+
}
|
|
98
|
+
return makeBuilder(bearing.nodeType, b, spec);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The recorded id for a token, or `undefined`.
|
|
102
|
+
*
|
|
103
|
+
* @param token - The unresolved lookup.
|
|
104
|
+
* @param resolutions - Everything `prepare --resolve` has recorded.
|
|
105
|
+
* @returns The connector-facing id, when this exact `(nodeType, field, by, value)` was resolved.
|
|
106
|
+
*/
|
|
107
|
+
export function resolvedValue(token, resolutions) {
|
|
108
|
+
const { nodeType, field, by, value } = token.__lookup;
|
|
109
|
+
return resolutions[lookupKey(nodeType, field, by, value)]?.value;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The message for a lookup nothing has resolved — the command that fixes it.
|
|
113
|
+
*
|
|
114
|
+
* A missing resolution is the same class of error as a missing schema, and it
|
|
115
|
+
* reads the same way on purpose: name the thing, then print the one command.
|
|
116
|
+
*
|
|
117
|
+
* @param token - The unresolved lookup.
|
|
118
|
+
* @returns A diagnostic whose last line can be pasted into a shell.
|
|
119
|
+
*/
|
|
120
|
+
export function unresolvedLookupMessage(token) {
|
|
121
|
+
const { nodeType, field, by, value } = token.__lookup;
|
|
122
|
+
// Event tokens carry the role segment (`uipath.connector.event.<key>.<event>`);
|
|
123
|
+
// the prepare command takes the bare `<key> <event>` either way.
|
|
124
|
+
const rest = nodeType.replace(/^uipath\.connector\.(?:trigger\.|event\.)?/, '');
|
|
125
|
+
const dot = rest.lastIndexOf('.');
|
|
126
|
+
const key = dot > 0 ? rest.slice(0, dot) : rest;
|
|
127
|
+
const action = dot > 0 ? rest.slice(dot + 1) : rest;
|
|
128
|
+
// Spelled for whoever is driving. This used to hard-code `npx flow-sdk`
|
|
129
|
+
// because `uip maestro registry` offered help/path/pull/search only
|
|
130
|
+
// (@uipath/cli 1.201.0-preview.115). It carries `prepare` as of 1.202, so the
|
|
131
|
+
// hard-coding now sends a `uip` user to a different binary than the one in
|
|
132
|
+
// their hand — the same detour the old note said cost an eval agent four
|
|
133
|
+
// tool calls, pointing the other way (#695).
|
|
134
|
+
return (`input "${field}" is an unresolved lookup (${by}=${JSON.stringify(value)}). ` +
|
|
135
|
+
`Compile does not make network calls, so the value has to be resolved first:\n` +
|
|
136
|
+
` ${prepareCommand(key, action)} \\\n` +
|
|
137
|
+
` --resolve ${field}:${by}=${String(value)}`);
|
|
138
|
+
}
|
|
139
|
+
// ─── Classification, mirroring `_lookups.py` ─────────────────────────────────
|
|
140
|
+
//
|
|
141
|
+
// The generator decides which fields get a helper; `check` has to agree, or it
|
|
142
|
+
// tells an author to call a `.by*` that was never emitted. The rules are three
|
|
143
|
+
// lines, so they are restated here rather than shipped as data — but they are
|
|
144
|
+
// restated ONCE, in this function, and both `check` and the compile path read
|
|
145
|
+
// it. The invariant-collection ledger travels as data because it is a list
|
|
146
|
+
// somebody curated, not a rule.
|
|
147
|
+
/** A `reference` block whose "resolution" would return the value it was given. */
|
|
148
|
+
function isIdentityLookup(reference) {
|
|
149
|
+
const names = reference.lookupNames ?? [];
|
|
150
|
+
return names.length === 1 && names[0] === reference.lookupValue;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The {@link LookupSpec} for one field, or `undefined` when it earns no helper.
|
|
154
|
+
*
|
|
155
|
+
* @param reference - The field's raw registry `reference` block.
|
|
156
|
+
* @param invariant - `objectName`s the ledger declares connector-invariant.
|
|
157
|
+
* @returns The spec a `.by*` helper would be generated from, or `undefined`.
|
|
158
|
+
*/
|
|
159
|
+
export function lookupSpecOf(reference, invariant = new Set()) {
|
|
160
|
+
if (!reference?.lookupValue)
|
|
161
|
+
return undefined;
|
|
162
|
+
if (isIdentityLookup(reference))
|
|
163
|
+
return undefined;
|
|
164
|
+
if (reference.objectName && invariant.has(reference.objectName))
|
|
165
|
+
return undefined;
|
|
166
|
+
const by = reference.lookupNames ?? [];
|
|
167
|
+
const aliases = {};
|
|
168
|
+
const counts = new Map();
|
|
169
|
+
for (const name of by) {
|
|
170
|
+
const alias = byAlias(name);
|
|
171
|
+
if (alias)
|
|
172
|
+
counts.set(alias, (counts.get(alias) ?? 0) + 1);
|
|
173
|
+
}
|
|
174
|
+
for (const name of by) {
|
|
175
|
+
const alias = byAlias(name);
|
|
176
|
+
if (alias && counts.get(alias) === 1)
|
|
177
|
+
aliases[alias] = name;
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
...(reference.objectName ? { objectName: reference.objectName } : {}),
|
|
181
|
+
path: reference.path ?? '',
|
|
182
|
+
by,
|
|
183
|
+
value: reference.lookupValue,
|
|
184
|
+
aliases,
|
|
185
|
+
strategy: reference.dependsOn?.length
|
|
186
|
+
? 'dependent'
|
|
187
|
+
: reference.filterPattern ? 'filter'
|
|
188
|
+
: reference.childPath ? 'tree'
|
|
189
|
+
: 'scan',
|
|
190
|
+
...(reference.dependsOn?.length ? { dependsOn: reference.dependsOn } : {}),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/** `profile.email` -> `byEmail`; the last dotted segment, camelised. */
|
|
194
|
+
function byAlias(lookupName) {
|
|
195
|
+
const last = lookupName.split('.').pop() ?? '';
|
|
196
|
+
const words = last.split(/[^A-Za-z0-9]+/).filter(Boolean);
|
|
197
|
+
if (words.length === 0)
|
|
198
|
+
return '';
|
|
199
|
+
return 'by' + words.map((w) => w[0].toUpperCase() + w.slice(1)).join('');
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Refuse a lookup token where the family cannot resolve one.
|
|
203
|
+
*
|
|
204
|
+
* `lookup()` is a FLOW surface today: only `serialize.ts` substitutes a
|
|
205
|
+
* recorded resolution, and only `check.ts` reports an unresolved one. Case and
|
|
206
|
+
* BPMN pass connector input values straight into their emitted payload, so a
|
|
207
|
+
* token reaching either one is embedded verbatim — a `.case` carrying
|
|
208
|
+
* `{"__lookup": {…}}` where the connector expects an id.
|
|
209
|
+
*
|
|
210
|
+
* That is silent wrongness, which is the failure this whole surface exists to
|
|
211
|
+
* remove; emitting it from the tool that removes it would be the worst possible
|
|
212
|
+
* outcome. Until Case and BPMN read `resolutions.json` too, they refuse the
|
|
213
|
+
* token and say so.
|
|
214
|
+
*
|
|
215
|
+
* @param value - A connector input value.
|
|
216
|
+
* @param family - The authoring family, for the message.
|
|
217
|
+
* @param field - The input name, for the message.
|
|
218
|
+
* @throws If `value` is an unresolved {@link LookupToken}.
|
|
219
|
+
*/
|
|
220
|
+
export function refuseLookupToken(value, family, field) {
|
|
221
|
+
if (!isLookupToken(value))
|
|
222
|
+
return;
|
|
223
|
+
const { nodeType, by, value: wanted } = value.__lookup;
|
|
224
|
+
throw new Error(`${family}: input "${field}" is a lookup(), which ${family} cannot resolve — ` +
|
|
225
|
+
`only Flow reads connectors-local/resolutions.json today, so this would be ` +
|
|
226
|
+
`emitted as a raw token where the connector expects an id.\n` +
|
|
227
|
+
`Resolve it first and pass the value:\n` +
|
|
228
|
+
` ${prepareCommand()} ${nodeType.replace(/^uipath\.connector\.(?:trigger\.|event\.)?/, '').replace(/\.([^.]+)$/, ' $1')} \\\n` +
|
|
229
|
+
` --resolve ${field}:${by}=${String(wanted)}\n` +
|
|
230
|
+
`then read the id out of connectors-local/resolutions.json.`);
|
|
231
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Definition-backed node base classes — the public extension surface.
|
|
3
|
+
*
|
|
4
|
+
* The built-in factories (`http()`, `script()`, `scheduled()`, …) cover the
|
|
5
|
+
* node families the SDK ships typed helpers for. Everything else the platform
|
|
6
|
+
* can validly express — a less-common OOTB node, a tenant-specific registry
|
|
7
|
+
* definition — is authorable by subclassing {@link FlowAction} or
|
|
8
|
+
* {@link FlowTrigger} and returning a {@link NodeContribution}: an exact
|
|
9
|
+
* definition reference plus the semantic inputs. The shared serializer keeps
|
|
10
|
+
* ownership of everything structural (instance ids, `typeVersion`, definition
|
|
11
|
+
* deduplication, edges, variables), so an extension cannot bypass the file's
|
|
12
|
+
* invariants.
|
|
13
|
+
*
|
|
14
|
+
* {@link rawNode} is the same contract without the subclass: it carries a
|
|
15
|
+
* definition and its manifest verbatim for a node type the SDK has no factory
|
|
16
|
+
* for. It is not a raw-JSON escape hatch — the serializer still owns every
|
|
17
|
+
* structural field, and the manifest must be an exact copy of one the platform
|
|
18
|
+
* serves.
|
|
19
|
+
*
|
|
20
|
+
* Parity reference: `docs/FLOW_PARITY.md`.
|
|
21
|
+
*/
|
|
22
|
+
export interface ContributionDiagnostic {
|
|
23
|
+
/** Stable machine-readable code, SCREAMING_SNAKE by convention. */
|
|
24
|
+
code: string;
|
|
25
|
+
/** Human-readable, single-sentence problem statement. */
|
|
26
|
+
message: string;
|
|
27
|
+
/** `error` blocks compilation; `warning` reports and continues. */
|
|
28
|
+
severity: 'error' | 'warning';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* An exact reference to the node definition a contribution compiles against.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* All three forms are exact: `version` names one definition, and no form means
|
|
35
|
+
* "latest". `bundled` resolves from the SDK's own `core-definitions.json`;
|
|
36
|
+
* `library` resolves from the connector library supplied at compile time;
|
|
37
|
+
* `snapshot` carries a validated Workbench/registry manifest in memory — it is
|
|
38
|
+
* an exact copy of a real definition, not permission to invent one.
|
|
39
|
+
*/
|
|
40
|
+
export type DefinitionReference = {
|
|
41
|
+
/** Resolve from the SDK's bundled core definitions. */
|
|
42
|
+
source: 'bundled';
|
|
43
|
+
/** The definition's `nodeType`, e.g. `'core.logic.delay'`. */
|
|
44
|
+
nodeType: string;
|
|
45
|
+
/** The exact definition version; also becomes the node's `typeVersion`. */
|
|
46
|
+
version: string;
|
|
47
|
+
} | {
|
|
48
|
+
/** Resolve from the connector library supplied at compile time. */
|
|
49
|
+
source: 'library';
|
|
50
|
+
/** The definition's `nodeType`. */
|
|
51
|
+
nodeType: string;
|
|
52
|
+
/** The exact definition version; also becomes the node's `typeVersion`. */
|
|
53
|
+
version: string;
|
|
54
|
+
} | {
|
|
55
|
+
/** Carry an exact registry/Workbench definition in memory. */
|
|
56
|
+
source: 'snapshot';
|
|
57
|
+
/** The definition's `nodeType`; must equal `manifest.nodeType`. */
|
|
58
|
+
nodeType: string;
|
|
59
|
+
/** The exact definition version; must equal `manifest.version`. */
|
|
60
|
+
version: string;
|
|
61
|
+
/** The complete node manifest, exactly as the platform serves it. */
|
|
62
|
+
manifest: unknown;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* What the serializer tells a contributor before asking for its contribution.
|
|
66
|
+
*/
|
|
67
|
+
export interface ContributionContext {
|
|
68
|
+
/**
|
|
69
|
+
* The exact definition version the author requested on the node-producing
|
|
70
|
+
* builder method, if any. A contributor that supports several versions must
|
|
71
|
+
* return a {@link DefinitionReference} with this exact version or throw;
|
|
72
|
+
* substituting its own default for an explicit request is forbidden.
|
|
73
|
+
*/
|
|
74
|
+
requestedVersion?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A resource binding a contribution hoists to the flow's top-level `bindings`
|
|
78
|
+
* array — the shape the `.flow` format persists.
|
|
79
|
+
*/
|
|
80
|
+
export interface BindingContribution {
|
|
81
|
+
/** Unique binding id within the flow. */
|
|
82
|
+
id: string;
|
|
83
|
+
/** The binding's display name. */
|
|
84
|
+
name: string;
|
|
85
|
+
/** Binding value type, e.g. `'string'`. */
|
|
86
|
+
type: string;
|
|
87
|
+
/** Bound resource kind: `'connection'`, `'process'`, `'queue'`, … */
|
|
88
|
+
resource: string;
|
|
89
|
+
/** The key the platform resolves the resource by. */
|
|
90
|
+
resourceKey: string;
|
|
91
|
+
/** Optional default value. */
|
|
92
|
+
default?: string;
|
|
93
|
+
/** Which attribute of the resource the binding reads. */
|
|
94
|
+
propertyAttribute?: string;
|
|
95
|
+
/** Optional resource sub-type discriminator. */
|
|
96
|
+
resourceSubType?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* One validated construct, returned by {@link FlowNode.contribute}.
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* A contribution is NOT a serialized node: the serializer owns ids, labels,
|
|
103
|
+
* `typeVersion`, edge wiring, and definition deduplication. The contributor
|
|
104
|
+
* supplies author intent — which definition, which inputs — and nothing else.
|
|
105
|
+
*/
|
|
106
|
+
export interface NodeContribution {
|
|
107
|
+
/** The exact definition this node compiles against. */
|
|
108
|
+
definition: DefinitionReference;
|
|
109
|
+
/**
|
|
110
|
+
* The node's `inputs`. Values may be `Expr` instances; the serializer
|
|
111
|
+
* renders them with the same expression pipeline the built-in factories use.
|
|
112
|
+
*/
|
|
113
|
+
inputs?: Record<string, unknown>;
|
|
114
|
+
/**
|
|
115
|
+
* Overrides for the node's `outputs` beyond what the definition's
|
|
116
|
+
* `outputDefinition` declares. Rarely needed; most contributions omit it.
|
|
117
|
+
*/
|
|
118
|
+
outputs?: Record<string, unknown>;
|
|
119
|
+
/** Resource bindings to hoist into the flow's `bindings` array. */
|
|
120
|
+
bindings?: BindingContribution[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The abstract root of every definition-backed node the builder can place.
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* Do not extend this class directly — extend {@link FlowAction},
|
|
127
|
+
* {@link FlowTrigger}, or {@link FlowResource}, which fix the `role`.
|
|
128
|
+
* The built-in factory results are instances of these classes too, but they
|
|
129
|
+
* are lowered by the serializer's built-in paths; only custom subclasses have
|
|
130
|
+
* their {@link FlowNode.contribute | contribute} called.
|
|
131
|
+
*/
|
|
132
|
+
export declare abstract class FlowNode<TOutputs = unknown> {
|
|
133
|
+
/**
|
|
134
|
+
* Type-only phantom carrying what the node publishes; never set at runtime.
|
|
135
|
+
* It exists so a future typed `out()` can read a subclass's output shape.
|
|
136
|
+
*/
|
|
137
|
+
readonly __outputs?: TOutputs;
|
|
138
|
+
/** Where this node may appear: a step, a trigger, or an attached resource. */
|
|
139
|
+
abstract readonly role: 'action' | 'trigger' | 'resource';
|
|
140
|
+
/**
|
|
141
|
+
* Produce this node's validated construct. Called once per placement during
|
|
142
|
+
* compilation, only for custom subclasses — built-in factory results are
|
|
143
|
+
* lowered by the serializer directly and never reach this method.
|
|
144
|
+
*
|
|
145
|
+
* @param context - What the serializer knows about this placement, including
|
|
146
|
+
* any exact `version` the author requested on the builder method.
|
|
147
|
+
* @returns The exact definition reference and semantic inputs to compile.
|
|
148
|
+
*/
|
|
149
|
+
abstract contribute(context: ContributionContext): NodeContribution;
|
|
150
|
+
/**
|
|
151
|
+
* Report node-specific diagnostics during `check`. The default reports
|
|
152
|
+
* nothing; override to add family-specific rules.
|
|
153
|
+
*
|
|
154
|
+
* @returns Diagnostics to merge into the flow's check results.
|
|
155
|
+
*/
|
|
156
|
+
diagnostics(): ContributionDiagnostic[];
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* A node placed as a step — pass an instance to `.step(name, …)`.
|
|
160
|
+
*/
|
|
161
|
+
export declare abstract class FlowAction<TOutputs = unknown> extends FlowNode<TOutputs> {
|
|
162
|
+
/** Always `'action'` for a step-placed node. */
|
|
163
|
+
get role(): 'action';
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* A node that starts the flow — pass an instance to `.trigger(…)`.
|
|
167
|
+
*/
|
|
168
|
+
export declare abstract class FlowTrigger<TPayload = unknown> extends FlowNode<TPayload> {
|
|
169
|
+
/** Always `'trigger'` for a flow-starting node. */
|
|
170
|
+
get role(): 'trigger';
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* A node attached to another semantic node — an inline agent's tool, context,
|
|
174
|
+
* memory, or escalation. Not accepted by `.step()`.
|
|
175
|
+
*/
|
|
176
|
+
export declare abstract class FlowResource extends FlowNode<never> {
|
|
177
|
+
/** Always `'resource'` for an attached node. */
|
|
178
|
+
get role(): 'resource';
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Place a node this SDK has no factory for, carrying its definition verbatim
|
|
182
|
+
* (`uipath.exotic.thing@2.1` and the manifest the platform served for it).
|
|
183
|
+
*
|
|
184
|
+
* @remarks
|
|
185
|
+
* This is the escape hatch the coverage plan requires: an unknown registry
|
|
186
|
+
* definition is expressible without bypassing serializer invariants. The
|
|
187
|
+
* serializer still owns the node's id, label, `typeVersion` and edge wiring; you
|
|
188
|
+
* supply which definition and which inputs, exactly as a hand-written
|
|
189
|
+
* {@link FlowAction} subclass would.
|
|
190
|
+
*
|
|
191
|
+
* It is also what `decompile` emits for a node type it cannot name, so a
|
|
192
|
+
* round trip preserves the node's TYPE and VERSION instead of degrading it to a
|
|
193
|
+
* placeholder:
|
|
194
|
+
*
|
|
195
|
+
* ```ts
|
|
196
|
+
* .step('exotic', rawNode({
|
|
197
|
+
* nodeType: 'uipath.exotic.thing',
|
|
198
|
+
* version: '2.1',
|
|
199
|
+
* manifest: exoticManifest, // exactly what `registry get` returned
|
|
200
|
+
* inputs: { where: input('scope') },
|
|
201
|
+
* }))
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* `manifest` must be a real definition — an exact copy of what the registry or
|
|
205
|
+
* Workbench serves for that `nodeType@version`. It is not permission to invent
|
|
206
|
+
* one: the platform resolves the node against its own catalog at run time, so a
|
|
207
|
+
* hand-written manifest validates locally and fails on the tenant.
|
|
208
|
+
*
|
|
209
|
+
* Prefer a typed factory when one exists — it carries the family's checks, its
|
|
210
|
+
* defaults, and its output contract, none of which a raw node can know.
|
|
211
|
+
*
|
|
212
|
+
* **Never for a connector.** A `uipath.connector.*` node type is refused by
|
|
213
|
+
* `check` and `compile`: a raw node carries the author's inputs verbatim, so the
|
|
214
|
+
* emitted node has no `inputs.detail` and no connection binding — `validate`
|
|
215
|
+
* only warns ("Connector is not configured") and the run can never reach
|
|
216
|
+
* Integration Service. Use {@link connector}, and `registry prepare` when
|
|
217
|
+
* compile reports an input the static library does not carry; use
|
|
218
|
+
* {@link onEvent} for a connector event trigger.
|
|
219
|
+
*
|
|
220
|
+
* @param spec - The definition to compile against, plus the node's inputs.
|
|
221
|
+
* @returns A node to pass to `.step(...)`.
|
|
222
|
+
*/
|
|
223
|
+
export declare function rawNode(spec: {
|
|
224
|
+
/** The definition's `nodeType`, verbatim. */
|
|
225
|
+
nodeType: string;
|
|
226
|
+
/** The exact definition version; also becomes the node's `typeVersion`. */
|
|
227
|
+
version: string;
|
|
228
|
+
/** The complete node manifest, exactly as the platform serves it. */
|
|
229
|
+
manifest: unknown;
|
|
230
|
+
/** The node's `inputs`. `Expr` values render through the usual pipeline. */
|
|
231
|
+
inputs?: Record<string, unknown>;
|
|
232
|
+
/** Overrides for the node's `outputs`; rarely needed. */
|
|
233
|
+
outputs?: Record<string, unknown>;
|
|
234
|
+
}): FlowAction;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Definition-backed node base classes — the public extension surface.
|
|
3
|
+
*
|
|
4
|
+
* The built-in factories (`http()`, `script()`, `scheduled()`, …) cover the
|
|
5
|
+
* node families the SDK ships typed helpers for. Everything else the platform
|
|
6
|
+
* can validly express — a less-common OOTB node, a tenant-specific registry
|
|
7
|
+
* definition — is authorable by subclassing {@link FlowAction} or
|
|
8
|
+
* {@link FlowTrigger} and returning a {@link NodeContribution}: an exact
|
|
9
|
+
* definition reference plus the semantic inputs. The shared serializer keeps
|
|
10
|
+
* ownership of everything structural (instance ids, `typeVersion`, definition
|
|
11
|
+
* deduplication, edges, variables), so an extension cannot bypass the file's
|
|
12
|
+
* invariants.
|
|
13
|
+
*
|
|
14
|
+
* {@link rawNode} is the same contract without the subclass: it carries a
|
|
15
|
+
* definition and its manifest verbatim for a node type the SDK has no factory
|
|
16
|
+
* for. It is not a raw-JSON escape hatch — the serializer still owns every
|
|
17
|
+
* structural field, and the manifest must be an exact copy of one the platform
|
|
18
|
+
* serves.
|
|
19
|
+
*
|
|
20
|
+
* Parity reference: `docs/FLOW_PARITY.md`.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* A diagnostic a node contributes during `check` — surfaced alongside the
|
|
24
|
+
* built-in rules with the same severities.
|
|
25
|
+
*/
|
|
26
|
+
import { connectorRawNodeRefusal } from './connector-raw-node.js';
|
|
27
|
+
/**
|
|
28
|
+
* The abstract root of every definition-backed node the builder can place.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* Do not extend this class directly — extend {@link FlowAction},
|
|
32
|
+
* {@link FlowTrigger}, or {@link FlowResource}, which fix the `role`.
|
|
33
|
+
* The built-in factory results are instances of these classes too, but they
|
|
34
|
+
* are lowered by the serializer's built-in paths; only custom subclasses have
|
|
35
|
+
* their {@link FlowNode.contribute | contribute} called.
|
|
36
|
+
*/
|
|
37
|
+
export class FlowNode {
|
|
38
|
+
/**
|
|
39
|
+
* Report node-specific diagnostics during `check`. The default reports
|
|
40
|
+
* nothing; override to add family-specific rules.
|
|
41
|
+
*
|
|
42
|
+
* @returns Diagnostics to merge into the flow's check results.
|
|
43
|
+
*/
|
|
44
|
+
diagnostics() {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A node placed as a step — pass an instance to `.step(name, …)`.
|
|
50
|
+
*/
|
|
51
|
+
export class FlowAction extends FlowNode {
|
|
52
|
+
/** Always `'action'` for a step-placed node. */
|
|
53
|
+
get role() {
|
|
54
|
+
return 'action';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A node that starts the flow — pass an instance to `.trigger(…)`.
|
|
59
|
+
*/
|
|
60
|
+
export class FlowTrigger extends FlowNode {
|
|
61
|
+
/** Always `'trigger'` for a flow-starting node. */
|
|
62
|
+
get role() {
|
|
63
|
+
return 'trigger';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A node attached to another semantic node — an inline agent's tool, context,
|
|
68
|
+
* memory, or escalation. Not accepted by `.step()`.
|
|
69
|
+
*/
|
|
70
|
+
export class FlowResource extends FlowNode {
|
|
71
|
+
/** Always `'resource'` for an attached node. */
|
|
72
|
+
get role() {
|
|
73
|
+
return 'resource';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Place a node this SDK has no factory for, carrying its definition verbatim
|
|
78
|
+
* (`uipath.exotic.thing@2.1` and the manifest the platform served for it).
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* This is the escape hatch the coverage plan requires: an unknown registry
|
|
82
|
+
* definition is expressible without bypassing serializer invariants. The
|
|
83
|
+
* serializer still owns the node's id, label, `typeVersion` and edge wiring; you
|
|
84
|
+
* supply which definition and which inputs, exactly as a hand-written
|
|
85
|
+
* {@link FlowAction} subclass would.
|
|
86
|
+
*
|
|
87
|
+
* It is also what `decompile` emits for a node type it cannot name, so a
|
|
88
|
+
* round trip preserves the node's TYPE and VERSION instead of degrading it to a
|
|
89
|
+
* placeholder:
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* .step('exotic', rawNode({
|
|
93
|
+
* nodeType: 'uipath.exotic.thing',
|
|
94
|
+
* version: '2.1',
|
|
95
|
+
* manifest: exoticManifest, // exactly what `registry get` returned
|
|
96
|
+
* inputs: { where: input('scope') },
|
|
97
|
+
* }))
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* `manifest` must be a real definition — an exact copy of what the registry or
|
|
101
|
+
* Workbench serves for that `nodeType@version`. It is not permission to invent
|
|
102
|
+
* one: the platform resolves the node against its own catalog at run time, so a
|
|
103
|
+
* hand-written manifest validates locally and fails on the tenant.
|
|
104
|
+
*
|
|
105
|
+
* Prefer a typed factory when one exists — it carries the family's checks, its
|
|
106
|
+
* defaults, and its output contract, none of which a raw node can know.
|
|
107
|
+
*
|
|
108
|
+
* **Never for a connector.** A `uipath.connector.*` node type is refused by
|
|
109
|
+
* `check` and `compile`: a raw node carries the author's inputs verbatim, so the
|
|
110
|
+
* emitted node has no `inputs.detail` and no connection binding — `validate`
|
|
111
|
+
* only warns ("Connector is not configured") and the run can never reach
|
|
112
|
+
* Integration Service. Use {@link connector}, and `registry prepare` when
|
|
113
|
+
* compile reports an input the static library does not carry; use
|
|
114
|
+
* {@link onEvent} for a connector event trigger.
|
|
115
|
+
*
|
|
116
|
+
* @param spec - The definition to compile against, plus the node's inputs.
|
|
117
|
+
* @returns A node to pass to `.step(...)`.
|
|
118
|
+
*/
|
|
119
|
+
export function rawNode(spec) {
|
|
120
|
+
return new RawNode(spec);
|
|
121
|
+
}
|
|
122
|
+
/** The {@link rawNode} implementation — a snapshot-backed contribution. */
|
|
123
|
+
class RawNode extends FlowAction {
|
|
124
|
+
spec;
|
|
125
|
+
constructor(spec) {
|
|
126
|
+
super();
|
|
127
|
+
this.spec = spec;
|
|
128
|
+
}
|
|
129
|
+
/** `check` surfaces the connector refusal as an error; `compile` throws it (see {@link contribute}). */
|
|
130
|
+
diagnostics() {
|
|
131
|
+
const refusal = connectorRawNodeRefusal(this.spec.nodeType);
|
|
132
|
+
return refusal ? [{ code: 'RAW_NODE_CONNECTOR', severity: 'error', message: refusal }] : [];
|
|
133
|
+
}
|
|
134
|
+
contribute(context) {
|
|
135
|
+
// compile does not run diagnostics(); refuse here too so the escape hatch
|
|
136
|
+
// cannot emit an unconfigured connector node.
|
|
137
|
+
const refusal = connectorRawNodeRefusal(this.spec.nodeType);
|
|
138
|
+
if (refusal)
|
|
139
|
+
throw new Error(refusal);
|
|
140
|
+
const version = context.requestedVersion ?? this.spec.version;
|
|
141
|
+
if (context.requestedVersion !== undefined && context.requestedVersion !== this.spec.version) {
|
|
142
|
+
// Versions are exact everywhere in this SDK: a contributor may not
|
|
143
|
+
// substitute its own for an explicit request (design §2.6).
|
|
144
|
+
throw new Error(`rawNode("${this.spec.nodeType}") carries version ${this.spec.version}, but the step requests `
|
|
145
|
+
+ `${context.requestedVersion}. Pass the manifest for the requested version, or drop { version }.`);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
definition: {
|
|
149
|
+
source: 'snapshot',
|
|
150
|
+
nodeType: this.spec.nodeType,
|
|
151
|
+
version,
|
|
152
|
+
manifest: this.spec.manifest,
|
|
153
|
+
},
|
|
154
|
+
...(this.spec.inputs !== undefined ? { inputs: this.spec.inputs } : {}),
|
|
155
|
+
...(this.spec.outputs !== undefined ? { outputs: this.spec.outputs } : {}),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|