@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.
Files changed (238) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +322 -0
  3. package/dist/bindings-v2.d.ts +37 -0
  4. package/dist/bindings-v2.js +155 -0
  5. package/dist/bindings.d.ts +6 -0
  6. package/dist/bindings.js +6 -0
  7. package/dist/bpmn/bpmn-expr-check.d.ts +41 -0
  8. package/dist/bpmn/bpmn-expr-check.js +218 -0
  9. package/dist/bpmn/bpmn-sdk.d.ts +2257 -0
  10. package/dist/bpmn/bpmn-sdk.js +1476 -0
  11. package/dist/bpmn/check-cli.d.ts +3 -0
  12. package/dist/bpmn/check-cli.js +32 -0
  13. package/dist/bpmn/check.d.ts +25 -0
  14. package/dist/bpmn/check.js +430 -0
  15. package/dist/bpmn/compile-cli.d.ts +3 -0
  16. package/dist/bpmn/compile-cli.js +60 -0
  17. package/dist/bpmn/connector.d.ts +56 -0
  18. package/dist/bpmn/connector.js +199 -0
  19. package/dist/bpmn/decompile-cli.d.ts +8 -0
  20. package/dist/bpmn/decompile-cli.js +54 -0
  21. package/dist/bpmn/decompile.d.ts +6 -0
  22. package/dist/bpmn/decompile.js +1108 -0
  23. package/dist/bpmn/format-profile.d.ts +27 -0
  24. package/dist/bpmn/format-profile.js +11 -0
  25. package/dist/bpmn/intsvc.d.ts +77 -0
  26. package/dist/bpmn/intsvc.js +155 -0
  27. package/dist/bpmn/load.d.ts +4 -0
  28. package/dist/bpmn/load.js +22 -0
  29. package/dist/bpmn/merge-cli.d.ts +3 -0
  30. package/dist/bpmn/merge-cli.js +45 -0
  31. package/dist/bpmn/merge.d.ts +19 -0
  32. package/dist/bpmn/merge.js +293 -0
  33. package/dist/bpmn/registry-types.json +1869 -0
  34. package/dist/bpmn/serialize.d.ts +28 -0
  35. package/dist/bpmn/serialize.js +757 -0
  36. package/dist/bpmn/tidy-cli.d.ts +2 -0
  37. package/dist/bpmn/tidy-cli.js +39 -0
  38. package/dist/bpmn/typed-node.d.ts +382 -0
  39. package/dist/bpmn/typed-node.js +551 -0
  40. package/dist/bpmn/uipath-moddle.v1.json +823 -0
  41. package/dist/bpmn/xml-ranges.d.ts +45 -0
  42. package/dist/bpmn/xml-ranges.js +151 -0
  43. package/dist/case/case-expr-check.d.ts +35 -0
  44. package/dist/case/case-expr-check.js +85 -0
  45. package/dist/case/case-sdk.d.ts +1282 -0
  46. package/dist/case/case-sdk.js +923 -0
  47. package/dist/case/check-cli.d.ts +3 -0
  48. package/dist/case/check-cli.js +31 -0
  49. package/dist/case/check.d.ts +18 -0
  50. package/dist/case/check.js +456 -0
  51. package/dist/case/compile-cli.d.ts +3 -0
  52. package/dist/case/compile-cli.js +291 -0
  53. package/dist/case/decompile-cli.d.ts +9 -0
  54. package/dist/case/decompile-cli.js +117 -0
  55. package/dist/case/decompile.d.ts +187 -0
  56. package/dist/case/decompile.js +1170 -0
  57. package/dist/case/entry-points.d.ts +79 -0
  58. package/dist/case/entry-points.js +118 -0
  59. package/dist/case/format-profile.d.ts +60 -0
  60. package/dist/case/format-profile.js +79 -0
  61. package/dist/case/ids.d.ts +24 -0
  62. package/dist/case/ids.js +76 -0
  63. package/dist/case/load.d.ts +12 -0
  64. package/dist/case/load.js +32 -0
  65. package/dist/case/preserve.d.ts +133 -0
  66. package/dist/case/preserve.js +105 -0
  67. package/dist/case/serialize.d.ts +10 -0
  68. package/dist/case/serialize.js +1414 -0
  69. package/dist/check-cli.d.ts +3 -0
  70. package/dist/check-cli.js +118 -0
  71. package/dist/check.d.ts +146 -0
  72. package/dist/check.js +4898 -0
  73. package/dist/cli/commands/bpmn.d.ts +2 -0
  74. package/dist/cli/commands/bpmn.js +73 -0
  75. package/dist/cli/commands/case.d.ts +2 -0
  76. package/dist/cli/commands/case.js +60 -0
  77. package/dist/cli/commands/flow.d.ts +2 -0
  78. package/dist/cli/commands/flow.js +99 -0
  79. package/dist/cli/commands/registry.d.ts +10 -0
  80. package/dist/cli/commands/registry.js +170 -0
  81. package/dist/cli/common.d.ts +30 -0
  82. package/dist/cli/common.js +92 -0
  83. package/dist/cli/index.d.ts +2 -0
  84. package/dist/cli/index.js +18 -0
  85. package/dist/cli-run.d.ts +2 -0
  86. package/dist/cli-run.js +42 -0
  87. package/dist/compile-cli.d.ts +3 -0
  88. package/dist/compile-cli.js +160 -0
  89. package/dist/config.d.ts +47 -0
  90. package/dist/config.js +201 -0
  91. package/dist/core/actions.d.ts +3244 -0
  92. package/dist/core/actions.js +1062 -0
  93. package/dist/core/binding-messages.d.ts +1 -0
  94. package/dist/core/binding-messages.js +16 -0
  95. package/dist/core/bindings.d.ts +12 -0
  96. package/dist/core/bindings.js +67 -0
  97. package/dist/core/ceql.d.ts +73 -0
  98. package/dist/core/ceql.js +272 -0
  99. package/dist/core/cli-spelling.d.ts +39 -0
  100. package/dist/core/cli-spelling.js +62 -0
  101. package/dist/core/connector-raw-node.d.ts +21 -0
  102. package/dist/core/connector-raw-node.js +47 -0
  103. package/dist/core/connectors.d.ts +184 -0
  104. package/dist/core/connectors.js +128 -0
  105. package/dist/core/expr-check.d.ts +93 -0
  106. package/dist/core/expr-check.js +186 -0
  107. package/dist/core/expr.d.ts +323 -0
  108. package/dist/core/expr.js +400 -0
  109. package/dist/core/index.d.ts +10 -0
  110. package/dist/core/index.js +10 -0
  111. package/dist/core/library.d.ts +440 -0
  112. package/dist/core/library.js +1183 -0
  113. package/dist/core/list-envelope.d.ts +45 -0
  114. package/dist/core/list-envelope.js +97 -0
  115. package/dist/core/lookup-store.d.ts +22 -0
  116. package/dist/core/lookup-store.js +85 -0
  117. package/dist/core/lookups.d.ts +227 -0
  118. package/dist/core/lookups.js +231 -0
  119. package/dist/core/node-classes.d.ts +234 -0
  120. package/dist/core/node-classes.js +158 -0
  121. package/dist/core/script-return.d.ts +68 -0
  122. package/dist/core/script-return.js +197 -0
  123. package/dist/core/stable-id.d.ts +28 -0
  124. package/dist/core/stable-id.js +37 -0
  125. package/dist/core-definitions.json +16249 -0
  126. package/dist/decompile-cli.d.ts +3 -0
  127. package/dist/decompile-cli.js +131 -0
  128. package/dist/decompile.d.ts +138 -0
  129. package/dist/decompile.js +2482 -0
  130. package/dist/emit.d.ts +10 -0
  131. package/dist/emit.js +60 -0
  132. package/dist/event-filters.d.ts +130 -0
  133. package/dist/event-filters.js +137 -0
  134. package/dist/flow-expr-check.d.ts +17 -0
  135. package/dist/flow-expr-check.js +193 -0
  136. package/dist/flow-sdk.d.ts +1341 -0
  137. package/dist/flow-sdk.js +1164 -0
  138. package/dist/flow-variables.d.ts +13 -0
  139. package/dist/flow-variables.js +42 -0
  140. package/dist/format-profile.d.ts +72 -0
  141. package/dist/format-profile.js +97 -0
  142. package/dist/generators/_connections.py +287 -0
  143. package/dist/generators/_events.py +355 -0
  144. package/dist/generators/_lookups.py +114 -0
  145. package/dist/generators/_naming.py +185 -0
  146. package/dist/generators/_objects.py +299 -0
  147. package/dist/generators/_resolve.py +273 -0
  148. package/dist/generators/convert_library_to_md.py +1441 -0
  149. package/dist/generators/extract_library.py +125 -0
  150. package/dist/generators/generate_connectors_ts.py +936 -0
  151. package/dist/generators/generate_library_json.py +2527 -0
  152. package/dist/generators/generate_triggers_ts.py +110 -0
  153. package/dist/generators/materialize_registry.py +155 -0
  154. package/dist/generators/prepare_connector.py +1688 -0
  155. package/dist/index.d.ts +35 -0
  156. package/dist/index.js +35 -0
  157. package/dist/ixp-definition.json +1982 -0
  158. package/dist/library.d.ts +6 -0
  159. package/dist/library.js +6 -0
  160. package/dist/load.d.ts +16 -0
  161. package/dist/load.js +95 -0
  162. package/dist/merge-cli.d.ts +3 -0
  163. package/dist/merge-cli.js +47 -0
  164. package/dist/merge.d.ts +125 -0
  165. package/dist/merge.js +0 -0
  166. package/dist/migrate.d.ts +15 -0
  167. package/dist/migrate.js +245 -0
  168. package/dist/node-runtime.d.ts +3 -0
  169. package/dist/node-runtime.js +22 -0
  170. package/dist/package-name.d.ts +17 -0
  171. package/dist/package-name.js +17 -0
  172. package/dist/ref-resolve.d.ts +77 -0
  173. package/dist/ref-resolve.js +170 -0
  174. package/dist/registry/cache.d.ts +55 -0
  175. package/dist/registry/cache.js +134 -0
  176. package/dist/registry/curated-overlay.d.ts +16 -0
  177. package/dist/registry/curated-overlay.js +62 -0
  178. package/dist/registry/extractor.d.ts +22 -0
  179. package/dist/registry/extractor.js +18 -0
  180. package/dist/registry/materialize-bin.d.ts +2 -0
  181. package/dist/registry/materialize-bin.js +7 -0
  182. package/dist/registry/materialize-cli.d.ts +1 -0
  183. package/dist/registry/materialize-cli.js +46 -0
  184. package/dist/registry/materializer.d.ts +23 -0
  185. package/dist/registry/materializer.js +34 -0
  186. package/dist/registry/path-cli.d.ts +1 -0
  187. package/dist/registry/path-cli.js +56 -0
  188. package/dist/registry/prepare-cli.d.ts +62 -0
  189. package/dist/registry/prepare-cli.js +185 -0
  190. package/dist/registry/pull-cli.d.ts +1 -0
  191. package/dist/registry/pull-cli.js +274 -0
  192. package/dist/registry/python.d.ts +26 -0
  193. package/dist/registry/python.js +46 -0
  194. package/dist/registry/search-cli.d.ts +52 -0
  195. package/dist/registry/search-cli.js +159 -0
  196. package/dist/schema-version.d.ts +165 -0
  197. package/dist/schema-version.js +148 -0
  198. package/dist/serialize.d.ts +64 -0
  199. package/dist/serialize.js +6398 -0
  200. package/lib/README.md +112 -0
  201. package/lib/library-json.samples/index.json +158 -0
  202. package/lib/library-json.samples/invariant-collections.json +83 -0
  203. package/lib/library-json.samples/list-envelopes.json +123 -0
  204. package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.json +131 -0
  205. package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.v1def.json +306 -0
  206. package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.json +86 -0
  207. package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.v1def.json +208 -0
  208. package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.json +2040 -0
  209. package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.v1def.json +195 -0
  210. package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.json +169 -0
  211. package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.v1def.json +209 -0
  212. package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.json +63 -0
  213. package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.v1def.json +262 -0
  214. package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.json +63 -0
  215. package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.v1def.json +213 -0
  216. package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.json +227 -0
  217. package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.v1def.json +373 -0
  218. package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.json +116 -0
  219. package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.v1def.json +369 -0
  220. package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.json +56 -0
  221. package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.v1def.json +256 -0
  222. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.json +116 -0
  223. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.v1def.json +320 -0
  224. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.json +56 -0
  225. package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.v1def.json +207 -0
  226. package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.json +107 -0
  227. package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.v1def.json +264 -0
  228. package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.json +142 -0
  229. package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.v1def.json +306 -0
  230. package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.json +107 -0
  231. package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.v1def.json +217 -0
  232. package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.json +85 -0
  233. package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.v1def.json +209 -0
  234. package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.json +755 -0
  235. package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.v1def.json +513 -0
  236. package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.json +122 -0
  237. package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.v1def.json +227 -0
  238. package/package.json +85 -0
