@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
package/dist/library.js
ADDED
package/dist/load.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BuiltFlow } from './flow-sdk.js';
|
|
2
|
+
/** Resolve a user argument (a `.ts` path or a BaseName) to a flow source file. */
|
|
3
|
+
export declare function resolveFlowFile(arg: string): string;
|
|
4
|
+
export declare function loadBuiltFlow(file: string): Promise<BuiltFlow>;
|
|
5
|
+
/**
|
|
6
|
+
* Turn a failed connector import into an error naming the file that exists.
|
|
7
|
+
*
|
|
8
|
+
* Exported for tests. It cannot be exercised through a real `import()` under
|
|
9
|
+
* vitest: vite resolves `./x.js` to `x.ts` itself, so the import succeeds and
|
|
10
|
+
* there is no resolution error to diagnose. Node's own loader — what runs in
|
|
11
|
+
* production — does not, which is the case this handles. So the tests hand it
|
|
12
|
+
* the error object Node produces instead of trying to provoke one.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare function connectorImportDiagnostic(error: unknown): Error | undefined;
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** Shared: dynamic-import an authored flow module and return its BuiltFlow. */
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { statSync } from 'node:fs';
|
|
5
|
+
/** Resolve a user argument (a `.ts` path or a BaseName) to a flow source file. */
|
|
6
|
+
export function resolveFlowFile(arg) {
|
|
7
|
+
const candidates = [arg, `${arg}.flow.ts`, `${arg}.ts`];
|
|
8
|
+
const resolvedArg = resolve(arg);
|
|
9
|
+
const argStat = statSync(resolvedArg, { throwIfNoEntry: false });
|
|
10
|
+
for (const candidate of candidates) {
|
|
11
|
+
const resolvedCandidate = resolve(candidate);
|
|
12
|
+
if (!statSync(resolvedCandidate, { throwIfNoEntry: false })?.isFile())
|
|
13
|
+
continue;
|
|
14
|
+
if (candidate !== arg && argStat?.isDirectory()) {
|
|
15
|
+
console.error(`flow source: "${resolvedArg}" is a directory; using "${resolvedCandidate}"`);
|
|
16
|
+
}
|
|
17
|
+
return resolvedCandidate;
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`flow source not found: tried ${candidates.join(', ')}`);
|
|
20
|
+
}
|
|
21
|
+
export async function loadBuiltFlow(file) {
|
|
22
|
+
let mod;
|
|
23
|
+
try {
|
|
24
|
+
mod = await import(pathToFileURL(file).href);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw connectorImportDiagnostic(error) ?? error;
|
|
28
|
+
}
|
|
29
|
+
const exp = mod.default ?? mod.flow ?? mod.workflow;
|
|
30
|
+
if (!exp)
|
|
31
|
+
throw new Error(`${file} has no default export. Add: export default flow('id')...build();`);
|
|
32
|
+
const built = typeof exp.build === 'function' ? exp.build() : exp;
|
|
33
|
+
if (!built || !Array.isArray(built.steps))
|
|
34
|
+
throw new Error(`${file} default export is not a built flow. Did you call .build()?`);
|
|
35
|
+
return built;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Turn a failed connector import into an error naming the file that exists.
|
|
39
|
+
*
|
|
40
|
+
* Exported for tests. It cannot be exercised through a real `import()` under
|
|
41
|
+
* vitest: vite resolves `./x.js` to `x.ts` itself, so the import succeeds and
|
|
42
|
+
* there is no resolution error to diagnose. Node's own loader — what runs in
|
|
43
|
+
* production — does not, which is the case this handles. So the tests hand it
|
|
44
|
+
* the error object Node produces instead of trying to provoke one.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export function connectorImportDiagnostic(error) {
|
|
49
|
+
const resolutionError = error;
|
|
50
|
+
if (!error ||
|
|
51
|
+
typeof resolutionError.url !== 'string' ||
|
|
52
|
+
!['ERR_MODULE_NOT_FOUND', 'ERR_UNSUPPORTED_DIR_IMPORT'].includes(String(resolutionError.code))) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
let unresolved;
|
|
56
|
+
try {
|
|
57
|
+
unresolved = fileURLToPath(resolutionError.url);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
// Both trees emit plain `.ts`, so the conventional `./x.js` specifier resolves
|
|
63
|
+
// to nothing. `connectors-local/` is written by `registry prepare` and keeps
|
|
64
|
+
// its descriptor data in a sibling directory; `connectors/` is written by
|
|
65
|
+
// `registry pull` and is modules only. Covering both matters because the pull
|
|
66
|
+
// is the FIRST thing an author does — without it that path fails with a bare
|
|
67
|
+
// "Cannot find module" and no clue that the extension is the problem.
|
|
68
|
+
const parent = basename(dirname(unresolved));
|
|
69
|
+
if (parent !== 'connectors-local' && parent !== 'connectors')
|
|
70
|
+
return undefined;
|
|
71
|
+
// The specifier an author actually writes is `./connectors/<key>.js` — the ESM
|
|
72
|
+
// convention of naming the compiled output. So the candidate is that path with
|
|
73
|
+
// `.js` SWAPPED for `.ts`, not `.ts` appended: appending produced
|
|
74
|
+
// `<key>.js.ts`, which never exists, so this diagnostic only fired for an
|
|
75
|
+
// extensionless import and was therefore unreachable in practice.
|
|
76
|
+
const stem = unresolved.endsWith('.js')
|
|
77
|
+
? unresolved.slice(0, -'.js'.length)
|
|
78
|
+
: unresolved;
|
|
79
|
+
const moduleFile = `${stem}.ts`;
|
|
80
|
+
if (!statSync(moduleFile, { throwIfNoEntry: false })?.isFile()) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
if (parent === 'connectors') {
|
|
84
|
+
return new Error(`connector import "${unresolved}" does not name a file. The generated ` +
|
|
85
|
+
`descriptors are TypeScript, so the specifier keeps its real extension; ` +
|
|
86
|
+
`import "${moduleFile}"`);
|
|
87
|
+
}
|
|
88
|
+
const descriptorData = join(dirname(unresolved), 'descriptors', basename(stem));
|
|
89
|
+
if (!statSync(descriptorData, { throwIfNoEntry: false })?.isDirectory()) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
return new Error(`connector import "${unresolved}" does not name a file; module candidate ` +
|
|
93
|
+
`"${moduleFile}" and descriptor data "${descriptorData}" are separate; ` +
|
|
94
|
+
`import "${moduleFile}"`);
|
|
95
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* merge-cli — merge an edited flow back into the original `.flow` (bin `flow-merge`)
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* flow-merge <original.flow> <edited.flow> [-o merged.flow] [--baseline <baseline.flow>]
|
|
7
|
+
*
|
|
8
|
+
* `edited.flow` is compile(decompile(original) after your edits). `--baseline`
|
|
9
|
+
* is compile(decompile(original)) BEFORE any edit — supplying it enables the
|
|
10
|
+
* delta merge (untouched nodes keep their original content, placeholder-safe);
|
|
11
|
+
* omit it for a two-way merge (take the edited graph, re-attach original layout).
|
|
12
|
+
* See merge.ts.
|
|
13
|
+
*/
|
|
14
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
15
|
+
import { basename } from 'node:path';
|
|
16
|
+
import { mergeFlow } from './merge.js';
|
|
17
|
+
import { runWhenInvokedDirectly } from './cli-run.js';
|
|
18
|
+
function opt(argv, name) {
|
|
19
|
+
const i = argv.indexOf(name);
|
|
20
|
+
return i >= 0 ? argv[i + 1] : undefined;
|
|
21
|
+
}
|
|
22
|
+
export function run(argv) {
|
|
23
|
+
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
24
|
+
console.error('usage: flow-merge <original.flow> <edited.flow> [-o merged.flow] [--baseline <baseline.flow>]');
|
|
25
|
+
return 2;
|
|
26
|
+
}
|
|
27
|
+
const flags = new Set(['-o', '--baseline']);
|
|
28
|
+
const positionals = argv.filter((a, i) => !flags.has(a) && !flags.has(argv[i - 1]) && !a.startsWith('-'));
|
|
29
|
+
const [originalPath, editedPath] = positionals;
|
|
30
|
+
if (!originalPath || !editedPath) {
|
|
31
|
+
console.error('flow-merge: need <original.flow> and <edited.flow>');
|
|
32
|
+
return 2;
|
|
33
|
+
}
|
|
34
|
+
const original = JSON.parse(readFileSync(originalPath, 'utf8'));
|
|
35
|
+
const edited = JSON.parse(readFileSync(editedPath, 'utf8'));
|
|
36
|
+
const baselinePath = opt(argv, '--baseline');
|
|
37
|
+
const baseline = baselinePath ? JSON.parse(readFileSync(baselinePath, 'utf8')) : undefined;
|
|
38
|
+
const merged = mergeFlow(original, edited, {
|
|
39
|
+
baseline,
|
|
40
|
+
warn: (m) => console.error(`flow-merge: warning: ${m}`),
|
|
41
|
+
});
|
|
42
|
+
const out = opt(argv, '-o') ?? 'merged.flow';
|
|
43
|
+
writeFileSync(out, JSON.stringify(merged, null, 2) + '\n');
|
|
44
|
+
console.log(`flow-merge: wrote ${basename(out)} (${(merged.nodes ?? []).length} nodes, ${(merged.edges ?? []).length} edges)`);
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
runWhenInvokedDirectly(import.meta.url, 'flow-merge', run);
|
package/dist/merge.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* merge — write a decompiled-then-edited flow back into the ORIGINAL `.flow`
|
|
3
|
+
* JSON, splicing in only what changed and preserving everything cosmetic or
|
|
4
|
+
* mechanically-reconstructable.
|
|
5
|
+
*
|
|
6
|
+
* The brownfield pipeline is:
|
|
7
|
+
*
|
|
8
|
+
* original.flow --decompile--> Flow.flow.ts --(edit)--> --compile--> edited.flow
|
|
9
|
+
* mergeFlow(original, edited[, baseline]) --> merged.flow
|
|
10
|
+
*
|
|
11
|
+
* Why not just take `edited` wholesale? Because decompile is **semantically**
|
|
12
|
+
* lossless, not byte-for-byte: it discards layout, and it lowers node types it
|
|
13
|
+
* cannot yet fully invert (some agents / IxP / …) to `mock()` placeholders. A
|
|
14
|
+
* blind overwrite would flatten an untouched connector's layout and turn an
|
|
15
|
+
* untouched agent into a mock. So the merge is a **delta**:
|
|
16
|
+
*
|
|
17
|
+
* - `baseline` (optional) = compile(decompile(original)) BEFORE any edit — i.e.
|
|
18
|
+
* what a faithful round-trip of the original produces. When a node in
|
|
19
|
+
* `edited` is byte-equal to its `baseline` counterpart, the user did NOT
|
|
20
|
+
* touch it, so the merge keeps the ORIGINAL node verbatim (its real type,
|
|
21
|
+
* inputs, layout — even for a placeholder). Only nodes the user actually
|
|
22
|
+
* changed (or added) are taken from `edited`.
|
|
23
|
+
* - Without a `baseline`, the merge is two-way: it takes `edited`'s graph and
|
|
24
|
+
* re-attaches the original layout by node-id match. This is correct as long
|
|
25
|
+
* as decompile was faithful for every node (the common case).
|
|
26
|
+
*
|
|
27
|
+
* Layout, `metadata`, `solutionId`, `projectId`, `runtime` and `layout` are
|
|
28
|
+
* preserved from the original; `definitions` and `bindings` are unioned
|
|
29
|
+
* (original wins on conflict, since the original's are the tenant-resolved
|
|
30
|
+
* authority). Node ids are stable by construction (decompile names every step by
|
|
31
|
+
* its node id), which is what lets every re-attach key on id.
|
|
32
|
+
*
|
|
33
|
+
* ## Definitions are keyed by `nodeType@version`, not by `nodeType`
|
|
34
|
+
*
|
|
35
|
+
* The node array a merge produces is deliberately MIXED: an untouched node is
|
|
36
|
+
* emitted from the original (so it keeps the original's `typeVersion`), while an
|
|
37
|
+
* edited or added one comes from `edited` (so it carries whatever version the
|
|
38
|
+
* SDK resolved). Both are correct. What was not correct was keying
|
|
39
|
+
* `definitions[]` by `nodeType` alone — one slot per type, original winning —
|
|
40
|
+
* because that dropped the edited file's definition for a type whose version
|
|
41
|
+
* differed, and left the added node pointing at a version the emitted
|
|
42
|
+
* `definitions[]` no longer contained:
|
|
43
|
+
*
|
|
44
|
+
* nodes: convertToCelsius core.action.script@1.0.0
|
|
45
|
+
* definitions: core.action.script@1.0 <- original won, 1.0.0 discarded
|
|
46
|
+
* → validate: Node type "core.action.script:1.0.0" has no matching definition
|
|
47
|
+
*
|
|
48
|
+
* That is flow-builder-sdk#673's second-order failure: it fires on any
|
|
49
|
+
* STRUCTURAL edit (add / move / remove / regroup a node) and never on an
|
|
50
|
+
* in-place field edit, because `nodeUnchanged` keys on type+inputs only. Every
|
|
51
|
+
* agent that hit it abandoned the merge and copied `edited.flow` over the
|
|
52
|
+
* target, which is how a brownfield edit silently rewrote every untouched
|
|
53
|
+
* node's version.
|
|
54
|
+
*
|
|
55
|
+
* So the union is keyed by the `(nodeType, version)` PAIR and selected by the
|
|
56
|
+
* pairs the final node array actually uses. Pair-keying also makes the emitted
|
|
57
|
+
* `definitions[]` able to hold two versions of one family at once — which the
|
|
58
|
+
* format always allowed, which the bundle already ships (`core.logic.loop@1.0.0`
|
|
59
|
+
* + `@2.4`), and which a flow legitimately needs when the author pins one node
|
|
60
|
+
* to an older version and takes the default on another.
|
|
61
|
+
*
|
|
62
|
+
* A node whose pair is in NEITHER file cannot be given a definition here, and a
|
|
63
|
+
* merge that stayed silent about it wrote a file it already knew would fail
|
|
64
|
+
* `validate`. Those are reported through {@link MergeOptions.warn}.
|
|
65
|
+
*/
|
|
66
|
+
interface AnyNode {
|
|
67
|
+
id: string;
|
|
68
|
+
type: string;
|
|
69
|
+
typeVersion?: string;
|
|
70
|
+
parentId?: string;
|
|
71
|
+
ui?: unknown;
|
|
72
|
+
display?: unknown;
|
|
73
|
+
inputs?: Record<string, unknown>;
|
|
74
|
+
outputs?: Record<string, unknown>;
|
|
75
|
+
[k: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
interface AnyEdge {
|
|
78
|
+
id?: string;
|
|
79
|
+
sourceNodeId: string;
|
|
80
|
+
sourcePort: string;
|
|
81
|
+
targetNodeId: string;
|
|
82
|
+
targetPort: string;
|
|
83
|
+
[k: string]: unknown;
|
|
84
|
+
}
|
|
85
|
+
interface AnyFlow {
|
|
86
|
+
id?: string;
|
|
87
|
+
name?: string;
|
|
88
|
+
version?: string;
|
|
89
|
+
nodes?: AnyNode[];
|
|
90
|
+
edges?: AnyEdge[];
|
|
91
|
+
definitions?: Array<{
|
|
92
|
+
nodeType?: string;
|
|
93
|
+
[k: string]: unknown;
|
|
94
|
+
}>;
|
|
95
|
+
variables?: unknown;
|
|
96
|
+
subflows?: Record<string, unknown>;
|
|
97
|
+
bindings?: Array<{
|
|
98
|
+
id?: string;
|
|
99
|
+
[k: string]: unknown;
|
|
100
|
+
}>;
|
|
101
|
+
metadata?: unknown;
|
|
102
|
+
solutionId?: unknown;
|
|
103
|
+
projectId?: unknown;
|
|
104
|
+
layout?: unknown;
|
|
105
|
+
runtime?: unknown;
|
|
106
|
+
[k: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
export interface MergeOptions {
|
|
109
|
+
/**
|
|
110
|
+
* compile(decompile(original)) captured BEFORE the user's edits. Enables the
|
|
111
|
+
* delta merge: a node byte-equal to its baseline is treated as untouched and
|
|
112
|
+
* kept from the original. Omit for a two-way merge (take `edited`, re-attach
|
|
113
|
+
* original layout by id).
|
|
114
|
+
*/
|
|
115
|
+
baseline?: AnyFlow;
|
|
116
|
+
/**
|
|
117
|
+
* Called once per finding, mirroring `DecompileOptions.warn`. Today the only
|
|
118
|
+
* finding is a node whose `(type, typeVersion)` pair has no definition in
|
|
119
|
+
* either input — the one case where the merge cannot produce a self-consistent
|
|
120
|
+
* file and `validate` will refuse the result.
|
|
121
|
+
*/
|
|
122
|
+
warn?: (message: string) => void;
|
|
123
|
+
}
|
|
124
|
+
export declare function mergeFlow(original: AnyFlow, edited: AnyFlow, options?: MergeOptions): AnyFlow;
|
|
125
|
+
export {};
|
package/dist/merge.js
ADDED
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bring a freshly-built FlowFile up to `target`, the file-format version the
|
|
3
|
+
* document will declare.
|
|
4
|
+
*
|
|
5
|
+
* @param flow - The serializer's in-progress FlowFile, mutated in place.
|
|
6
|
+
* @param target - The declared target version. Defaults to the profile pin, so
|
|
7
|
+
* every existing caller keeps its behaviour exactly.
|
|
8
|
+
*/
|
|
9
|
+
export declare function migrateToSchemaVersion(flow: any, target?: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Use {@link migrateToSchemaVersion}. Kept because the name says
|
|
12
|
+
* "1.6" while the function has emitted the profile's version for several floors
|
|
13
|
+
* now — the rename is the point, and callers that pass no target are unchanged.
|
|
14
|
+
*/
|
|
15
|
+
export declare function migrateTo16(flow: any): void;
|
package/dist/migrate.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node inputs the wrap must LEAVE ALONE, keyed by node-type prefix.
|
|
3
|
+
*
|
|
4
|
+
* The envelope is the current file format's general spelling for a dynamic
|
|
5
|
+
* value, and wrapping by a blanket `startsWith('=')` rule is right almost
|
|
6
|
+
* everywhere. It is not right everywhere, and the platform's own migration says
|
|
7
|
+
* so out loud: `migrateV1_2_to_v1_3` skips `node.inputs` entirely for the agent
|
|
8
|
+
* families (`isAgentNodeType` / `isAgentResourceNodeType`, flow-v1
|
|
9
|
+
* `packages/migrations/src/migrations/v1.2-to-v1.3.ts:187`) because "their
|
|
10
|
+
* prompt/template inputs flow through agent.json + the PromptEditor, neither of
|
|
11
|
+
* which is EV-aware". This SDK mirrored the wrap without mirroring the
|
|
12
|
+
* exemption mechanism, and one field paid for it.
|
|
13
|
+
*
|
|
14
|
+
* **`uipath.ixp.*` → `fileRef`** (card ga7, measured 2026-08-01):
|
|
15
|
+
*
|
|
16
|
+
* - `uip maestro flow validate` REFUSES the envelope outright. The product's
|
|
17
|
+
* `ixp-node` validator tests `typeof fileRef !== 'string'` and errors with
|
|
18
|
+
* *"inputs.fileRef must be a `=js:$vars.…` expression"*
|
|
19
|
+
* (uipath-cli `packages/flow-tool/src/services/node-validators/ixp-node-validator.ts:78`).
|
|
20
|
+
* That is criterion 1 of GA row 7, weight 3.0 — so every SDK-authored IxP
|
|
21
|
+
* flow was failing 30% of that row's bar.
|
|
22
|
+
* - The node's OWN registry manifest agrees: `inputDefinition.properties.fileRef`
|
|
23
|
+
* is `{ type: 'string', minLength: 1 }` (`ixp-definition.json`, pulled
|
|
24
|
+
* 2026-07-31), and an object satisfies neither half.
|
|
25
|
+
* - So does the deployed corpus: of the **150** v1-authored `uipath.ixp.*`
|
|
26
|
+
* nodes in `~/root/workspaces/runs` that carry a `fileRef`, **150 carry a
|
|
27
|
+
* STRING** (148 the `=js:$vars.…` expression form, 2 a literal) and **ZERO
|
|
28
|
+
* carry an envelope**. The only 18 envelopes anywhere are this SDK's own
|
|
29
|
+
* output. Spread across file versions 1.6, 1.8 AND 1.9, so this is NOT an
|
|
30
|
+
* era difference — 1.9 is the newest era present and spells it the same way.
|
|
31
|
+
* (Reproduce: `runs/flow-sdk-ga7-2026-08-01/ixp-fileref-scan.py`.)
|
|
32
|
+
*
|
|
33
|
+
* Why the bug survived a platform run: the RUNTIME accepts both. G-19/G-20's
|
|
34
|
+
* `flow debug` runs Completed with the envelope and really extracted six fields
|
|
35
|
+
* from the real PDF, so nothing before this card had reason to look. `flow
|
|
36
|
+
* validate` is the only reader that refuses it, and it was never run on an
|
|
37
|
+
* SDK-authored IxP flow until now (lesson 45, one family over).
|
|
38
|
+
*/
|
|
39
|
+
import { FLOW_FORMAT_PROFILE } from './format-profile.js';
|
|
40
|
+
import { schemaVersionAtLeast } from './schema-version.js';
|
|
41
|
+
import { readFlowGlobals } from './flow-variables.js';
|
|
42
|
+
const UNWRAPPED_INPUTS = [
|
|
43
|
+
{ typePrefix: 'uipath.ixp.', keys: new Set(['fileRef']) },
|
|
44
|
+
];
|
|
45
|
+
/** True if `key` on a node of type `nodeType` must stay a plain string. */
|
|
46
|
+
function isUnwrappedInput(nodeType, key) {
|
|
47
|
+
if (typeof nodeType !== 'string')
|
|
48
|
+
return false;
|
|
49
|
+
return UNWRAPPED_INPUTS.some((r) => nodeType.startsWith(r.typePrefix) && r.keys.has(key));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The only `fieldType` values `@uipath/flow-schema`'s `expressionValueSchema`
|
|
53
|
+
* accepts (it is `.strict()`, so anything else fails the file's schema and with
|
|
54
|
+
* it every migration hop and `uip maestro flow validate`).
|
|
55
|
+
*/
|
|
56
|
+
const FIELD_TYPES = new Set(['string', 'number', 'boolean', 'object', 'array', 'null']);
|
|
57
|
+
/**
|
|
58
|
+
* The emission steps that are CONDITIONAL on the target file-format version,
|
|
59
|
+
* newest gate last.
|
|
60
|
+
*
|
|
61
|
+
* The ladder exists because a declared version is a claim about the whole
|
|
62
|
+
* document (`schema-version.ts`), so "which target am I writing?" has to be
|
|
63
|
+
* able to change what gets written — the alternative is stamping a version and
|
|
64
|
+
* hoping the bytes match it. Today one step is version-gated and it is the
|
|
65
|
+
* expression envelope: the `{ type, expression, fieldType }` spelling is the
|
|
66
|
+
* 1.6-and-later form, so the gate is `>= 1.6` rather than unconditional.
|
|
67
|
+
*
|
|
68
|
+
* Nothing in this table distinguishes 1.9 from 1.10, and that is a READ result
|
|
69
|
+
* rather than an omission: `workflowSchemaV1_10` is `workflowSchemaV1_9.extend`
|
|
70
|
+
* with a new `version` literal, and the 1.9 -> 1.10 hop is a binding-name data
|
|
71
|
+
* repair for a defect this SDK cannot emit (see `FLOW_SCHEMA_VERSIONS`). The
|
|
72
|
+
* first genuine divergence gets a row here, and gets it in one place.
|
|
73
|
+
*/
|
|
74
|
+
const VERSION_CONDITIONAL = [
|
|
75
|
+
{
|
|
76
|
+
from: '1.6',
|
|
77
|
+
what: 'wrap dynamic values into the { type, expression, fieldType } envelope',
|
|
78
|
+
apply: wrapDynamicValues,
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
/**
|
|
82
|
+
* Bring a freshly-built FlowFile up to `target`, the file-format version the
|
|
83
|
+
* document will declare.
|
|
84
|
+
*
|
|
85
|
+
* @param flow - The serializer's in-progress FlowFile, mutated in place.
|
|
86
|
+
* @param target - The declared target version. Defaults to the profile pin, so
|
|
87
|
+
* every existing caller keeps its behaviour exactly.
|
|
88
|
+
*/
|
|
89
|
+
export function migrateToSchemaVersion(flow, target = FLOW_FORMAT_PROFILE.version) {
|
|
90
|
+
flow.version = target;
|
|
91
|
+
delete flow.metadata;
|
|
92
|
+
for (const step of VERSION_CONDITIONAL)
|
|
93
|
+
if (schemaVersionAtLeast(target, step.from))
|
|
94
|
+
step.apply(flow);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated Use {@link migrateToSchemaVersion}. Kept because the name says
|
|
98
|
+
* "1.6" while the function has emitted the profile's version for several floors
|
|
99
|
+
* now — the rename is the point, and callers that pass no target are unchanged.
|
|
100
|
+
*/
|
|
101
|
+
export function migrateTo16(flow) {
|
|
102
|
+
migrateToSchemaVersion(flow);
|
|
103
|
+
}
|
|
104
|
+
function wrapDynamicValues(flow) {
|
|
105
|
+
const schemaByType = new Map();
|
|
106
|
+
for (const d of flow.definitions ?? []) {
|
|
107
|
+
schemaByType.set(d.nodeType, {
|
|
108
|
+
inputs: d.inputDefinition?.properties,
|
|
109
|
+
outputs: d.outputDefinition?.properties,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const globalTypeByName = new Map();
|
|
113
|
+
for (const g of readFlowGlobals(flow.variables))
|
|
114
|
+
if (g.id && g.type)
|
|
115
|
+
globalTypeByName.set(g.id, g.type);
|
|
116
|
+
const subflows = (flow.subflows ?? {});
|
|
117
|
+
wrapNodes(flow.nodes ?? [], schemaByType, globalTypeByName, subflows);
|
|
118
|
+
wrapVariableUpdates(flow.variables, globalTypeByName);
|
|
119
|
+
for (const sub of Object.values(subflows)) {
|
|
120
|
+
// Each subflow body has its OWN globals — an End node inside it maps the
|
|
121
|
+
// subflow's outputs, not the parent flow's, so the fieldType lookup has to
|
|
122
|
+
// follow the scope. (Before subflows existed this always fell back to
|
|
123
|
+
// "string", which is right only by accident for a string-typed output.)
|
|
124
|
+
const scopeTypes = new Map();
|
|
125
|
+
for (const g of readFlowGlobals(sub?.variables))
|
|
126
|
+
if (g.id && g.type)
|
|
127
|
+
scopeTypes.set(g.id, g.type);
|
|
128
|
+
wrapNodes(sub?.nodes ?? [], schemaByType, scopeTypes, subflows);
|
|
129
|
+
wrapVariableUpdates(sub?.variables, scopeTypes);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function wrapNodes(nodes, schemaByType, globalTypeByName, subflows = {}) {
|
|
133
|
+
for (const n of nodes) {
|
|
134
|
+
const schema = schemaByType.get(n.type);
|
|
135
|
+
// A subflow node's inputs are declared by its BODY, not by its type
|
|
136
|
+
// (`core.subflow` has no inputDefinition), so its fieldTypes come from the
|
|
137
|
+
// subflow's `in` variables — keyed, as everywhere, by the node's own id.
|
|
138
|
+
const childInputType = new Map();
|
|
139
|
+
if (n.type === 'core.subflow') {
|
|
140
|
+
for (const g of readFlowGlobals(subflows[n.id]?.variables))
|
|
141
|
+
if (g?.direction === 'in' && g.id && g.type)
|
|
142
|
+
childInputType.set(g.id, g.type);
|
|
143
|
+
}
|
|
144
|
+
if (n.inputs) {
|
|
145
|
+
for (const [k, v] of Object.entries(n.inputs)) {
|
|
146
|
+
if (typeof v !== 'string')
|
|
147
|
+
continue;
|
|
148
|
+
if (isWrappedSource(v))
|
|
149
|
+
continue;
|
|
150
|
+
// The platform reads a few inputs as plain `=js:` strings and refuses
|
|
151
|
+
// the envelope on them — see UNWRAPPED_INPUTS for each one's evidence.
|
|
152
|
+
if (isUnwrappedInput(n.type, k))
|
|
153
|
+
continue;
|
|
154
|
+
const declared = fieldTypeOf(childInputType.get(k) ?? schema?.inputs?.[k]?.type);
|
|
155
|
+
if (v.startsWith('=') || declared !== 'string')
|
|
156
|
+
n.inputs[k] = wrap(v, declared);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (n.outputs) {
|
|
160
|
+
for (const [k, vobj] of Object.entries(n.outputs)) {
|
|
161
|
+
if (!vobj || typeof vobj !== 'object')
|
|
162
|
+
continue;
|
|
163
|
+
const src = vobj.source;
|
|
164
|
+
if (typeof src !== 'string' || isWrappedSource(src))
|
|
165
|
+
continue;
|
|
166
|
+
const declared = fieldTypeOf(n.type === 'core.control.end' || n.type === 'core.logic.terminate'
|
|
167
|
+
? globalTypeByName.get(k)
|
|
168
|
+
: schema?.outputs?.[k]?.type);
|
|
169
|
+
vobj.source = wrap(src, declared);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* `variables.variableUpdates[*][*].expression` — an ExpressionValue object, not
|
|
176
|
+
* a string, from file version **1.3** on: the 1.2→1.3 migration is what
|
|
177
|
+
* converted the legacy strings ("Migration v1.2 → v1.3 converts legacy
|
|
178
|
+
* strings", `v1_3VariableUpdateSchema` in `@uipath/flow-schema`), and every
|
|
179
|
+
* later version inherits that shape.
|
|
180
|
+
*
|
|
181
|
+
* Leaving them as raw strings while declaring 1.8 makes the file
|
|
182
|
+
* self-inconsistent, and the product rejects it at the first migration hop it
|
|
183
|
+
* tries — `uip maestro flow validate` reports
|
|
184
|
+
* `[MIGRATION] Workflow migration failed at 1.8→1.9 … Offending field(s):
|
|
185
|
+
* variables.variableUpdates.end.0.expression`, because each migration validates
|
|
186
|
+
* its input against that version's schema. (Only flows that write a variable —
|
|
187
|
+
* i.e. every flow with a `.return(…)` — carry the field at all, which is why
|
|
188
|
+
* connector-only fixtures passed while any flow with an End-node update failed.)
|
|
189
|
+
*/
|
|
190
|
+
function wrapVariableUpdates(variables, typeByName) {
|
|
191
|
+
const byNode = variables?.variableUpdates;
|
|
192
|
+
if (!byNode || typeof byNode !== 'object')
|
|
193
|
+
return;
|
|
194
|
+
for (const updates of Object.values(byNode)) {
|
|
195
|
+
for (const u of updates ?? []) {
|
|
196
|
+
if (!u || typeof u.expression !== 'string')
|
|
197
|
+
continue;
|
|
198
|
+
u.expression = wrap(u.expression, fieldTypeOf(typeByName.get(u.variableId)));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function isWrappedSource(v) {
|
|
203
|
+
return typeof v === 'object' && v !== null && 'type' in v && 'expression' in v && 'fieldType' in v;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Normalize a declared type to a `fieldType` the platform's schema accepts,
|
|
207
|
+
* mirroring flow-schema's own `jsonSchemaTypeToFieldType` +
|
|
208
|
+
* `expectedTypeToFieldType`: `integer`→`number`, `text`→`string`, a JSON-Schema
|
|
209
|
+
* type UNION (`["object","null"]`, which `core.action.http`'s
|
|
210
|
+
* `swaggerDefinition` declares) → its first mappable member, and anything else
|
|
211
|
+
* — including the SDK's own `types.file` / `types.any` — → `string`, the
|
|
212
|
+
* platform's own default.
|
|
213
|
+
*
|
|
214
|
+
* Without this a single `.output({ blob: types.any })` (or any node input typed
|
|
215
|
+
* `integer`, of which the connector library has 593) emitted `fieldType: "any"`
|
|
216
|
+
* and made the whole file unparseable: `expressionValueSchema` is `.strict()`
|
|
217
|
+
* over a six-value enum.
|
|
218
|
+
*/
|
|
219
|
+
function fieldTypeOf(declared) {
|
|
220
|
+
if (Array.isArray(declared)) {
|
|
221
|
+
for (const t of declared) {
|
|
222
|
+
const mapped = mapScalarType(t);
|
|
223
|
+
if (mapped)
|
|
224
|
+
return mapped;
|
|
225
|
+
}
|
|
226
|
+
return 'string';
|
|
227
|
+
}
|
|
228
|
+
return mapScalarType(declared) ?? 'string';
|
|
229
|
+
}
|
|
230
|
+
function mapScalarType(t) {
|
|
231
|
+
if (typeof t !== 'string')
|
|
232
|
+
return undefined;
|
|
233
|
+
if (FIELD_TYPES.has(t))
|
|
234
|
+
return t;
|
|
235
|
+
if (t === 'integer')
|
|
236
|
+
return 'number';
|
|
237
|
+
if (t === 'text')
|
|
238
|
+
return 'string';
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
function wrap(value, fieldType) {
|
|
242
|
+
if (value.startsWith('=js:'))
|
|
243
|
+
return { type: 'jsExpression', expression: value.slice(4), fieldType };
|
|
244
|
+
return { type: 'literal', expression: value, fieldType };
|
|
245
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
export function typeStripDecision(version, execArgv = []) {
|
|
3
|
+
const [major = 0, minor = 0] = version.split('.').map(Number);
|
|
4
|
+
if (major >= 23 || (major === 22 && minor >= 18))
|
|
5
|
+
return 'native';
|
|
6
|
+
if (major === 22 && minor >= 6) {
|
|
7
|
+
return execArgv.includes('--experimental-strip-types') ? 'native' : 'flag';
|
|
8
|
+
}
|
|
9
|
+
return 'unsupported';
|
|
10
|
+
}
|
|
11
|
+
export function ensureTypeScriptRuntime() {
|
|
12
|
+
const decision = typeStripDecision(process.versions.node, process.execArgv);
|
|
13
|
+
if (decision === 'native')
|
|
14
|
+
return;
|
|
15
|
+
if (decision === 'unsupported') {
|
|
16
|
+
throw new Error(`authoring TypeScript requires Node >= 22.6 (found ${process.versions.node}); install Node 22 LTS or newer`);
|
|
17
|
+
}
|
|
18
|
+
const child = spawnSync(process.execPath, ['--experimental-strip-types', ...process.execArgv, ...process.argv.slice(1)], { stdio: 'inherit', env: process.env });
|
|
19
|
+
if (child.error)
|
|
20
|
+
throw child.error;
|
|
21
|
+
process.exit(child.status ?? 1);
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The published package name, in one place.
|
|
3
|
+
*
|
|
4
|
+
* Four CLIs and the registry materializer bake this into the `import { … } from
|
|
5
|
+
* '…'` line of the source they emit, so that decompiled and generated files
|
|
6
|
+
* resolve for a package consumer rather than only inside this checkout. Before
|
|
7
|
+
* the rename to `@uipath/maestro-builder-sdk` those were five independent string
|
|
8
|
+
* literals; a sixth emitter would have been a sixth. Import the constant.
|
|
9
|
+
*
|
|
10
|
+
* These are the *defaults* — every emitter still takes `--import` to override
|
|
11
|
+
* the specifier, which is what an in-tree or vendored consumer uses.
|
|
12
|
+
*/
|
|
13
|
+
export declare const PACKAGE_NAME = "@uipath/maestro-builder-sdk";
|
|
14
|
+
/** The `./case` subpath export. */
|
|
15
|
+
export declare const CASE_IMPORT = "@uipath/maestro-builder-sdk/case";
|
|
16
|
+
/** The `./bpmn` subpath export. */
|
|
17
|
+
export declare const BPMN_IMPORT = "@uipath/maestro-builder-sdk/bpmn";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The published package name, in one place.
|
|
3
|
+
*
|
|
4
|
+
* Four CLIs and the registry materializer bake this into the `import { … } from
|
|
5
|
+
* '…'` line of the source they emit, so that decompiled and generated files
|
|
6
|
+
* resolve for a package consumer rather than only inside this checkout. Before
|
|
7
|
+
* the rename to `@uipath/maestro-builder-sdk` those were five independent string
|
|
8
|
+
* literals; a sixth emitter would have been a sixth. Import the constant.
|
|
9
|
+
*
|
|
10
|
+
* These are the *defaults* — every emitter still takes `--import` to override
|
|
11
|
+
* the specifier, which is what an in-tree or vendored consumer uses.
|
|
12
|
+
*/
|
|
13
|
+
export const PACKAGE_NAME = '@uipath/maestro-builder-sdk';
|
|
14
|
+
/** The `./case` subpath export. */
|
|
15
|
+
export const CASE_IMPORT = `${PACKAGE_NAME}/case`;
|
|
16
|
+
/** The `./bpmn` subpath export. */
|
|
17
|
+
export const BPMN_IMPORT = `${PACKAGE_NAME}/bpmn`;
|