@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
@@ -0,0 +1,254 @@
1
+ /**
2
+ * The shapes on disk.
3
+ *
4
+ * One connector operation is three files: a `.json` entry that says how it is
5
+ * addressed, a `.v1def.json` sidecar that is the platform's node definition
6
+ * verbatim, and a Markdown page an agent reads. `index.json` maps node types to
7
+ * entry paths. A project overlay written by `prepare` uses the same entry and
8
+ * sidecar shapes under `connectors-local/descriptors/`, plus a ledger of
9
+ * resolved ids and a bindings document.
10
+ *
11
+ * These are the types the registry code passes around. They are deliberately
12
+ * loose where the registry itself is loose — a node definition is whatever the
13
+ * platform served, and the generators copy fields they do not interpret — and
14
+ * tight where the SDK depends on a field.
15
+ */
16
+ export type JsonPrimitive = string | number | boolean | null;
17
+ export type JsonValue = JsonPrimitive | JsonValue[] | {
18
+ [key: string]: JsonValue;
19
+ };
20
+ export type JsonObject = {
21
+ [key: string]: JsonValue;
22
+ };
23
+ /** A field's `reference`: where its id-valued input can be resolved from. */
24
+ export interface FieldReference {
25
+ objectName?: string;
26
+ path?: string;
27
+ lookupNames?: string[];
28
+ lookupValue?: string;
29
+ filterPattern?: string;
30
+ childPath?: string;
31
+ dependsOn?: string[];
32
+ [key: string]: unknown;
33
+ }
34
+ /** One input or output field as the library records it. */
35
+ export interface LibraryField {
36
+ name: string;
37
+ type?: string;
38
+ dataType?: string;
39
+ required?: boolean;
40
+ description?: string;
41
+ displayName?: string;
42
+ enum?: unknown[];
43
+ reference?: FieldReference;
44
+ /** `query` | `path` | `multipart` | `event` for operation parameters; absent for body fields. */
45
+ location?: string;
46
+ bucket?: string;
47
+ hidden?: boolean;
48
+ sortOrder?: number | null;
49
+ dependsOn?: string[];
50
+ [key: string]: unknown;
51
+ }
52
+ export interface ConnectorDiscovery {
53
+ type?: string;
54
+ hasObjectDiscovery?: boolean;
55
+ hasFieldDiscovery?: boolean;
56
+ hasCustomObjectDiscovery?: boolean;
57
+ hasCustomFieldDiscovery?: boolean;
58
+ }
59
+ export interface EntryConnector {
60
+ key: string;
61
+ name?: string;
62
+ tier?: string;
63
+ discovery?: ConnectorDiscovery;
64
+ [key: string]: unknown;
65
+ }
66
+ export type ActivityType = "Curated" | "Generic" | "GenericExpanded" | "CuratedTrigger" | "GenericTrigger" | "Http" | (string & {});
67
+ export interface SchemaAction {
68
+ name?: string;
69
+ parents: string[];
70
+ trigger?: string;
71
+ replaces?: "input" | "output" | "both";
72
+ [key: string]: unknown;
73
+ }
74
+ export interface EntryOperation {
75
+ name: string;
76
+ objectName: string;
77
+ objectDisplayName?: string;
78
+ activityType: ActivityType;
79
+ httpMethod?: string;
80
+ path?: string;
81
+ pathTemplate?: string;
82
+ parameters?: LibraryField[];
83
+ subType?: string;
84
+ sourceNodeType?: string;
85
+ objectFromDiscovery?: boolean;
86
+ eventOperation?: string;
87
+ eventMode?: string;
88
+ schemaAction?: SchemaAction | null;
89
+ dispatchStyle?: string;
90
+ paramGrammars?: unknown;
91
+ [key: string]: unknown;
92
+ }
93
+ export interface EntryRuntime {
94
+ requiresConnection?: boolean;
95
+ requiresFolderKey?: boolean;
96
+ requiresConnectionForSchema?: boolean;
97
+ bpmnType?: string;
98
+ [key: string]: unknown;
99
+ }
100
+ export interface EventSchema {
101
+ eventParameters?: {
102
+ fields: LibraryField[];
103
+ };
104
+ filterFields?: {
105
+ fields: LibraryField[];
106
+ };
107
+ eventMode?: string;
108
+ byoaConnection?: boolean;
109
+ isWebhookUrlVisible?: boolean;
110
+ }
111
+ /** The canonical `<key>/<action>@<version>.json`. */
112
+ export interface LibraryEntry {
113
+ nodeType: string;
114
+ version: string;
115
+ connector: EntryConnector;
116
+ operation: EntryOperation;
117
+ display: {
118
+ label?: string;
119
+ description?: string;
120
+ [key: string]: unknown;
121
+ };
122
+ runtime: EntryRuntime;
123
+ inputSchema: {
124
+ fields: LibraryField[];
125
+ };
126
+ outputSchema: {
127
+ fields: LibraryField[];
128
+ };
129
+ eventSchema?: EventSchema;
130
+ [key: string]: unknown;
131
+ }
132
+ /**
133
+ * The `.v1def.json` sidecar: the platform's node definition. Only the members
134
+ * the registry reads are named; everything else rides along untouched.
135
+ */
136
+ export interface V1Definition {
137
+ inputDefinition?: {
138
+ fields?: LibraryField[];
139
+ [key: string]: unknown;
140
+ };
141
+ outputDefinition?: {
142
+ fields?: LibraryField[];
143
+ [key: string]: unknown;
144
+ };
145
+ eventParameters?: {
146
+ fields?: LibraryField[];
147
+ [key: string]: unknown;
148
+ };
149
+ filterFields?: {
150
+ fields?: LibraryField[];
151
+ [key: string]: unknown;
152
+ };
153
+ eventMode?: string;
154
+ byoaConnection?: boolean;
155
+ isWebhookUrlVisible?: boolean;
156
+ model?: {
157
+ bindings?: unknown[];
158
+ context?: Array<{
159
+ name?: string;
160
+ value?: unknown;
161
+ }>;
162
+ [key: string]: unknown;
163
+ };
164
+ form?: unknown;
165
+ supportsErrorHandling?: boolean;
166
+ inputDefaults?: Record<string, unknown>;
167
+ debug?: {
168
+ runtime?: string;
169
+ };
170
+ [key: string]: unknown;
171
+ }
172
+ /** One row of `index.json`. */
173
+ export interface IndexRow {
174
+ nodeType: string;
175
+ version: string;
176
+ connectorKey: string;
177
+ label: string;
178
+ activityType: ActivityType;
179
+ objectName: string;
180
+ operationName: string;
181
+ path: string;
182
+ objectFromDiscovery?: true;
183
+ [key: string]: unknown;
184
+ }
185
+ export interface LibraryIndex {
186
+ schemaVersion: string;
187
+ entries: IndexRow[];
188
+ [key: string]: unknown;
189
+ }
190
+ /** `connectors-local/index.json`: the same rows, paths under `descriptors/`. */
191
+ export type OverlayIndex = LibraryIndex;
192
+ /** One recorded lookup resolution, keyed in the ledger by `lookupKey(...)`. */
193
+ export interface LedgerResolution {
194
+ nodeType: string;
195
+ field: string;
196
+ by: string;
197
+ match: string;
198
+ value: string;
199
+ }
200
+ /** One recorded object decision under `objects[nodeType][requestedName]`. */
201
+ export interface LedgerObject {
202
+ value: string;
203
+ displayName: string;
204
+ custom: boolean;
205
+ operation?: string;
206
+ }
207
+ /** `connectors-local/resolutions.json`. */
208
+ export interface Ledger {
209
+ schemaVersion: string;
210
+ objects?: Record<string, Record<string, LedgerObject>>;
211
+ resolutions: Record<string, LedgerResolution>;
212
+ }
213
+ export interface BindingRow {
214
+ id: string;
215
+ name: string;
216
+ resource: string;
217
+ resourceKey: string;
218
+ default?: boolean;
219
+ propertyAttribute?: string;
220
+ [key: string]: unknown;
221
+ }
222
+ /** `bindings.json`. */
223
+ export interface BindingsDocument {
224
+ schemaVersion: string;
225
+ bindings: BindingRow[];
226
+ [key: string]: unknown;
227
+ }
228
+ /** One row of `registry-triggers.json`, PascalCase except `connectorKey`. */
229
+ export interface TriggerCatalogueRow {
230
+ NodeType: string;
231
+ DisplayName?: string;
232
+ Description?: string;
233
+ Version?: string;
234
+ connectorKey: string;
235
+ }
236
+ export interface TriggerCatalogue {
237
+ schemaVersion: string;
238
+ note?: string;
239
+ count: number;
240
+ triggers: TriggerCatalogueRow[];
241
+ }
242
+ /** `invariant-collections.json`: collections whose ids never depend on a connection. */
243
+ export interface InvariantCollections {
244
+ collections: Array<{
245
+ objectName: string;
246
+ [key: string]: unknown;
247
+ }>;
248
+ }
249
+ /** Node-type prefixes that mark the three roles a connector node can play. */
250
+ export declare const CONNECTOR_PREFIX = "uipath.connector.";
251
+ export declare const TRIGGER_PREFIX = "uipath.connector.trigger.";
252
+ export declare const EVENT_PREFIX = "uipath.connector.event.";
253
+ /** True for a start trigger or a mid-flow event wait. */
254
+ export declare function isEventNodeType(nodeType: string): boolean;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The shapes on disk.
3
+ *
4
+ * One connector operation is three files: a `.json` entry that says how it is
5
+ * addressed, a `.v1def.json` sidecar that is the platform's node definition
6
+ * verbatim, and a Markdown page an agent reads. `index.json` maps node types to
7
+ * entry paths. A project overlay written by `prepare` uses the same entry and
8
+ * sidecar shapes under `connectors-local/descriptors/`, plus a ledger of
9
+ * resolved ids and a bindings document.
10
+ *
11
+ * These are the types the registry code passes around. They are deliberately
12
+ * loose where the registry itself is loose — a node definition is whatever the
13
+ * platform served, and the generators copy fields they do not interpret — and
14
+ * tight where the SDK depends on a field.
15
+ */
16
+ /** Node-type prefixes that mark the three roles a connector node can play. */
17
+ export const CONNECTOR_PREFIX = "uipath.connector.";
18
+ export const TRIGGER_PREFIX = "uipath.connector.trigger.";
19
+ export const EVENT_PREFIX = "uipath.connector.event.";
20
+ /** True for a start trigger or a mid-flow event wait. */
21
+ export function isEventNodeType(nodeType) {
22
+ return nodeType.startsWith(TRIGGER_PREFIX) || nodeType.startsWith(EVENT_PREFIX);
23
+ }
@@ -0,0 +1,54 @@
1
+ /** `send-message-to-user` → `SendMessageToUser`. */
2
+ export declare function pascal(actionId: string): string;
3
+ /** A small deterministic singulariser for array field names used as type names. */
4
+ export declare function singular(name: string): string;
5
+ /** The subset of an entry or index row that naming reads. */
6
+ export interface NamedEntry {
7
+ nodeType?: string;
8
+ connectorKey?: string;
9
+ activityType?: string;
10
+ label?: string;
11
+ operation?: {
12
+ activityType?: string;
13
+ [key: string]: unknown;
14
+ } | null;
15
+ display?: {
16
+ label?: string;
17
+ [key: string]: unknown;
18
+ } | null;
19
+ [key: string]: unknown;
20
+ }
21
+ /**
22
+ * `(nodeType, activityType, label)` from either entry shape: the flat
23
+ * `index.json` row or the nested per-operation entry file.
24
+ */
25
+ export declare function opIdentity(entry: NamedEntry): [nodeType: string, activityType: string, label: string];
26
+ /**
27
+ * The exported const name for one operation, de-collided within its module.
28
+ *
29
+ * `seen` is the per-module set of names already emitted and it is MUTATED here;
30
+ * a later operation whose name collides gets a trailing `_`. A `GenericExpanded`
31
+ * entry is named from its display label because its action id is the shared
32
+ * generic verb.
33
+ */
34
+ export declare function opSymbolName(entry: NamedEntry, seen: Set<string>): string;
35
+ /** The connector key an entry belongs to, from the row or from its node type. */
36
+ export declare function connectorKeyOf(entry: NamedEntry): string;
37
+ /**
38
+ * `{ nodeType → exportedConstName }` for every operation a module will export.
39
+ *
40
+ * Groups by connector, walks connectors sorted by key and entries sorted by
41
+ * node type, exactly as the descriptor generator emits them. An operation with
42
+ * no entry in the map has no descriptor (a `GenericExpanded` one, by default).
43
+ */
44
+ export declare function symbolIndex(entries: readonly NamedEntry[], includeGenericExpanded?: boolean): Map<string, string>;
45
+ /** `profile.email` → `byEmail`; only the last dotted segment is used. */
46
+ export declare function byAlias(lookupName: string): string;
47
+ /**
48
+ * `{ lookupName → alias }` for every name that earns an unambiguous alias.
49
+ *
50
+ * Two names that camelise to one alias are BOTH dropped rather than awarded to
51
+ * whichever came first; they stay reachable through the generic `.by(name, v)`.
52
+ * An empty map is normal and means "generic form only".
53
+ */
54
+ export declare function byAliases(lookupNames: readonly string[]): Map<string, string>;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Symbol-name derivation shared by the descriptor and Markdown generators.
3
+ *
4
+ * `library-json/` feeds two derived views: the TypeScript descriptors an author
5
+ * imports, and the Markdown an agent reads. The Markdown cites the TypeScript by
6
+ * name — `connector(SendMessageToUser, …)`, `.byEmail(…)` — and neither name
7
+ * exists in the JSON. Both are derived, here, once.
8
+ *
9
+ * The de-collision loop is the reason this cannot be re-derived per page: it is
10
+ * stateful across a whole connector module, so a second implementation walking
11
+ * in a different order would print an import that does not resolve. Both
12
+ * generators call {@link symbolIndex} and neither owns a copy.
13
+ *
14
+ * Ported from `integrations/scripts/_naming.py`; the behaviour is that file's.
15
+ */
16
+ import { sortedByCodePoint, sortedStrings } from "./compat/compare.js";
17
+ import { afterLast, beforeLast, upperFirst } from "./compat/pystr.js";
18
+ /** `send-message-to-user` → `SendMessageToUser`. */
19
+ export function pascal(actionId) {
20
+ const joined = actionId
21
+ .split(/[^A-Za-z0-9]+/)
22
+ .filter((w) => w.length > 0)
23
+ .map((w) => upperFirst(w))
24
+ .join("");
25
+ return joined || "Op";
26
+ }
27
+ /** A small deterministic singulariser for array field names used as type names. */
28
+ export function singular(name) {
29
+ const lower = name.toLowerCase();
30
+ if (lower.endsWith("ies") && name.length > 3)
31
+ return `${name.slice(0, -3)}y`;
32
+ if (lower.endsWith("sses"))
33
+ return name.slice(0, -2);
34
+ if (lower.endsWith("s") && !lower.endsWith("ss") && !lower.endsWith("us"))
35
+ return name.slice(0, -1);
36
+ return name;
37
+ }
38
+ /**
39
+ * `(nodeType, activityType, label)` from either entry shape: the flat
40
+ * `index.json` row or the nested per-operation entry file.
41
+ */
42
+ export function opIdentity(entry) {
43
+ const nodeType = entry.nodeType || "";
44
+ const operation = entry.operation;
45
+ const activityType = operation && typeof operation === "object" ? operation.activityType || "" : entry.activityType || "";
46
+ const display = entry.display;
47
+ let label = display && typeof display === "object" && display.label ? display.label : entry.label || "";
48
+ if (!label)
49
+ label = afterLast(nodeType, ".");
50
+ return [nodeType, activityType, label];
51
+ }
52
+ /**
53
+ * The exported const name for one operation, de-collided within its module.
54
+ *
55
+ * `seen` is the per-module set of names already emitted and it is MUTATED here;
56
+ * a later operation whose name collides gets a trailing `_`. A `GenericExpanded`
57
+ * entry is named from its display label because its action id is the shared
58
+ * generic verb.
59
+ */
60
+ export function opSymbolName(entry, seen) {
61
+ const [nodeType, activityType, label] = opIdentity(entry);
62
+ const actionId = afterLast(nodeType, ".");
63
+ let name = pascal(activityType === "GenericExpanded" ? label : actionId);
64
+ while (seen.has(name))
65
+ name += "_";
66
+ seen.add(name);
67
+ return name;
68
+ }
69
+ /** The connector key an entry belongs to, from the row or from its node type. */
70
+ export function connectorKeyOf(entry) {
71
+ if (entry.connectorKey)
72
+ return entry.connectorKey;
73
+ // `str.replace` replaces every occurrence; JavaScript's `replace` with a
74
+ // string pattern replaces only the first.
75
+ const rest = (entry.nodeType || "").replaceAll("uipath.connector.", "");
76
+ return rest.includes(".") ? beforeLast(rest, ".") : rest;
77
+ }
78
+ /**
79
+ * `{ nodeType → exportedConstName }` for every operation a module will export.
80
+ *
81
+ * Groups by connector, walks connectors sorted by key and entries sorted by
82
+ * node type, exactly as the descriptor generator emits them. An operation with
83
+ * no entry in the map has no descriptor (a `GenericExpanded` one, by default).
84
+ */
85
+ export function symbolIndex(entries, includeGenericExpanded = false) {
86
+ const byConnector = new Map();
87
+ for (const entry of entries) {
88
+ const [, activityType] = opIdentity(entry);
89
+ if (activityType === "GenericExpanded" && !includeGenericExpanded)
90
+ continue;
91
+ const key = connectorKeyOf(entry);
92
+ const group = byConnector.get(key);
93
+ if (group)
94
+ group.push(entry);
95
+ else
96
+ byConnector.set(key, [entry]);
97
+ }
98
+ const names = new Map();
99
+ for (const key of sortedStrings(byConnector.keys())) {
100
+ const seen = new Set();
101
+ for (const entry of sortedByCodePoint(byConnector.get(key), (e) => e.nodeType || "")) {
102
+ // `names[entry["nodeType"]]` raised `KeyError` on a row without one. An
103
+ // index row is malformed without a node type, and silently keying it
104
+ // under `undefined` would hand a page a symbol nothing exports.
105
+ if (typeof entry.nodeType !== "string") {
106
+ throw new TypeError(`symbolIndex: an entry for connector '${key}' has no nodeType (label ${JSON.stringify(entry.label ?? entry.display?.label ?? "")})`);
107
+ }
108
+ names.set(entry.nodeType, opSymbolName(entry, seen));
109
+ }
110
+ }
111
+ return names;
112
+ }
113
+ /** `profile.email` → `byEmail`; only the last dotted segment is used. */
114
+ export function byAlias(lookupName) {
115
+ const last = afterLast(lookupName, ".");
116
+ const words = last.split(/[^A-Za-z0-9]+/).filter((w) => w.length > 0);
117
+ if (words.length === 0)
118
+ return "";
119
+ return `by${words.map((w) => upperFirst(w)).join("")}`;
120
+ }
121
+ /**
122
+ * `{ lookupName → alias }` for every name that earns an unambiguous alias.
123
+ *
124
+ * Two names that camelise to one alias are BOTH dropped rather than awarded to
125
+ * whichever came first; they stay reachable through the generic `.by(name, v)`.
126
+ * An empty map is normal and means "generic form only".
127
+ */
128
+ export function byAliases(lookupNames) {
129
+ const counts = new Map();
130
+ for (const name of lookupNames) {
131
+ const alias = byAlias(name);
132
+ if (alias)
133
+ counts.set(alias, (counts.get(alias) ?? 0) + 1);
134
+ }
135
+ const out = new Map();
136
+ for (const name of lookupNames) {
137
+ const alias = byAlias(name);
138
+ if (alias && counts.get(alias) === 1)
139
+ out.set(name, alias);
140
+ }
141
+ return out;
142
+ }
@@ -0,0 +1,4 @@
1
+ /** Every file under `libraryPath` that no index row points at, sorted. */
2
+ export declare function findOrphans(libraryPath: string): string[];
3
+ /** {@link findOrphans}, as the fatal error the shell script raised. */
4
+ export declare function assertNoOrphans(libraryPath: string): void;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The ORPHAN CHECK: an entry file that `index.json` does not list is invisible.
3
+ *
4
+ * The resolver looks operations up through the index and never scans the tree,
5
+ * so a `<key>/<action>@<ver>.json` with no index row is dead weight — `compile`
6
+ * answers *"connector not in library"* for an operation whose definition is
7
+ * sitting right there. Measured on the shipped snapshot (2026-07-31) it found
8
+ * exactly one orphan in 7,030 entry files: the Data Service
9
+ * `query-entity-records` two path-to-GA scenarios are built on, GA and served
10
+ * by the tenant, and unauthorable. `library-json.samples/` now carries the
11
+ * corrected entry AND its index row, so the expected count is zero.
12
+ *
13
+ * Fatal rather than a warning, deliberately: this is the silent-degradation
14
+ * class the campaign keeps finding, and the fix for a new orphan is always the
15
+ * same one line in the overlay's index.
16
+ *
17
+ * The check is deliberately kept naive: a file is resolvable or it is not. In
18
+ * particular it does NOT forgive a file whose (nodeType, version) is indexed at
19
+ * some other path — forgiving that would have hidden the real problem, which is
20
+ * an overlay correction the index no longer points at. `curated-overlay.ts`
21
+ * refuses to create such a file in the first place, and says which correction
22
+ * it dropped, so this check has nothing to forgive.
23
+ *
24
+ * Ported from the inline `python3` heredoc in `unpack-library.sh`, which is why
25
+ * the skip list is the Python's literal one rather than anything derived.
26
+ */
27
+ import { existsSync, readFileSync } from "node:fs";
28
+ import { join } from "node:path";
29
+ import { Refusal } from "./errors.js";
30
+ import { listFiles } from "./files.js";
31
+ import { sortedStrings } from "./compat/compare.js";
32
+ /**
33
+ * Files that are not operation entries and so carry no index row by design.
34
+ *
35
+ * `list-envelopes.json` is the LIST-ENVELOPE LEDGER (a side-table keyed by
36
+ * nodeType, flow-builder-sdk#156); `invariant-collections.json` is the second
37
+ * such side-table, keyed by a reference's `objectName` instead
38
+ * (CONNECTOR_LOOKUP_DESIGN.md §5.3). Asking either for an index row is the
39
+ * wrong question. Dotfiles are excluded separately — see {@link isDotfile}.
40
+ */
41
+ const SIDE_TABLES = new Set(["index.json", "list-envelopes.json", "invariant-collections.json"]);
42
+ /**
43
+ * A dotfile is never an operation entry, so it can never have an index row.
44
+ *
45
+ * The Python walked every file and knew nothing about dotfiles, because the
46
+ * only tree it ever saw was a freshly unzipped one inside an image. Run the
47
+ * same check over a library a developer has opened in Finder and `.DS_Store`
48
+ * is an orphan; over one `registry pull` wrote and `.registry-source.json`
49
+ * (the url and sha256 the library came from) is another. Neither is a missing
50
+ * row — they are files the check was never meant to see.
51
+ */
52
+ function isDotfile(name) {
53
+ return name.startsWith(".");
54
+ }
55
+ /** Every file under `libraryPath` that no index row points at, sorted. */
56
+ export function findOrphans(libraryPath) {
57
+ const indexPath = join(libraryPath, "index.json");
58
+ if (!existsSync(indexPath))
59
+ return [];
60
+ const index = JSON.parse(readFileSync(indexPath, "utf8"));
61
+ const indexed = new Set((index.entries ?? [])
62
+ .map((entry) => entry.path)
63
+ .filter((path) => typeof path === "string"));
64
+ // Every file, not only `.json`: the Python excluded the three side-tables and
65
+ // the sidecars and nothing else, so a stray page or a leftover temp file is
66
+ // an orphan too — which is the point, since neither can be resolved either.
67
+ const files = listFiles(libraryPath, (rel) => {
68
+ const name = rel.slice(rel.lastIndexOf("/") + 1);
69
+ return !SIDE_TABLES.has(name) && !isDotfile(name) && !name.endsWith(".v1def.json");
70
+ });
71
+ return sortedStrings(files.filter((rel) => !indexed.has(rel)));
72
+ }
73
+ /** {@link findOrphans}, as the fatal error the shell script raised. */
74
+ export function assertNoOrphans(libraryPath) {
75
+ const orphans = findOrphans(libraryPath);
76
+ if (orphans.length === 0)
77
+ return;
78
+ throw new Refusal([
79
+ `error: ${orphans.length} library entry file(s) have NO index.json entry,`,
80
+ ' so nothing can resolve them (`compile` says "connector not in library"):',
81
+ ...orphans.map((rel) => ` ${rel}`),
82
+ " Fix: add each one's entry to typescript/sdk/lib/library-json.samples/index.json",
83
+ " (with a corrected <key>/<action>@<ver>.json + .v1def.json beside it if the",
84
+ " snapshot's copy is stale), then re-run.",
85
+ ].join("\n"), "LIBRARY_ORPHANS");
86
+ }
@@ -0,0 +1,26 @@
1
+ import type { UipClient } from "../uip/client.js";
2
+ /**
3
+ * The action ids in a `registry search <key>` reply, sorted.
4
+ *
5
+ * Exact prefix only: the same search returns
6
+ * `uipath.agent.resource.tool.connector.<key>.<action>` and
7
+ * `uipath.connector.trigger.<key>.<event>`, which are not actions of this node
8
+ * and would read as alternatives an author could pass.
9
+ */
10
+ export declare function registryActionIds(payload: unknown, connectorKey: string): string[];
11
+ /**
12
+ * Candidates ranked by shared hyphen tokens, best first.
13
+ *
14
+ * Token overlap rather than edit distance because the two namespaces differ by
15
+ * whole words, not typos: the baked library's `list-all-records` against the
16
+ * registry's `list-records`. Python sorted `(overlap, -len, name)` descending,
17
+ * so ties on overlap prefer the SHORTER id, and ties on both fall back to the
18
+ * name in reverse code-point order.
19
+ */
20
+ export declare function closestActions(action: string, candidates: readonly string[]): string[];
21
+ /**
22
+ * `_registry_actions`: the action ids the registry serves for `connectorKey`,
23
+ * or `[]` when the search fails or does not answer JSON. This runs only on the
24
+ * failure path, where an empty answer is itself the message ("returned nothing").
25
+ */
26
+ export declare function registryActions(client: UipClient, connectorKey: string, timeoutMs?: number): Promise<string[]>;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * What the REGISTRY serves for a connector, for the failure path only.
3
+ *
4
+ * When `registry get uipath.connector.<key>.<action>` finds nothing — and the
5
+ * event namespaces do not have it either — the one question left is what the
6
+ * tenant actually serves for that connector, so the refusal can list it. That
7
+ * is a `registry search <key>` against the live catalog rather than a cached
8
+ * index, because a stale index is one of the ways this failure happens.
9
+ *
10
+ * Ported from `_registry_actions` / `_closest_actions` in
11
+ * `prepare_connector.py`. The fetch goes through the injected {@link UipClient};
12
+ * everything else is pure over the parsed reply.
13
+ */
14
+ import { compareCodePoints, sortedStrings } from "../compat/compare.js";
15
+ import { registrySearch } from "../uip/commands.js";
16
+ import { isPlainObject, pyOr } from "./support.js";
17
+ /**
18
+ * The action ids in a `registry search <key>` reply, sorted.
19
+ *
20
+ * Exact prefix only: the same search returns
21
+ * `uipath.agent.resource.tool.connector.<key>.<action>` and
22
+ * `uipath.connector.trigger.<key>.<event>`, which are not actions of this node
23
+ * and would read as alternatives an author could pass.
24
+ */
25
+ export function registryActionIds(payload, connectorKey) {
26
+ // `json.loads(stdout).get("Data") or []`: a reply that is not an object has
27
+ // no `.get` and the Python would have crashed; a list is the useful answer.
28
+ if (!isPlainObject(payload))
29
+ return [];
30
+ const data = pyOr(payload.Data, []);
31
+ if (!Array.isArray(data))
32
+ return [];
33
+ const prefix = `uipath.connector.${connectorKey}.`;
34
+ const ids = new Set();
35
+ for (const entry of data) {
36
+ if (!isPlainObject(entry))
37
+ continue;
38
+ const nodeType = pyOr(entry.NodeType, "");
39
+ if (typeof nodeType !== "string" || !nodeType.startsWith(prefix))
40
+ continue;
41
+ const rest = nodeType.slice(prefix.length);
42
+ if (!rest.includes("."))
43
+ ids.add(rest);
44
+ }
45
+ return sortedStrings(ids);
46
+ }
47
+ /**
48
+ * Candidates ranked by shared hyphen tokens, best first.
49
+ *
50
+ * Token overlap rather than edit distance because the two namespaces differ by
51
+ * whole words, not typos: the baked library's `list-all-records` against the
52
+ * registry's `list-records`. Python sorted `(overlap, -len, name)` descending,
53
+ * so ties on overlap prefer the SHORTER id, and ties on both fall back to the
54
+ * name in reverse code-point order.
55
+ */
56
+ export function closestActions(action, candidates) {
57
+ const wanted = new Set(action.split("-"));
58
+ const scored = candidates
59
+ .map((candidate) => {
60
+ const tokens = new Set(candidate.split("-"));
61
+ let overlap = 0;
62
+ for (const token of wanted)
63
+ if (tokens.has(token))
64
+ overlap += 1;
65
+ return { overlap, candidate };
66
+ })
67
+ .filter(({ overlap }) => overlap > 0);
68
+ scored.sort((a, b) => {
69
+ if (a.overlap !== b.overlap)
70
+ return b.overlap - a.overlap;
71
+ if (a.candidate.length !== b.candidate.length)
72
+ return a.candidate.length - b.candidate.length;
73
+ return compareCodePoints(b.candidate, a.candidate);
74
+ });
75
+ return scored.map(({ candidate }) => candidate);
76
+ }
77
+ /**
78
+ * `_registry_actions`: the action ids the registry serves for `connectorKey`,
79
+ * or `[]` when the search fails or does not answer JSON. This runs only on the
80
+ * failure path, where an empty answer is itself the message ("returned nothing").
81
+ */
82
+ export async function registryActions(client, connectorKey, timeoutMs) {
83
+ const result = await client.run(registrySearch(connectorKey), timeoutMs === undefined ? undefined : { timeoutMs });
84
+ if (result.code !== 0)
85
+ return [];
86
+ let payload;
87
+ try {
88
+ payload = JSON.parse(result.stdout);
89
+ }
90
+ catch {
91
+ return [];
92
+ }
93
+ return registryActionIds(payload, connectorKey);
94
+ }