@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,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* compile-cli — flow.ts → <Name>.flow
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* node --experimental-strip-types compile-cli.js <flow.ts | BaseName> \
|
|
7
|
+
* [-o out.flow] [--library <library-json dir>] [--bindings <bindings.json>] \
|
|
8
|
+
* [--no-check]
|
|
9
|
+
*
|
|
10
|
+
* --library defaults to $FLOW_SDK_LIBRARY_JSON; --bindings defaults to
|
|
11
|
+
* ./bindings.json when present. Connector actions require a library.
|
|
12
|
+
*
|
|
13
|
+
* `--no-check` skips the SDK's static `check()` pass and emits whatever
|
|
14
|
+
* `.build()` produced. It exists for loops whose verification is somewhere else
|
|
15
|
+
* entirely — e.g. authoring against the product CLI (`uip maestro flow
|
|
16
|
+
* validate` / `debug`), where a pre-emit static pass would answer questions the
|
|
17
|
+
* product's own gates are supposed to answer. `.build()` still throws on
|
|
18
|
+
* structural problems; only the diagnostic pass is skipped.
|
|
19
|
+
*/
|
|
20
|
+
import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
21
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
22
|
+
import { resolveFlowFile, loadBuiltFlow } from './load.js';
|
|
23
|
+
import { serializeWithSidecars, connectorInputErrors } from './serialize.js';
|
|
24
|
+
import { check } from './check.js';
|
|
25
|
+
import { Library } from './library.js';
|
|
26
|
+
import { resolveLibraryDir } from './registry/cache.js';
|
|
27
|
+
import { Bindings } from './bindings.js';
|
|
28
|
+
import { runWhenInvokedDirectly } from './cli-run.js';
|
|
29
|
+
import { connectionResources, mergeBindingsV2, readBindingsV2 } from './bindings-v2.js';
|
|
30
|
+
import { ensureTypeScriptRuntime } from './node-runtime.js';
|
|
31
|
+
function opt(argv, name) {
|
|
32
|
+
const i = argv.indexOf(name);
|
|
33
|
+
return i >= 0 ? argv[i + 1] : undefined;
|
|
34
|
+
}
|
|
35
|
+
export async function run(argv) {
|
|
36
|
+
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
37
|
+
console.error('usage: compile <flow.ts | BaseName> [-o out.flow] [--library <dir>] [--bindings <file>]');
|
|
38
|
+
return 2;
|
|
39
|
+
}
|
|
40
|
+
const flags = new Set(['-o', '--library', '--bindings', '--connectors-local']);
|
|
41
|
+
const noCheck = argv.includes('--no-check');
|
|
42
|
+
const pos = argv.find((a, i) => !flags.has(a) && !flags.has(argv[i - 1]));
|
|
43
|
+
if (!pos) {
|
|
44
|
+
console.error('compile: missing <flow.ts | BaseName>');
|
|
45
|
+
return 2;
|
|
46
|
+
}
|
|
47
|
+
const file = resolveFlowFile(pos);
|
|
48
|
+
ensureTypeScriptRuntime();
|
|
49
|
+
const built = await loadBuiltFlow(file);
|
|
50
|
+
// --library, else $FLOW_SDK_LIBRARY_JSON, else the shared cache `registry pull`
|
|
51
|
+
// filled. Resolving through one helper is what stops `pull` and `compile`
|
|
52
|
+
// disagreeing about where the library is — they did, and a pulled library was
|
|
53
|
+
// invisible to this command.
|
|
54
|
+
const libDir = resolveLibraryDir(opt(argv, '--library'));
|
|
55
|
+
const bindFile = opt(argv, '--bindings') ?? (existsSync('bindings.json') ? 'bindings.json' : undefined);
|
|
56
|
+
// A `prepare-connector`/`prepare-trigger` overlay: auto-detected next to the
|
|
57
|
+
// flow (like bindings.json), it shadows the baked library with full,
|
|
58
|
+
// connection-resolved field schemas. See core/library.ts (LibraryOpts.overlayDir).
|
|
59
|
+
const overlayDir = opt(argv, '--connectors-local')
|
|
60
|
+
?? (existsSync(join('connectors-local', 'index.json')) ? 'connectors-local' : undefined);
|
|
61
|
+
// Only load the library when it's actually present; flows without connectors
|
|
62
|
+
// (e.g. HTTP-only) then compile fine even if the connector cache isn't built.
|
|
63
|
+
// A connector action with no library resolves to a clear error in serialize().
|
|
64
|
+
//
|
|
65
|
+
// Loaded BEFORE check() on purpose: one of check's rules (whether a connector
|
|
66
|
+
// event operation declares any event parameters) can only be answered from the
|
|
67
|
+
// library, and answering it from an assumption instead is what made
|
|
68
|
+
// EVENT_NO_SCOPE an error for HTTP Webhook, whose only correct `where` is empty.
|
|
69
|
+
const library = libDir && existsSync(join(libDir, 'index.json')) ? new Library(libDir, { overlayDir }) : undefined;
|
|
70
|
+
const bindings = new Bindings(bindFile);
|
|
71
|
+
if (!noCheck) {
|
|
72
|
+
const diags = check(built, library
|
|
73
|
+
? {
|
|
74
|
+
eventParams: (connector, event) => {
|
|
75
|
+
try {
|
|
76
|
+
return library.eventParameterFields(connector, event);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined; // unresolvable: serialize() reports it properly
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
lookups: (connector, action, version, object) => library.lookupSpecs(connector, action, version, object),
|
|
83
|
+
resolutions: library.lookupResolutions,
|
|
84
|
+
// Same validator serialize() runs below, so the check pass names the
|
|
85
|
+
// refusal (and stops) instead of printing `0 error(s)` first.
|
|
86
|
+
connectorInputs: (spec, inputs) => {
|
|
87
|
+
try {
|
|
88
|
+
const rc = library.resolve(spec.key, spec.action, spec.version, spec.object);
|
|
89
|
+
return connectorInputErrors(rc, inputs, library.lookupResolutions ?? {}, library.lookupSpecs(spec.key, spec.action, spec.version, spec.object) ?? {});
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
bindings,
|
|
96
|
+
}
|
|
97
|
+
: { bindings });
|
|
98
|
+
const errors = diags.filter((d) => d.level === 'error');
|
|
99
|
+
for (const d of diags)
|
|
100
|
+
console.error(` ${d.level === 'error' ? '✗' : '⚠'} [${d.code}] ${d.message}${d.suggestion ? ` (did you mean "${d.suggestion}"?)` : ''}`);
|
|
101
|
+
if (errors.length) {
|
|
102
|
+
console.error(`compile: ${errors.length} error(s); not emitting.`);
|
|
103
|
+
return 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// The serializer's own observations — a connection or folder value that can
|
|
107
|
+
// never be a tenant resource key — printed in the same `⚠ [CODE]` shape as
|
|
108
|
+
// check()'s, and never fatal: the .flow is still written, exit stays 0.
|
|
109
|
+
const warnings = [];
|
|
110
|
+
const { flow: flowJson, sidecars } = serializeWithSidecars(built, {
|
|
111
|
+
library, bindings, warn: (w) => warnings.push(w),
|
|
112
|
+
});
|
|
113
|
+
for (const w of warnings)
|
|
114
|
+
console.error(` ⚠ [${w.code}] ${w.message}`);
|
|
115
|
+
const out = opt(argv, '-o') ?? `${built.name || basename(file).replace(/\.flow\.ts$|\.ts$/, '')}.flow`;
|
|
116
|
+
writeFileSync(out, JSON.stringify(flowJson, null, 2) + '\n');
|
|
117
|
+
console.log(`compile: wrote ${out} (${flowJson.nodes.length} nodes, ${flowJson.edges.length} edges)`);
|
|
118
|
+
// An inline agent is TWO artifacts: the node, and the agent's own configuration
|
|
119
|
+
// at `<source>/agent.json` — which is where flow-v1's serializer points the
|
|
120
|
+
// runtime (`entryPoint: "<source>/agent.json"`, resolved relative to the
|
|
121
|
+
// project). Writing only the `.flow` would emit a node referencing a definition
|
|
122
|
+
// that is not on disk, which validates locally and has nothing to run deployed.
|
|
123
|
+
// Sidecar paths are relative to the emitted flow, and are confined to its
|
|
124
|
+
// directory: a `..` or absolute path in one would be a bug here, not author
|
|
125
|
+
// input, but it is cheap to refuse rather than write outside the project.
|
|
126
|
+
const outDir = dirname(resolve(out));
|
|
127
|
+
for (const s of sidecars) {
|
|
128
|
+
const target = resolve(outDir, s.path);
|
|
129
|
+
if (target !== outDir && !target.startsWith(outDir + '/')) {
|
|
130
|
+
console.error(`compile: refusing to write a sidecar outside the flow's directory: ${s.path}`);
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
134
|
+
writeFileSync(target, JSON.stringify(s.json, null, 2) + '\n');
|
|
135
|
+
console.log(`compile: wrote ${s.path}`);
|
|
136
|
+
}
|
|
137
|
+
// `bindings_v2.json` — the solution-resource sidecar `uip solution resources
|
|
138
|
+
// refresh` reads. Without it the connection is never declared, so the canvas
|
|
139
|
+
// and the VS Code extension flag the Flow's connection as invalid
|
|
140
|
+
// (flow-builder-sdk#689). Written only inside a scaffolded Flow project:
|
|
141
|
+
// `project.uiproj` is what makes the output directory a project rather than
|
|
142
|
+
// somewhere a `.flow` was merely dropped, and littering a scratch directory
|
|
143
|
+
// with a resource declaration nothing reads would be worse than not writing it.
|
|
144
|
+
if (existsSync(join(outDir, 'project.uiproj'))) {
|
|
145
|
+
const sidecarPath = join(outDir, 'bindings_v2.json');
|
|
146
|
+
const connections = connectionResources(flowJson);
|
|
147
|
+
const existing = readBindingsV2(sidecarPath);
|
|
148
|
+
// Nothing to declare and nothing already declared — do not create an empty
|
|
149
|
+
// file for a flow that has no resources at all.
|
|
150
|
+
if (connections.length > 0 || existing !== undefined) {
|
|
151
|
+
const merged = mergeBindingsV2(existing, connections);
|
|
152
|
+
writeFileSync(sidecarPath, JSON.stringify(merged, null, 2) + '\n');
|
|
153
|
+
const kept = merged.resources.length - connections.length;
|
|
154
|
+
console.log(`compile: wrote bindings_v2.json (${connections.length} connection resource(s)`
|
|
155
|
+
+ `${kept > 0 ? `, ${kept} other resource(s) preserved` : ''})`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return 0;
|
|
159
|
+
}
|
|
160
|
+
runWhenInvokedDirectly(import.meta.url, 'compile', run);
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config — build a connector node's `inputs.detail.configuration` envelope.
|
|
3
|
+
*
|
|
4
|
+
* `uip maestro flow validate` requires connector configuration to be a
|
|
5
|
+
* `=jsonString:`-wrapped `{ essentialConfiguration, optionalConfiguration }`
|
|
6
|
+
* envelope. This mirrors the platform's own rehydrateConfiguration (Tier-A defaults
|
|
7
|
+
* + library-derived per-connector statics), minus the fieldsContainer sidecar.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Convert an Integration Service operation discriminator into an HTTP transport
|
|
11
|
+
* verb. `GETBYID` identifies a curated Retrieve operation in the connector
|
|
12
|
+
* library, but the runtime's transport fields accept real HTTP methods only.
|
|
13
|
+
* Keep the discriminator in `instanceParameters`; normalize only fields that
|
|
14
|
+
* drive the request transport.
|
|
15
|
+
*/
|
|
16
|
+
export declare function transportHttpMethod(method: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Compose the `=jsonString:`-wrapped configuration for a connector library entry.
|
|
19
|
+
*
|
|
20
|
+
* ## Two things here are measured, not chosen
|
|
21
|
+
*
|
|
22
|
+
* Census over **every** connector node in the deployed corpus — 4,026 `.flow`
|
|
23
|
+
* artifacts from the v1 nightlies, 1,421 nodes carrying an `instanceParameters`:
|
|
24
|
+
*
|
|
25
|
+
* | activityType | n | `instanceParameters` keys | `essentialConfiguration.operation` |
|
|
26
|
+
* |---|--:|---|---|
|
|
27
|
+
* | `Curated` | 1,104 | activityType · connectorKey · **httpMethod** · objectName · **subType** · supportsStreaming · version | the VERB: create 452 · list 332 · retrieve 319 · update 1 |
|
|
28
|
+
* | `Generic` | 84 | activityType · connectorKey · objectName · **operation** · supportsStreaming · version | the VERB: list 72 · retrieve 12 |
|
|
29
|
+
* | `CuratedTrigger`/`WaitFor` | 233 | + eventOperation · eventMode | absent |
|
|
30
|
+
*
|
|
31
|
+
* 1. **`operation` is the operation's VERB.** It was hard-wired to the Tier-A
|
|
32
|
+
* default `'create'` here, so a List node shipped `operation: "create"` —
|
|
33
|
+
* wrong on 736 of the 1,188 platform nodes that declare it (62%), silently,
|
|
34
|
+
* since nothing local reads it. It is `lowercase(entry.operation.name)`; the
|
|
35
|
+
* library's names (`List` 2,149 · `Create` 1,969 · `Retrieve` 1,180 · `Delete`
|
|
36
|
+
* 742 · `Update` 573 · `Replace` 390 · …) lower-case exactly onto the
|
|
37
|
+
* platform's values.
|
|
38
|
+
* 2. **`instanceParameters` branches on activityType.** `operation` appears there
|
|
39
|
+
* on exactly **84** nodes and `activityType: "Generic"` on exactly **84** —
|
|
40
|
+
* the same 84 — while `httpMethod` and `subType` appear on **none** of them.
|
|
41
|
+
* So a Generic instance names its verb there and drops the two curated fields.
|
|
42
|
+
*
|
|
43
|
+
* Neither is cosmetic for a generic node: v1's own `check_generic_dynamic_node.py`
|
|
44
|
+
* identifies the activity semantically, by `activityType == 'generic'` **and
|
|
45
|
+
* `operation == 'list'`**, read from these very keys.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildConfiguration(entry: any, version: string, inputValues?: Record<string, unknown>, seed?: string): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config — build a connector node's `inputs.detail.configuration` envelope.
|
|
3
|
+
*
|
|
4
|
+
* `uip maestro flow validate` requires connector configuration to be a
|
|
5
|
+
* `=jsonString:`-wrapped `{ essentialConfiguration, optionalConfiguration }`
|
|
6
|
+
* envelope. This mirrors the platform's own rehydrateConfiguration (Tier-A defaults
|
|
7
|
+
* + library-derived per-connector statics), minus the fieldsContainer sidecar.
|
|
8
|
+
*/
|
|
9
|
+
import { parseCeql } from './core/ceql.js';
|
|
10
|
+
const TIER_A_DEFAULTS = {
|
|
11
|
+
additionalHeaders: null,
|
|
12
|
+
baseObject: null,
|
|
13
|
+
cachedBrowserItems: [],
|
|
14
|
+
cachedLookupValues: [],
|
|
15
|
+
cachedPropertyMappings: [],
|
|
16
|
+
customFieldsRequestDetails: null,
|
|
17
|
+
eventMode: null,
|
|
18
|
+
eventOperation: null,
|
|
19
|
+
executionType: null,
|
|
20
|
+
hasBreakingChanges: false,
|
|
21
|
+
isAutopilotInvalidConfig: false,
|
|
22
|
+
jobArguments: null,
|
|
23
|
+
language: 'en-US',
|
|
24
|
+
maxPageSize: 1000,
|
|
25
|
+
objectActions: [],
|
|
26
|
+
operation: 'create',
|
|
27
|
+
packageVersion: '1.0.0',
|
|
28
|
+
primaryKeys: [],
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Which of an operation's parameters carries a CEQL filter.
|
|
32
|
+
*
|
|
33
|
+
* The authoritative signal is live IS metadata (`design.component ===
|
|
34
|
+
* "FilterBuilder"`), which the offline connector library does not carry. The
|
|
35
|
+
* description does: measured over the shipped library's 7,036 entries, **738 of
|
|
36
|
+
* the 769 parameters named `where` say "CEQL" in their description**, and the
|
|
37
|
+
* marker correctly EXCLUDES the 102 parameters named `filter` and 9 named
|
|
38
|
+
* `$filter` — those are OData, a different language whose strings would be
|
|
39
|
+
* mangled by a CEQL parser.
|
|
40
|
+
*
|
|
41
|
+
* So the description is the discriminator and the name is not. The ~31 `where`
|
|
42
|
+
* parameters with a terse description ("Where clause") are left alone rather
|
|
43
|
+
* than guessed at: emitting a tree that disagrees with the query is worse than
|
|
44
|
+
* emitting none.
|
|
45
|
+
*/
|
|
46
|
+
function ceqlParameterNames(op) {
|
|
47
|
+
const parameters = Array.isArray(op.parameters) ? op.parameters : [];
|
|
48
|
+
return parameters
|
|
49
|
+
.filter((p) => typeof p?.name === 'string' && /ceql/i.test(String(p?.description ?? '')))
|
|
50
|
+
.map((p) => p.name);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The design-time filter trees for an operation's CEQL parameters, keyed by
|
|
54
|
+
* parameter name — `null` when it has none, matching what the platform's own
|
|
55
|
+
* artifacts carry.
|
|
56
|
+
*
|
|
57
|
+
* Only a LITERAL string is parsed. A filter built from a runtime expression
|
|
58
|
+
* renders as `=js:…` here, and the v1 authoring path turns that into a
|
|
59
|
+
* `{var_…}` placeholder plus `inputs.detail.filterVariables`; nothing offline
|
|
60
|
+
* can reproduce that pairing, and a tree that disagrees with the query string is
|
|
61
|
+
* the one outcome worse than no tree. Those keep their runtime half and get no
|
|
62
|
+
* tree — unchanged from before, rather than wrong.
|
|
63
|
+
*/
|
|
64
|
+
function savedFilterTrees(op, inputValues, seed) {
|
|
65
|
+
if (!inputValues)
|
|
66
|
+
return null;
|
|
67
|
+
const trees = {};
|
|
68
|
+
for (const name of ceqlParameterNames(op)) {
|
|
69
|
+
const raw = inputValues[name];
|
|
70
|
+
if (typeof raw !== 'string' || raw.trim() === '' || raw.startsWith('=js:'))
|
|
71
|
+
continue;
|
|
72
|
+
trees[name] = parseCeql(raw, `${seed}:${name}`);
|
|
73
|
+
}
|
|
74
|
+
return Object.keys(trees).length > 0 ? trees : null;
|
|
75
|
+
}
|
|
76
|
+
const ESSENTIAL_KEYS = new Set([
|
|
77
|
+
'connectorVersion',
|
|
78
|
+
'savedFilterTrees',
|
|
79
|
+
'customFieldsRequestDetails',
|
|
80
|
+
'executionType',
|
|
81
|
+
'httpMethod',
|
|
82
|
+
'instanceParameters',
|
|
83
|
+
'objectName',
|
|
84
|
+
'operation',
|
|
85
|
+
'packageVersion',
|
|
86
|
+
'path',
|
|
87
|
+
'unifiedTypesCompatible',
|
|
88
|
+
]);
|
|
89
|
+
/**
|
|
90
|
+
* Convert an Integration Service operation discriminator into an HTTP transport
|
|
91
|
+
* verb. `GETBYID` identifies a curated Retrieve operation in the connector
|
|
92
|
+
* library, but the runtime's transport fields accept real HTTP methods only.
|
|
93
|
+
* Keep the discriminator in `instanceParameters`; normalize only fields that
|
|
94
|
+
* drive the request transport.
|
|
95
|
+
*/
|
|
96
|
+
export function transportHttpMethod(method) {
|
|
97
|
+
return method === 'GETBYID' ? 'GET' : method;
|
|
98
|
+
}
|
|
99
|
+
function schemaReplayDetails(operation, inputValues) {
|
|
100
|
+
if (operation.customFieldsRequestDetails)
|
|
101
|
+
return operation.customFieldsRequestDetails;
|
|
102
|
+
const action = operation.schemaAction;
|
|
103
|
+
const parents = Array.isArray(action?.parents) ? action.parents : [];
|
|
104
|
+
if (!inputValues || typeof action?.name !== 'string' || parents.length === 0)
|
|
105
|
+
return null;
|
|
106
|
+
const parameterValues = [];
|
|
107
|
+
for (const parent of parents) {
|
|
108
|
+
const value = inputValues[parent];
|
|
109
|
+
if (!['string', 'number', 'boolean'].includes(typeof value)
|
|
110
|
+
|| (typeof value === 'string' && value.startsWith('=js:'))) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
parameterValues.push([parent.replaceAll('.', '_sub_'), String(value)]);
|
|
114
|
+
}
|
|
115
|
+
return { objectActionName: action.name, parameterValues };
|
|
116
|
+
}
|
|
117
|
+
function envelope(flat) {
|
|
118
|
+
const essential = {};
|
|
119
|
+
const optional = {};
|
|
120
|
+
for (const [k, v] of Object.entries(flat)) {
|
|
121
|
+
if (ESSENTIAL_KEYS.has(k))
|
|
122
|
+
essential[k] = v;
|
|
123
|
+
else
|
|
124
|
+
optional[k] = v;
|
|
125
|
+
}
|
|
126
|
+
return { essentialConfiguration: essential, optionalConfiguration: optional };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Compose the `=jsonString:`-wrapped configuration for a connector library entry.
|
|
130
|
+
*
|
|
131
|
+
* ## Two things here are measured, not chosen
|
|
132
|
+
*
|
|
133
|
+
* Census over **every** connector node in the deployed corpus — 4,026 `.flow`
|
|
134
|
+
* artifacts from the v1 nightlies, 1,421 nodes carrying an `instanceParameters`:
|
|
135
|
+
*
|
|
136
|
+
* | activityType | n | `instanceParameters` keys | `essentialConfiguration.operation` |
|
|
137
|
+
* |---|--:|---|---|
|
|
138
|
+
* | `Curated` | 1,104 | activityType · connectorKey · **httpMethod** · objectName · **subType** · supportsStreaming · version | the VERB: create 452 · list 332 · retrieve 319 · update 1 |
|
|
139
|
+
* | `Generic` | 84 | activityType · connectorKey · objectName · **operation** · supportsStreaming · version | the VERB: list 72 · retrieve 12 |
|
|
140
|
+
* | `CuratedTrigger`/`WaitFor` | 233 | + eventOperation · eventMode | absent |
|
|
141
|
+
*
|
|
142
|
+
* 1. **`operation` is the operation's VERB.** It was hard-wired to the Tier-A
|
|
143
|
+
* default `'create'` here, so a List node shipped `operation: "create"` —
|
|
144
|
+
* wrong on 736 of the 1,188 platform nodes that declare it (62%), silently,
|
|
145
|
+
* since nothing local reads it. It is `lowercase(entry.operation.name)`; the
|
|
146
|
+
* library's names (`List` 2,149 · `Create` 1,969 · `Retrieve` 1,180 · `Delete`
|
|
147
|
+
* 742 · `Update` 573 · `Replace` 390 · …) lower-case exactly onto the
|
|
148
|
+
* platform's values.
|
|
149
|
+
* 2. **`instanceParameters` branches on activityType.** `operation` appears there
|
|
150
|
+
* on exactly **84** nodes and `activityType: "Generic"` on exactly **84** —
|
|
151
|
+
* the same 84 — while `httpMethod` and `subType` appear on **none** of them.
|
|
152
|
+
* So a Generic instance names its verb there and drops the two curated fields.
|
|
153
|
+
*
|
|
154
|
+
* Neither is cosmetic for a generic node: v1's own `check_generic_dynamic_node.py`
|
|
155
|
+
* identifies the activity semantically, by `activityType == 'generic'` **and
|
|
156
|
+
* `operation == 'list'`**, read from these very keys.
|
|
157
|
+
*/
|
|
158
|
+
export function buildConfiguration(entry, version, inputValues, seed = 'node') {
|
|
159
|
+
const op = entry.operation ?? {};
|
|
160
|
+
const conn = entry.connector ?? {};
|
|
161
|
+
const at = op.activityType;
|
|
162
|
+
const isGeneric = at === 'Generic' || at === 'GenericExpanded';
|
|
163
|
+
const v1ActivityType = isGeneric ? 'Generic' : 'Curated';
|
|
164
|
+
// `operation.name` is the verb (`List`, `Create`, …); the platform stores it
|
|
165
|
+
// lower-cased. Falls back to the Tier-A default for an entry that declares no
|
|
166
|
+
// name, which keeps such an entry's emission exactly as it was.
|
|
167
|
+
const verb = typeof op.name === 'string' && op.name
|
|
168
|
+
? op.name.toLowerCase()
|
|
169
|
+
: TIER_A_DEFAULTS.operation;
|
|
170
|
+
const composed = {
|
|
171
|
+
...TIER_A_DEFAULTS,
|
|
172
|
+
operation: verb,
|
|
173
|
+
customFieldsRequestDetails: schemaReplayDetails(op, inputValues),
|
|
174
|
+
savedFilterTrees: savedFilterTrees(op, inputValues, seed),
|
|
175
|
+
connectorKey: conn.key,
|
|
176
|
+
objectName: op.objectName,
|
|
177
|
+
httpMethod: transportHttpMethod(op.httpMethod),
|
|
178
|
+
instanceParameters: isGeneric
|
|
179
|
+
? {
|
|
180
|
+
connectorKey: conn.key,
|
|
181
|
+
objectName: op.objectName,
|
|
182
|
+
activityType: v1ActivityType,
|
|
183
|
+
version,
|
|
184
|
+
operation: verb,
|
|
185
|
+
supportsStreaming: op.supportsStreaming,
|
|
186
|
+
}
|
|
187
|
+
: {
|
|
188
|
+
connectorKey: conn.key,
|
|
189
|
+
objectName: op.objectName,
|
|
190
|
+
httpMethod: op.httpMethod,
|
|
191
|
+
activityType: v1ActivityType,
|
|
192
|
+
version,
|
|
193
|
+
supportsStreaming: op.supportsStreaming,
|
|
194
|
+
subType: op.subType,
|
|
195
|
+
},
|
|
196
|
+
...(conn.name ? { connectorName: conn.name } : {}),
|
|
197
|
+
...(op.objectDisplayName ? { objectDisplayName: op.objectDisplayName } : {}),
|
|
198
|
+
...(op.pathTemplate || op.path ? { path: op.pathTemplate || op.path } : {}),
|
|
199
|
+
};
|
|
200
|
+
return '=jsonString:' + JSON.stringify(envelope(composed));
|
|
201
|
+
}
|