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