@uipath/maestro-builder-sdk 6.3.0 → 6.5.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 (161) hide show
  1. package/dist/api-index.md +6 -6
  2. package/dist/cli/commands/registry.js +68 -12
  3. package/dist/registry/archive/entry-policy.d.ts +36 -0
  4. package/dist/registry/archive/entry-policy.js +60 -0
  5. package/dist/registry/archive/extract.d.ts +31 -0
  6. package/dist/registry/archive/extract.js +92 -0
  7. package/dist/registry/archive/zip-reader.d.ts +38 -0
  8. package/dist/registry/archive/zip-reader.js +256 -0
  9. package/dist/registry/codecs/pyjson.d.ts +62 -0
  10. package/dist/registry/codecs/pyjson.js +208 -0
  11. package/dist/registry/compat/compare.d.ts +18 -0
  12. package/dist/registry/compat/compare.js +32 -0
  13. package/dist/registry/compat/paths.d.ts +4 -0
  14. package/dist/registry/compat/paths.js +17 -0
  15. package/dist/registry/compat/pystr.d.ts +50 -0
  16. package/dist/registry/compat/pystr.js +221 -0
  17. package/dist/registry/concurrency.d.ts +10 -0
  18. package/dist/registry/concurrency.js +34 -0
  19. package/dist/registry/curated-overlay.d.ts +36 -4
  20. package/dist/registry/curated-overlay.js +87 -14
  21. package/dist/registry/errors.d.ts +26 -0
  22. package/dist/registry/errors.js +38 -0
  23. package/dist/registry/extractor.d.ts +9 -10
  24. package/dist/registry/extractor.js +5 -15
  25. package/dist/registry/files.d.ts +26 -0
  26. package/dist/registry/files.js +160 -0
  27. package/dist/registry/generators/descriptors.d.ts +81 -0
  28. package/dist/registry/generators/descriptors.js +405 -0
  29. package/dist/registry/generators/fields.d.ts +46 -0
  30. package/dist/registry/generators/fields.js +111 -0
  31. package/dist/registry/generators/markdown/common.d.ts +21 -0
  32. package/dist/registry/generators/markdown/common.js +55 -0
  33. package/dist/registry/generators/markdown/index.d.ts +33 -0
  34. package/dist/registry/generators/markdown/index.js +37 -0
  35. package/dist/registry/generators/markdown/page.d.ts +8 -0
  36. package/dist/registry/generators/markdown/page.js +52 -0
  37. package/dist/registry/generators/markdown/pyvalue.d.ts +34 -0
  38. package/dist/registry/generators/markdown/pyvalue.js +106 -0
  39. package/dist/registry/generators/markdown/sections/choosing-object.d.ts +2 -0
  40. package/dist/registry/generators/markdown/sections/choosing-object.js +52 -0
  41. package/dist/registry/generators/markdown/sections/example.d.ts +22 -0
  42. package/dist/registry/generators/markdown/sections/example.js +295 -0
  43. package/dist/registry/generators/markdown/sections/filtering.d.ts +2 -0
  44. package/dist/registry/generators/markdown/sections/filtering.js +76 -0
  45. package/dist/registry/generators/markdown/sections/header.d.ts +2 -0
  46. package/dist/registry/generators/markdown/sections/header.js +37 -0
  47. package/dist/registry/generators/markdown/sections/inputs.d.ts +30 -0
  48. package/dist/registry/generators/markdown/sections/inputs.js +151 -0
  49. package/dist/registry/generators/markdown/sections/lookups.d.ts +12 -0
  50. package/dist/registry/generators/markdown/sections/lookups.js +150 -0
  51. package/dist/registry/generators/markdown/sections/outputs.d.ts +3 -0
  52. package/dist/registry/generators/markdown/sections/outputs.js +9 -0
  53. package/dist/registry/generators/markdown/sections/resolving-fields.d.ts +2 -0
  54. package/dist/registry/generators/markdown/sections/resolving-fields.js +139 -0
  55. package/dist/registry/generators/markdown/sections/schema-dynamic.d.ts +2 -0
  56. package/dist/registry/generators/markdown/sections/schema-dynamic.js +86 -0
  57. package/dist/registry/generators/materialize.d.ts +30 -0
  58. package/dist/registry/generators/materialize.js +132 -0
  59. package/dist/registry/generators/md-symbols.d.ts +22 -0
  60. package/dist/registry/generators/md-symbols.js +58 -0
  61. package/dist/registry/generators/triggers.d.ts +15 -0
  62. package/dist/registry/generators/triggers.js +85 -0
  63. package/dist/registry/generators/type-registry.d.ts +50 -0
  64. package/dist/registry/generators/type-registry.js +154 -0
  65. package/dist/registry/generators/type-tree.d.ts +65 -0
  66. package/dist/registry/generators/type-tree.js +179 -0
  67. package/dist/registry/library-build/build.d.ts +57 -0
  68. package/dist/registry/library-build/build.js +286 -0
  69. package/dist/registry/library-build/canonical.d.ts +119 -0
  70. package/dist/registry/library-build/canonical.js +512 -0
  71. package/dist/registry/library-build/cli.d.ts +45 -0
  72. package/dist/registry/library-build/cli.js +182 -0
  73. package/dist/registry/library-build/context.d.ts +107 -0
  74. package/dist/registry/library-build/context.js +267 -0
  75. package/dist/registry/library-build/enrich.d.ts +36 -0
  76. package/dist/registry/library-build/enrich.js +158 -0
  77. package/dist/registry/library-build/events.d.ts +108 -0
  78. package/dist/registry/library-build/events.js +476 -0
  79. package/dist/registry/library-build/generic-expand.d.ts +77 -0
  80. package/dist/registry/library-build/generic-expand.js +363 -0
  81. package/dist/registry/library-build/plan.d.ts +71 -0
  82. package/dist/registry/library-build/plan.js +270 -0
  83. package/dist/registry/library-build/py.d.ts +45 -0
  84. package/dist/registry/library-build/py.js +167 -0
  85. package/dist/registry/library-build/schema-action.d.ts +38 -0
  86. package/dist/registry/library-build/schema-action.js +107 -0
  87. package/dist/registry/library-build/write.d.ts +6 -0
  88. package/dist/registry/library-build/write.js +26 -0
  89. package/dist/registry/library-reader.d.ts +20 -0
  90. package/dist/registry/library-reader.js +50 -0
  91. package/dist/registry/lookup-specs.d.ts +55 -0
  92. package/dist/registry/lookup-specs.js +140 -0
  93. package/dist/registry/materialize-cli.js +28 -14
  94. package/dist/registry/materializer.d.ts +25 -3
  95. package/dist/registry/materializer.js +45 -29
  96. package/dist/registry/model/library.d.ts +254 -0
  97. package/dist/registry/model/library.js +23 -0
  98. package/dist/registry/naming.d.ts +54 -0
  99. package/dist/registry/naming.js +142 -0
  100. package/dist/registry/orphans.d.ts +4 -0
  101. package/dist/registry/orphans.js +86 -0
  102. package/dist/registry/prepare/actions.d.ts +26 -0
  103. package/dist/registry/prepare/actions.js +94 -0
  104. package/dist/registry/prepare/connections.d.ts +181 -0
  105. package/dist/registry/prepare/connections.js +399 -0
  106. package/dist/registry/prepare/event.d.ts +96 -0
  107. package/dist/registry/prepare/event.js +268 -0
  108. package/dist/registry/prepare/handoff.d.ts +21 -0
  109. package/dist/registry/prepare/handoff.js +91 -0
  110. package/dist/registry/prepare/ledger.d.ts +104 -0
  111. package/dist/registry/prepare/ledger.js +216 -0
  112. package/dist/registry/prepare/messages.d.ts +190 -0
  113. package/dist/registry/prepare/messages.js +472 -0
  114. package/dist/registry/prepare/objects.d.ts +130 -0
  115. package/dist/registry/prepare/objects.js +318 -0
  116. package/dist/registry/prepare/overlay.d.ts +149 -0
  117. package/dist/registry/prepare/overlay.js +487 -0
  118. package/dist/registry/prepare/parents.d.ts +41 -0
  119. package/dist/registry/prepare/parents.js +122 -0
  120. package/dist/registry/prepare/pipeline.d.ts +91 -0
  121. package/dist/registry/prepare/pipeline.js +376 -0
  122. package/dist/registry/prepare/regenerate.d.ts +9 -0
  123. package/dist/registry/prepare/regenerate.js +50 -0
  124. package/dist/registry/prepare/resolve.d.ts +199 -0
  125. package/dist/registry/prepare/resolve.js +470 -0
  126. package/dist/registry/prepare/retry.d.ts +83 -0
  127. package/dist/registry/prepare/retry.js +109 -0
  128. package/dist/registry/prepare/source-import.d.ts +54 -0
  129. package/dist/registry/prepare/source-import.js +192 -0
  130. package/dist/registry/prepare/support.d.ts +41 -0
  131. package/dist/registry/prepare/support.js +178 -0
  132. package/dist/registry/prepare-cli.d.ts +16 -5
  133. package/dist/registry/prepare-cli.js +60 -53
  134. package/dist/registry/pull-cli.js +8 -7
  135. package/dist/registry/reporter.d.ts +26 -0
  136. package/dist/registry/reporter.js +41 -0
  137. package/dist/registry/uip/client.d.ts +99 -0
  138. package/dist/registry/uip/client.js +226 -0
  139. package/dist/registry/uip/commands.d.ts +40 -0
  140. package/dist/registry/uip/commands.js +80 -0
  141. package/dist/registry/uip/envelope.d.ts +37 -0
  142. package/dist/registry/uip/envelope.js +84 -0
  143. package/dist/registry/uip/response-cache.d.ts +28 -0
  144. package/dist/registry/uip/response-cache.js +57 -0
  145. package/lib/README.md +10 -8
  146. package/package.json +3 -3
  147. package/dist/generators/_connections.py +0 -331
  148. package/dist/generators/_events.py +0 -355
  149. package/dist/generators/_lookups.py +0 -114
  150. package/dist/generators/_naming.py +0 -185
  151. package/dist/generators/_objects.py +0 -299
  152. package/dist/generators/_resolve.py +0 -319
  153. package/dist/generators/convert_library_to_md.py +0 -1441
  154. package/dist/generators/extract_library.py +0 -125
  155. package/dist/generators/generate_connectors_ts.py +0 -936
  156. package/dist/generators/generate_library_json.py +0 -2527
  157. package/dist/generators/generate_triggers_ts.py +0 -110
  158. package/dist/generators/materialize_registry.py +0 -155
  159. package/dist/generators/prepare_connector.py +0 -1860
  160. package/dist/registry/python.d.ts +0 -26
  161. package/dist/registry/python.js +0 -46
