@uipath/integrationservice-tool 0.1.8 → 0.1.9

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 (2) hide show
  1. package/dist/tool.js +236 -233
  2. package/package.json +6 -5
package/dist/tool.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@uipath/integrationservice-tool",
4
- version: "0.1.8",
4
+ version: "0.1.9",
5
5
  description: "Manage Integration Service connectors, connections, and triggers.",
6
6
  private: false,
7
7
  maintainers: [
@@ -11,14 +11,14 @@ var package_default = {
11
11
  ],
12
12
  repository: {
13
13
  type: "git",
14
- url: "https://github.com/UiPath/uipcli.git",
14
+ url: "https://github.com/UiPath/cli.git",
15
15
  directory: "packages/integrationservice-tool"
16
16
  },
17
17
  publishConfig: {
18
18
  registry: "https://registry.npmjs.org/"
19
19
  },
20
20
  keywords: [
21
- "uipcli-tool"
21
+ "cli-tool"
22
22
  ],
23
23
  type: "module",
24
24
  main: "./dist/tool.js",
@@ -32,7 +32,7 @@ var package_default = {
32
32
  "dist"
33
33
  ],
34
34
  scripts: {
35
- build: "bun build ./src/tool.ts --outdir dist --format esm --target node --external commander --external @uipath/common --external @uipath/auth && bun build ./src/index.ts --outdir dist --format esm --target node --external '*/tool.js' --external commander --external @uipath/common --external @uipath/auth",
35
+ build: "bun build ./src/tool.ts --outdir dist --format esm --target node --external commander --external @uipath/common --external @uipath/auth --external @uipath/filesystem && bun build ./src/index.ts --outdir dist --format esm --target node --external '*/tool.js' --external commander --external @uipath/common --external @uipath/auth --external @uipath/filesystem",
36
36
  package: "bun run build && bun pm pack",
37
37
  lint: "biome check .",
38
38
  "lint:fix": "biome check --write .",
@@ -42,7 +42,8 @@ var package_default = {
42
42
  peerDependencies: {
43
43
  commander: "^14.0.3",
44
44
  "@uipath/common": "^0.1.7",
45
- "@uipath/auth": "^0.1.6"
45
+ "@uipath/auth": "^0.1.6",
46
+ "@uipath/filesystem": "^0.1.6"
46
47
  },
47
48
  devDependencies: {
48
49
  "@uipath/integrationservice-sdk": "workspace:*",
@@ -53,7 +54,7 @@ var package_default = {
53
54
 
54
55
  // src/commands/activities.ts
55
56
  import {
56
- catchError,
57
+ catchError as catchError2,
57
58
  logger,
58
59
  OutputFormatter,
59
60
  processContext
@@ -6418,11 +6419,11 @@ var SWAGGER_DIR = join(process.cwd(), "swagger");
6418
6419
  var HTTP_METHODS = new Set(["get", "post", "put", "patch", "delete"]);
6419
6420
  if (false) {}
6420
6421
  // src/utils/metadata-cache.ts
6421
- import * as fs from "node:fs/promises";
6422
- import * as os from "node:os";
6423
- import * as path from "node:path";
6424
- import { UIPATH_HOME_DIR } from "@uipath/common";
6425
- var CACHE_BASE = path.join(os.homedir(), UIPATH_HOME_DIR, "cache", "integrationservice");
6422
+ import { catchError, UIPATH_HOME_DIR } from "@uipath/common";
6423
+ import { getFileSystem } from "@uipath/filesystem";
6424
+ function getCacheBase() {
6425
+ return getFileSystem().path.join(getFileSystem().env.homedir(), UIPATH_HOME_DIR, "cache", "integrationservice");
6426
+ }
6426
6427
  var METHOD_TO_OPERATION = {
6427
6428
  GET: "List",
6428
6429
  GETBYID: "Retrieve",
@@ -6432,32 +6433,37 @@ var METHOD_TO_OPERATION = {
6432
6433
  PUT: "Replace"
6433
6434
  };
6434
6435
  function getConnectorDir(connectorKey) {
6435
- return path.join(CACHE_BASE, connectorKey);
6436
+ return getFileSystem().path.join(getCacheBase(), connectorKey);
6436
6437
  }
6437
6438
  function getConnectionDir(connectorKey, connectionId) {
6438
- return path.join(CACHE_BASE, connectorKey, connectionId);
6439
+ return getFileSystem().path.join(getCacheBase(), connectorKey, connectionId);
6439
6440
  }
6440
6441
  function getOperationFilePath(connectorKey, connectionId, objectName, operation) {
6441
- return path.join(getConnectionDir(connectorKey, connectionId), `${objectName}.${operation}.json`);
6442
+ return getFileSystem().path.join(getConnectionDir(connectorKey, connectionId), `${objectName}.${operation}.json`);
6442
6443
  }
6443
6444
  function isHidden(item) {
6444
6445
  return item?.design?.isHidden === true;
6445
6446
  }
6446
6447
  async function readJsonFile(filePath) {
6447
- try {
6448
- const data = await fs.readFile(filePath, "utf-8");
6449
- return JSON.parse(data);
6450
- } catch {
6448
+ const [readError, data] = await catchError(getFileSystem().readFile(filePath, "utf-8"));
6449
+ if (readError) {
6450
+ return null;
6451
+ }
6452
+ const [parseError, parsed] = catchError(() => JSON.parse(data));
6453
+ if (parseError) {
6451
6454
  return null;
6452
6455
  }
6456
+ return parsed;
6453
6457
  }
6454
6458
  async function writeJsonFile(filePath, data) {
6455
- await fs.mkdir(path.dirname(filePath), { recursive: true });
6456
- await fs.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
6459
+ await getFileSystem().mkdir(getFileSystem().path.dirname(filePath), {
6460
+ recursive: true
6461
+ });
6462
+ await getFileSystem().writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
6457
6463
  return filePath;
6458
6464
  }
6459
6465
  async function cacheConnectors(connectors) {
6460
- const filePath = path.join(CACHE_BASE, "connectors.json");
6466
+ const filePath = getFileSystem().path.join(getCacheBase(), "connectors.json");
6461
6467
  const compact = connectors.map((c) => ({
6462
6468
  id: c.id,
6463
6469
  name: c.name,
@@ -6478,10 +6484,10 @@ async function cacheConnectors(connectors) {
6478
6484
  return writeJsonFile(filePath, compact);
6479
6485
  }
6480
6486
  async function readCachedConnectors() {
6481
- return readJsonFile(path.join(CACHE_BASE, "connectors.json"));
6487
+ return readJsonFile(getFileSystem().path.join(getCacheBase(), "connectors.json"));
6482
6488
  }
6483
6489
  async function cacheConnections(connectorKey, connections) {
6484
- const filePath = path.join(getConnectorDir(connectorKey), "connections.json");
6490
+ const filePath = getFileSystem().path.join(getConnectorDir(connectorKey), "connections.json");
6485
6491
  const compact = connections.map((conn) => ({
6486
6492
  id: conn.id,
6487
6493
  name: conn.name,
@@ -6497,10 +6503,10 @@ async function cacheConnections(connectorKey, connections) {
6497
6503
  return writeJsonFile(filePath, compact);
6498
6504
  }
6499
6505
  async function readCachedConnections(connectorKey) {
6500
- return readJsonFile(path.join(getConnectorDir(connectorKey), "connections.json"));
6506
+ return readJsonFile(getFileSystem().path.join(getConnectorDir(connectorKey), "connections.json"));
6501
6507
  }
6502
6508
  async function cacheActivities(connectorKey, activities) {
6503
- const filePath = path.join(getConnectorDir(connectorKey), "activities.json");
6509
+ const filePath = getFileSystem().path.join(getConnectorDir(connectorKey), "activities.json");
6504
6510
  const compact = activities.map((a) => ({
6505
6511
  name: a.name,
6506
6512
  displayName: a.displayName,
@@ -6514,10 +6520,10 @@ async function cacheActivities(connectorKey, activities) {
6514
6520
  return writeJsonFile(filePath, compact);
6515
6521
  }
6516
6522
  async function readCachedActivities(connectorKey) {
6517
- return readJsonFile(path.join(getConnectorDir(connectorKey), "activities.json"));
6523
+ return readJsonFile(getFileSystem().path.join(getConnectorDir(connectorKey), "activities.json"));
6518
6524
  }
6519
6525
  async function cacheResourcesList(connectorKey, connectionId, resources) {
6520
- const filePath = path.join(getConnectionDir(connectorKey, connectionId), "resources.json");
6526
+ const filePath = getFileSystem().path.join(getConnectionDir(connectorKey, connectionId), "resources.json");
6521
6527
  const compact = resources.map((r) => ({
6522
6528
  name: r.name,
6523
6529
  displayName: r.displayName,
@@ -6531,7 +6537,7 @@ async function cacheResourcesList(connectorKey, connectionId, resources) {
6531
6537
  return writeJsonFile(filePath, compact);
6532
6538
  }
6533
6539
  async function readCachedResourcesList(connectorKey, connectionId) {
6534
- return readJsonFile(path.join(getConnectionDir(connectorKey, connectionId), "resources.json"));
6540
+ return readJsonFile(getFileSystem().path.join(getConnectionDir(connectorKey, connectionId), "resources.json"));
6535
6541
  }
6536
6542
  function buildOperationFile(rawMetadata, methodKey) {
6537
6543
  const methodInfo = rawMetadata?.metadata?.method?.[methodKey];
@@ -6640,21 +6646,21 @@ async function readCachedForPathResolution(connectorKey, connectionId, objectNam
6640
6646
  };
6641
6647
  }
6642
6648
  function getTriggerDir(connectorKey, connectionId, operation) {
6643
- return path.join(getConnectionDir(connectorKey, connectionId), "triggers", operation);
6649
+ return getFileSystem().path.join(getConnectionDir(connectorKey, connectionId), "triggers", operation);
6644
6650
  }
6645
6651
  async function cacheTriggerObjects(connectorKey, connectionId, operation, objects) {
6646
- const filePath = path.join(getTriggerDir(connectorKey, connectionId, operation), "objects.json");
6652
+ const filePath = getFileSystem().path.join(getTriggerDir(connectorKey, connectionId, operation), "objects.json");
6647
6653
  return writeJsonFile(filePath, objects);
6648
6654
  }
6649
6655
  async function readCachedTriggerObjects(connectorKey, connectionId, operation) {
6650
- return readJsonFile(path.join(getTriggerDir(connectorKey, connectionId, operation), "objects.json"));
6656
+ return readJsonFile(getFileSystem().path.join(getTriggerDir(connectorKey, connectionId, operation), "objects.json"));
6651
6657
  }
6652
6658
  async function cacheTriggerMetadata(connectorKey, connectionId, operation, objectName, metadata) {
6653
- const filePath = path.join(getTriggerDir(connectorKey, connectionId, operation), `${objectName}.metadata.json`);
6659
+ const filePath = getFileSystem().path.join(getTriggerDir(connectorKey, connectionId, operation), `${objectName}.metadata.json`);
6654
6660
  return writeJsonFile(filePath, metadata);
6655
6661
  }
6656
6662
  async function readCachedTriggerMetadata(connectorKey, connectionId, operation, objectName) {
6657
- return readJsonFile(path.join(getTriggerDir(connectorKey, connectionId, operation), `${objectName}.metadata.json`));
6663
+ return readJsonFile(getFileSystem().path.join(getTriggerDir(connectorKey, connectionId, operation), `${objectName}.metadata.json`));
6658
6664
  }
6659
6665
 
6660
6666
  // src/commands/activities.ts
@@ -6672,7 +6678,7 @@ var registerActivitiesCommand = (program) => {
6672
6678
  }
6673
6679
  }
6674
6680
  if (!activitiesResponse) {
6675
- const [error, api] = await catchError(createApiClient(ElementsApi, {
6681
+ const [error, api] = await catchError2(createApiClient(ElementsApi, {
6676
6682
  tenant: options.tenant
6677
6683
  }));
6678
6684
  if (error) {
@@ -6684,7 +6690,7 @@ var registerActivitiesCommand = (program) => {
6684
6690
  processContext.exit(1);
6685
6691
  return;
6686
6692
  }
6687
- const [fetchError, fetched] = await catchError(api.getActivities({
6693
+ const [fetchError, fetched] = await catchError2(api.getActivities({
6688
6694
  elementKey: connectorKey
6689
6695
  }));
6690
6696
  if (fetchError) {
@@ -6738,37 +6744,42 @@ var registerActivitiesCommand = (program) => {
6738
6744
  };
6739
6745
 
6740
6746
  // src/commands/connections.ts
6741
- import { execFile } from "node:child_process";
6742
6747
  import {
6743
- catchError as catchError2,
6748
+ catchError as catchError3,
6749
+ extractErrorMessage,
6744
6750
  logger as logger2,
6745
6751
  OutputFormatter as OutputFormatter2,
6752
+ PollOutcome,
6753
+ pollUntil,
6746
6754
  processContext as processContext2
6747
6755
  } from "@uipath/common";
6748
-
6749
- // src/utils/error-handler.ts
6750
- async function extractErrorMessage(error) {
6751
- const status = error.status || error.response?.status;
6752
- if (status === 401) {
6753
- return "Unauthorized. Run `uip login` to authenticate.";
6754
- }
6755
- let errorMessage = error.message;
6756
- if (error.response) {
6757
- try {
6758
- const parsedResponse = JSON.parse(await error.response.text());
6759
- errorMessage = parsedResponse.message || error.message;
6760
- } catch {}
6761
- }
6762
- return errorMessage;
6756
+ import { getFileSystem as getFileSystem2 } from "@uipath/filesystem";
6757
+ var POLL_EXIT_CODES = {
6758
+ [PollOutcome.Timeout]: 2,
6759
+ [PollOutcome.Failed]: 1,
6760
+ [PollOutcome.Interrupted]: 1,
6761
+ [PollOutcome.Aborted]: 1
6762
+ };
6763
+ function handleAuthPollFailure(outcome, error, noun) {
6764
+ const messages = {
6765
+ [PollOutcome.Timeout]: `${noun} timed out after 5 minutes`,
6766
+ [PollOutcome.Failed]: `${noun} polling failed: ${error?.message ?? "too many consecutive errors"}`,
6767
+ [PollOutcome.Interrupted]: `${noun} polling was interrupted`,
6768
+ [PollOutcome.Aborted]: `${noun} polling was aborted`
6769
+ };
6770
+ OutputFormatter2.error({
6771
+ Result: "Failure",
6772
+ Message: messages[outcome] ?? `${noun} polling failed`,
6773
+ Instructions: "Please try again and complete the authentication more quickly."
6774
+ });
6775
+ processContext2.exit(POLL_EXIT_CODES[outcome] ?? 1);
6763
6776
  }
6764
-
6765
- // src/commands/connections.ts
6766
6777
  var registerConnectionsCommand = (program) => {
6767
6778
  const connections = program.command("connections").description("Manage UiPath Integration Service connections");
6768
6779
  connections.command("list").description("List connections. Without a connector key, lists all connections across all connectors.").argument("[connector-key]", "Connector key to filter by (e.g., uipath-salesforce-sfdc)").option("--folder-key <key>", "Folder key (x-uipath-folderkey) to filter connections by folder (optional)").option("--connection-id <id>", "Filter results to a specific connection ID (optional)").option("-t, --tenant <tenant-name>", "Tenant (optional, defaults to value selected during auth)").option("--refresh", "Force re-fetch from API, ignoring cache").trackedAction(processContext2, async (connectorKey, options) => {
6769
6780
  logger2.info(`Listing connections${connectorKey ? ` for connector: ${connectorKey}` : " (all connectors)"}${options.folderKey ? ` in folder: ${options.folderKey}` : ""}${options.connectionId ? ` filter by ID: ${options.connectionId}` : ""}${options.refresh ? " [refresh]" : ""}`);
6770
6781
  let connections2 = null;
6771
- const [configError, config] = await catchError2(createConnectionsConfig({
6782
+ const [configError, config] = await catchError3(createConnectionsConfig({
6772
6783
  tenant: options.tenant
6773
6784
  }));
6774
6785
  if (configError) {
@@ -6789,7 +6800,7 @@ var registerConnectionsCommand = (program) => {
6789
6800
  }
6790
6801
  if (!connections2) {
6791
6802
  const connectorsApi = new ConnectorsApi(config);
6792
- const [fetchError, fetched] = await catchError2(connectorsApi.apiV1ConnectorsKeyOrIdConnectionsGet({ keyOrId: connectorKey }, folderOverride(options.folderKey)));
6803
+ const [fetchError, fetched] = await catchError3(connectorsApi.apiV1ConnectorsKeyOrIdConnectionsGet({ keyOrId: connectorKey }, folderOverride(options.folderKey)));
6793
6804
  if (fetchError) {
6794
6805
  const errorMessage = await extractErrorMessage(fetchError);
6795
6806
  logger2.error(`Error listing connections: ${errorMessage}`);
@@ -6809,7 +6820,7 @@ var registerConnectionsCommand = (program) => {
6809
6820
  }
6810
6821
  } else {
6811
6822
  const connectionsApi = new ConnectionsApi(config);
6812
- const [fetchError, fetched] = await catchError2(connectionsApi.apiV1ConnectionsGet({}, folderOverride(options.folderKey)));
6823
+ const [fetchError, fetched] = await catchError3(connectionsApi.apiV1ConnectionsGet({}, folderOverride(options.folderKey)));
6813
6824
  if (fetchError) {
6814
6825
  const errorMessage = await extractErrorMessage(fetchError);
6815
6826
  logger2.error(`Error listing connections: ${errorMessage}`);
@@ -6907,78 +6918,67 @@ ${createResponse.authUrl}
6907
6918
  logger2.info(` (This may take a minute. Please complete the authentication in your browser)
6908
6919
  `);
6909
6920
  const sessionId = createResponse.sessionId;
6910
- const maxAttempts = 60;
6911
- const pollInterval = 5000;
6912
- let attempts = 0;
6913
- let sessionStatus = null;
6914
- while (attempts < maxAttempts) {
6915
- attempts++;
6916
- try {
6917
- sessionStatus = await sessionsApi.apiV1SessionsSessionIdGet({
6918
- sessionId
6919
- });
6920
- if (sessionStatus.status === "success") {
6921
- logger2.info(`
6921
+ const pollResult = await pollUntil({
6922
+ fn: () => sessionsApi.apiV1SessionsSessionIdGet({
6923
+ sessionId
6924
+ }),
6925
+ until: (s) => s.status === "success" || s.status === "failed",
6926
+ getStatus: (s) => s.status ?? "pending",
6927
+ logPrefix: "auth",
6928
+ intervalMs: 5000,
6929
+ timeoutMs: 300000,
6930
+ maxConsecutiveErrors: 0,
6931
+ onPoll: () => logger2.info("."),
6932
+ signal: processContext2.pollSignal
6933
+ });
6934
+ if (pollResult.outcome === PollOutcome.Completed && pollResult.data?.status === "success") {
6935
+ logger2.info(`
6922
6936
  ✅ Authentication successful!
6923
6937
  `);
6924
- logger2.info(`\uD83D\uDCCB Fetching updated connection list...
6938
+ logger2.info(`\uD83D\uDCCB Fetching updated connection list...
6925
6939
  `);
6926
- const connections2 = await connectorsApi.apiV1ConnectorsKeyOrIdConnectionsGet({ keyOrId: connectorKey });
6927
- if (connections2 && connections2.length > 0) {
6928
- await cacheConnections(connectorKey, connections2);
6929
- }
6930
- if (connections2 && connections2.length > 0) {
6931
- const latestConnection = connections2[0];
6932
- OutputFormatter2.success({
6933
- Result: "Success",
6934
- Code: "ConnectionCreated",
6935
- Message: "Connection created successfully!",
6936
- Data: {
6937
- ConnectionId: latestConnection.id,
6938
- ConnectionName: latestConnection.name,
6939
- Connector: latestConnection.connector.name,
6940
- State: latestConnection.state,
6941
- Owner: latestConnection.owner,
6942
- Folder: latestConnection.folder.name,
6943
- FolderKey: latestConnection.folder.key
6944
- }
6945
- });
6946
- } else {
6947
- OutputFormatter2.success({
6948
- Result: "Success",
6949
- Code: "ConnectionCreated",
6950
- Message: "Connection created successfully! Run 'uip is connection list' to see it."
6951
- });
6940
+ const connections2 = await connectorsApi.apiV1ConnectorsKeyOrIdConnectionsGet({ keyOrId: connectorKey });
6941
+ if (connections2 && connections2.length > 0) {
6942
+ await cacheConnections(connectorKey, connections2);
6943
+ }
6944
+ if (connections2 && connections2.length > 0) {
6945
+ const latestConnection = connections2[0];
6946
+ OutputFormatter2.success({
6947
+ Result: "Success",
6948
+ Code: "ConnectionCreated",
6949
+ Message: "Connection created successfully!",
6950
+ Data: {
6951
+ ConnectionId: latestConnection.id,
6952
+ ConnectionName: latestConnection.name,
6953
+ Connector: latestConnection.connector.name,
6954
+ State: latestConnection.state,
6955
+ Owner: latestConnection.owner,
6956
+ Folder: latestConnection.folder.name,
6957
+ FolderKey: latestConnection.folder.key
6952
6958
  }
6953
- return;
6954
- }
6955
- if (sessionStatus.status === "failed") {
6956
- logger2.info(`
6957
- Authentication failed!
6958
- `);
6959
- OutputFormatter2.error({
6960
- Result: "Failure",
6961
- Message: sessionStatus.message || "Authentication failed",
6962
- Instructions: "Please check your credentials and try again."
6963
- });
6964
- return;
6965
- }
6966
- logger2.info(".");
6967
- await sleep(pollInterval);
6968
- } catch (_error) {
6969
- logger2.info(".");
6970
- await sleep(pollInterval);
6959
+ });
6960
+ } else {
6961
+ OutputFormatter2.success({
6962
+ Result: "Success",
6963
+ Code: "ConnectionCreated",
6964
+ Message: "Connection created successfully! Run 'uip is connection list' to see it."
6965
+ });
6971
6966
  }
6967
+ return;
6972
6968
  }
6973
- logger2.info(`
6974
-
6975
- ⏱️ Authentication timeout!
6969
+ if (pollResult.outcome === PollOutcome.Completed && pollResult.data?.status === "failed") {
6970
+ logger2.info(`
6971
+ Authentication failed!
6976
6972
  `);
6977
- OutputFormatter2.error({
6978
- Result: "Failure",
6979
- Message: "Authentication timed out after 5 minutes",
6980
- Instructions: "Please try again and complete the authentication more quickly."
6981
- });
6973
+ OutputFormatter2.error({
6974
+ Result: "Failure",
6975
+ Message: pollResult.data.message ?? "Authentication failed",
6976
+ Instructions: "Please check your credentials and try again."
6977
+ });
6978
+ processContext2.exit(1);
6979
+ return;
6980
+ }
6981
+ handleAuthPollFailure(pollResult.outcome, pollResult.error, "Authentication");
6982
6982
  } catch (error) {
6983
6983
  const errorMessage = await extractErrorMessage(error);
6984
6984
  OutputFormatter2.error({
@@ -6991,7 +6991,7 @@ ${createResponse.authUrl}
6991
6991
  });
6992
6992
  connections.command("ping").description("Check if a connection is active and enabled").argument("<connection-id>", "Connection ID to ping").option("-t, --tenant <tenant-name>", "Tenant (optional, defaults to value selected during auth)").trackedAction(processContext2, async (connectionId, options) => {
6993
6993
  logger2.info(`Pinging connection: ${connectionId}`);
6994
- const [configError, config] = await catchError2(createConnectionsConfig({
6994
+ const [configError, config] = await catchError3(createConnectionsConfig({
6995
6995
  tenant: options.tenant
6996
6996
  }));
6997
6997
  if (configError) {
@@ -7004,7 +7004,7 @@ ${createResponse.authUrl}
7004
7004
  return;
7005
7005
  }
7006
7006
  const connectionsApi = new ConnectionsApi(config);
7007
- const [error, result] = await catchError2(connectionsApi.apiV1ConnectionsConnectionIdPingGet({
7007
+ const [error, result] = await catchError3(connectionsApi.apiV1ConnectionsConnectionIdPingGet({
7008
7008
  connectionId
7009
7009
  }));
7010
7010
  if (error) {
@@ -7074,56 +7074,47 @@ ${editResponse.authUrl}
7074
7074
  logger2.info(` (This may take a minute. Please complete the authentication in your browser)
7075
7075
  `);
7076
7076
  const sessionId = editResponse.sessionId;
7077
- const maxAttempts = 60;
7078
- const pollInterval = 5000;
7079
- let attempts = 0;
7080
- while (attempts < maxAttempts) {
7081
- attempts++;
7082
- try {
7083
- const sessionStatus = await sessionsApi.apiV1SessionsSessionIdGet({
7084
- sessionId
7085
- });
7086
- if (sessionStatus.status === "success") {
7087
- logger2.info(`
7077
+ const pollResult = await pollUntil({
7078
+ fn: () => sessionsApi.apiV1SessionsSessionIdGet({
7079
+ sessionId
7080
+ }),
7081
+ until: (s) => s.status === "success" || s.status === "failed",
7082
+ getStatus: (s) => s.status ?? "pending",
7083
+ logPrefix: "auth",
7084
+ intervalMs: 5000,
7085
+ timeoutMs: 300000,
7086
+ maxConsecutiveErrors: 0,
7087
+ onPoll: () => logger2.info("."),
7088
+ signal: processContext2.pollSignal
7089
+ });
7090
+ if (pollResult.outcome === PollOutcome.Completed && pollResult.data?.status === "success") {
7091
+ logger2.info(`
7088
7092
  Re-authentication successful!
7089
7093
  `);
7090
- OutputFormatter2.success({
7091
- Result: "Success",
7092
- Code: "ConnectionEdited",
7093
- Message: "Connection re-authenticated successfully!",
7094
- Data: {
7095
- ConnectionId: connectionId,
7096
- State: "Enabled"
7097
- }
7098
- });
7099
- return;
7094
+ OutputFormatter2.success({
7095
+ Result: "Success",
7096
+ Code: "ConnectionEdited",
7097
+ Message: "Connection re-authenticated successfully!",
7098
+ Data: {
7099
+ ConnectionId: connectionId,
7100
+ State: "Enabled"
7100
7101
  }
7101
- if (sessionStatus.status === "failed") {
7102
- logger2.info(`
7102
+ });
7103
+ return;
7104
+ }
7105
+ if (pollResult.outcome === PollOutcome.Completed && pollResult.data?.status === "failed") {
7106
+ logger2.info(`
7103
7107
  Re-authentication failed!
7104
7108
  `);
7105
- OutputFormatter2.error({
7106
- Result: "Failure",
7107
- Message: sessionStatus.message || "Re-authentication failed",
7108
- Instructions: "Please check your credentials and try again."
7109
- });
7110
- return;
7111
- }
7112
- logger2.info(".");
7113
- await sleep(pollInterval);
7114
- } catch (_error) {
7115
- logger2.info(".");
7116
- await sleep(pollInterval);
7117
- }
7109
+ OutputFormatter2.error({
7110
+ Result: "Failure",
7111
+ Message: pollResult.data.message ?? "Re-authentication failed",
7112
+ Instructions: "Please check your credentials and try again."
7113
+ });
7114
+ processContext2.exit(1);
7115
+ return;
7118
7116
  }
7119
- logger2.info(`
7120
- Authentication timeout!
7121
- `);
7122
- OutputFormatter2.error({
7123
- Result: "Failure",
7124
- Message: "Re-authentication timed out after 5 minutes",
7125
- Instructions: "Please try again and complete the authentication more quickly."
7126
- });
7117
+ handleAuthPollFailure(pollResult.outcome, pollResult.error, "Re-authentication");
7127
7118
  } catch (error) {
7128
7119
  const errorMessage = await extractErrorMessage(error);
7129
7120
  OutputFormatter2.error({
@@ -7136,24 +7127,13 @@ Authentication timeout!
7136
7127
  });
7137
7128
  };
7138
7129
  async function openBrowser(url) {
7139
- const platform = process.platform;
7140
- const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
7141
- return new Promise((resolve, reject) => {
7142
- execFile(cmd, [url], (error) => {
7143
- if (error)
7144
- reject(error);
7145
- else
7146
- resolve();
7147
- });
7148
- });
7149
- }
7150
- function sleep(ms) {
7151
- return new Promise((resolve) => setTimeout(resolve, ms));
7130
+ await getFileSystem2().utils.open(url);
7152
7131
  }
7153
7132
 
7154
7133
  // src/commands/connectors.ts
7155
7134
  import {
7156
- catchError as catchError3,
7135
+ catchError as catchError4,
7136
+ extractErrorMessage as extractErrorMessage2,
7157
7137
  logger as logger3,
7158
7138
  OutputFormatter as OutputFormatter3,
7159
7139
  processContext as processContext3
@@ -7162,6 +7142,18 @@ var registerConnectorsCommand = (program) => {
7162
7142
  const connectors = program.command("connectors").description("Manage UiPath Integration Service connectors");
7163
7143
  connectors.command("list").description("List all connectors").option("-t, --tenant <tenant-name>", "Tenant (optional, defaults to value selected during auth").option("-f, --filter <filter>", "Filter connectors by name or key").option("--refresh", "Force re-fetch from API, ignoring cache").trackedAction(processContext3, async (options) => {
7164
7144
  logger3.info(`Listing connectors${options.filter ? ` (filter: ${options.filter})` : ""}${options.refresh ? " [refresh]" : ""}`);
7145
+ const [apiError, api] = await catchError4(createApiClient(ConnectorsApi, {
7146
+ tenant: options.tenant
7147
+ }));
7148
+ if (apiError) {
7149
+ OutputFormatter3.error({
7150
+ Result: "Failure",
7151
+ Message: "Error listing connectors",
7152
+ Instructions: apiError.message
7153
+ });
7154
+ processContext3.exit(1);
7155
+ return;
7156
+ }
7165
7157
  let connectors2 = null;
7166
7158
  if (!options.refresh) {
7167
7159
  connectors2 = await readCachedConnectors();
@@ -7170,21 +7162,9 @@ var registerConnectorsCommand = (program) => {
7170
7162
  }
7171
7163
  }
7172
7164
  if (!connectors2) {
7173
- const [apiError, api] = await catchError3(createApiClient(ConnectorsApi, {
7174
- tenant: options.tenant
7175
- }));
7176
- if (apiError) {
7177
- OutputFormatter3.error({
7178
- Result: "Failure",
7179
- Message: "Error listing connectors",
7180
- Instructions: apiError.message
7181
- });
7182
- processContext3.exit(1);
7183
- return;
7184
- }
7185
- const [fetchError, fetched] = await catchError3(api.apiV1ConnectorsGet({}));
7165
+ const [fetchError, fetched] = await catchError4(api.apiV1ConnectorsGet({}));
7186
7166
  if (fetchError) {
7187
- const errorMessage = await extractErrorMessage(fetchError);
7167
+ const errorMessage = await extractErrorMessage2(fetchError);
7188
7168
  logger3.error(`Error listing connectors: ${errorMessage}`);
7189
7169
  OutputFormatter3.error({
7190
7170
  Result: "Failure",
@@ -7234,7 +7214,7 @@ var registerConnectorsCommand = (program) => {
7234
7214
  });
7235
7215
  connectors.command("get").description("Get connector by key").argument("<connector-key>", "Connector key (e.g., uipath-zoho-desk)").option("-t, --tenant <tenant-name>", "Tenant (optional, defaults to value selected during auth").trackedAction(processContext3, async (connectorKey, options) => {
7236
7216
  logger3.info(`Getting connector: ${connectorKey}`);
7237
- const [apiError, api] = await catchError3(createApiClient(ConnectorsApi, {
7217
+ const [apiError, api] = await catchError4(createApiClient(ConnectorsApi, {
7238
7218
  tenant: options.tenant
7239
7219
  }));
7240
7220
  if (apiError) {
@@ -7246,11 +7226,11 @@ var registerConnectorsCommand = (program) => {
7246
7226
  processContext3.exit(1);
7247
7227
  return;
7248
7228
  }
7249
- const [error, connector] = await catchError3(api.apiV1ConnectorsKeyOrIdGet({
7229
+ const [error, connector] = await catchError4(api.apiV1ConnectorsKeyOrIdGet({
7250
7230
  keyOrId: connectorKey
7251
7231
  }));
7252
7232
  if (error) {
7253
- const errorMessage = await extractErrorMessage(error);
7233
+ const errorMessage = await extractErrorMessage2(error);
7254
7234
  logger3.error(`Error getting connector '${connectorKey}': ${errorMessage}`);
7255
7235
  OutputFormatter3.error({
7256
7236
  Result: "Failure",
@@ -7298,7 +7278,8 @@ var registerConnectorsCommand = (program) => {
7298
7278
 
7299
7279
  // src/commands/resources.ts
7300
7280
  import {
7301
- catchError as catchError4,
7281
+ catchError as catchError5,
7282
+ extractErrorMessage as extractErrorMessage3,
7302
7283
  logger as logger4,
7303
7284
  OutputFormatter as OutputFormatter4,
7304
7285
  processContext as processContext4,
@@ -7329,15 +7310,36 @@ function metadataFilePath(connectorKey, connectionId, objectName, operationName)
7329
7310
  return `${CACHE_PATH_PREFIX}/${connectorKey}/${connectionId}/${objectName}.${operationName}.json`;
7330
7311
  }
7331
7312
  function buildDescribeSummary(cached, connectorKey, connectionId, objectName, operationName, hasExplicitConnectionId) {
7313
+ const parameters = cached.parameters ?? [];
7314
+ const queryParams = parameters.filter((p) => p.type === "query");
7315
+ const pathParams = parameters.filter((p) => p.type === "path");
7332
7316
  const summary = {
7333
7317
  name: cached.name,
7334
7318
  displayName: cached.displayName,
7319
+ path: cached.path,
7335
7320
  operation: cached.operation,
7336
7321
  metadataFile: metadataFilePath(connectorKey, connectionId, objectName, operationName),
7337
7322
  requiredFields: cached.requestFields.filter((f) => f.required).map((f) => f.name),
7338
7323
  optionalFields: cached.requestFields.filter((f) => !f.required).map((f) => f.name),
7339
7324
  responseFields: cached.responseFields.map((f) => f.name)
7340
7325
  };
7326
+ if (queryParams.length > 0) {
7327
+ summary.queryParameters = queryParams.map((p) => ({
7328
+ name: p.name,
7329
+ displayName: p.displayName,
7330
+ required: p.required ?? false,
7331
+ defaultValue: p.defaultValue,
7332
+ description: p.description
7333
+ }));
7334
+ }
7335
+ if (pathParams.length > 0) {
7336
+ summary.pathParameters = pathParams.map((p) => ({
7337
+ name: p.name,
7338
+ displayName: p.displayName,
7339
+ required: p.required ?? false,
7340
+ description: p.description
7341
+ }));
7342
+ }
7341
7343
  if (!hasExplicitConnectionId) {
7342
7344
  summary.Warning = "Results may not include custom fields. Use --connection-id <id> for connection-specific metadata including custom objects and fields. Run 'is connections list <connector-key>' to get available connection IDs.";
7343
7345
  }
@@ -7352,9 +7354,9 @@ function parseBody(options) {
7352
7354
  });
7353
7355
  return null;
7354
7356
  }
7355
- try {
7356
- return JSON.parse(options.body);
7357
- } catch (error) {
7357
+ const body = options.body;
7358
+ const [error, parsed] = catchError5(() => JSON.parse(body));
7359
+ if (error) {
7358
7360
  OutputFormatter4.error({
7359
7361
  Result: "Failure",
7360
7362
  Message: "Invalid JSON in --body parameter",
@@ -7362,6 +7364,7 @@ function parseBody(options) {
7362
7364
  });
7363
7365
  return null;
7364
7366
  }
7367
+ return parsed;
7365
7368
  }
7366
7369
  function addExecuteOptions(cmd) {
7367
7370
  return cmd.option("--connection-id <id>", "Connection/Instance ID (required)").option("-t, --tenant <tenant-name>", "Tenant (optional, defaults to value selected during auth)").option("--query <params>", "Query parameters as key=value pairs, separated by & (e.g., limit=10&offset=0)");
@@ -7410,7 +7413,7 @@ async function fetchResourceMetadata(api, connectorKey, objectName, connectionId
7410
7413
  async function resolveOperationPath(api, connectorKey, objectName, connectionId, normalizedOperation, queryParams) {
7411
7414
  let resolvedPath = objectName;
7412
7415
  let resolvedQuery = queryParams;
7413
- try {
7416
+ const [resolveError] = await catchError5(async () => {
7414
7417
  const operationName = METHOD_TO_OPERATION[normalizedOperation] || normalizedOperation;
7415
7418
  const cached = await readCachedForPathResolution(connectorKey, connectionId, objectName, operationName);
7416
7419
  let methodPath;
@@ -7457,8 +7460,9 @@ async function resolveOperationPath(api, connectorKey, objectName, connectionId,
7457
7460
  }
7458
7461
  resolvedPath = methodPath.startsWith("/") ? methodPath.substring(1) : methodPath;
7459
7462
  }
7460
- } catch (e) {
7461
- logger4.warn(`Failed to resolve operation path for '${objectName}' on connector '${connectorKey}', falling back to object name:`, e);
7463
+ });
7464
+ if (resolveError) {
7465
+ logger4.warn(`Failed to resolve operation path for '${objectName}' on connector '${connectorKey}', falling back to object name:`, resolveError);
7462
7466
  }
7463
7467
  return { resolvedPath, resolvedQuery };
7464
7468
  }
@@ -7479,18 +7483,17 @@ async function executeAndOutput(connectorKey, objectName, httpMethod, normalized
7479
7483
  });
7480
7484
  }
7481
7485
  async function handleExecuteAction(connectorKey, objectName, httpMethod, normalizedOperation, options, requiresBody) {
7482
- try {
7483
- if (!validateConnectionId(options))
7486
+ if (!validateConnectionId(options))
7487
+ return;
7488
+ let requestBody;
7489
+ if (requiresBody) {
7490
+ requestBody = parseBody(options);
7491
+ if (requestBody === null)
7484
7492
  return;
7485
- let requestBody;
7486
- if (requiresBody) {
7487
- requestBody = parseBody(options);
7488
- if (requestBody === null)
7489
- return;
7490
- }
7491
- await executeAndOutput(connectorKey, objectName, httpMethod, normalizedOperation, options, requestBody);
7492
- } catch (error) {
7493
- const errorMessage = await extractErrorMessage(error);
7493
+ }
7494
+ const [error] = await catchError5(executeAndOutput(connectorKey, objectName, httpMethod, normalizedOperation, options, requestBody));
7495
+ if (error) {
7496
+ const errorMessage = await extractErrorMessage3(error);
7494
7497
  OutputFormatter4.error({
7495
7498
  Result: "Failure",
7496
7499
  Message: errorMessage,
@@ -7511,7 +7514,7 @@ var registerResourcesCommand = (program) => {
7511
7514
  }
7512
7515
  }
7513
7516
  if (!resourcesList) {
7514
- const [apiError, api] = await catchError4(createApiClient(ElementsApi, {
7517
+ const [apiError, api] = await catchError5(createApiClient(ElementsApi, {
7515
7518
  tenant: options.tenant
7516
7519
  }));
7517
7520
  if (apiError) {
@@ -7529,9 +7532,9 @@ var registerResourcesCommand = (program) => {
7529
7532
  }) : api.getObjects({
7530
7533
  elementKey: connectorKey
7531
7534
  });
7532
- const [fetchError, fetched] = await catchError4(fetchFn);
7535
+ const [fetchError, fetched] = await catchError5(fetchFn);
7533
7536
  if (fetchError) {
7534
- const errorMessage = await extractErrorMessage(fetchError);
7537
+ const errorMessage = await extractErrorMessage3(fetchError);
7535
7538
  logger4.error(`Error listing resources for connector '${connectorKey}': ${errorMessage}`);
7536
7539
  OutputFormatter4.error({
7537
7540
  Result: "Failure",
@@ -7630,7 +7633,7 @@ var registerResourcesCommand = (program) => {
7630
7633
  return;
7631
7634
  }
7632
7635
  }
7633
- const [apiError2, api2] = await catchError4(createApiClient(ElementsApi, {
7636
+ const [apiError2, api2] = await catchError5(createApiClient(ElementsApi, {
7634
7637
  tenant: options.tenant
7635
7638
  }));
7636
7639
  if (apiError2) {
@@ -7642,9 +7645,9 @@ var registerResourcesCommand = (program) => {
7642
7645
  processContext4.exit(1);
7643
7646
  return;
7644
7647
  }
7645
- const [metaError2, metadata2] = await catchError4(fetchResourceMetadata(api2, connectorKey, objectName, options.connectionId));
7648
+ const [metaError2, metadata2] = await catchError5(fetchResourceMetadata(api2, connectorKey, objectName, options.connectionId));
7646
7649
  if (metaError2) {
7647
- const errorMessage = await extractErrorMessage(metaError2);
7650
+ const errorMessage = await extractErrorMessage3(metaError2);
7648
7651
  OutputFormatter4.error({
7649
7652
  Result: "Failure",
7650
7653
  Message: errorMessage,
@@ -7670,7 +7673,7 @@ var registerResourcesCommand = (program) => {
7670
7673
  }
7671
7674
  return;
7672
7675
  }
7673
- const [apiError, api] = await catchError4(createApiClient(ElementsApi, {
7676
+ const [apiError, api] = await catchError5(createApiClient(ElementsApi, {
7674
7677
  tenant: options.tenant
7675
7678
  }));
7676
7679
  if (apiError) {
@@ -7682,9 +7685,9 @@ var registerResourcesCommand = (program) => {
7682
7685
  processContext4.exit(1);
7683
7686
  return;
7684
7687
  }
7685
- const [metaError, metadata] = await catchError4(fetchResourceMetadata(api, connectorKey, objectName, options.connectionId));
7688
+ const [metaError, metadata] = await catchError5(fetchResourceMetadata(api, connectorKey, objectName, options.connectionId));
7686
7689
  if (metaError) {
7687
- const errorMessage = await extractErrorMessage(metaError);
7690
+ const errorMessage = await extractErrorMessage3(metaError);
7688
7691
  OutputFormatter4.error({
7689
7692
  Result: "Failure",
7690
7693
  Message: errorMessage,
@@ -7726,7 +7729,7 @@ var registerResourcesCommand = (program) => {
7726
7729
 
7727
7730
  // src/commands/triggers.ts
7728
7731
  import {
7729
- catchError as catchError5,
7732
+ catchError as catchError6,
7730
7733
  logger as logger5,
7731
7734
  OutputFormatter as OutputFormatter5,
7732
7735
  processContext as processContext5
@@ -7734,20 +7737,20 @@ import {
7734
7737
  var CRUD_OPERATIONS = new Set(["CREATED", "UPDATED", "DELETED"]);
7735
7738
  async function fetchTriggerObjects(api, connectorKey, operationName, connectionId) {
7736
7739
  if (connectionId) {
7737
- return catchError5(api.getInstanceEventObjects({
7740
+ return catchError6(api.getInstanceEventObjects({
7738
7741
  connectionOrInstanceId: connectionId,
7739
7742
  elementKey: connectorKey,
7740
7743
  operationName
7741
7744
  }));
7742
7745
  }
7743
- return catchError5(api.getEventObjects({
7746
+ return catchError6(api.getEventObjects({
7744
7747
  elementKey: connectorKey,
7745
7748
  operationName
7746
7749
  }));
7747
7750
  }
7748
7751
  async function fetchTriggerMetadata(api, connectorKey, operationName, objectName, connectionId) {
7749
7752
  if (connectionId) {
7750
- return catchError5(api.getInstanceEventObjectMetadata({
7753
+ return catchError6(api.getInstanceEventObjectMetadata({
7751
7754
  connectionOrInstanceId: connectionId,
7752
7755
  elementKey: connectorKey,
7753
7756
  operationName,
@@ -7755,7 +7758,7 @@ async function fetchTriggerMetadata(api, connectorKey, operationName, objectName
7755
7758
  allFields: true
7756
7759
  }));
7757
7760
  }
7758
- return catchError5(api.getEventObjectMetadata({
7761
+ return catchError6(api.getEventObjectMetadata({
7759
7762
  elementKey: connectorKey,
7760
7763
  operationName,
7761
7764
  objectName,
@@ -7779,7 +7782,7 @@ var registerTriggersCommand = (program) => {
7779
7782
  return;
7780
7783
  }
7781
7784
  }
7782
- const [clientError, api] = await catchError5(createApiClient(ElementsApi, {
7785
+ const [clientError, api] = await catchError6(createApiClient(ElementsApi, {
7783
7786
  tenant: options.tenant
7784
7787
  }));
7785
7788
  if (clientError) {
@@ -7839,7 +7842,7 @@ var registerTriggersCommand = (program) => {
7839
7842
  return;
7840
7843
  }
7841
7844
  }
7842
- const [clientError, api] = await catchError5(createApiClient(ElementsApi, {
7845
+ const [clientError, api] = await catchError6(createApiClient(ElementsApi, {
7843
7846
  tenant: options.tenant
7844
7847
  }));
7845
7848
  if (clientError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/integrationservice-tool",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Manage Integration Service connectors, connections, and triggers.",
5
5
  "private": false,
6
6
  "maintainers": [
@@ -10,14 +10,14 @@
10
10
  ],
11
11
  "repository": {
12
12
  "type": "git",
13
- "url": "https://github.com/UiPath/uipcli.git",
13
+ "url": "https://github.com/UiPath/cli.git",
14
14
  "directory": "packages/integrationservice-tool"
15
15
  },
16
16
  "publishConfig": {
17
17
  "registry": "https://registry.npmjs.org/"
18
18
  },
19
19
  "keywords": [
20
- "uipcli-tool"
20
+ "cli-tool"
21
21
  ],
22
22
  "type": "module",
23
23
  "main": "./dist/tool.js",
@@ -31,7 +31,7 @@
31
31
  "dist"
32
32
  ],
33
33
  "scripts": {
34
- "build": "bun build ./src/tool.ts --outdir dist --format esm --target node --external commander --external @uipath/common --external @uipath/auth && bun build ./src/index.ts --outdir dist --format esm --target node --external '*/tool.js' --external commander --external @uipath/common --external @uipath/auth",
34
+ "build": "bun build ./src/tool.ts --outdir dist --format esm --target node --external commander --external @uipath/common --external @uipath/auth --external @uipath/filesystem && bun build ./src/index.ts --outdir dist --format esm --target node --external '*/tool.js' --external commander --external @uipath/common --external @uipath/auth --external @uipath/filesystem",
35
35
  "package": "bun run build && bun pm pack",
36
36
  "lint": "biome check .",
37
37
  "lint:fix": "biome check --write .",
@@ -41,7 +41,8 @@
41
41
  "peerDependencies": {
42
42
  "commander": "^14.0.3",
43
43
  "@uipath/common": "^0.1.7",
44
- "@uipath/auth": "^0.1.6"
44
+ "@uipath/auth": "^0.1.6",
45
+ "@uipath/filesystem": "^0.1.6"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@uipath/integrationservice-sdk": "workspace:*",