@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,77 @@
1
+ /**
2
+ * `$ref` resolution for SPLIT `.flow` files (design §5, Phase 5E).
3
+ *
4
+ * The format lets a `.flow` be split across sibling files with JSON Reference
5
+ * (`{ "$ref": "./layout.json" }`) — used to sideline layout or definitions, or
6
+ * to extract a subflow out of an oversized file
7
+ * (`flow-schema/REF_RESOLUTION.md`, MST-8579). Decompile has to READ those, so
8
+ * this resolves them into ONE object model before anything else looks at the
9
+ * document.
10
+ *
11
+ * Compile keeps writing a single file, deliberately: nothing in the designer or
12
+ * the skills splits files today, so write-through splitting would be a merge
13
+ * concern with no producer to round-trip against.
14
+ *
15
+ * The semantics below are the platform resolver's, mirrored rather than
16
+ * reinvented (`flow-schema/src/ref-resolver/`), because a file the platform
17
+ * reads one way and the SDK another is worse than no support at all:
18
+ *
19
+ * - **`$ref` replaces the whole object.** JSON Reference, not JSON Schema —
20
+ * sibling properties beside a `$ref` are dropped, not merged.
21
+ * - **Same-document fragments (`#/…`) are left ALONE.** They are legitimate
22
+ * internal pointers — a connector tool's `outputSchema` carries them — and
23
+ * they are not file references. Resolving them as filenames is the exact
24
+ * regression the platform's own guard exists to prevent.
25
+ * - **Relative paths only.** Absolute paths, Windows drive letters, protocol
26
+ * URIs and traversal above the referencing file's root are REFUSED, because
27
+ * a `.flow` is untrusted input and the alternative is a file-exfiltration
28
+ * primitive (`$ref: '/etc/passwd'`, `$ref: 'https://…'`).
29
+ * - **Any depth**, and resolved content is walked again for its own refs.
30
+ *
31
+ * Where this deliberately differs: an unresolvable ref is an ERROR here, not a
32
+ * warning. The platform's resolver collects non-fatal errors because a canvas
33
+ * can render a partial document and let a person fix it; decompile turns the
34
+ * document into SOURCE, and a silently-missing subtree becomes source that
35
+ * compiles to a different flow. Failing names the file that is missing.
36
+ */
37
+ /** How this module reads a sibling file. Injected so it is testable and so the
38
+ * SDK core stays free of `node:fs`. */
39
+ export type RefReader = (resolvedPath: string) => string;
40
+ export interface ResolveRefsOptions {
41
+ /**
42
+ * The referencing document's own path — `$ref`s resolve against its
43
+ * DIRECTORY. May be project-relative (`project/main.flow`), POSIX absolute,
44
+ * or Windows absolute (backslashes are normalized).
45
+ */
46
+ baseUri: string;
47
+ /** Reads a sibling file's text, by resolved path. */
48
+ read: RefReader;
49
+ /** Recursion ceiling, mirroring the platform's own. Defaults to 10. */
50
+ maxDepth?: number;
51
+ }
52
+ /**
53
+ * Resolve one `$ref` value against the referencing file, refusing everything
54
+ * the platform refuses (see the module note for why each is refused).
55
+ */
56
+ export declare function resolveRefPath(baseUri: string, refPath: string): string;
57
+ /**
58
+ * Resolve every local-file `$ref` in `doc` into one object model.
59
+ *
60
+ * ```ts
61
+ * const raw = JSON.parse(readFileSync('Main.flow', 'utf8'));
62
+ * const flow = resolveFlowRefs(raw, {
63
+ * baseUri: 'Main.flow',
64
+ * read: (p) => readFileSync(p, 'utf8'),
65
+ * });
66
+ * ```
67
+ *
68
+ * @param doc - The parsed document, straight from the main file.
69
+ * @param options - The referencing path, the file reader, and the depth cap.
70
+ * @returns The same document with every resolvable `$ref` replaced in place
71
+ * (a new object; the input is not mutated).
72
+ * @throws If a `$ref` is unreadable, circular, over the depth cap, or names a
73
+ * path the format refuses.
74
+ */
75
+ export declare function resolveFlowRefs(doc: unknown, options: ResolveRefsOptions): unknown;
76
+ /** True if `doc` contains any local-file `$ref` — i.e. it is a SPLIT document. */
77
+ export declare function hasFileRefs(doc: unknown): boolean;
@@ -0,0 +1,170 @@
1
+ /**
2
+ * `$ref` resolution for SPLIT `.flow` files (design §5, Phase 5E).
3
+ *
4
+ * The format lets a `.flow` be split across sibling files with JSON Reference
5
+ * (`{ "$ref": "./layout.json" }`) — used to sideline layout or definitions, or
6
+ * to extract a subflow out of an oversized file
7
+ * (`flow-schema/REF_RESOLUTION.md`, MST-8579). Decompile has to READ those, so
8
+ * this resolves them into ONE object model before anything else looks at the
9
+ * document.
10
+ *
11
+ * Compile keeps writing a single file, deliberately: nothing in the designer or
12
+ * the skills splits files today, so write-through splitting would be a merge
13
+ * concern with no producer to round-trip against.
14
+ *
15
+ * The semantics below are the platform resolver's, mirrored rather than
16
+ * reinvented (`flow-schema/src/ref-resolver/`), because a file the platform
17
+ * reads one way and the SDK another is worse than no support at all:
18
+ *
19
+ * - **`$ref` replaces the whole object.** JSON Reference, not JSON Schema —
20
+ * sibling properties beside a `$ref` are dropped, not merged.
21
+ * - **Same-document fragments (`#/…`) are left ALONE.** They are legitimate
22
+ * internal pointers — a connector tool's `outputSchema` carries them — and
23
+ * they are not file references. Resolving them as filenames is the exact
24
+ * regression the platform's own guard exists to prevent.
25
+ * - **Relative paths only.** Absolute paths, Windows drive letters, protocol
26
+ * URIs and traversal above the referencing file's root are REFUSED, because
27
+ * a `.flow` is untrusted input and the alternative is a file-exfiltration
28
+ * primitive (`$ref: '/etc/passwd'`, `$ref: 'https://…'`).
29
+ * - **Any depth**, and resolved content is walked again for its own refs.
30
+ *
31
+ * Where this deliberately differs: an unresolvable ref is an ERROR here, not a
32
+ * warning. The platform's resolver collects non-fatal errors because a canvas
33
+ * can render a partial document and let a person fix it; decompile turns the
34
+ * document into SOURCE, and a silently-missing subtree becomes source that
35
+ * compiles to a different flow. Failing names the file that is missing.
36
+ */
37
+ /**
38
+ * Collapse `.` and `..` segments, preserving a leading `/` for POSIX absolute
39
+ * paths — the platform's `normalizePath`, same behavior.
40
+ */
41
+ function normalizePath(path) {
42
+ const isAbsolute = path.startsWith('/');
43
+ const segments = path.split('/');
44
+ const result = [];
45
+ for (const segment of segments) {
46
+ if (segment === '' || segment === '.')
47
+ continue;
48
+ if (segment === '..' && result.length > 0 && result[result.length - 1] !== '..') {
49
+ result.pop();
50
+ }
51
+ else {
52
+ result.push(segment);
53
+ }
54
+ }
55
+ return (isAbsolute ? '/' : '') + result.join('/');
56
+ }
57
+ /**
58
+ * Resolve one `$ref` value against the referencing file, refusing everything
59
+ * the platform refuses (see the module note for why each is refused).
60
+ */
61
+ export function resolveRefPath(baseUri, refPath) {
62
+ if (refPath.startsWith('#')) {
63
+ throw new Error(`$ref "${refPath}" is a same-document fragment, not a file — it must not be resolved as a path.`);
64
+ }
65
+ if (refPath.startsWith('/') || /^[a-zA-Z]:/.test(refPath)) {
66
+ throw new Error(`$ref "${refPath}" is an absolute path; only relative paths are allowed.`);
67
+ }
68
+ if (refPath.includes('://')) {
69
+ throw new Error(`$ref "${refPath}" is a protocol URI; only relative file paths are allowed.`);
70
+ }
71
+ const normalizedBase = baseUri.replace(/\\/g, '/');
72
+ const lastSlash = normalizedBase.lastIndexOf('/');
73
+ const baseDir = lastSlash >= 0 ? normalizedBase.slice(0, lastSlash + 1) : '';
74
+ const resolved = normalizePath(`${baseDir}${refPath}`);
75
+ const isAbsoluteBase = normalizedBase.startsWith('/') || /^[a-zA-Z]:\//.test(normalizedBase);
76
+ if (!isAbsoluteBase && resolved.startsWith('..')) {
77
+ throw new Error(`$ref "${refPath}" escapes the project root.`);
78
+ }
79
+ return resolved;
80
+ }
81
+ /** True for `{ $ref: '<string>' }` — the only shape JSON Reference defines. */
82
+ function isRefObject(value) {
83
+ return (typeof value === 'object' && value !== null && !Array.isArray(value)
84
+ && typeof value.$ref === 'string');
85
+ }
86
+ /**
87
+ * Resolve every local-file `$ref` in `doc` into one object model.
88
+ *
89
+ * ```ts
90
+ * const raw = JSON.parse(readFileSync('Main.flow', 'utf8'));
91
+ * const flow = resolveFlowRefs(raw, {
92
+ * baseUri: 'Main.flow',
93
+ * read: (p) => readFileSync(p, 'utf8'),
94
+ * });
95
+ * ```
96
+ *
97
+ * @param doc - The parsed document, straight from the main file.
98
+ * @param options - The referencing path, the file reader, and the depth cap.
99
+ * @returns The same document with every resolvable `$ref` replaced in place
100
+ * (a new object; the input is not mutated).
101
+ * @throws If a `$ref` is unreadable, circular, over the depth cap, or names a
102
+ * path the format refuses.
103
+ */
104
+ export function resolveFlowRefs(doc, options) {
105
+ const maxDepth = options.maxDepth ?? 10;
106
+ // The chain of files currently being resolved — a file that references
107
+ // itself, directly or through others, would otherwise recurse forever.
108
+ const visiting = new Set();
109
+ const walk = (node, baseUri, depth, where) => {
110
+ if (Array.isArray(node))
111
+ return node.map((v, i) => walk(v, baseUri, depth, `${where}/${i}`));
112
+ if (isRefObject(node)) {
113
+ // A same-document pointer is not ours to resolve — hand it back untouched
114
+ // for the JSON-Schema consumer downstream.
115
+ if (node.$ref.startsWith('#'))
116
+ return node;
117
+ if (depth >= maxDepth) {
118
+ throw new Error(`$ref resolution exceeded ${maxDepth} levels at ${where} ("${node.$ref}").`);
119
+ }
120
+ const path = resolveRefPath(baseUri, node.$ref);
121
+ if (visiting.has(path)) {
122
+ throw new Error(`Circular $ref at ${where}: "${node.$ref}" is already being resolved.`);
123
+ }
124
+ let text;
125
+ try {
126
+ text = options.read(path);
127
+ }
128
+ catch (err) {
129
+ const why = err instanceof Error ? err.message : String(err);
130
+ throw new Error(`$ref at ${where} points at "${node.$ref}", which could not be read (${why}).`);
131
+ }
132
+ let parsed;
133
+ try {
134
+ parsed = JSON.parse(text);
135
+ }
136
+ catch (err) {
137
+ const why = err instanceof Error ? err.message : String(err);
138
+ throw new Error(`$ref at ${where} points at "${node.$ref}", which is not valid JSON (${why}).`);
139
+ }
140
+ visiting.add(path);
141
+ try {
142
+ // The referenced file's OWN refs resolve against ITS location, not the
143
+ // referrer's — a sidecar may point at a sibling of its own.
144
+ return walk(parsed, path, depth + 1, where);
145
+ }
146
+ finally {
147
+ visiting.delete(path);
148
+ }
149
+ }
150
+ if (typeof node === 'object' && node !== null) {
151
+ const out = {};
152
+ for (const [k, v] of Object.entries(node)) {
153
+ out[k] = walk(v, baseUri, depth, `${where}/${k}`);
154
+ }
155
+ return out;
156
+ }
157
+ return node;
158
+ };
159
+ return walk(doc, options.baseUri, 0, '');
160
+ }
161
+ /** True if `doc` contains any local-file `$ref` — i.e. it is a SPLIT document. */
162
+ export function hasFileRefs(doc) {
163
+ if (Array.isArray(doc))
164
+ return doc.some(hasFileRefs);
165
+ if (isRefObject(doc) && !doc.$ref.startsWith('#'))
166
+ return true;
167
+ if (typeof doc === 'object' && doc !== null)
168
+ return Object.values(doc).some(hasFileRefs);
169
+ return false;
170
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Where the connector library lives.
3
+ *
4
+ * One shared copy per machine, not one per project. The extracted `library-json`
5
+ * and the generated `library-md` are a pure function of the archive plus the
6
+ * SDK's curated corrections. Two projects pulling the same inputs produce
7
+ * byte-identical trees, so duplicating 159 MB into every project bought nothing.
8
+ * They are cached by a hash of both inputs, and `current` names the entry the
9
+ * next compile should use.
10
+ *
11
+ * <root>/<archive-sha256>.zip the downloaded archive
12
+ * <root>/<library-sha256>/library-json/ extracted + curated
13
+ * <root>/<library-sha256>/library-md/ generated
14
+ * <root>/current -> <library-sha256> moved by the last `registry pull`
15
+ *
16
+ * Only `connectors/` and `connectors-local/` stay in a project: the first
17
+ * because an author imports it by relative path, the second because a
18
+ * connection-resolved schema belongs to the tenant it came from, not the
19
+ * machine.
20
+ */
21
+ export declare const LIBRARY_JSON_DIR = "library-json";
22
+ export declare const LIBRARY_MARKDOWN_DIR = "library-md";
23
+ export declare const CURRENT_LINK = "current";
24
+ /**
25
+ * Root of the library cache. `UIP_FLOW_SDK_LIBRARY_CACHE` overrides it.
26
+ *
27
+ * An environment variable and no flag, on purpose. The writer and the readers
28
+ * are different processes: `registry pull` fills the cache, while this package's
29
+ * own compile and `uip maestro flow compile` (which carries its own copy of this
30
+ * resolution) read it. A flag can only reach the one process it was typed on, so
31
+ * `pull --cache /tmp/x` would leave `current` in a directory no reader ever
32
+ * looks at — the pull reports success and the next compile finds no library.
33
+ * There was such a flag; it is gone. Use this variable to relocate the cache,
34
+ * or `--library`/`--library-md` to bypass it entirely for one command.
35
+ */
36
+ export declare function libraryCacheRoot(): string;
37
+ export declare function cacheEntry(sha256: string, root?: string): string;
38
+ /**
39
+ * The `library-json` the next compile should use, or undefined when nothing has
40
+ * been pulled yet. Resolved through `current` so a pull updates every project at
41
+ * once.
42
+ */
43
+ export declare function resolveCachedLibrary(root?: string): string | undefined;
44
+ /** The matching `library-md`, for an agent that wants to read rather than compile. */
45
+ export declare function resolveCachedMarkdown(root?: string): string | undefined;
46
+ /**
47
+ * The library a command should use: what the caller named, else the environment,
48
+ * else the cache. Every compile entry point resolves through this so `pull` and
49
+ * `compile` cannot disagree about where the library is — they did, and a library
50
+ * written by `pull` was invisible to the SDK's own compile.
51
+ */
52
+ export declare function resolveLibraryDir(named?: string): string | undefined;
53
+ /** What `current` points at, for reporting. */
54
+ export declare function currentEntrySha(root?: string): string | undefined;
55
+ export declare function referencedConnectorKeys(projectDir: string): string[];
@@ -0,0 +1,134 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ /**
5
+ * Where the connector library lives.
6
+ *
7
+ * One shared copy per machine, not one per project. The extracted `library-json`
8
+ * and the generated `library-md` are a pure function of the archive plus the
9
+ * SDK's curated corrections. Two projects pulling the same inputs produce
10
+ * byte-identical trees, so duplicating 159 MB into every project bought nothing.
11
+ * They are cached by a hash of both inputs, and `current` names the entry the
12
+ * next compile should use.
13
+ *
14
+ * <root>/<archive-sha256>.zip the downloaded archive
15
+ * <root>/<library-sha256>/library-json/ extracted + curated
16
+ * <root>/<library-sha256>/library-md/ generated
17
+ * <root>/current -> <library-sha256> moved by the last `registry pull`
18
+ *
19
+ * Only `connectors/` and `connectors-local/` stay in a project: the first
20
+ * because an author imports it by relative path, the second because a
21
+ * connection-resolved schema belongs to the tenant it came from, not the
22
+ * machine.
23
+ */
24
+ export const LIBRARY_JSON_DIR = "library-json";
25
+ export const LIBRARY_MARKDOWN_DIR = "library-md";
26
+ export const CURRENT_LINK = "current";
27
+ /**
28
+ * Root of the library cache. `UIP_FLOW_SDK_LIBRARY_CACHE` overrides it.
29
+ *
30
+ * An environment variable and no flag, on purpose. The writer and the readers
31
+ * are different processes: `registry pull` fills the cache, while this package's
32
+ * own compile and `uip maestro flow compile` (which carries its own copy of this
33
+ * resolution) read it. A flag can only reach the one process it was typed on, so
34
+ * `pull --cache /tmp/x` would leave `current` in a directory no reader ever
35
+ * looks at — the pull reports success and the next compile finds no library.
36
+ * There was such a flag; it is gone. Use this variable to relocate the cache,
37
+ * or `--library`/`--library-md` to bypass it entirely for one command.
38
+ */
39
+ export function libraryCacheRoot() {
40
+ return (process.env.UIP_FLOW_SDK_LIBRARY_CACHE ||
41
+ join(homedir(), ".uipath", "cache", "flow-sdk", "library"));
42
+ }
43
+ export function cacheEntry(sha256, root = libraryCacheRoot()) {
44
+ return join(root, sha256);
45
+ }
46
+ /** A directory is a usable library only once its index has landed. */
47
+ function hasIndex(dir) {
48
+ return existsSync(join(dir, "index.json"));
49
+ }
50
+ /**
51
+ * The `library-json` the next compile should use, or undefined when nothing has
52
+ * been pulled yet. Resolved through `current` so a pull updates every project at
53
+ * once.
54
+ */
55
+ export function resolveCachedLibrary(root = libraryCacheRoot()) {
56
+ const dir = join(root, CURRENT_LINK, LIBRARY_JSON_DIR);
57
+ return hasIndex(dir) ? dir : undefined;
58
+ }
59
+ /** The matching `library-md`, for an agent that wants to read rather than compile. */
60
+ export function resolveCachedMarkdown(root = libraryCacheRoot()) {
61
+ const dir = join(root, CURRENT_LINK, LIBRARY_MARKDOWN_DIR);
62
+ return hasIndex(dir) ? dir : undefined;
63
+ }
64
+ /**
65
+ * The library a command should use: what the caller named, else the environment,
66
+ * else the cache. Every compile entry point resolves through this so `pull` and
67
+ * `compile` cannot disagree about where the library is — they did, and a library
68
+ * written by `pull` was invisible to the SDK's own compile.
69
+ */
70
+ export function resolveLibraryDir(named) {
71
+ return named ?? process.env.FLOW_SDK_LIBRARY_JSON ?? resolveCachedLibrary();
72
+ }
73
+ /** What `current` points at, for reporting. */
74
+ export function currentEntrySha(root = libraryCacheRoot()) {
75
+ const link = join(root, CURRENT_LINK);
76
+ try {
77
+ if (!statSync(link).isDirectory())
78
+ return undefined;
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ const source = join(link, LIBRARY_JSON_DIR, ".registry-source.json");
84
+ if (!existsSync(source))
85
+ return undefined;
86
+ try {
87
+ const parsed = JSON.parse(readFileSync(source, "utf8"));
88
+ return typeof parsed.sha256 === "string" ? parsed.sha256 : undefined;
89
+ }
90
+ catch {
91
+ return undefined;
92
+ }
93
+ }
94
+ /**
95
+ * Connector keys a project actually authors against.
96
+ *
97
+ * Read so `pull` can generate only the descriptors that will be imported. The
98
+ * full set is 30 modules and 1.1 MB, of which a Slack project uses 32 KB; the
99
+ * rest is weight in someone's repository for operations they never call.
100
+ *
101
+ * Both authoring forms count: the typed import names the module by file, and the
102
+ * string form names the connector as the first argument.
103
+ */
104
+ const IMPORT_FORM = /connectors(?:-local)?\/([a-z0-9][a-z0-9-]*)\.ts/g;
105
+ const STRING_FORM = /\bconnector\(\s*['"]([a-z0-9][a-z0-9-]*)['"]/g;
106
+ const AUTHORED = /\.(flow|case|bpmn)\.ts$/;
107
+ export function referencedConnectorKeys(projectDir) {
108
+ const found = new Set();
109
+ let entries;
110
+ try {
111
+ entries = readdirSync(projectDir);
112
+ }
113
+ catch {
114
+ return [];
115
+ }
116
+ for (const entry of entries) {
117
+ if (!AUTHORED.test(entry))
118
+ continue;
119
+ let source;
120
+ try {
121
+ source = readFileSync(join(projectDir, entry), "utf8");
122
+ }
123
+ catch {
124
+ continue;
125
+ }
126
+ for (const pattern of [IMPORT_FORM, STRING_FORM]) {
127
+ pattern.lastIndex = 0;
128
+ for (let match = pattern.exec(source); match; match = pattern.exec(source)) {
129
+ found.add(match[1]);
130
+ }
131
+ }
132
+ }
133
+ return [...found].sort();
134
+ }
@@ -0,0 +1,16 @@
1
+ /** The corrections and definitions that the raw registry dump does not carry. */
2
+ export declare function bundledOverlayPath(): string;
3
+ /** Stable identity of the curated data, so a changed overlay gets a new cache entry. */
4
+ export declare function curatedOverlayIdentity(overlayPath?: string): Promise<string>;
5
+ /**
6
+ * Apply the SDK's curated corrections after extracting the raw registry dump.
7
+ *
8
+ * Files replace the dump's copy, while index rows are a union where the dump
9
+ * wins collisions. This is the same contract as the former unpack script: a
10
+ * correction changes the referenced file, and a definition absent from the
11
+ * dump (notably connector triggers) is made resolvable by its added index row.
12
+ */
13
+ export declare function applyCuratedOverlay(libraryPath: string, overlayPath?: string): Promise<{
14
+ files: number;
15
+ entries: number;
16
+ }>;
@@ -0,0 +1,62 @@
1
+ import { createHash } from "node:crypto";
2
+ import { cp, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, join, relative } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ /** The corrections and definitions that the raw registry dump does not carry. */
6
+ export function bundledOverlayPath() {
7
+ return fileURLToPath(new URL("../../lib/library-json.samples", import.meta.url));
8
+ }
9
+ async function jsonFiles(root, directory = root) {
10
+ const entries = await readdir(directory, { withFileTypes: true });
11
+ const files = await Promise.all(entries.map(async (entry) => {
12
+ const path = join(directory, entry.name);
13
+ if (entry.isDirectory())
14
+ return jsonFiles(root, path);
15
+ return entry.isFile() && entry.name.endsWith(".json") ? [path] : [];
16
+ }));
17
+ return files.flat().sort((left, right) => relative(root, left).localeCompare(relative(root, right)));
18
+ }
19
+ /** Stable identity of the curated data, so a changed overlay gets a new cache entry. */
20
+ export async function curatedOverlayIdentity(overlayPath = bundledOverlayPath()) {
21
+ const hash = createHash("sha256");
22
+ for (const path of await jsonFiles(overlayPath)) {
23
+ hash.update(relative(overlayPath, path));
24
+ hash.update("\0");
25
+ hash.update(await readFile(path));
26
+ hash.update("\0");
27
+ }
28
+ return hash.digest("hex");
29
+ }
30
+ function entryIdentity(entry) {
31
+ return `${String(entry.nodeType)}\0${String(entry.version)}`;
32
+ }
33
+ /**
34
+ * Apply the SDK's curated corrections after extracting the raw registry dump.
35
+ *
36
+ * Files replace the dump's copy, while index rows are a union where the dump
37
+ * wins collisions. This is the same contract as the former unpack script: a
38
+ * correction changes the referenced file, and a definition absent from the
39
+ * dump (notably connector triggers) is made resolvable by its added index row.
40
+ */
41
+ export async function applyCuratedOverlay(libraryPath, overlayPath = bundledOverlayPath()) {
42
+ const overlayFiles = await jsonFiles(overlayPath);
43
+ for (const source of overlayFiles) {
44
+ const rel = relative(overlayPath, source);
45
+ if (rel === "index.json")
46
+ continue;
47
+ const destination = join(libraryPath, rel);
48
+ await mkdir(dirname(destination), { recursive: true });
49
+ await cp(source, destination);
50
+ }
51
+ const indexPath = join(libraryPath, "index.json");
52
+ const destination = JSON.parse(await readFile(indexPath, "utf8"));
53
+ const overlay = JSON.parse(await readFile(join(overlayPath, "index.json"), "utf8"));
54
+ const entries = destination.entries ?? [];
55
+ const seen = new Set(entries.map(entryIdentity));
56
+ const additions = (overlay.entries ?? []).filter((entry) => !seen.has(entryIdentity(entry)));
57
+ if (additions.length > 0) {
58
+ destination.entries = [...entries, ...additions];
59
+ await writeFile(indexPath, `${JSON.stringify(destination, null, 2)}\n`);
60
+ }
61
+ return { files: overlayFiles.length - 1, entries: additions.length };
62
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Unpack a downloaded connector-library archive.
3
+ *
4
+ * Python does the unpacking: `zipfile` is in its standard library, and this is
5
+ * the only step of the pull that needs an archive reader. Adding the SDK's first
6
+ * zip dependency to avoid one subprocess would be the worse trade, especially
7
+ * for code whose whole job is refusing hostile paths — `extract_library.py`
8
+ * carries that guard and its tests.
9
+ *
10
+ * Shaped like `materializer.ts` on purpose: same generator-path
11
+ * resolution, same `--python` override, same failure translation.
12
+ */
13
+ export interface ExtractLibraryOptions {
14
+ archivePath: string;
15
+ destinationPath: string;
16
+ /** Only entries under this zip prefix are taken. */
17
+ root?: string;
18
+ pythonExecutable?: string;
19
+ /** Override used by tests and source checkouts. */
20
+ extractorPath?: string;
21
+ }
22
+ export declare function extractLibrary(options: ExtractLibraryOptions): Promise<void>;
@@ -0,0 +1,18 @@
1
+ import { packagedGenerator, runGenerator } from "./python.js";
2
+ export async function extractLibrary(options) {
3
+ const args = [
4
+ "--archive",
5
+ options.archivePath,
6
+ "--into",
7
+ options.destinationPath,
8
+ ];
9
+ if (options.root) {
10
+ args.push("--root", options.root);
11
+ }
12
+ await runGenerator({
13
+ script: options.extractorPath ?? packagedGenerator("extract_library.py"),
14
+ args,
15
+ pythonExecutable: options.pythonExecutable,
16
+ what: "Unpacking the connector library",
17
+ });
18
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ // The `flow-registry-materialize` bin. Kept as a separate entry file so
3
+ // `materialize-cli.ts` can stay a plain `run(argv)` module that the
4
+ // umbrella CLI mounts. Exit codes are identical to the pre-refactor script:
5
+ // 2 for a usage error, 1 for a failed generation, 0 on success.
6
+ import { run } from "./materialize-cli.js";
7
+ process.exitCode = await run(process.argv.slice(2));
@@ -0,0 +1 @@
1
+ export declare function run(argv: string[]): Promise<number>;
@@ -0,0 +1,46 @@
1
+ import { materializeRegistry } from "./materializer.js";
2
+ /**
3
+ * Generate `library-md` and `connectors/` from an extracted `library-json`.
4
+ *
5
+ * Exposed as `run(argv)` rather than as a top-level script so the umbrella CLI
6
+ * can mount it the same way it mounts every other verb: `cli/common.ts` does
7
+ * `(await import(...)).run(argv)` and maps the returned code onto
8
+ * `process.exitCode`. A module that read `process.argv` and called
9
+ * `process.exit` at import time could not be mounted at all — which is why
10
+ * this verb used to be reachable only through its own bin, and why the product
11
+ * CLI had to resolve that bin out of the package's `bin` map instead of
12
+ * delegating to `dist/cli/index.js` like it does for compile and check.
13
+ *
14
+ * The bin still works: `materialize-bin.ts` is a two-line shim over
15
+ * this function, so both entry points share one implementation.
16
+ */
17
+ const USAGE = "Usage: flow-sdk registry materialize --library-json <path> --library-md <path> --connectors <path> [--import <specifier>] [--triggers <path>] [--python <executable>] [--generator <path>]";
18
+ function value(args, name) {
19
+ const index = args.indexOf(name);
20
+ return index >= 0 ? args[index + 1] : undefined;
21
+ }
22
+ export async function run(argv) {
23
+ const libraryJsonPath = value(argv, "--library-json");
24
+ const libraryMarkdownPath = value(argv, "--library-md");
25
+ const connectorsPath = value(argv, "--connectors");
26
+ if (!libraryJsonPath || !libraryMarkdownPath || !connectorsPath) {
27
+ console.error(USAGE);
28
+ return 2;
29
+ }
30
+ try {
31
+ await materializeRegistry({
32
+ libraryJsonPath,
33
+ libraryMarkdownPath,
34
+ connectorsPath,
35
+ connectorImport: value(argv, "--import"),
36
+ pythonExecutable: value(argv, "--python"),
37
+ triggersPath: value(argv, "--triggers"),
38
+ generatorPath: value(argv, "--generator"),
39
+ });
40
+ return 0;
41
+ }
42
+ catch (error) {
43
+ console.error(error instanceof Error ? error.message : String(error));
44
+ return 1;
45
+ }
46
+ }
@@ -0,0 +1,23 @@
1
+ export interface MaterializeRegistryOptions {
2
+ libraryJsonPath: string;
3
+ /** Where the Markdown goes. Omit to skip it — see `connectorsPath`. */
4
+ libraryMarkdownPath?: string;
5
+ /**
6
+ * Where the typed descriptors go. Omit to generate none — every error the
7
+ * compiler reports comes from the library JSON, so the modules are for an
8
+ * editor's autocomplete rather than for validation, and a project that imports
9
+ * none does not need them.
10
+ */
11
+ connectorsPath?: string;
12
+ /**
13
+ * Connector keys to emit, instead of all of them. The full set is 30 modules
14
+ * and 1.1 MB; a project usually imports one.
15
+ */
16
+ connectorSubset?: string[];
17
+ connectorImport?: string;
18
+ pythonExecutable?: string;
19
+ triggersPath?: string;
20
+ /** Override used by tests and source checkouts. */
21
+ generatorPath?: string;
22
+ }
23
+ export declare function materializeRegistry(options: MaterializeRegistryOptions): Promise<void>;