package/dist/emit.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { BuiltFlow } from './flow-sdk.js';
2
+ import type { SerializeOpts } from './serialize.js';
3
+ export interface EmitFlowOpts extends SerializeOpts {
4
+ /** Connector library dir; defaults to `$FLOW_SDK_LIBRARY_JSON`. */
5
+ libraryDir?: string;
6
+ /** bindings.json path; defaults to `./bindings.json` when it exists. */
7
+ bindingsFile?: string;
8
+ }
9
+ /** Serialize `built` and write it to `path`; returns the `.flow` JSON. */
10
+ export declare function emitFlow(built: BuiltFlow, path: string, opts?: EmitFlowOpts): any;
package/dist/emit.js ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * emit — write a built flow to a `.flow` file, from the authored script itself.
3
+ *
4
+ * `serialize()` is the library call that turns a `BuiltFlow` into the `.flow`
5
+ * JSON. Using it directly means also resolving the connector library and the
6
+ * bindings file, which is boilerplate every author would repeat identically:
7
+ *
8
+ * ```ts
9
+ * const built = flow('release-rollup')…build();
10
+ * writeFileSync('ReleaseRollup/ReleaseRollup.flow',
11
+ * JSON.stringify(serialize(built, { library: new Library(process.env.FLOW_SDK_LIBRARY_JSON!),
12
+ * bindings: new Bindings('bindings.json') }), null, 2));
13
+ * ```
14
+ *
15
+ * `emitFlow(built, path)` is that, with the two resolutions defaulted the same
16
+ * way `compile-cli` defaults them — library from `$FLOW_SDK_LIBRARY_JSON`,
17
+ * bindings from `./bindings.json` when it exists:
18
+ *
19
+ * ```ts
20
+ * export default emitFlow(flow('release-rollup')…build(), 'ReleaseRollup/ReleaseRollup.flow');
21
+ * ```
22
+ *
23
+ * It deliberately does NOT run `check()`. `compile-cli` does, and refuses to
24
+ * emit on errors; this is the plain library path, so the only errors it raises
25
+ * are the ones `.build()` and `serialize()` raise themselves. Callers who want
26
+ * the static pass should call `check()` — or use `compile-cli`.
27
+ */
28
+ import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
29
+ import { dirname, join } from 'node:path';
30
+ import { serialize } from './serialize.js';
31
+ import { Library } from './library.js';
32
+ import { Bindings } from './bindings.js';
33
+ import { resolveLibraryDir } from './registry/cache.js';
34
+ /**
35
+ * Resolve the connector library the same way `compile-cli` does: only load it
36
+ * when it is actually there, so a flow with no connectors emits fine without a
37
+ * built library. A connector action with no library then fails inside
38
+ * `serialize()` with its own clear error.
39
+ */
40
+ function defaultLibrary(dir) {
41
+ const libDir = resolveLibraryDir(dir);
42
+ if (!libDir || !existsSync(join(libDir, 'index.json')))
43
+ return undefined;
44
+ return new Library(libDir);
45
+ }
46
+ /** Serialize `built` and write it to `path`; returns the `.flow` JSON. */
47
+ export function emitFlow(built, path, opts = {}) {
48
+ const bindFile = opts.bindingsFile ?? (existsSync('bindings.json') ? 'bindings.json' : undefined);
49
+ const flowJson = serialize(built, {
50
+ library: opts.library ?? defaultLibrary(opts.libraryDir),
51
+ bindings: opts.bindings ?? new Bindings(bindFile),
52
+ // Same channel `compile` uses; a host that wants them elsewhere passes `warn`.
53
+ warn: opts.warn ?? ((w) => console.error(` ⚠ [${w.code}] ${w.message}`)),
54
+ });
55
+ const dir = dirname(path);
56
+ if (dir && dir !== '.' && !existsSync(dir))
57
+ mkdirSync(dir, { recursive: true });
58
+ writeFileSync(path, JSON.stringify(flowJson, null, 2) + '\n');
59
+ return flowJson;
60
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * event-filters — ONE connector-event filter condition, lowered the way the
3
+ * platform's own designer lowers it.
4
+ *
5
+ * The designer (`@uipath/maestro-sdk` `JmesHelper`, bundled in the product CLI
6
+ * and driving `uip maestro flow node configure`) stores a filter twice: as a
7
+ * structured tree in `configuration.essentialConfiguration.filter` (what the
8
+ * canvas shows) and as the JMESPath `filterExpression` the runtime subscribes
9
+ * with. Both encodings below were MEASURED against that code path on 2026-09-02
10
+ * (a Data Fabric `record-created` trigger, one operator at a time) and against
11
+ * the deployed corpus (199 archived trigger/event nodes):
12
+ *
13
+ * | authored | designer operator | JMESPath |
14
+ * |--------------------|-------------------|-------------------------------------------|
15
+ * | `contains: 'v'` | `Contains` | `contains(f,'v')` |
16
+ * | `startsWith: 'v'` | `StartsWith` | `starts_with(f,'v')` |
17
+ * | `endsWith: 'v'` | `EndsWith` | `ends_with(f,'v')` |
18
+ * | `equals: 'v'` | `Equals` | `f=='v'` |
19
+ * | `notEquals: 'v'` | `NotEquals` | `f!='v'` |
20
+ * | `lessThan: 3` | `LessThan` | `` f<`3` `` |
21
+ * | `lessThan: '2026-08-04'` (ISO date) | `LessThan` | `to_number(f)<to_number('2026-08-04')` |
22
+ * | … and `lessThanOrEqual` / `greaterThan` / `greaterThanOrEqual` likewise. |
23
+ *
24
+ * Literals follow the designer's `_formatLiteral`: a string is single-quoted, a
25
+ * number or boolean is a JMESPath backtick literal. A DATE is the one case the
26
+ * designer decides from the field's type (`DateTimeOffset` → `to_number(...)` on
27
+ * both sides, because JMESPath compares only numbers). Offline the SDK has no
28
+ * field types for a connection-scoped object, so the VALUE decides: an ISO-8601
29
+ * date/time string under a comparison operator takes the date form. A plain
30
+ * string under a comparison would compare nothing at runtime (JMESPath `<` on
31
+ * strings is null), so `check` refuses it rather than emit a filter that never
32
+ * matches.
33
+ */
34
+ /** The designer's operator vocabulary this SDK emits, keyed by the authored key. */
35
+ export declare const EVENT_FILTER_OPERATORS: {
36
+ readonly contains: {
37
+ readonly designer: "Contains";
38
+ readonly kind: "function";
39
+ readonly jmes: "contains";
40
+ };
41
+ readonly startsWith: {
42
+ readonly designer: "StartsWith";
43
+ readonly kind: "function";
44
+ readonly jmes: "starts_with";
45
+ };
46
+ readonly endsWith: {
47
+ readonly designer: "EndsWith";
48
+ readonly kind: "function";
49
+ readonly jmes: "ends_with";
50
+ };
51
+ readonly equals: {
52
+ readonly designer: "Equals";
53
+ readonly kind: "comparison";
54
+ readonly jmes: "==";
55
+ };
56
+ readonly notEquals: {
57
+ readonly designer: "NotEquals";
58
+ readonly kind: "comparison";
59
+ readonly jmes: "!=";
60
+ };
61
+ readonly lessThan: {
62
+ readonly designer: "LessThan";
63
+ readonly kind: "comparison";
64
+ readonly jmes: "<";
65
+ };
66
+ readonly lessThanOrEqual: {
67
+ readonly designer: "LessThanOrEqual";
68
+ readonly kind: "comparison";
69
+ readonly jmes: "<=";
70
+ };
71
+ readonly greaterThan: {
72
+ readonly designer: "GreaterThan";
73
+ readonly kind: "comparison";
74
+ readonly jmes: ">";
75
+ };
76
+ readonly greaterThanOrEqual: {
77
+ readonly designer: "GreaterThanOrEqual";
78
+ readonly kind: "comparison";
79
+ readonly jmes: ">=";
80
+ };
81
+ };
82
+ export type EventFilterOperatorKey = keyof typeof EVENT_FILTER_OPERATORS;
83
+ /** One authored filter, read structurally: which operator, and its value. */
84
+ export interface ReadEventFilter {
85
+ field: string;
86
+ operator: EventFilterOperatorKey;
87
+ value: string | number | boolean;
88
+ }
89
+ /**
90
+ * Read an authored filter leaf. Returns the operator keys it carries (0, 1 or
91
+ * many) so `check` can name the exact mistake, and the parsed condition when
92
+ * exactly one is present.
93
+ */
94
+ export declare function readEventFilter(leaf: unknown): {
95
+ keys: EventFilterOperatorKey[];
96
+ read?: ReadEventFilter;
97
+ };
98
+ export declare function isIsoDateString(value: unknown): value is string;
99
+ /**
100
+ * Why a filter cannot be lowered, or `undefined` when it can. A comparison on a
101
+ * plain string is the one refused shape: JMESPath `<`/`>` compare numbers only,
102
+ * so the emitted expression would match nothing and nobody would be told.
103
+ */
104
+ export declare function eventFilterProblem(read: ReadEventFilter): string | undefined;
105
+ /**
106
+ * The JMESPath condition for one filter — the grammar the designer emits,
107
+ * without the outer parentheses (the caller groups conditions).
108
+ */
109
+ export declare function eventFilterJmes(read: ReadEventFilter): string;
110
+ /** The designer's tree leaf for one filter — `uiId` is the caller's (it is what keeps a rebuild byte-identical). */
111
+ export declare function eventFilterTreeLeaf(read: ReadEventFilter): {
112
+ id: string;
113
+ operator: string;
114
+ value: {
115
+ value: string | number | boolean;
116
+ rawString: string;
117
+ isLiteral: true;
118
+ };
119
+ };
120
+ /**
121
+ * Read a designer tree leaf back into the authored key + value (decompile).
122
+ * Returns `undefined` for an operator this SDK does not author (`In`, `IsEmpty`, …).
123
+ */
124
+ export declare function eventFilterFromTreeLeaf(leaf: {
125
+ id?: unknown;
126
+ operator?: unknown;
127
+ value?: {
128
+ value?: unknown;
129
+ };
130
+ }): ReadEventFilter | undefined;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * event-filters — ONE connector-event filter condition, lowered the way the
3
+ * platform's own designer lowers it.
4
+ *
5
+ * The designer (`@uipath/maestro-sdk` `JmesHelper`, bundled in the product CLI
6
+ * and driving `uip maestro flow node configure`) stores a filter twice: as a
7
+ * structured tree in `configuration.essentialConfiguration.filter` (what the
8
+ * canvas shows) and as the JMESPath `filterExpression` the runtime subscribes
9
+ * with. Both encodings below were MEASURED against that code path on 2026-09-02
10
+ * (a Data Fabric `record-created` trigger, one operator at a time) and against
11
+ * the deployed corpus (199 archived trigger/event nodes):
12
+ *
13
+ * | authored | designer operator | JMESPath |
14
+ * |--------------------|-------------------|-------------------------------------------|
15
+ * | `contains: 'v'` | `Contains` | `contains(f,'v')` |
16
+ * | `startsWith: 'v'` | `StartsWith` | `starts_with(f,'v')` |
17
+ * | `endsWith: 'v'` | `EndsWith` | `ends_with(f,'v')` |
18
+ * | `equals: 'v'` | `Equals` | `f=='v'` |
19
+ * | `notEquals: 'v'` | `NotEquals` | `f!='v'` |
20
+ * | `lessThan: 3` | `LessThan` | `` f<`3` `` |
21
+ * | `lessThan: '2026-08-04'` (ISO date) | `LessThan` | `to_number(f)<to_number('2026-08-04')` |
22
+ * | … and `lessThanOrEqual` / `greaterThan` / `greaterThanOrEqual` likewise. |
23
+ *
24
+ * Literals follow the designer's `_formatLiteral`: a string is single-quoted, a
25
+ * number or boolean is a JMESPath backtick literal. A DATE is the one case the
26
+ * designer decides from the field's type (`DateTimeOffset` → `to_number(...)` on
27
+ * both sides, because JMESPath compares only numbers). Offline the SDK has no
28
+ * field types for a connection-scoped object, so the VALUE decides: an ISO-8601
29
+ * date/time string under a comparison operator takes the date form. A plain
30
+ * string under a comparison would compare nothing at runtime (JMESPath `<` on
31
+ * strings is null), so `check` refuses it rather than emit a filter that never
32
+ * matches.
33
+ */
34
+ /** The designer's operator vocabulary this SDK emits, keyed by the authored key. */
35
+ export const EVENT_FILTER_OPERATORS = {
36
+ contains: { designer: 'Contains', kind: 'function', jmes: 'contains' },
37
+ startsWith: { designer: 'StartsWith', kind: 'function', jmes: 'starts_with' },
38
+ endsWith: { designer: 'EndsWith', kind: 'function', jmes: 'ends_with' },
39
+ equals: { designer: 'Equals', kind: 'comparison', jmes: '==' },
40
+ notEquals: { designer: 'NotEquals', kind: 'comparison', jmes: '!=' },
41
+ lessThan: { designer: 'LessThan', kind: 'comparison', jmes: '<' },
42
+ lessThanOrEqual: { designer: 'LessThanOrEqual', kind: 'comparison', jmes: '<=' },
43
+ greaterThan: { designer: 'GreaterThan', kind: 'comparison', jmes: '>' },
44
+ greaterThanOrEqual: { designer: 'GreaterThanOrEqual', kind: 'comparison', jmes: '>=' },
45
+ };
46
+ /** The designer operator names that come back as each authored key on decompile. */
47
+ const DESIGNER_TO_KEY = {
48
+ Contains: 'contains',
49
+ StartsWith: 'startsWith',
50
+ EndsWith: 'endsWith',
51
+ Equals: 'equals',
52
+ DateTimeEquals: 'equals',
53
+ NotEquals: 'notEquals',
54
+ DateTimeNotEqual: 'notEquals',
55
+ LessThan: 'lessThan',
56
+ Before: 'lessThan',
57
+ LessThanOrEqual: 'lessThanOrEqual',
58
+ BeforeOrEqual: 'lessThanOrEqual',
59
+ GreaterThan: 'greaterThan',
60
+ After: 'greaterThan',
61
+ GreaterThanOrEqual: 'greaterThanOrEqual',
62
+ AfterOrEqual: 'greaterThanOrEqual',
63
+ };
64
+ /**
65
+ * Read an authored filter leaf. Returns the operator keys it carries (0, 1 or
66
+ * many) so `check` can name the exact mistake, and the parsed condition when
67
+ * exactly one is present.
68
+ */
69
+ export function readEventFilter(leaf) {
70
+ const f = (leaf ?? {});
71
+ const keys = Object.keys(EVENT_FILTER_OPERATORS).filter((k) => f[k] !== undefined);
72
+ if (keys.length !== 1)
73
+ return { keys };
74
+ const value = f[keys[0]];
75
+ if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean')
76
+ return { keys };
77
+ return { keys, read: { field: String(f.field ?? ''), operator: keys[0], value } };
78
+ }
79
+ /** An ISO-8601 calendar date, optionally with a time part — what the designer serializes a date filter as. */
80
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?)?$/;
81
+ export function isIsoDateString(value) {
82
+ return typeof value === 'string' && ISO_DATE.test(value);
83
+ }
84
+ /**
85
+ * Why a filter cannot be lowered, or `undefined` when it can. A comparison on a
86
+ * plain string is the one refused shape: JMESPath `<`/`>` compare numbers only,
87
+ * so the emitted expression would match nothing and nobody would be told.
88
+ */
89
+ export function eventFilterProblem(read) {
90
+ const op = EVENT_FILTER_OPERATORS[read.operator];
91
+ if (op.kind === 'function' && typeof read.value !== 'string') {
92
+ return `\`${read.operator}\` is a text test, so its value must be a string — got ${JSON.stringify(read.value)}.`;
93
+ }
94
+ const ordering = read.operator !== 'equals' && read.operator !== 'notEquals';
95
+ if (op.kind === 'comparison' && ordering && typeof read.value === 'string' && !isIsoDateString(read.value)) {
96
+ return `\`${read.operator}\` orders numbers or dates, and ${JSON.stringify(read.value)} is neither. JMESPath `
97
+ + `compares only numbers, so the runtime would match nothing. Pass a number (\`${read.operator}: 100\`) or an `
98
+ + `ISO date (\`${read.operator}: '2026-08-04'\`); for text use \`equals\`, \`contains\`, \`startsWith\` or \`endsWith\`.`;
99
+ }
100
+ return undefined;
101
+ }
102
+ /** The JMESPath literal for one filter value, per the designer's `_formatLiteral`. */
103
+ function jmesLiteral(value) {
104
+ return typeof value === 'string' ? `'${value}'` : `\`${JSON.stringify(value)}\``;
105
+ }
106
+ /**
107
+ * The JMESPath condition for one filter — the grammar the designer emits,
108
+ * without the outer parentheses (the caller groups conditions).
109
+ */
110
+ export function eventFilterJmes(read) {
111
+ const op = EVENT_FILTER_OPERATORS[read.operator];
112
+ if (op.kind === 'function')
113
+ return `${op.jmes}(${read.field},${jmesLiteral(read.value)})`;
114
+ if (isIsoDateString(read.value))
115
+ return `to_number(${read.field})${op.jmes}to_number('${read.value}')`;
116
+ return `${read.field}${op.jmes}${jmesLiteral(read.value)}`;
117
+ }
118
+ /** The designer's tree leaf for one filter — `uiId` is the caller's (it is what keeps a rebuild byte-identical). */
119
+ export function eventFilterTreeLeaf(read) {
120
+ return {
121
+ id: read.field,
122
+ operator: EVENT_FILTER_OPERATORS[read.operator].designer,
123
+ value: { value: read.value, rawString: JSON.stringify(read.value), isLiteral: true },
124
+ };
125
+ }
126
+ /**
127
+ * Read a designer tree leaf back into the authored key + value (decompile).
128
+ * Returns `undefined` for an operator this SDK does not author (`In`, `IsEmpty`, …).
129
+ */
130
+ export function eventFilterFromTreeLeaf(leaf) {
131
+ const key = DESIGNER_TO_KEY[String(leaf?.operator ?? '')];
132
+ if (!key || typeof leaf?.id !== 'string')
133
+ return undefined;
134
+ const raw = leaf.value?.value;
135
+ const value = typeof raw === 'number' || typeof raw === 'boolean' ? raw : String(raw ?? '');
136
+ return { field: leaf.id, operator: key, value };
137
+ }
@@ -0,0 +1,17 @@
1
+ import { type ExprDiagnostic } from './core/expr-check.js';
2
+ import type { BuiltFlow } from './flow-sdk.js';
3
+ /** A diagnostic plus the node / field it was found in. */
4
+ export interface LocatedDiagnostic extends ExprDiagnostic {
5
+ where: string;
6
+ }
7
+ /** Every first-level expression problem in a built flow, each stamped with its location. */
8
+ export declare function checkFlowExpressions(built: BuiltFlow): LocatedDiagnostic[];
9
+ /**
10
+ * Thrown by `build()` when the first-level expression check finds errors. Its
11
+ * `message` lists every problem (so a runner that prints `err.message` shows them
12
+ * all at once); `diagnostics` carries them structured for a caller that wants them.
13
+ */
14
+ export declare class FlowBuildError extends Error {
15
+ readonly diagnostics: LocatedDiagnostic[];
16
+ constructor(built: BuiltFlow, diagnostics: LocatedDiagnostic[]);
17
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * flow-expr-check — the FLOW adapter over the shared, format-agnostic
3
+ * `core/expr-check`. It is what `FlowBuilder.build()` runs, unconditionally,
4
+ * before it hands back the model to be serialized: a cheap first-level check that
5
+ * every `$vars.*` reference in an expression resolves to something the runtime
6
+ * will provide.
7
+ *
8
+ * WHY IN build(), AND WHY IT THROWS. The full validation is `uip maestro flow
9
+ * validate`, run after the `.flow` is written — richer, but a slower loop. This
10
+ * catches the definite mistakes at the moment the SDK code runs, so a typo'd
11
+ * reference fails HERE, with the node and a suggestion, instead of surviving into
12
+ * a serialized `.flow` and surfacing three steps later. Because `build()`'s return
13
+ * value IS what gets serialized, throwing is the only way to reliably stop a
14
+ * broken model from being written — and since a `.flow.ts` file's default export
15
+ * is `flow(…).build()`, the throw becomes a failed import that any runner (the
16
+ * compile CLI's `.catch`, or a bare `node`) surfaces as a message + non-zero exit
17
+ * with no file emitted.
18
+ *
19
+ * WHY IT ONLY CHECKS REFERENCE ROOTS. The rule is conservative on purpose: it
20
+ * flags only what it can be CERTAIN is wrong — a root that names no declared
21
+ * input, variable, or step. Field-shape and type checks (does step X really
22
+ * output `.foo`, is the comparison type-sound) are heavier and easier to get
23
+ * wrong offline, so they stay with the `validate` CLI. A first-level check that
24
+ * cried wolf would be worse than none.
25
+ *
26
+ * SCRIPT BODIES ARE NOT CHECKED YET — only expressions (`Expr` values). A script
27
+ * body is a plain string carrying its own `$vars.*` references; checking those is
28
+ * the same mechanism and a natural next step, deliberately out of this first cut.
29
+ */
30
+ import { Expr } from './core/expr.js';
31
+ import { checkExpression } from './core/expr-check.js';
32
+ const NOUN = 'input, variable, or step';
33
+ /**
34
+ * Every `$vars` root a reference may legitimately resolve to, across the WHOLE
35
+ * flow: declared inputs, outputs and variables, an event trigger's `start`, and
36
+ * every step name (the runtime's variable bag is flat, so a step's output is
37
+ * readable by name from anywhere it has run). Collecting names globally rather
38
+ * than per-scope is deliberate — it keeps the check from ever flagging a
39
+ * legitimate cross-scope read, which is the conservative direction.
40
+ *
41
+ * Mirrors `check.ts`'s own `declared` set so the two never disagree about what a
42
+ * valid root is.
43
+ */
44
+ function globalRoots(built) {
45
+ const roots = new Set([
46
+ ...built.inputs.map((x) => x.name),
47
+ ...built.outputs.map((x) => x.name),
48
+ ...built.vars.map((x) => x.name),
49
+ ]);
50
+ // The trigger node is always addressable as `start`, and its output carries the
51
+ // flow's own inputs (`$vars.start.output.<input>`) for every trigger kind — an
52
+ // event trigger also publishes the event payload there. So `start` is a valid
53
+ // root whenever a flow reads its trigger; the conservative choice is to allow it
54
+ // unconditionally and leave "is this field really on the trigger" to `validate`.
55
+ // Both spellings are valid at CHECK time: `input('x')` always lowers to
56
+ // `$vars.start.output.x`, and serialize rewrites `start` to a renamed
57
+ // trigger id afterwards — so the check runs while both are in play.
58
+ roots.add('start');
59
+ if (built.triggerId)
60
+ roots.add(built.triggerId);
61
+ for (const ep of built.entryPoints ?? []) {
62
+ roots.add(ep.id);
63
+ addStepNames(ep.steps, roots);
64
+ }
65
+ addStepNames(built.steps, roots);
66
+ return roots;
67
+ }
68
+ function addStepNames(steps, roots) {
69
+ for (const s of steps) {
70
+ // `return` carries a synthetic name; the port-edge kinds carry none at all —
71
+ // they are edges, not nodes, so there is nothing to reference them by.
72
+ if (s.kind !== 'return' && s.kind !== 'stepToRef' && s.kind !== 'stepToList' && s.kind !== 'break')
73
+ roots.add(s.name);
74
+ switch (s.kind) {
75
+ case 'stepToList':
76
+ addStepNames(s.body, roots);
77
+ break;
78
+ case 'branch':
79
+ addStepNames(s.then, roots);
80
+ addStepNames(s.otherwise, roots);
81
+ break;
82
+ case 'switch':
83
+ for (const c of s.cases)
84
+ addStepNames(c.body, roots);
85
+ if (s.default)
86
+ addStepNames(s.default, roots);
87
+ break;
88
+ case 'loop':
89
+ addStepNames(s.body, roots);
90
+ break;
91
+ case 'doWhile':
92
+ addStepNames(s.body, roots);
93
+ break;
94
+ case 'parallel':
95
+ for (const a of s.arms)
96
+ addStepNames(a, roots);
97
+ break;
98
+ }
99
+ }
100
+ }
101
+ function pushExpr(js, literal, where, roots, out) {
102
+ if (literal)
103
+ return; // a literal carries no reference to resolve
104
+ for (const d of checkExpression(js, { roots, noun: NOUN, syntax: 'javascript' }))
105
+ out.push({ ...d, where });
106
+ }
107
+ /** Reach `Expr`s nested anywhere in an action's inputs (connector/http/… inputs can be structured). */
108
+ function deepExprs(val, where, roots, out) {
109
+ if (val instanceof Expr)
110
+ return pushExpr(val.js, val.literal, where, roots, out);
111
+ if (Array.isArray(val)) {
112
+ for (const v of val)
113
+ deepExprs(v, where, roots, out);
114
+ return;
115
+ }
116
+ if (val && typeof val === 'object') {
117
+ for (const v of Object.values(val))
118
+ deepExprs(v, where, roots, out);
119
+ }
120
+ }
121
+ function walk(steps, roots, out) {
122
+ for (const s of steps) {
123
+ switch (s.kind) {
124
+ case 'action':
125
+ // Only `spec.inputs` — NOT a subflow's `spec.child`, whose body is a
126
+ // separate scope already checked by the child's own `build()`.
127
+ deepExprs(s.spec.inputs, s.name, roots, out);
128
+ break;
129
+ case 'stepToList':
130
+ walk(s.body, roots, out);
131
+ break;
132
+ case 'branch':
133
+ pushExpr(s.cond.js, s.cond.literal, s.name, roots, out);
134
+ walk(s.then, roots, out);
135
+ walk(s.otherwise, roots, out);
136
+ break;
137
+ case 'switch': {
138
+ pushExpr(s.on.js, s.on.literal, s.name, roots, out);
139
+ // Inside a case (or default) body the discriminant is bound to
140
+ // `$vars.value`, so it is a valid root only there.
141
+ const caseRoots = new Set(roots).add('value');
142
+ for (const c of s.cases)
143
+ walk(c.body, caseRoots, out);
144
+ if (s.default)
145
+ walk(s.default, caseRoots, out);
146
+ break;
147
+ }
148
+ case 'loop':
149
+ pushExpr(s.collection.js, s.collection.literal, s.name, roots, out);
150
+ if (s.options?.completionCondition) {
151
+ pushExpr(s.options.completionCondition.js, s.options.completionCondition.literal, s.name, roots, out);
152
+ }
153
+ walk(s.body, roots, out);
154
+ break;
155
+ case 'doWhile':
156
+ pushExpr(s.condition.js, s.condition.literal, s.name, roots, out);
157
+ walk(s.body, roots, out);
158
+ break;
159
+ case 'parallel':
160
+ for (const a of s.arms)
161
+ walk(a, roots, out);
162
+ break;
163
+ case 'return':
164
+ for (const [k, v] of Object.entries(s.values))
165
+ pushExpr(v.js, v.literal, `return "${k}"`, roots, out);
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ /** Every first-level expression problem in a built flow, each stamped with its location. */
171
+ export function checkFlowExpressions(built) {
172
+ const out = [];
173
+ const roots = globalRoots(built);
174
+ walk(built.steps, roots, out);
175
+ for (const ep of built.entryPoints ?? [])
176
+ walk(ep.steps, roots, out);
177
+ return out;
178
+ }
179
+ /**
180
+ * Thrown by `build()` when the first-level expression check finds errors. Its
181
+ * `message` lists every problem (so a runner that prints `err.message` shows them
182
+ * all at once); `diagnostics` carries them structured for a caller that wants them.
183
+ */
184
+ export class FlowBuildError extends Error {
185
+ diagnostics;
186
+ constructor(built, diagnostics) {
187
+ const label = built.name || built.id || 'flow';
188
+ const lines = diagnostics.map((d) => ` ✗ [${d.code}] in ${d.where}: ${d.message}${d.suggestion ? ` (did you mean "${d.suggestion}"?)` : ''}`);
189
+ super(`Cannot build flow "${label}" — ${diagnostics.length} expression problem(s):\n${lines.join('\n')}`);
190
+ this.name = 'FlowBuildError';
191
+ this.diagnostics = diagnostics;
192
+ }
193
+ }