@uipath/packager-tool-flow 1.197.0 → 1.198.0-preview.80

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.
@@ -1,9 +1,9 @@
1
1
  import type { Workflow } from "@uipath/flow-core";
2
2
  import type { IToolLogger } from "@uipath/solutionpackager-tool-core";
3
3
  /**
4
- * Safety net: ensure every process/agent node in the workflow has corresponding
5
- * entries in the workflow `bindings` array and that `<bindings.*>` placeholders
6
- * in model.context are resolved to `=bindings.<id>` references.
4
+ * Safety net: ensure every process/agent/connector-tool node in the workflow has
5
+ * corresponding entries in the workflow `bindings` array and that `<bindings.*>`
6
+ * placeholders in model.context are resolved to `=bindings.<id>` references.
7
7
  *
8
8
  * This handles flows authored outside the CLI (e.g. direct file edits or
9
9
  * skill-generated files) where `addNodeToFlow` was never called, so the
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  // package.json
33
33
  var package_default = {
34
34
  name: "@uipath/packager-tool-flow",
35
- version: "1.197.0",
35
+ version: "1.198.0-preview.80",
36
36
  description: "UiPath Flow tool implementation",
37
37
  type: "module",
38
38
  exports: {
@@ -170,10 +170,14 @@ var PROCESS_NODE_PREFIXES = [
170
170
  "uipath.core.agent.",
171
171
  "uipath.core.api-workflow."
172
172
  ];
173
- var UNRESOLVED_BINDING_PATTERN = /^<bindings\.\w+>$/;
173
+ var CONNECTOR_TOOL_PREFIX = "uipath.agent.resource.tool.connector.";
174
+ var UNRESOLVED_BINDING_PATTERN = /^<bindings\.[^>]+>$/;
174
175
  function isProcessNode(nodeType) {
175
176
  return PROCESS_NODE_PREFIXES.some((prefix) => nodeType?.startsWith(prefix));
176
177
  }
178
+ function isConnectorToolNode(nodeType) {
179
+ return nodeType?.startsWith(CONNECTOR_TOOL_PREFIX) ?? false;
180
+ }
177
181
  function extractProcessGuid(nodeType) {
178
182
  const match = nodeType.match(/^(?:uipath\.core\.rpa-workflow|uipath\.agent\.resource\.tool\.process|uipath\.core\.agent|uipath\.core\.api-workflow)\.([0-9a-f-]+)$/i);
179
183
  if (!match) {
@@ -225,13 +229,50 @@ function resolveContextPlaceholders(context, storedName, storedFolder) {
225
229
  }
226
230
  }
227
231
  }
232
+ function createConnectorToolBindings(node, definition) {
233
+ const model = definition.model;
234
+ const detail = node.inputs?.detail;
235
+ const connectionId = detail?.connectionId ?? "";
236
+ const connectionFolderKey = detail?.connectionFolderKey ?? "";
237
+ const values = model?.bindings?.values ?? [];
238
+ const connValue = values.find((v) => v.propertyAttribute === "ConnectionId");
239
+ const folderValue = values.find((v) => v.propertyAttribute === "FolderKey");
240
+ const connectionBinding = createBinding({
241
+ name: connValue?.name ?? "connection",
242
+ value: connectionId,
243
+ resource: "Connection",
244
+ resourceKey: connectionId,
245
+ propertyAttribute: "ConnectionId"
246
+ });
247
+ const folderKeyBinding = createBinding({
248
+ name: folderValue?.name ?? "FolderKey",
249
+ value: connectionFolderKey,
250
+ resource: "Connection",
251
+ resourceKey: connectionId,
252
+ propertyAttribute: "FolderKey"
253
+ });
254
+ return { connectionBinding, folderKeyBinding };
255
+ }
256
+ function resolveConnectorContextPlaceholders(context, storedConnection, storedFolderKey) {
257
+ if (!context)
258
+ return;
259
+ for (const entry of context) {
260
+ if (typeof entry.value === "string" && UNRESOLVED_BINDING_PATTERN.test(entry.value)) {
261
+ if (entry.name === "connection") {
262
+ entry.default = storedConnection.default;
263
+ entry.value = `=bindings.${storedConnection.id}`;
264
+ } else if (entry.name === "folderKey") {
265
+ entry.default = storedFolderKey.default;
266
+ entry.value = `=bindings.${storedFolderKey.id}`;
267
+ }
268
+ }
269
+ }
270
+ }
228
271
  function ensureProcessBindings(workflow, logger) {
229
272
  const nodes = workflow.nodes ?? [];
230
273
  const definitions = workflow.definitions ?? [];
231
274
  let bindingsCreated = 0;
232
275
  for (const node of nodes) {
233
- if (!isProcessNode(node.type))
234
- continue;
235
276
  const nodeModel = node.model;
236
277
  const defModel = definitions.find((d) => d.nodeType === node.type)?.model;
237
278
  const hasUnresolved = [nodeModel, defModel].some((m) => m?.context?.some((entry) => typeof entry.value === "string" && UNRESOLVED_BINDING_PATTERN.test(entry.value)));
@@ -240,25 +281,49 @@ function ensureProcessBindings(workflow, logger) {
240
281
  const definition = definitions.find((d) => d.nodeType === node.type);
241
282
  if (!definition)
242
283
  continue;
243
- let nameBinding;
244
- let folderBinding;
245
- try {
246
- ({ nameBinding, folderBinding } = createProcessBindings(definition));
247
- } catch (err) {
248
- logger.warn(`Skipping binding resolution for node "${node.id}": ${err instanceof Error ? err.message : String(err)}`);
284
+ if (isProcessNode(node.type)) {
285
+ let nameBinding;
286
+ let folderBinding;
287
+ try {
288
+ ({ nameBinding, folderBinding } = createProcessBindings(definition));
289
+ } catch (err) {
290
+ logger.warn(`Skipping binding resolution for node "${node.id}": ${err instanceof Error ? err.message : String(err)}`);
291
+ continue;
292
+ }
293
+ const beforeCount = workflow.bindings?.length ?? 0;
294
+ addBinding(workflow, nameBinding);
295
+ addBinding(workflow, folderBinding);
296
+ const storedBindings = workflow.bindings;
297
+ const storedName = storedBindings.find((b) => b.resourceKey === nameBinding.resourceKey && b.propertyAttribute === nameBinding.propertyAttribute) ?? nameBinding;
298
+ const storedFolder = storedBindings.find((b) => b.resourceKey === folderBinding.resourceKey && b.propertyAttribute === folderBinding.propertyAttribute) ?? folderBinding;
299
+ resolveContextPlaceholders(nodeModel?.context, storedName, storedFolder);
300
+ resolveContextPlaceholders(defModel?.context, storedName, storedFolder);
301
+ const added = (workflow.bindings?.length ?? 0) - beforeCount;
302
+ bindingsCreated += added;
303
+ logger.info(`Resolved process bindings for node "${node.id}" (${node.type})`);
249
304
  continue;
250
305
  }
251
- const beforeCount = workflow.bindings?.length ?? 0;
252
- addBinding(workflow, nameBinding);
253
- addBinding(workflow, folderBinding);
254
- const storedBindings = workflow.bindings;
255
- const storedName = storedBindings.find((b) => b.resourceKey === nameBinding.resourceKey && b.propertyAttribute === nameBinding.propertyAttribute) ?? nameBinding;
256
- const storedFolder = storedBindings.find((b) => b.resourceKey === folderBinding.resourceKey && b.propertyAttribute === folderBinding.propertyAttribute) ?? folderBinding;
257
- resolveContextPlaceholders(nodeModel?.context, storedName, storedFolder);
258
- resolveContextPlaceholders(defModel?.context, storedName, storedFolder);
259
- const added = (workflow.bindings?.length ?? 0) - beforeCount;
260
- bindingsCreated += added;
261
- logger.info(`Resolved process bindings for node "${node.id}" (${node.type})`);
306
+ if (isConnectorToolNode(node.type)) {
307
+ let connectionBinding;
308
+ let folderKeyBinding;
309
+ try {
310
+ ({ connectionBinding, folderKeyBinding } = createConnectorToolBindings(node, definition));
311
+ } catch (err) {
312
+ logger.warn(`Skipping connector binding resolution for node "${node.id}": ${err instanceof Error ? err.message : String(err)}`);
313
+ continue;
314
+ }
315
+ const beforeCount = workflow.bindings?.length ?? 0;
316
+ addBinding(workflow, connectionBinding);
317
+ addBinding(workflow, folderKeyBinding);
318
+ const storedBindings = workflow.bindings;
319
+ const storedConn = storedBindings.find((b) => b.resourceKey === connectionBinding.resourceKey && b.propertyAttribute === connectionBinding.propertyAttribute) ?? connectionBinding;
320
+ const storedFk = storedBindings.find((b) => b.resourceKey === folderKeyBinding.resourceKey && b.propertyAttribute === folderKeyBinding.propertyAttribute) ?? folderKeyBinding;
321
+ resolveConnectorContextPlaceholders(nodeModel?.context, storedConn, storedFk);
322
+ resolveConnectorContextPlaceholders(defModel?.context, storedConn, storedFk);
323
+ const added = (workflow.bindings?.length ?? 0) - beforeCount;
324
+ bindingsCreated += added;
325
+ logger.info(`Resolved connector bindings for node "${node.id}" (${node.type})`);
326
+ }
262
327
  }
263
328
  if (bindingsCreated > 0) {
264
329
  logger.info(`ensureProcessBindings: created ${bindingsCreated} binding(s) for directly-authored nodes`);
@@ -641,4 +706,4 @@ export {
641
706
  FlowTool
642
707
  };
643
708
 
644
- //# debugId=7CD644DAD87726AA64756E2164756E21
709
+ //# debugId=B5F6A24E354FED0464756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/packager-tool-flow",
3
- "version": "1.197.0",
3
+ "version": "1.198.0-preview.80",
4
4
  "description": "UiPath Flow tool implementation",
5
5
  "type": "module",
6
6
  "exports": {
@@ -25,13 +25,13 @@
25
25
  "author": "",
26
26
  "license": "ISC",
27
27
  "peerDependencies": {
28
- "@uipath/filesystem": "1.197.0",
28
+ "@uipath/filesystem": "1.198.0",
29
29
  "@uipath/flow-converter": "^0.8.2",
30
30
  "@uipath/flow-core": "^0.10.3",
31
31
  "@uipath/flow-migrations": "^0.8.0",
32
32
  "@uipath/flow-schema": "^0.10.3",
33
- "@uipath/solutionpackager-tool-core": "1.197.0",
33
+ "@uipath/solutionpackager-tool-core": "1.198.0",
34
34
  "@uipath/tool-agent": "^2.0.0"
35
35
  },
36
- "gitHead": "56f68b263cec4ea1f2a39d738bd99ecf52f88fea"
36
+ "gitHead": "9b2c3c0f21a256d2f38dd28bc97e72e6f7b10a9c"
37
37
  }
@@ -13,12 +13,23 @@ const PROCESS_NODE_PREFIXES = [
13
13
  "uipath.core.api-workflow.",
14
14
  ];
15
15
 
16
- const UNRESOLVED_BINDING_PATTERN = /^<bindings\.\w+>$/;
16
+ /**
17
+ * Node type prefix for IS connector tool nodes attached to inline agents.
18
+ * These use Connection-style bindings (ConnectionId + FolderKey) instead of
19
+ * process-style bindings (name + folderPath).
20
+ */
21
+ const CONNECTOR_TOOL_PREFIX = "uipath.agent.resource.tool.connector.";
22
+
23
+ const UNRESOLVED_BINDING_PATTERN = /^<bindings\.[^>]+>$/;
17
24
 
