@uipath/maestro-builder-sdk 6.4.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 (160) hide show
  1. package/dist/cli/commands/registry.js +68 -12
  2. package/dist/registry/archive/entry-policy.d.ts +36 -0
  3. package/dist/registry/archive/entry-policy.js +60 -0
  4. package/dist/registry/archive/extract.d.ts +31 -0
  5. package/dist/registry/archive/extract.js +92 -0
  6. package/dist/registry/archive/zip-reader.d.ts +38 -0
  7. package/dist/registry/archive/zip-reader.js +256 -0
  8. package/dist/registry/codecs/pyjson.d.ts +62 -0
  9. package/dist/registry/codecs/pyjson.js +208 -0
  10. package/dist/registry/compat/compare.d.ts +18 -0
  11. package/dist/registry/compat/compare.js +32 -0
  12. package/dist/registry/compat/paths.d.ts +4 -0
  13. package/dist/registry/compat/paths.js +17 -0
  14. package/dist/registry/compat/pystr.d.ts +50 -0
  15. package/dist/registry/compat/pystr.js +221 -0
  16. package/dist/registry/concurrency.d.ts +10 -0
  17. package/dist/registry/concurrency.js +34 -0
  18. package/dist/registry/curated-overlay.d.ts +36 -4
  19. package/dist/registry/curated-overlay.js +87 -14
  20. package/dist/registry/errors.d.ts +26 -0
  21. package/dist/registry/errors.js +38 -0
  22. package/dist/registry/extractor.d.ts +9 -10
  23. package/dist/registry/extractor.js +5 -15
  24. package/dist/registry/files.d.ts +26 -0
  25. package/dist/registry/files.js +160 -0
  26. package/dist/registry/generators/descriptors.d.ts +81 -0
  27. package/dist/registry/generators/descriptors.js +405 -0
  28. package/dist/registry/generators/fields.d.ts +46 -0
  29. package/dist/registry/generators/fields.js +111 -0
  30. package/dist/registry/generators/markdown/common.d.ts +21 -0
  31. package/dist/registry/generators/markdown/common.js +55 -0
  32. package/dist/registry/generators/markdown/index.d.ts +33 -0
  33. package/dist/registry/generators/markdown/index.js +37 -0
  34. package/dist/registry/generators/markdown/page.d.ts +8 -0
  35. package/dist/registry/generators/markdown/page.js +52 -0
  36. package/dist/registry/generators/markdown/pyvalue.d.ts +34 -0
  37. package/dist/registry/generators/markdown/pyvalue.js +106 -0
  38. package/dist/registry/generators/markdown/sections/choosing-object.d.ts +2 -0
  39. package/dist/registry/generators/markdown/sections/choosing-object.js +52 -0
  40. package/dist/registry/generators/markdown/sections/example.d.ts +22 -0
  41. package/dist/registry/generators/markdown/sections/example.js +295 -0
  42. package/dist/registry/generators/markdown/sections/filtering.d.ts +2 -0
  43. package/dist/registry/generators/markdown/sections/filtering.js +76 -0
  44. package/dist/registry/generators/markdown/sections/header.d.ts +2 -0
  45. package/dist/registry/generators/markdown/sections/header.js +37 -0
  46. package/dist/registry/generators/markdown/sections/inputs.d.ts +30 -0
  47. package/dist/registry/generators/markdown/sections/inputs.js +151 -0
  48. package/dist/registry/generators/markdown/sections/lookups.d.ts +12 -0
  49. package/dist/registry/generators/markdown/sections/lookups.js +150 -0
  50. package/dist/registry/generators/markdown/sections/outputs.d.ts +3 -0
  51. package/dist/registry/generators/markdown/sections/outputs.js +9 -0
  52. package/dist/registry/generators/markdown/sections/resolving-fields.d.ts +2 -0
  53. package/dist/registry/generators/markdown/sections/resolving-fields.js +139 -0
  54. package/dist/registry/generators/markdown/sections/schema-dynamic.d.ts +2 -0
  55. package/dist/registry/generators/markdown/sections/schema-dynamic.js +86 -0
  56. package/dist/registry/generators/materialize.d.ts +30 -0
  57. package/dist/registry/generators/materialize.js +132 -0
  58. package/dist/registry/generators/md-symbols.d.ts +22 -0
  59. package/dist/registry/generators/md-symbols.js +58 -0
  60. package/dist/registry/generators/triggers.d.ts +15 -0
  61. package/dist/registry/generators/triggers.js +85 -0
  62. package/dist/registry/generators/type-registry.d.ts +50 -0
  63. package/dist/registry/generators/type-registry.js +154 -0
  64. package/dist/registry/generators/type-tree.d.ts +65 -0
  65. package/dist/registry/generators/type-tree.js +179 -0
  66. package/dist/registry/library-build/build.d.ts +57 -0
  67. package/dist/registry/library-build/build.js +286 -0
  68. package/dist/registry/library-build/canonical.d.ts +119 -0
  69. package/dist/registry/library-build/canonical.js +512 -0
  70. package/dist/registry/library-build/cli.d.ts +45 -0
  71. package/dist/registry/library-build/cli.js +182 -0
  72. package/dist/registry/library-build/context.d.ts +107 -0
  73. package/dist/registry/library-build/context.js +267 -0
  74. package/dist/registry/library-build/enrich.d.ts +36 -0
  75. package/dist/registry/library-build/enrich.js +158 -0
  76. package/dist/registry/library-build/events.d.ts +108 -0
  77. package/dist/registry/library-build/events.js +476 -0
  78. package/dist/registry/library-build/generic-expand.d.ts +77 -0
  79. package/dist/registry/library-build/generic-expand.js +363 -0
  80. package/dist/registry/library-build/plan.d.ts +71 -0
  81. package/dist/registry/library-build/plan.js +270 -0
  82. package/dist/registry/library-build/py.d.ts +45 -0
  83. package/dist/registry/library-build/py.js +167 -0
  84. package/dist/registry/library-build/schema-action.d.ts +38 -0
  85. package/dist/registry/library-build/schema-action.js +107 -0
  86. package/dist/registry/library-build/write.d.ts +6 -0
  87. package/dist/registry/library-build/write.js +26 -0
  88. package/dist/registry/library-reader.d.ts +20 -0
  89. package/dist/registry/library-reader.js +50 -0
  90. package/dist/registry/lookup-specs.d.ts +55 -0
  91. package/dist/registry/lookup-specs.js +140 -0
  92. package/dist/registry/materialize-cli.js +28 -14
  93. package/dist/registry/materializer.d.ts +25 -3
  94. package/dist/registry/materializer.js +45 -29
  95. package/dist/registry/model/library.d.ts +254 -0
  96. package/dist/registry/model/library.js +23 -0
  97. package/dist/registry/naming.d.ts +54 -0
  98. package/dist/registry/naming.js +142 -0
  99. package/dist/registry/orphans.d.ts +4 -0
  100. package/dist/registry/orphans.js +86 -0
  101. package/dist/registry/prepare/actions.d.ts +26 -0
  102. package/dist/registry/prepare/actions.js +94 -0
  103. package/dist/registry/prepare/connections.d.ts +181 -0
  104. package/dist/registry/prepare/connections.js +399 -0
  105. package/dist/registry/prepare/event.d.ts +96 -0
  106. package/dist/registry/prepare/event.js +268 -0
  107. package/dist/registry/prepare/handoff.d.ts +21 -0
  108. package/dist/registry/prepare/handoff.js +91 -0
  109. package/dist/registry/prepare/ledger.d.ts +104 -0
  110. package/dist/registry/prepare/ledger.js +216 -0
  111. package/dist/registry/prepare/messages.d.ts +190 -0
  112. package/dist/registry/prepare/messages.js +472 -0
  113. package/dist/registry/prepare/objects.d.ts +130 -0
  114. package/dist/registry/prepare/objects.js +318 -0
  115. package/dist/registry/prepare/overlay.d.ts +149 -0
  116. package/dist/registry/prepare/overlay.js +487 -0
  117. package/dist/registry/prepare/parents.d.ts +41 -0
  118. package/dist/registry/prepare/parents.js +122 -0
  119. package/dist/registry/prepare/pipeline.d.ts +91 -0
  120. package/dist/registry/prepare/pipeline.js +376 -0
  121. package/dist/registry/prepare/regenerate.d.ts +9 -0
  122. package/dist/registry/prepare/regenerate.js +50 -0
  123. package/dist/registry/prepare/resolve.d.ts +199 -0
  124. package/dist/registry/prepare/resolve.js +470 -0
  125. package/dist/registry/prepare/retry.d.ts +83 -0
  126. package/dist/registry/prepare/retry.js +109 -0
  127. package/dist/registry/prepare/source-import.d.ts +54 -0
  128. package/dist/registry/prepare/source-import.js +192 -0
  129. package/dist/registry/prepare/support.d.ts +41 -0
  130. package/dist/registry/prepare/support.js +178 -0
  131. package/dist/registry/prepare-cli.d.ts +16 -5
  132. package/dist/registry/prepare-cli.js +60 -53
  133. package/dist/registry/pull-cli.js +8 -7
  134. package/dist/registry/reporter.d.ts +26 -0
  135. package/dist/registry/reporter.js +41 -0
  136. package/dist/registry/uip/client.d.ts +99 -0
  137. package/dist/registry/uip/client.js +226 -0
  138. package/dist/registry/uip/commands.d.ts +40 -0
  139. package/dist/registry/uip/commands.js +80 -0
  140. package/dist/registry/uip/envelope.d.ts +37 -0
  141. package/dist/registry/uip/envelope.js +84 -0
  142. package/dist/registry/uip/response-cache.d.ts +28 -0
  143. package/dist/registry/uip/response-cache.js +57 -0
  144. package/lib/README.md +10 -8
  145. package/package.json +3 -3
  146. package/dist/generators/_connections.py +0 -331
  147. package/dist/generators/_events.py +0 -355
  148. package/dist/generators/_lookups.py +0 -114
  149. package/dist/generators/_naming.py +0 -185
  150. package/dist/generators/_objects.py +0 -299
  151. package/dist/generators/_resolve.py +0 -319
  152. package/dist/generators/convert_library_to_md.py +0 -1441
  153. package/dist/generators/extract_library.py +0 -125
  154. package/dist/generators/generate_connectors_ts.py +0 -936
  155. package/dist/generators/generate_library_json.py +0 -2527
  156. package/dist/generators/generate_triggers_ts.py +0 -110
  157. package/dist/generators/materialize_registry.py +0 -155
  158. package/dist/generators/prepare_connector.py +0 -1860
  159. package/dist/registry/python.d.ts +0 -26
  160. package/dist/registry/python.js +0 -46
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The Markdown library: one page per operation plus a rewritten `index.json`.
3
+ *
4
+ * Reads an extracted `library-json/` tree and renders the parallel tree of
5
+ * `.md` pages agents read for connector discovery, with an index whose `path`s
6
+ * point at the pages. Symbol names the pages cite (`connector(SendMessageToUser,
7
+ * …)`) are derived by `naming.symbolIndex`, the same map the descriptor
8
+ * generator uses, so a page cannot cite a symbol that module did not emit.
9
+ *
10
+ * Ported from `integrations/scripts/convert_library_to_md.py`; the output is
11
+ * byte-for-byte that script's. A caller writes each page as-is and the index
12
+ * with `pyJsonDocument(index)`.
13
+ */
14
+ import type { LoadedLibrary } from "../../library-reader.js";
15
+ import type { LibraryEntry, LibraryIndex, V1Definition } from "../../model/library.js";
16
+ export interface MarkdownContext {
17
+ /** `naming.symbolIndex` over the index: `nodeType → exported descriptor name`. */
18
+ symbols: ReadonlyMap<string, string>;
19
+ /** `objectName`s the curated ledger declares connector-invariant. */
20
+ invariant: ReadonlySet<string>;
21
+ }
22
+ /** One operation's page. `v1def` is the sidecar already unwrapped from a one-element list. */
23
+ export declare function renderMarkdownPage(entry: LibraryEntry, v1def: V1Definition | undefined, ctx: MarkdownContext): string;
24
+ export interface MarkdownOutput {
25
+ /** `<index path with .json → .md>` → page text, in index order. */
26
+ pages: Map<string, string>;
27
+ /** The source index with each converted row's `path` rewritten; other keys untouched. */
28
+ index: LibraryIndex;
29
+ /** One ` WARN: missing source entry <path>` line per row whose entry file is absent. */
30
+ warnings: string[];
31
+ }
32
+ /** Every operation the index names, rendered. Rows whose path is not a `.json` or whose file is missing are left as they are. */
33
+ export declare function renderMarkdownLibrary(library: LoadedLibrary): MarkdownOutput;
@@ -0,0 +1,37 @@
1
+ import { pyStr } from "../../compat/pystr.js";
2
+ import { symbolIndex } from "../../naming.js";
3
+ import { renderOp } from "./page.js";
4
+ import { pyOr } from "./pyvalue.js";
5
+ /** One operation's page. `v1def` is the sidecar already unwrapped from a one-element list. */
6
+ export function renderMarkdownPage(entry, v1def, ctx) {
7
+ return renderOp(entry, v1def, ctx.symbols.get(entry.nodeType), ctx.invariant);
8
+ }
9
+ /** Every operation the index names, rendered. Rows whose path is not a `.json` or whose file is missing are left as they are. */
10
+ export function renderMarkdownLibrary(library) {
11
+ const index = library.index;
12
+ const pages = new Map();
13
+ const warnings = [];
14
+ const entries = index.entries;
15
+ if (!Array.isArray(entries))
16
+ return { pages, index, warnings };
17
+ // The SAME map the descriptor generator uses.
18
+ const symbols = symbolIndex(entries);
19
+ const rows = entries.map((row) => {
20
+ const relJson = pyStr(pyOr(row.path, ""));
21
+ if (!relJson || !relJson.endsWith(".json"))
22
+ return row;
23
+ const entry = library.readEntry(row);
24
+ if (entry === undefined) {
25
+ warnings.push(` WARN: missing source entry ${library.entryPath(row)}`);
26
+ return row;
27
+ }
28
+ // The Flow node shape lives beside the entry as `<op>.v1def.json`; its
29
+ // inputDefinition is what the compiler validates, so inputs render from it.
30
+ const v1def = library.readV1Def(row);
31
+ const md = renderOp(entry, v1def, symbols.get(row.nodeType), library.invariant);
32
+ const relMd = `${relJson.slice(0, -".json".length)}.md`;
33
+ pages.set(relMd, md);
34
+ return { ...row, path: relMd };
35
+ });
36
+ return { pages, index: { ...index, entries: rows }, warnings };
37
+ }
@@ -0,0 +1,8 @@
1
+ import { type Dict } from "./pyvalue.js";
2
+ /**
3
+ * @param j the canonical entry
4
+ * @param v1def the sidecar, or `undefined` when the operation ships none
5
+ * @param symbol the generated descriptor's exported name, or `undefined` when there is no descriptor
6
+ * @param invariant `objectName`s the curated ledger declares connector-invariant
7
+ */
8
+ export declare function renderOp(j: Dict, v1def: Dict | undefined, symbol: string | undefined, invariant: ReadonlySet<string>): string;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * One library entry rendered to Markdown: header → schema-dynamic notice →
3
+ * choosing the object → resolving the field set → required inputs → optional
4
+ * inputs → resolving lookups → example → filtering → outputs. Ported from
5
+ * `render_op`; the page is `"\n".join(lines)` with no trailing newline.
6
+ */
7
+ import { afterLast, pyStr } from "../../compat/pystr.js";
8
+ import { dictOf, getStr, pyOr, pyTruthy } from "./pyvalue.js";
9
+ import { choosingObjectLines } from "./sections/choosing-object.js";
10
+ import { exampleLines } from "./sections/example.js";
11
+ import { eventFilterLines } from "./sections/filtering.js";
12
+ import { headerLines } from "./sections/header.js";
13
+ import { assembleFields, optionalInputsLines, requiredInputsLines } from "./sections/inputs.js";
14
+ import { lookupLines } from "./sections/lookups.js";
15
+ import { outputsLines } from "./sections/outputs.js";
16
+ import { schemaActionLines } from "./sections/resolving-fields.js";
17
+ import { schemaDynamicLines } from "./sections/schema-dynamic.js";
18
+ /**
19
+ * @param j the canonical entry
20
+ * @param v1def the sidecar, or `undefined` when the operation ships none
21
+ * @param symbol the generated descriptor's exported name, or `undefined` when there is no descriptor
22
+ * @param invariant `objectName`s the curated ledger declares connector-invariant
23
+ */
24
+ export function renderOp(j, v1def, symbol, invariant) {
25
+ const nodeType = getStr(j, "nodeType", "?");
26
+ const conn = dictOf(j.connector);
27
+ const op = dictOf(j.operation);
28
+ const out = [];
29
+ out.push(...headerLines(j, nodeType));
30
+ out.push(...schemaDynamicLines(j, nodeType));
31
+ const fields = assembleFields(j, v1def);
32
+ const required = fields.filter((f) => pyTruthy(f.required));
33
+ const optional = fields.filter((f) => !pyTruthy(f.required));
34
+ out.push(...choosingObjectLines(j, nodeType));
35
+ const action = op.schemaAction;
36
+ if (pyTruthy(action)) {
37
+ out.push(...schemaActionLines(pyStr(pyOr(conn.key, "<connector>")), pyStr(pyOr(op.objectName, "")), pyStr(pyOr(op.name, "<operation>")), dictOf(action), fields));
38
+ }
39
+ out.push(...requiredInputsLines(required));
40
+ out.push(...optionalInputsLines(optional));
41
+ const lookups = lookupLines(pyStr(pyOr(conn.key, "<connector>")), afterLast(nodeType, "."), fields, symbol, invariant);
42
+ if (lookups.length) {
43
+ out.push("## Resolving lookups", "");
44
+ out.push(...lookups);
45
+ out.push("");
46
+ }
47
+ // The example goes AFTER the lookups section: it uses the helpers that section introduces.
48
+ out.push(...exampleLines(j, fields, symbol, invariant, v1def));
49
+ out.push(...eventFilterLines(j, v1def));
50
+ out.push(...outputsLines(j));
51
+ return out.join("\n");
52
+ }
@@ -0,0 +1,34 @@
1
+ export type Dict = Record<string, unknown>;
2
+ /** Python truthiness for JSON-shaped values: empty strings and containers are false, `NaN` is true. */
3
+ export declare function pyTruthy(v: unknown): boolean;
4
+ /** `a or b or …`: the first Python-truthy operand, else the last one. */
5
+ export declare function pyOr<T>(...values: T[]): T;
6
+ /** `isinstance(v, dict)`. */
7
+ export declare function isDict(v: unknown): v is Dict;
8
+ /** `(v or {})` where the Python goes on to call `.get` — a non-dict reads as empty. */
9
+ export declare function dictOf(v: unknown): Dict;
10
+ /**
11
+ * The items Python's `for x in (v or [])` would visit: a list's items, a
12
+ * string's code points, a dict's keys; nothing for anything else.
13
+ */
14
+ export declare function listOf(v: unknown): unknown[];
15
+ /** `str(d.get(key, default))`: a missing key yields `default`, a present `None` yields `"None"`. */
16
+ export declare function getStr(d: Dict, key: string, fallback: string): string;
17
+ /** `[str(x) for x in (v or [])]`. */
18
+ export declare function strList(v: unknown): string[];
19
+ /** The first value of an insertion-ordered map: `next(iter(d.values()))`. Callers check emptiness first. */
20
+ export declare function firstValue<V>(map: ReadonlyMap<unknown, V>): V;
21
+ /** `re.compile(r"[A-Za-z_$][A-Za-z0-9_$]*").fullmatch`: a bare object key. */
22
+ export declare const IDENT: RegExp;
23
+ /**
24
+ * Whether Python's `float(s)` accepts the string.
25
+ *
26
+ * `float()` strips whitespace (see {@link FLOAT_SPACE}), maps every `Nd`
27
+ * digit to ASCII, allows a single `_` between digits (PEP 515), and takes
28
+ * `inf`/`infinity`/`nan` in any ASCII case with an optional sign. It rejects
29
+ * the empty string, hex, a dangling exponent, an embedded NUL and underscores
30
+ * anywhere but between digits. The generator uses the verdict, not the value:
31
+ * an enum choice a number-typed field can carry prints bare, anything else
32
+ * falls through.
33
+ */
34
+ export declare function pyFloatAccepts(s: string): boolean;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Python value semantics the Markdown generator leans on.
3
+ *
4
+ * `convert_library_to_md.py` is written against dicts — `.get()`, `or`
5
+ * fallbacks, truthiness tests — and its output is byte-locked. These helpers
6
+ * spell those semantics once so each section module can be read beside the
7
+ * Python line for line. JSON has no `undefined`, so after `JSON.parse` an
8
+ * absent key is `undefined` and an explicit `null` is `null`: the same
9
+ * distinction Python's `d.get(k, default)` draws between a missing key (the
10
+ * default) and a `None` value (printed as `None`).
11
+ */
12
+ import { pyStr, pyStripChars } from "../../compat/pystr.js";
13
+ /** Python truthiness for JSON-shaped values: empty strings and containers are false, `NaN` is true. */
14
+ export function pyTruthy(v) {
15
+ if (v === null || v === undefined)
16
+ return false;
17
+ switch (typeof v) {
18
+ case "boolean":
19
+ return v;
20
+ case "number":
21
+ return v !== 0;
22
+ case "bigint":
23
+ return v !== 0n;
24
+ case "string":
25
+ return v.length > 0;
26
+ case "object":
27
+ if (Array.isArray(v))
28
+ return v.length > 0;
29
+ if (v instanceof Map || v instanceof Set)
30
+ return v.size > 0;
31
+ return Object.keys(v).length > 0;
32
+ default:
33
+ return true;
34
+ }
35
+ }
36
+ /** `a or b or …`: the first Python-truthy operand, else the last one. */
37
+ export function pyOr(...values) {
38
+ for (const v of values)
39
+ if (pyTruthy(v))
40
+ return v;
41
+ return values[values.length - 1];
42
+ }
43
+ /** `isinstance(v, dict)`. */
44
+ export function isDict(v) {
45
+ return v !== null && typeof v === "object" && !Array.isArray(v);
46
+ }
47
+ /** `(v or {})` where the Python goes on to call `.get` — a non-dict reads as empty. */
48
+ export function dictOf(v) {
49
+ return isDict(v) ? v : {};
50
+ }
51
+ /**
52
+ * The items Python's `for x in (v or [])` would visit: a list's items, a
53
+ * string's code points, a dict's keys; nothing for anything else.
54
+ */
55
+ export function listOf(v) {
56
+ if (Array.isArray(v))
57
+ return v;
58
+ if (typeof v === "string")
59
+ return Array.from(v);
60
+ if (isDict(v))
61
+ return Object.keys(v);
62
+ return [];
63
+ }
64
+ /** `str(d.get(key, default))`: a missing key yields `default`, a present `None` yields `"None"`. */
65
+ export function getStr(d, key, fallback) {
66
+ const v = d[key];
67
+ return v === undefined ? fallback : pyStr(v);
68
+ }
69
+ /** `[str(x) for x in (v or [])]`. */
70
+ export function strList(v) {
71
+ return listOf(pyOr(v, [])).map((x) => pyStr(x));
72
+ }
73
+ /** The first value of an insertion-ordered map: `next(iter(d.values()))`. Callers check emptiness first. */
74
+ export function firstValue(map) {
75
+ return map.values().next().value;
76
+ }
77
+ /** `re.compile(r"[A-Za-z_$][A-Za-z0-9_$]*").fullmatch`: a bare object key. */
78
+ export const IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
79
+ /** `digitpart ::= digit (["_"] digit)*` over every Unicode decimal digit, as `float()` accepts. */
80
+ const DIGITS = "\\p{Nd}(?:_?\\p{Nd})*";
81
+ const FLOAT_LITERAL = new RegExp(`^[+-]?(?:${DIGITS}(?:\\.(?:${DIGITS})?)?|\\.${DIGITS})(?:[eE][+-]?${DIGITS})?$`, "u");
82
+ const SPECIAL_FLOAT = /^[+-]?(?:inf|infinity|nan)$/i;
83
+ /**
84
+ * What `float()` strips: the C `isspace` set for ASCII (the transform copies
85
+ * ASCII verbatim, so `\x1c`–`\x1f` are NOT whitespace here although
86
+ * `str.strip()` removes them) plus every non-ASCII character `str.isspace()`
87
+ * is true for, which the transform maps to a space first.
88
+ */
89
+ const FLOAT_SPACE = " \t\n\u000b\u000c\r\u0085\u00a0\u1680" +
90
+ "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a" +
91
+ "\u2028\u2029\u202f\u205f\u3000";
92
+ /**
93
+ * Whether Python's `float(s)` accepts the string.
94
+ *
95
+ * `float()` strips whitespace (see {@link FLOAT_SPACE}), maps every `Nd`
96
+ * digit to ASCII, allows a single `_` between digits (PEP 515), and takes
97
+ * `inf`/`infinity`/`nan` in any ASCII case with an optional sign. It rejects
98
+ * the empty string, hex, a dangling exponent, an embedded NUL and underscores
99
+ * anywhere but between digits. The generator uses the verdict, not the value:
100
+ * an enum choice a number-typed field can carry prints bare, anything else
101
+ * falls through.
102
+ */
103
+ export function pyFloatAccepts(s) {
104
+ const text = pyStripChars(s, FLOAT_SPACE);
105
+ return FLOAT_LITERAL.test(text) || SPECIAL_FLOAT.test(text);
106
+ }
@@ -0,0 +1,2 @@
1
+ import { type Dict } from "../pyvalue.js";
2
+ export declare function choosingObjectLines(j: Dict, nodeType: string): string[];
@@ -0,0 +1,52 @@
1
+ /**
2
+ * `## Choosing the object`, on an operation that works on any object of the
3
+ * connection (`objectFromDiscovery`). Object selection precedes field
4
+ * selection, so this sits above the inputs.
5
+ */
6
+ import { afterLast, pyStr } from "../../../compat/pystr.js";
7
+ import { dictOf, pyOr, pyTruthy } from "../pyvalue.js";
8
+ export function choosingObjectLines(j, nodeType) {
9
+ const op = dictOf(j.operation);
10
+ if (!pyTruthy(op.objectFromDiscovery))
11
+ return [];
12
+ const conn = dictOf(j.connector);
13
+ const connectorKey = pyStr(pyOr(conn.key, "<connector>"));
14
+ const verb = pyStr(pyOr(op.name, "<operation>"));
15
+ const prefix = `uipath.connector.${connectorKey}.`;
16
+ const mdAction = nodeType.startsWith(prefix) ? nodeType.slice(prefix.length) : afterLast(nodeType, ".");
17
+ return [
18
+ "## Choosing the object",
19
+ "",
20
+ "This operation works on any object in the connection, including " +
21
+ "custom ones, so the object list is not in this catalog. Do not " +
22
+ "run discovery commands and do not hand-filter the catalog — " +
23
+ "author the step with the object name as the task said it (any " +
24
+ "casing), then one command matches it deterministically:",
25
+ "",
26
+ "```bash",
27
+ `npx flow-sdk registry prepare ${connectorKey} ${mdAction} --object <name-as-the-task-said-it>`,
28
+ "```",
29
+ "",
30
+ "The name is matched, never equality-tested: exact, then " +
31
+ "case-insensitive on API name and display name (`matched " +
32
+ "\"Company__C\" -> Company__c` is printed), narrowed to objects " +
33
+ `that support ${verb}. It then fetches the object's ` +
34
+ "connection-resolved fields, generates the typed descriptor, and " +
35
+ "prints the import line to use.",
36
+ "",
37
+ "**If the name matches several objects, the command refuses and " +
38
+ "prints the candidates** (API name, display name, custom, " +
39
+ "operations). `Custom: yes` marks an object that exists only on " +
40
+ "this tenant, so it could never have been in this catalog — a " +
41
+ "task that says \"custom\" means one of those rows. Pick by the " +
42
+ "task's wording, or present the candidates and let the user " +
43
+ "choose; never pick for them, and do not assume the user's " +
44
+ "wording is the API name. Then re-run with the chosen name.",
45
+ "",
46
+ "**If nothing matches**, the command has already retried against " +
47
+ "a refreshed catalog before saying so — the object genuinely is " +
48
+ "not on this connection. Check the value against the task's " +
49
+ "words, or surface it to the user rather than inventing one.",
50
+ "",
51
+ ];
52
+ }
@@ -0,0 +1,22 @@
1
+ import { type Dict } from "../pyvalue.js";
2
+ /** `fields.project.key` → `projectKey`: a readable input name, not a path. */
3
+ export declare function leafName(fieldName: string): string;
4
+ /** `send-message-to-user` → `sendMessageToUser`, a usable step name. */
5
+ export declare function pascalStep(action: string): string;
6
+ /** Render `[name, value]` pairs as the nested object literal an author writes. */
7
+ export declare function nestInputs(pairs: ReadonlyArray<readonly [unknown, string]>): string[];
8
+ /**
9
+ * The value to show for one required input: a resolvable lookup shows its
10
+ * helper; an enum shows its FIRST DECLARED CHOICE, typed to the declaration
11
+ * where it can be; anything else shows `input('<name>')`.
12
+ */
13
+ export declare function exampleValue(f: Dict, symbol: string | undefined, invariant: ReadonlySet<string>, connectorKey?: string, action?: string): string;
14
+ /** A compilable `connector(...)` call for this operation; events go to {@link eventExampleLines}. */
15
+ export declare function exampleLines(j: Dict, fields: readonly Dict[], symbol: string | undefined, invariant: ReadonlySet<string>, v1def: Dict | undefined): string[];
16
+ /**
17
+ * A compilable `onEvent(...)` / `waitForEvent(...)` call for a connector
18
+ * EVENT. A GENERIC event (`GenericTrigger`) watches ONE object the entry does
19
+ * not name, so the example shows the `object` option; a curated event shows
20
+ * `where` with the sidecar's event parameters.
21
+ */
22
+ export declare function eventExampleLines(j: Dict, symbol: string | undefined, connectorKey: string, action: string, step: string, v1def: Dict | undefined): string[];
@@ -0,0 +1,295 @@
1
+ /**
2
+ * `## Example`: a compilable `connector(...)` call — or, for an event, an
3
+ * `onEvent(...)` / `waitForEvent(...)` call — for the operation.
4
+ *
5
+ * Required inputs only, nested the way the descriptor's `Inputs` type is
6
+ * nested, with the import path DERIVED: a schema-dynamic operation's
7
+ * descriptor lives in `./connectors-local/` after a `prepare`. When a
8
+ * descriptor exists the example is type-checked against its `Inputs`, so the
9
+ * required set is the descriptor generator's, not this module's; the two
10
+ * vocabularies disagree about required-ness on most operations, and that
11
+ * disagreement is pre-existing. Ported from `example_lines`,
12
+ * `event_example_lines`, `nest_inputs`, `example_value`, `leaf_name` and
13
+ * `pascal_step`.
14
+ */
15
+ import { PACKAGE_NAME } from "../../../../package-name.js";
16
+ import { pyJsonString } from "../../../codecs/pyjson.js";
17
+ import { sortedStrings } from "../../../compat/compare.js";
18
+ import { afterLast, pyStr, upperFirst } from "../../../compat/pystr.js";
19
+ import { classify, referenceOf } from "../../../lookup-specs.js";
20
+ import { isEventNodeType, TRIGGER_PREFIX } from "../../../model/library.js";
21
+ import { byAliases } from "../../../naming.js";
22
+ import { descriptorInputFields, markLookupFields } from "../../fields.js";
23
+ import { authoringField, enumValue } from "../common.js";
24
+ import { dictOf, firstValue, getStr, IDENT, listOf, pyFloatAccepts, pyOr, pyTruthy, strList, } from "../pyvalue.js";
25
+ /** `fields.project.key` → `projectKey`: a readable input name, not a path. */
26
+ export function leafName(fieldName) {
27
+ const parts = fieldName.replaceAll("[*]", "").split(".").filter((p) => p);
28
+ if (!parts.length)
29
+ return "value";
30
+ if (parts.length === 1)
31
+ return parts[0];
32
+ const [head, ...rest] = parts.slice(-2);
33
+ return head + rest.map(upperFirst).join("");
34
+ }
35
+ /** `send-message-to-user` → `sendMessageToUser`, a usable step name. */
36
+ export function pascalStep(action) {
37
+ const words = action.replaceAll("_", "-").split("-").filter((w) => w);
38
+ if (!words.length)
39
+ return "step";
40
+ const [head, ...rest] = words;
41
+ return head + rest.map(upperFirst).join("");
42
+ }
43
+ /**
44
+ * One level of the example's input literal. A segment can be BOTH an array
45
+ * and an object (`contacts[*].name` is a list of objects), so array-ness is a
46
+ * flag on the node. `children` is insertion-ordered, like the Python dict.
47
+ */
48
+ class Node {
49
+ children = new Map();
50
+ isArray = false;
51
+ leaf;
52
+ }
53
+ /** Render `[name, value]` pairs as the nested object literal an author writes. */
54
+ export function nestInputs(pairs) {
55
+ const root = new Node();
56
+ for (const [name, value] of pairs) {
57
+ let node = root;
58
+ for (const segment of pyStr(name).split(".").filter((p) => p)) {
59
+ const isArray = segment.endsWith("[*]");
60
+ const key = isArray ? segment.slice(0, -3) : segment;
61
+ let child = node.children.get(key);
62
+ if (child === undefined) {
63
+ child = new Node();
64
+ node.children.set(key, child);
65
+ }
66
+ child.isArray = child.isArray || isArray;
67
+ node = child;
68
+ }
69
+ node.leaf = value;
70
+ }
71
+ const render = (node, indent) => {
72
+ const pad = " ".repeat(indent);
73
+ const lines = [];
74
+ for (const [key, child] of node.children) {
75
+ const safe = IDENT.test(key) ? key : pyJsonString(key);
76
+ if (child.children.size) {
77
+ const [openBrace, closeBrace] = child.isArray ? ["[{", "}],"] : ["{", "},"];
78
+ lines.push(`${pad}${safe}: ${openBrace}`);
79
+ lines.push(...render(child, indent + 1));
80
+ lines.push(`${pad}${closeBrace}`);
81
+ }
82
+ else {
83
+ const value = child.leaf !== undefined ? child.leaf : "undefined";
84
+ lines.push(child.isArray ? `${pad}${safe}: [${value}],` : `${pad}${safe}: ${value},`);
85
+ }
86
+ }
87
+ return lines;
88
+ };
89
+ return render(root, 1);
90
+ }
91
+ /**
92
+ * The value to show for one required input: a resolvable lookup shows its
93
+ * helper; an enum shows its FIRST DECLARED CHOICE, typed to the declaration
94
+ * where it can be; anything else shows `input('<name>')`.
95
+ */
96
+ export function exampleValue(f, symbol, invariant, connectorKey = "", action = "") {
97
+ const [name] = authoringField(f);
98
+ // The lookup table is keyed by the WIRE name (`addLabelIds[*]`), which is
99
+ // what `--resolve` and `buildConnectorInputs` both match on.
100
+ const wire = pyStr(pyOr(f.name, name));
101
+ const kind = classify(f, invariant);
102
+ if (kind === "lookup") {
103
+ const reference = referenceOf(f);
104
+ const names = strList(reference.lookupNames);
105
+ const aliases = byAliases(names);
106
+ const first = names.length ? names[0] : "id";
107
+ if (symbol) {
108
+ if (aliases.size)
109
+ return `lookup(${symbol}, '${wire}').${firstValue(aliases)}('…')`;
110
+ return `lookup(${symbol}, '${wire}').by('${first}', '…')`;
111
+ }
112
+ // NO DESCRIPTOR — a Generic CRUD expansion: the string form, generic `.by` only.
113
+ return `lookup('${connectorKey}', '${action}', '${wire}').by('${first}', '…')`;
114
+ }
115
+ const type = getStr(f, "type", "").toLowerCase();
116
+ const enumeration = f.enum;
117
+ if (pyTruthy(enumeration)) {
118
+ // The choice list is strings even when the field is not; fall back rather
119
+ // than emit something that does not compile.
120
+ const choice = enumValue(listOf(enumeration)[0]);
121
+ if (type === "boolean" || type === "bool") {
122
+ const lowered = choice.toLowerCase();
123
+ if (lowered === "true" || lowered === "false")
124
+ return lowered;
125
+ }
126
+ else if (type === "number" || type === "integer" || type === "float" || type === "double" || type === "long") {
127
+ if (pyFloatAccepts(choice))
128
+ return choice;
129
+ }
130
+ else {
131
+ return pyJsonString(choice);
132
+ }
133
+ }
134
+ return `input('${leafName(name)}')`;
135
+ }
136
+ /** A compilable `connector(...)` call for this operation; events go to {@link eventExampleLines}. */
137
+ export function exampleLines(j, fields, symbol, invariant, v1def) {
138
+ const connectorKey = pyStr(pyOr(dictOf(j.connector).key, "<connector>"));
139
+ const operation = dictOf(j.operation);
140
+ const runtime = dictOf(j.runtime);
141
+ const nodeType = pyStr(pyOr(j.nodeType, ""));
142
+ const action = afterLast(nodeType, ".");
143
+ const step = pascalStep(action);
144
+ if (isEventNodeType(nodeType))
145
+ return eventExampleLines(j, symbol, connectorKey, action, step, v1def);
146
+ // WHICH REQUIRED SET: the descriptor's `Inputs` when a descriptor exists,
147
+ // marked with the SAME call the descriptor generator uses; else this
148
+ // module's own vocabulary, which the string form cannot fail on.
149
+ let exampleFields;
150
+ if (symbol) {
151
+ const entry = j;
152
+ const raw = (v1def ?? {});
153
+ // Marked with the SAME call the descriptor generator uses — it also merges
154
+ // the catalog's `reference` into a field whose authoring vocabulary lacks
155
+ // one — so the example puts a helper on exactly the fields that have one.
156
+ exampleFields = markLookupFields(entry, descriptorInputFields(entry, raw), invariant);
157
+ }
158
+ else {
159
+ exampleFields = fields;
160
+ }
161
+ const required = exampleFields.filter((f) => pyTruthy(f.required));
162
+ const schemaDynamic = pyTruthy(operation.objectFromDiscovery) ||
163
+ pyTruthy(dictOf(operation.schemaAction).parents) ||
164
+ pyTruthy(runtime.requiresConnectionForSchema);
165
+ const out = ["## Example", ""];
166
+ const pairs = required.map((f) => {
167
+ const [name, , wireName] = authoringField(f);
168
+ return [wireName ? f.name : name, exampleValue(f, symbol, invariant, connectorKey, action)];
169
+ });
170
+ // Import exactly what the rendered body uses.
171
+ const bodyUses = new Set(["connector"]);
172
+ if (pairs.some(([, v]) => v.includes("lookup(")))
173
+ bodyUses.add("lookup");
174
+ if (pairs.some(([, v]) => v.includes("input(")))
175
+ bodyUses.add("input");
176
+ const imported = sortedStrings(bodyUses).join(", ");
177
+ out.push("```ts");
178
+ // THE PACKAGE, not a relative path.
179
+ out.push(`import { ${imported} } from '${PACKAGE_NAME}';`);
180
+ let head;
181
+ if (symbol) {
182
+ const directory = schemaDynamic ? "connectors-local" : "connectors";
183
+ out.push(`import { ${symbol} } from './${directory}/${connectorKey}.ts';`);
184
+ out.push("");
185
+ head = `.step('${step}', connector(${symbol}, {`;
186
+ }
187
+ else {
188
+ out.push("");
189
+ head = `.step('${step}', connector('${connectorKey}', '${action}', {`;
190
+ }
191
+ out.push(head);
192
+ if (pairs.length)
193
+ out.push(...nestInputs(pairs));
194
+ const opts = [];
195
+ if (pyTruthy(runtime.requiresConnection))
196
+ opts.push(`connection: '${afterLast(connectorKey, "-")}'`);
197
+ if (pyTruthy(runtime.requiresFolderKey))
198
+ opts.push("folder: 'shared'");
199
+ if (!symbol && (operation.activityType === "Generic" || operation.activityType === "GenericExpanded")) {
200
+ opts.push(`object: '${pyStr(pyOr(operation.objectName, "<object>"))}'`);
201
+ }
202
+ const tail = "}" + (opts.length ? `, { ${opts.join(", ")} }` : "") + "))";
203
+ out.push(tail);
204
+ out.push("```");
205
+ out.push("");
206
+ if (schemaDynamic && symbol) {
207
+ // ONE ordering per page: the import fact stays; authoring comes first.
208
+ if (pyTruthy(operation.objectFromDiscovery)) {
209
+ out.push("The descriptor comes from `./connectors-local/` and this " +
210
+ "import resolves only after " +
211
+ `\`npx flow-sdk registry prepare ${connectorKey} ${action} ` +
212
+ "--object <name>` runs. That never blocks authoring: write " +
213
+ "the step first with the string form and " +
214
+ "`{ object: '<name-as-the-task-said-it>' }` — `check` " +
215
+ "names this exact prepare — then switch to this import.");
216
+ }
217
+ else {
218
+ out.push("The descriptor comes from `./connectors-local/` and this " +
219
+ "import resolves only after " +
220
+ `\`npx flow-sdk registry prepare ${connectorKey} ${action}\` ` +
221
+ "runs. That never blocks authoring: the fields in this " +
222
+ "catalog are authorable immediately, and `check` flags any " +
223
+ "input outside them with this same command.");
224
+ }
225
+ out.push("");
226
+ }
227
+ return out;
228
+ }
229
+ /**
230
+ * A compilable `onEvent(...)` / `waitForEvent(...)` call for a connector
231
+ * EVENT. A GENERIC event (`GenericTrigger`) watches ONE object the entry does
232
+ * not name, so the example shows the `object` option; a curated event shows
233
+ * `where` with the sidecar's event parameters.
234
+ */
235
+ export function eventExampleLines(j, symbol, connectorKey, action, step, v1def) {
236
+ const operation = dictOf(j.operation);
237
+ const generic = operation.activityType === "GenericTrigger";
238
+ const start = getStr(j, "nodeType", "").startsWith(TRIGGER_PREFIX);
239
+ // The SIDECAR's event parameters: the raw input definition's names are not
240
+ // even legal object keys. No parameters, no `where`.
241
+ const params = listOf(pyOr(dictOf(pyOr(dictOf(v1def).eventParameters, {})).fields, []))
242
+ .map(dictOf)
243
+ .filter((f) => typeof f.name === "string" && !pyTruthy(f.hidden))
244
+ .map((f) => f.name);
245
+ const factory = start ? "onEvent" : "waitForEvent";
246
+ const out = ["## Example", "", "```ts"];
247
+ out.push(`import { ${factory} } from '${PACKAGE_NAME}';`);
248
+ if (symbol)
249
+ out.push(`import { ${symbol} } from './connectors/${connectorKey}.ts';`);
250
+ out.push("");
251
+ const opts = [];
252
+ let whereLines = [];
253
+ if (generic)
254
+ opts.push("object: '<Object>'");
255
+ else if (params.length) {
256
+ // NESTED, exactly as inputs are: the generated `…Where` interface splits a
257
+ // dotted parameter into an object (`channelData.channel.id` becomes
258
+ // `channelData: ConnectorValue<ChannelDataInput>`), so a flat key — quoted
259
+ // or not — is not a member of the type. Unnested, Teams'
260
+ // `channelData.channel.id` made the only two event examples in the library
261
+ // the only `## Example` fences in ~8,000 that did not parse.
262
+ whereLines = nestInputs(params.map((p) => [p, `'<${p}>'`])).map((line) => ` ${line}`);
263
+ }
264
+ opts.push(`connection: '${afterLast(connectorKey, "-")}'`);
265
+ opts.push("folder: 'shared'");
266
+ const lead = symbol
267
+ ? `${factory}(${symbol}, {`
268
+ : `${factory}({ connector: '${connectorKey}', event: '${action}',`;
269
+ if (whereLines.length > 0) {
270
+ // Multi-line, like the action example, because the nested `where` is.
271
+ out.push(start ? `.trigger(${lead}` : `.step('${step}', ${lead}`);
272
+ out.push(" where: {");
273
+ out.push(...whereLines);
274
+ out.push(" },");
275
+ for (const option of opts)
276
+ out.push(` ${option},`);
277
+ out.push("}))");
278
+ }
279
+ else {
280
+ const call = symbol
281
+ ? `${factory}(${symbol}, { ${opts.join(", ")} })`
282
+ : `${factory}({ connector: '${connectorKey}', event: '${action}', ${opts.join(", ")} })`;
283
+ out.push(start ? `.trigger(${call})` : `.step('${step}', ${call})`);
284
+ }
285
+ out.push("```");
286
+ out.push("");
287
+ if (generic) {
288
+ out.push("A GENERIC event: it fires for ONE object of the connection, so `object` " +
289
+ `names it. \`uip is triggers objects ${connectorKey} ` +
290
+ `${pyStr(pyOr(operation.eventOperation, operation.name, "<EVENT>"))} ` +
291
+ "--connection-id <id>` lists the objects the bound connection exposes.");
292
+ out.push("");
293
+ }
294
+ return out;
295
+ }
@@ -0,0 +1,2 @@
1
+ import { type Dict } from "../pyvalue.js";
2
+ export declare function eventFilterLines(j: Dict, v1def: Dict | undefined): string[];