@@ -1,319 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Resolve a connector lookup field against a live connection.
3
-
4
- `prepare --resolve channel:profile.email=dustin@example.com` turns a
5
- human-meaningful value into the opaque id the connector wants, and records the
6
- answer so `compile` can read it offline. This module is the retrieval half.
7
-
8
- WHY IT LIVES HERE AND NOT IN COMPILE. Resolution needs the network; compile must
9
- not have it. The eval harness runs `check` and `compile` with no `uip` login,
10
- and the byte-lock gates require that the same source produces the same bytes —
11
- a compile that made live calls would make those gates depend on tenant state and
12
- they would stop meaning anything. So the expensive call happens once, in an
13
- explicit command, and its result lands in a file that is diffable and reviewable.
14
-
15
- THE STRATEGY IS DATA, NOT CODE. `reference` says how to retrieve the collection:
16
- a `filterPattern` means one request; its absence means paging; `childPath` means
17
- a tree; `dependsOn` means another field must resolve first. That is why this is a
18
- generator reading metadata rather than 103 hand-written connector helpers.
19
- """
20
-
21
- from __future__ import annotations
22
-
23
- import json
24
- import subprocess
25
- import sys
26
-
27
- __all__ = [
28
- "LookupExhausted",
29
- "ResolutionError",
30
- "parse_resolve_flag",
31
- "resolve_one",
32
- "order_resolutions",
33
- ]
34
-
35
- # A scan has to stop somewhere, and the caps must be set against the MEASURED
36
- # page size rather than a guess. Integration Service serves **1,000 records per
37
- # page** for a curated collection (verified against a live Slack connection:
38
- # `curated_channels` returns 1000 with `HasMore: "true"`).
39
- #
40
- # The first version of this capped at 400 records — a number chosen for how many
41
- # rows a person might scroll, which is the wrong unit entirely. It meant the loop
42
- # broke partway through page ONE and never paginated at all. The eval task built
43
- # to exercise this puts its target channel on page 3 (record ~2,001), so the
44
- # resolver reported "not found" for a channel that is plainly there, and the
45
- # agent fell back to hand-rolling the paging this exists to do for it.
46
- #
47
- # 25 pages is ~30s of requests in the worst case, spent once, in an explicit
48
- # command whose whole job is this. A collection with a `filterPattern` never
49
- # reaches the scan at all.
50
- PAGE_SIZE_HINT = 1000
51
- MAX_SCANNED = 25 * PAGE_SIZE_HINT
52
- PAGE_GUARD = 50
53
-
54
-
55
- class ResolutionError(Exception):
56
- """A lookup that could not be resolved, with the reason a human needs."""
57
-
58
-
59
- class LookupExhausted(ResolutionError):
60
- """The collection was read to the end on THIS connection and had no match.
61
-
62
- Split out from its parent because the two failures want opposite responses
63
- and the caller cannot tell them apart from a message. A transport or
64
- permission failure says nothing about whether the value exists — retrying it
65
- on another connection would hide a broken call behind a confident "no
66
- connection has it". An exhaustive miss is positive evidence about this
67
- connection specifically, and is the signal `prepare` uses to demote it and
68
- try the next candidate (flow-builder-sdk#744).
69
-
70
- `capped` flips that: a scan stopped at the record cap did NOT reach the end,
71
- so it is not evidence of absence and must not demote anything.
72
-
73
- The attributes carry the counts so a caller can report per-candidate results
74
- without re-parsing the sentence.
75
- """
76
-
77
- def __init__(self, message: str, *, field: str, collection: str, by: str,
78
- value: str, scanned: int, pages: int, capped: bool) -> None:
79
- super().__init__(message)
80
- self.field = field
81
- self.collection = collection
82
- self.by = by
83
- self.value = value
84
- self.scanned = scanned
85
- self.pages = pages
86
- self.capped = capped
87
-
88
-
89
- def parse_resolve_flag(raw: str) -> tuple[str, str, str]:
90
- """`channel:profile.email=dustin@example.com` -> (field, by, value).
91
-
92
- Split on the FIRST colon and the FIRST `=`. Both halves can legitimately
93
- contain the other delimiter — `by` is a dotted path and a value can be
94
- anything a person typed — so a greedy split silently mis-parses real input.
95
- """
96
- field, sep, rest = raw.partition(":")
97
- if not sep or not field:
98
- raise ResolutionError(
99
- f"--resolve {raw!r}: expected <field>:<by>=<value>, "
100
- "e.g. --resolve channel:profile.email=someone@example.com"
101
- )
102
- by, sep, value = rest.partition("=")
103
- if not sep or not by:
104
- raise ResolutionError(
105
- f"--resolve {raw!r}: expected <field>:<by>=<value>, "
106
- f"but found no '=' after the search field {by or rest!r}."
107
- )
108
- return field, by, value
109
-
110
-
111
- def order_resolutions(
112
- requested: list[tuple[str, str, str]], specs: dict,
113
- ) -> list[tuple[str, str, str]]:
114
- """Order the requests so a `dependsOn` prerequisite resolves first.
115
-
116
- 27 fields in the shipped library are not addressable until another field is
117
- known — Jira's issue type needs the project, Amazon Connect's phone number
118
- needs the instance. Resolving in the order the flags were typed leaves an
119
- unsubstituted `{placeholder}` in a URL, and the error the connector returns
120
- for that names neither field.
121
- """
122
- by_field = {field: (field, by, value) for field, by, value in requested}
123
- ordered: list[tuple[str, str, str]] = []
124
- placed: set[str] = set()
125
-
126
- def place(field: str, trail: tuple[str, ...] = ()) -> None:
127
- if field in placed:
128
- return
129
- if field in trail:
130
- cycle = " -> ".join([*trail, field])
131
- raise ResolutionError(f"circular dependsOn among lookup fields: {cycle}")
132
- for prerequisite in (specs.get(field, {}).get("dependsOn") or []):
133
- if prerequisite in by_field:
134
- place(prerequisite, (*trail, field))
135
- else:
136
- raise ResolutionError(
137
- f"cannot resolve {field!r}: its collection is addressed through "
138
- f"{prerequisite!r}, which has no --resolve of its own. Add "
139
- f"--resolve {prerequisite}:<by>=<value> and re-run."
140
- )
141
- placed.add(field)
142
- ordered.append(by_field[field])
143
-
144
- for field, _by, _value in requested:
145
- place(field)
146
- return ordered
147
-
148
-
149
- def _envelope_items(payload: dict) -> list:
150
- """The records out of a `uip is resources run list` reply.
151
-
152
- The reply is `{"Result": "Success", "Code": ..., "Data": {"items": [...],
153
- "Pagination": {...}}}` — records live under `Data`, and `Result` is the
154
- STATUS STRING, not a container. Reading a top-level `items` finds nothing
155
- and reports "scanned 0 records" against a collection that is full, which is
156
- exactly what this did until an eval run walked it into the real CLI.
157
- """
158
- data = payload.get("Data")
159
- if isinstance(data, dict) and isinstance(data.get("items"), list):
160
- return data["items"]
161
- if isinstance(payload.get("items"), list):
162
- return payload["items"]
163
- return []
164
-
165
-
166
- def _envelope_pagination(payload: dict) -> dict:
167
- """The `Pagination` block, from under `Data`."""
168
- data = payload.get("Data")
169
- if isinstance(data, dict) and isinstance(data.get("Pagination"), dict):
170
- return data["Pagination"]
171
- if isinstance(payload.get("Pagination"), dict):
172
- return payload["Pagination"]
173
- return {}
174
-
175
-
176
- def _truthy(value: object) -> bool:
177
- """`HasMore` arrives as the STRING "false" as often as the boolean.
178
-
179
- `if payload["Pagination"]["HasMore"]` on the string "false" is True, which
180
- pages forever on a collection that just said it has no more.
181
- """
182
- if isinstance(value, str):
183
- return value.strip().lower() in ("true", "1", "yes")
184
- return bool(value)
185
-
186
-
187
- def _uip_list(connector_key: str, collection: str, connection_id: str,
188
- query: str | None) -> dict:
189
- """One `uip is resources run list` page, as parsed JSON."""
190
- command = [
191
- "uip", "is", "resources", "run", "list", connector_key, collection,
192
- "--connection-id", connection_id, "--output", "json",
193
- ]
194
- if query:
195
- command += ["--query", query]
196
- result = subprocess.run(command, capture_output=True, text=True)
197
- if result.returncode != 0:
198
- # `uip` prints a self-update failure to stderr before its real output,
199
- # so stderr being non-empty is not evidence of anything. Judge the exit
200
- # code and the payload.
201
- raise ResolutionError(
202
- f"listing {collection} failed: {result.stderr.strip() or 'no output'}"
203
- )
204
- try:
205
- return json.loads(result.stdout)
206
- except ValueError as error:
207
- raise ResolutionError(
208
- f"listing {collection} returned output that is not JSON: {error}"
209
- ) from error
210
-
211
-
212
- def _read_path(record: dict, dotted: str):
213
- """`profile.email` out of a record, or None."""
214
- cursor = record
215
- for part in dotted.split("."):
216
- if not isinstance(cursor, dict):
217
- return None
218
- cursor = cursor.get(part)
219
- return cursor
220
-
221
-
222
- def _substitute(template: str, resolved: dict[str, str]) -> str:
223
- """Fill `{fields.project.key}` placeholders from already-resolved fields."""
224
- out = template
225
- for field, value in resolved.items():
226
- out = out.replace("{" + field + "}", str(value))
227
- return out
228
-
229
-
230
- def resolve_one(
231
- connector_key: str,
232
- spec: dict,
233
- field: str,
234
- by: str,
235
- value: str,
236
- connection_id: str,
237
- resolved: dict[str, str],
238
- ) -> str:
239
- """The connector-facing id for one lookup, or raise `ResolutionError`.
240
-
241
- `resolved` carries the values of fields resolved earlier in this run, which
242
- is what makes a `dependsOn` path addressable.
243
- """
244
- if by not in (spec.get("by") or []):
245
- searchable = ", ".join(repr(b) for b in (spec.get("by") or []))
246
- raise ResolutionError(
247
- f"{field}: cannot search by {by!r}. Searchable by {searchable or '(nothing declared)'}."
248
- )
249
-
250
- path = _substitute(spec.get("path") or "", resolved)
251
- if "{" in path:
252
- missing = path[path.index("{") + 1: path.index("}")] if "}" in path else "?"
253
- raise ResolutionError(
254
- f"{field}: the collection path still contains {{{missing}}}. "
255
- f"Resolve {missing!r} first with --resolve {missing}:<by>=<value>."
256
- )
257
- collection = path.split("?", 1)[0].strip("/")
258
- query = path.partition("?")[2] or None
259
- send = spec.get("value") or "id"
260
-
261
- # A server-side filter turns the whole scan into one request. Where the
262
- # metadata declares one, use it; where it does not, page.
263
- filter_pattern = spec.get("filterPattern")
264
- if filter_pattern:
265
- filtered = filter_pattern.replace("{filter}", value)
266
- query = f"{query}&{filtered}" if query else filtered
267
-
268
- scanned = 0
269
- pages = 0
270
- while True:
271
- payload = _uip_list(connector_key, collection, connection_id, query)
272
- items = _envelope_items(payload)
273
- for record in items:
274
- scanned += 1
275
- if str(_read_path(record, by)) == value:
276
- got = _read_path(record, send)
277
- if got is None:
278
- raise ResolutionError(
279
- f"{field}: matched a record on {by}={value!r}, but it "
280
- f"carries no {send!r} to send."
281
- )
282
- return str(got)
283
- pagination = _envelope_pagination(payload)
284
- token = pagination.get("NextPageToken")
285
- if not _truthy(pagination.get("HasMore")) or not token or scanned >= MAX_SCANNED:
286
- break
287
- pages += 1
288
- if pages > PAGE_GUARD:
289
- break
290
- # Exactly `nextPage`. Guessing `page` / `pageToken` / `nextPageToken`
291
- # is a documented way to loop forever on page one.
292
- query = f"{query}&nextPage={token}" if query else f"nextPage={token}"
293
-
294
- capped = scanned >= MAX_SCANNED or pages > PAGE_GUARD
295
- # This states the FACT and stops; `prepare` owns the remedy, because
296
- # `prepare` is what knows the other candidate connections.
297
- #
298
- # It deliberately carries NO "check the value" and NO `uip is resources`
299
- # pointer. The old text led with both: it named only the value as suspect
300
- # when the connection is equally suspect, and then sent the reader to a
301
- # tenant crawl the skill explicitly rules out ("Tenant discovery is not a
302
- # phase of either loop", references/CLI-LOOP.md). An agent followed that
303
- # advice into exactly what it had been told not to do — 50 of 94 Bash calls
304
- # hand-crawling Integration Service, 41 of them paging this collection, and
305
- # the run hit its ceiling without producing a flow (flow-builder-sdk#744).
306
- #
307
- # The listing command is still offered, once, by the caller's terminal
308
- # report — where every connection has been tried and seeing what IS there
309
- # is finally the next step rather than a detour.
310
- raise LookupExhausted(
311
- f"{field}: no record in {collection!r} has {by}={value!r} "
312
- f"(scanned {scanned} record(s) across {pages + 1} page(s)"
313
- + (f"; STOPPED AT THE {MAX_SCANNED}-record cap, so the value may be "
314
- f"further in" if capped
315
- else "; collection exhausted")
316
- + f") on connection {connection_id}.",
317
- field=field, collection=collection, by=by, value=value,
318
- scanned=scanned, pages=pages + 1, capped=capped,
319
- )