18
25
  function isProcessNode(nodeType: string): boolean {
19
26
  return PROCESS_NODE_PREFIXES.some((prefix) => nodeType?.startsWith(prefix));
20
27
  }
21
28
 
29
+ function isConnectorToolNode(nodeType: string): boolean {
30
+ return nodeType?.startsWith(CONNECTOR_TOOL_PREFIX) ?? false;
31
+ }
32
+
22
33
  function extractProcessGuid(nodeType: string): string {
23
34
  const match = nodeType.match(
24
35
  /^(?:uipath\.core\.rpa-workflow|uipath\.agent\.resource\.tool\.process|uipath\.core\.agent|uipath\.core\.api-workflow)\.([0-9a-f-]+)$/i,
@@ -106,9 +117,88 @@ function resolveContextPlaceholders(
106
117
  }
107
118
 
108
119
  /**
109
- * Safety net: ensure every process/agent node in the workflow has corresponding
110
- * entries in the workflow `bindings` array and that `<bindings.*>` placeholders
111
- * in model.context are resolved to `=bindings.<id>` references.
120
+ * Create Connection bindings for an IS connector tool node.
121
+ * Reads binding names from the definition's model.bindings.values[]
122
+ * and defaults from the node's inputs.detail (connectionId, connectionFolderKey).
123
+ */
124
+ function createConnectorToolBindings(
125
+ node: NodeInstance,
126
+ definition: { model?: Record<string, unknown> },
127
+ ): { connectionBinding: Binding; folderKeyBinding: Binding } {
128
+ const model = definition.model as
129
+ | {
130
+ bindings?: {
131
+ resource?: string;
132
+ resourceKey?: string;
133
+ values?: Array<{
134
+ name?: string;
135
+ propertyAttribute?: string;
136
+ }>;
137
+ };
138
+ }
139
+ | undefined;
140
+
141
+ const detail = (node.inputs as Record<string, unknown> | undefined)
142
+ ?.detail as Record<string, unknown> | undefined;
143
+ const connectionId = (detail?.connectionId as string) ?? "";
144
+ const connectionFolderKey = (detail?.connectionFolderKey as string) ?? "";
145
+
146
+ // Read binding names from manifest definition
147
+ const values = model?.bindings?.values ?? [];
148
+ const connValue = values.find(
149
+ (v) => v.propertyAttribute === "ConnectionId",
150
+ );
151
+ const folderValue = values.find((v) => v.propertyAttribute === "FolderKey");
152
+
153
+ const connectionBinding = createBinding({
154
+ name: connValue?.name ?? "connection",
155
+ value: connectionId,
156
+ resource: "Connection",
157
+ resourceKey: connectionId,
158
+ propertyAttribute: "ConnectionId",
159
+ });
160
+
161
+ const folderKeyBinding = createBinding({
162
+ name: folderValue?.name ?? "FolderKey",
163
+ value: connectionFolderKey,
164
+ resource: "Connection",
165
+ resourceKey: connectionId,
166
+ propertyAttribute: "FolderKey",
167
+ });
168
+
169
+ return { connectionBinding, folderKeyBinding };
170
+ }
171
+
172
+ /**
173
+ * Resolve <bindings.*> placeholders in model.context for connector tool nodes.
174
+ * Connector tools use "connection" and "folderKey" context entries.
175
+ */
176
+ function resolveConnectorContextPlaceholders(
177
+ context: Array<Record<string, unknown>> | undefined,
178
+ storedConnection: Binding,
179
+ storedFolderKey: Binding,
180
+ ): void {
181
+ if (!context) return;
182
+ for (const entry of context) {
183
+ if (
184
+ typeof entry.value === "string" &&
185
+ UNRESOLVED_BINDING_PATTERN.test(entry.value)
186
+ ) {
187
+ if (entry.name === "connection") {
188
+ entry.default = storedConnection.default;
189
+ entry.value = `=bindings.${storedConnection.id}`;
190
+ } else if (entry.name === "folderKey") {
191
+ entry.default = storedFolderKey.default;
192
+ entry.value = `=bindings.${storedFolderKey.id}`;
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Safety net: ensure every process/agent/connector-tool node in the workflow has
200
+ * corresponding entries in the workflow `bindings` array and that `<bindings.*>`
201
+ * placeholders in model.context are resolved to `=bindings.<id>` references.
112
202
  *
113
203
  * This handles flows authored outside the CLI (e.g. direct file edits or
114
204
  * skill-generated files) where `addNodeToFlow` was never called, so the
@@ -130,8 +220,6 @@ export function ensureProcessBindings(
130
220
  let bindingsCreated = 0;
131
221
 
132
222
  for (const node of nodes) {
133
- if (!isProcessNode(node.type)) continue;
134
-
135
223
  const nodeModel = node.model as
136
224
  | { context?: Array<Record<string, unknown>> }
137
225
  | undefined;
@@ -151,56 +239,116 @@ export function ensureProcessBindings(
151
239
  const definition = definitions.find((d) => d.nodeType === node.type);
152
240
  if (!definition) continue;
153
241
 
154
- let nameBinding: Binding;
155
- let folderBinding: Binding;
156
- try {
157
- ({ nameBinding, folderBinding } =
158
- createProcessBindings(definition));
159
- } catch (err: unknown) {
160
- logger.warn(
161
- `Skipping binding resolution for node "${node.id}": ${err instanceof Error ? err.message : String(err)}`,
242
+ // --- Process-style nodes (RPA, agent, API workflow) ---
243
+ if (isProcessNode(node.type)) {
244
+ let nameBinding: Binding;
245
+ let folderBinding: Binding;
246
+ try {
247
+ ({ nameBinding, folderBinding } =
248
+ createProcessBindings(definition));
249
+ } catch (err: unknown) {
250
+ logger.warn(
251
+ `Skipping binding resolution for node "${node.id}": ${err instanceof Error ? err.message : String(err)}`,
252
+ );
253
+ continue;
254
+ }
255
+
256
+ const beforeCount =
257
+ (workflow.bindings as Binding[] | undefined)?.length ?? 0;
258
+ addBinding(workflow, nameBinding);
259
+ addBinding(workflow, folderBinding);
260
+
261
+ const storedBindings = workflow.bindings as Binding[];
262
+ const storedName =
263
+ storedBindings.find(
264
+ (b) =>
265
+ b.resourceKey === nameBinding.resourceKey &&
266
+ b.propertyAttribute === nameBinding.propertyAttribute,
267
+ ) ?? nameBinding;
268
+ const storedFolder =
269
+ storedBindings.find(
270
+ (b) =>
271
+ b.resourceKey === folderBinding.resourceKey &&
272
+ b.propertyAttribute === folderBinding.propertyAttribute,
273
+ ) ?? folderBinding;
274
+
275
+ resolveContextPlaceholders(
276
+ nodeModel?.context,
277
+ storedName,
278
+ storedFolder,
279
+ );
280
+ resolveContextPlaceholders(
281
+ defModel?.context,
282
+ storedName,
283
+ storedFolder,
284
+ );
285
+
286
+ const added =
287
+ ((workflow.bindings as Binding[] | undefined)?.length ?? 0) -
288
+ beforeCount;
289
+ bindingsCreated += added;
290
+
291
+ logger.info(
292
+ `Resolved process bindings for node "${node.id}" (${node.type})`,
162
293
  );
163
294
  continue;
164
295
  }
165
296
 
166
- const beforeCount =
167
- (workflow.bindings as Binding[] | undefined)?.length ?? 0;
168
- addBinding(workflow, nameBinding);
169
- addBinding(workflow, folderBinding);
170
-
171
- // Resolve against stored bindings (addBinding deduplicates)
172
- const storedBindings = workflow.bindings as Binding[];
173
- const storedName =
174
- storedBindings.find(
175
- (b) =>
176
- b.resourceKey === nameBinding.resourceKey &&
177
- b.propertyAttribute === nameBinding.propertyAttribute,
178
- ) ?? nameBinding;
179
- const storedFolder =
180
- storedBindings.find(
181
- (b) =>
182
- b.resourceKey === folderBinding.resourceKey &&
183
- b.propertyAttribute === folderBinding.propertyAttribute,
184
- ) ?? folderBinding;
185
-
186
- // Resolve placeholders in node model.context
187
- resolveContextPlaceholders(
188
- nodeModel?.context,
189
- storedName,
190
- storedFolder,
191
- );
297
+ // --- Connector tool nodes (IS activities as inline agent tools) ---
298
+ if (isConnectorToolNode(node.type)) {
299
+ let connectionBinding: Binding;
300
+ let folderKeyBinding: Binding;
301
+ try {
302
+ ({ connectionBinding, folderKeyBinding } =
303
+ createConnectorToolBindings(node, definition));
304
+ } catch (err: unknown) {
305
+ logger.warn(
306
+ `Skipping connector binding resolution for node "${node.id}": ${err instanceof Error ? err.message : String(err)}`,
307
+ );
308
+ continue;
309
+ }
192
310
 
193
- // Resolve in definition model.context for BPMN converter
194
- resolveContextPlaceholders(defModel?.context, storedName, storedFolder);
311
+ const beforeCount =
312
+ (workflow.bindings as Binding[] | undefined)?.length ?? 0;
313
+ addBinding(workflow, connectionBinding);
314
+ addBinding(workflow, folderKeyBinding);
195
315
 
196
- const added =
197
- ((workflow.bindings as Binding[] | undefined)?.length ?? 0) -
198
- beforeCount;
199
- bindingsCreated += added;
316
+ const storedBindings = workflow.bindings as Binding[];
317
+ const storedConn =
318
+ storedBindings.find(
319
+ (b) =>
320
+ b.resourceKey === connectionBinding.resourceKey &&
321
+ b.propertyAttribute ===
322
+ connectionBinding.propertyAttribute,
323
+ ) ?? connectionBinding;
324
+ const storedFk =
325
+ storedBindings.find(
326
+ (b) =>
327
+ b.resourceKey === folderKeyBinding.resourceKey &&
328
+ b.propertyAttribute ===
329
+ folderKeyBinding.propertyAttribute,
330
+ ) ?? folderKeyBinding;
200
331
 
201
- logger.info(
202
- `Resolved process bindings for node "${node.id}" (${node.type})`,
203
- );
332
+ resolveConnectorContextPlaceholders(
333
+ nodeModel?.context,
334
+ storedConn,
335
+ storedFk,
336
+ );
337
+ resolveConnectorContextPlaceholders(
338
+ defModel?.context,
339
+ storedConn,
340
+ storedFk,
341
+ );
342
+
343
+ const added =
344
+ ((workflow.bindings as Binding[] | undefined)?.length ?? 0) -
345
+ beforeCount;
346
+ bindingsCreated += added;
347
+
348
+ logger.info(
349
+ `Resolved connector bindings for node "${node.id}" (${node.type})`,
350
+ );
351
+ }
204
352
  }
205
353
 
206
354
  if (bindingsCreated > 0) {