@uipath/common 0.1.8 → 0.1.10

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/index.js +854 -200
  2. package/package.json +5 -4
package/dist/index.js CHANGED
@@ -11,6 +11,12 @@ function catchError(fnOrPromise) {
11
11
  }
12
12
  try {
13
13
  const result = fnOrPromise();
14
+ if (result instanceof Promise) {
15
+ return result.then((data) => [undefined, data]).catch((error) => [
16
+ error instanceof Error ? error : new Error(String(error)),
17
+ undefined
18
+ ]);
19
+ }
14
20
  return [undefined, result];
15
21
  } catch (error) {
16
22
  return [
@@ -4651,10 +4657,8 @@ import { dirname } from "node:path";
4651
4657
 
4652
4658
  // src/output-context.ts
4653
4659
  function createStorage() {
4654
- try {
4655
- const { AsyncLocalStorage } = __require("node:async_hooks");
4656
- return new AsyncLocalStorage;
4657
- } catch {
4660
+ const [error, mod2] = catchError(() => __require("node:async_hooks"));
4661
+ if (error) {
4658
4662
  return {
4659
4663
  getStore: () => {
4660
4664
  return;
@@ -4662,6 +4666,7 @@ function createStorage() {
4662
4666
  run: (_store, fn) => fn()
4663
4667
  };
4664
4668
  }
4669
+ return new mod2.AsyncLocalStorage;
4665
4670
  }
4666
4671
  var outputStorage = createStorage();
4667
4672
  var globalSink;
@@ -4724,13 +4729,19 @@ class SimpleLogger {
4724
4729
  static isNode = typeof process !== "undefined" && !!process.versions?.node;
4725
4730
  static resolveLevel() {
4726
4731
  if (SimpleLogger.isNode) {
4727
- return SimpleLogger.parseLevel(process.env?.UIPCLI_LOG_LEVEL ?? "") ?? (process.env?.DEBUG ? 0 /* DEBUG */ : DEFAULT_LOG_LEVEL);
4728
- }
4729
- try {
4730
- if (typeof localStorage !== "undefined" && localStorage.getItem("debug")) {
4732
+ const explicitLevel = SimpleLogger.parseLevel(process.env?.UIPCLI_LOG_LEVEL ?? "");
4733
+ if (explicitLevel !== undefined)
4734
+ return explicitLevel;
4735
+ const debugVal = process.env?.DEBUG;
4736
+ if (debugVal === "true" || debugVal === "1") {
4731
4737
  return 0 /* DEBUG */;
4732
4738
  }
4733
- } catch {}
4739
+ return DEFAULT_LOG_LEVEL;
4740
+ }
4741
+ const [localStorageError, hasDebug] = catchError(() => typeof localStorage !== "undefined" && !!localStorage.getItem("debug"));
4742
+ if (!localStorageError && hasDebug) {
4743
+ return 0 /* DEBUG */;
4744
+ }
4734
4745
  return DEFAULT_LOG_LEVEL;
4735
4746
  }
4736
4747
  static parseLevel(value) {
@@ -4761,10 +4772,8 @@ class SimpleLogger {
4761
4772
  const path = this.logFilePath || getGlobalLogFilePath();
4762
4773
  if (!path)
4763
4774
  return;
4764
- try {
4765
- const timestamp2 = new Date().toISOString();
4766
- appendFileSync(path, `${timestamp2} ${formatted}`);
4767
- } catch {}
4775
+ const timestamp2 = new Date().toISOString();
4776
+ catchError(() => appendFileSync(path, `${timestamp2} ${formatted}`));
4768
4777
  }
4769
4778
  debug(message, ...args) {
4770
4779
  if (this.level > 0 /* DEBUG */)
@@ -4824,13 +4833,11 @@ class SimpleLogger {
4824
4833
  setGlobalLogFilePath(path);
4825
4834
  if (!path)
4826
4835
  return;
4827
- try {
4836
+ const [error] = catchError(() => {
4828
4837
  mkdirSync(dirname(path), { recursive: true });
4829
4838
  writeFileSync(path, "");
4830
- this.fileLoggingEnabled = true;
4831
- } catch {
4832
- this.fileLoggingEnabled = false;
4833
- }
4839
+ });
4840
+ this.fileLoggingEnabled = !error;
4834
4841
  }
4835
4842
  getLogFilePath() {
4836
4843
  return this.logFilePath || getGlobalLogFilePath();
@@ -4896,137 +4903,8 @@ function getOutputFilter() {
4896
4903
  return currentFilter;
4897
4904
  }
4898
4905
 
4899
- // ../../node_modules/@uipath/telemetry/dist/node.js
4900
- import { AsyncLocalStorage } from "async_hooks";
4901
- function node_context_storage_define_property(obj, key, value) {
4902
- if (key in obj)
4903
- Object.defineProperty(obj, key, {
4904
- value,
4905
- enumerable: true,
4906
- configurable: true,
4907
- writable: true
4908
- });
4909
- else
4910
- obj[key] = value;
4911
- return obj;
4912
- }
4913
-
4914
- class NodeContextStorage {
4915
- run(context, fn) {
4916
- return this.storage.run(context, fn);
4917
- }
4918
- getContext() {
4919
- return this.storage.getStore();
4920
- }
4921
- constructor() {
4922
- node_context_storage_define_property(this, "storage", new AsyncLocalStorage);
4923
- }
4924
- }
4925
- function telemetry_service_define_property(obj, key, value) {
4926
- if (key in obj)
4927
- Object.defineProperty(obj, key, {
4928
- value,
4929
- enumerable: true,
4930
- configurable: true,
4931
- writable: true
4932
- });
4933
- else
4934
- obj[key] = value;
4935
- return obj;
4936
- }
4937
-
4938
- class TelemetryService {
4939
- setOperationId(operationId) {
4940
- this.operationId = operationId;
4941
- }
4942
- setProvider(provider) {
4943
- this.telemetryProvider = provider;
4944
- }
4945
- setDefaultProperties(properties) {
4946
- this.defaultProperties = properties;
4947
- }
4948
- trackEvent(name, properties) {
4949
- const context = this.getCurrentContext();
4950
- const enrichedProperties = this.enrichPropertiesWithContext(properties, context);
4951
- this.telemetryProvider.trackEvent(name, enrichedProperties);
4952
- }
4953
- trackException(error, properties) {
4954
- const context = this.getCurrentContext();
4955
- const enrichedProperties = this.enrichPropertiesWithContext(properties, context);
4956
- this.telemetryProvider.trackException(error, enrichedProperties);
4957
- }
4958
- async trackRequest(name, fn, properties) {
4959
- const context = {
4960
- operationId: this.operationId ?? this.generateId(),
4961
- id: this.generateId()
4962
- };
4963
- const startTime = performance.now();
4964
- try {
4965
- const result = await this.contextStorage.run(context, fn);
4966
- const durationMs = performance.now() - startTime;
4967
- const enrichedProperties = this.enrichPropertiesWithContext(properties, context);
4968
- await this.telemetryProvider.trackRequest(name, durationMs, true, enrichedProperties);
4969
- return result;
4970
- } catch (error) {
4971
- const durationMs = performance.now() - startTime;
4972
- const err = error instanceof Error ? error : new Error(String(error));
4973
- const enrichedProperties = this.enrichPropertiesWithContext({
4974
- ...properties,
4975
- errorMessage: err.message
4976
- }, context);
4977
- await this.telemetryProvider.trackRequest(name, durationMs, false, enrichedProperties);
4978
- throw error;
4979
- }
4980
- }
4981
- async trackDependencyOperation(name, type2, fn, properties) {
4982
- const parentContext = this.getCurrentContext();
4983
- if (!parentContext)
4984
- throw new Error("trackDependencyOperation must be called within a trackRequest block.");
4985
- const childContext = {
4986
- operationId: parentContext.operationId,
4987
- parentId: parentContext.id,
4988
- id: this.generateId()
4989
- };
4990
- const startTime = performance.now();
4991
- try {
4992
- const result = await this.contextStorage.run(childContext, fn);
4993
- const durationMs = performance.now() - startTime;
4994
- const enrichedProperties = this.enrichPropertiesWithContext(properties, childContext);
4995
- await this.telemetryProvider.trackDependency(name, type2, durationMs, true, enrichedProperties);
4996
- return result;
4997
- } catch (error) {
4998
- const durationMs = performance.now() - startTime;
4999
- const err = error instanceof Error ? error : new Error(String(error));
5000
- const enrichedProperties = this.enrichPropertiesWithContext({
5001
- ...properties,
5002
- errorMessage: err.message
5003
- }, childContext);
5004
- await this.telemetryProvider.trackDependency(name, type2, durationMs, false, enrichedProperties);
5005
- throw error;
5006
- }
5007
- }
5008
- getCurrentContext() {
5009
- return this.contextStorage.getContext();
5010
- }
5011
- enrichPropertiesWithContext(properties, context) {
5012
- return {
5013
- ...this.defaultProperties,
5014
- ...properties,
5015
- ...context
5016
- };
5017
- }
5018
- generateId() {
5019
- return crypto.randomUUID().replaceAll("-", "");
5020
- }
5021
- constructor(telemetryProvider, contextStorage) {
5022
- telemetry_service_define_property(this, "telemetryProvider", undefined);
5023
- telemetry_service_define_property(this, "contextStorage", undefined);
5024
- telemetry_service_define_property(this, "operationId", undefined);
5025
- telemetry_service_define_property(this, "defaultProperties", undefined);
5026
- this.telemetryProvider = telemetryProvider;
5027
- this.contextStorage = contextStorage;
5028
- }
5029
- }
4906
+ // src/telemetry.ts
4907
+ import { NodeContextStorage, TelemetryService } from "@uipath/telemetry/node";
5030
4908
 
5031
4909
  // src/registry.ts
5032
4910
  import { execFileSync } from "node:child_process";
@@ -5034,16 +4912,15 @@ function readRegistryValue(keyPath, valueName) {
5034
4912
  if (process.platform !== "win32") {
5035
4913
  return "";
5036
4914
  }
5037
- try {
5038
- const output = execFileSync("reg", ["query", keyPath, "/v", valueName], {
5039
- encoding: "utf-8",
5040
- stdio: ["pipe", "pipe", "pipe"]
5041
- });
5042
- const match = output.match(new RegExp(`${valueName}\\s+REG_SZ\\s+(.+)`));
5043
- return match?.[1]?.trim() ?? "";
5044
- } catch {
4915
+ const [error, output] = catchError(() => execFileSync("reg", ["query", keyPath, "/v", valueName], {
4916
+ encoding: "utf-8",
4917
+ stdio: ["pipe", "pipe", "pipe"]
4918
+ }));
4919
+ if (error) {
5045
4920
  return "";
5046
4921
  }
4922
+ const match = output.match(new RegExp(`${valueName}\\s+REG_SZ\\s+(.+)`));
4923
+ return match?.[1]?.trim() ?? "";
5047
4924
  }
5048
4925
 
5049
4926
  // src/logger-telemetry-provider.ts
@@ -5059,7 +4936,7 @@ class LoggerTelemetryProvider {
5059
4936
  };
5060
4937
  }
5061
4938
  async trackEvent(eventName, properties) {
5062
- logger.info(formatMessage("Event", eventName, this.enrich(properties)));
4939
+ logger.debug(formatMessage("Event", eventName, this.enrich(properties)));
5063
4940
  }
5064
4941
  async trackException(error, properties) {
5065
4942
  logger.error(formatMessage("Exception", error.message, this.enrich({
@@ -5068,7 +4945,7 @@ class LoggerTelemetryProvider {
5068
4945
  })));
5069
4946
  }
5070
4947
  async trackRequest(name, duration, success, properties) {
5071
- logger.info(formatMessage("Request", name, this.enrich({
4948
+ logger.debug(formatMessage("Request", name, this.enrich({
5072
4949
  ...properties,
5073
4950
  duration: `${duration}ms`,
5074
4951
  success
@@ -5108,7 +4985,12 @@ function getGlobalTelemetryProperties() {
5108
4985
  return globalThis[GLOBAL_TELEMETRY_PROPS_KEY];
5109
4986
  }
5110
4987
  async function loadApplicationInsights() {
4988
+ const savedDebug = process.env.DEBUG;
4989
+ delete process.env.DEBUG;
5111
4990
  const [error, mod2] = await catchError(import("applicationinsights"));
4991
+ if (savedDebug !== undefined) {
4992
+ process.env.DEBUG = savedDebug;
4993
+ }
5112
4994
  if (error) {
5113
4995
  logger.warn(`[Telemetry] applicationinsights package not available: ${error.message}. Telemetry will use logger fallback.`);
5114
4996
  return;
@@ -5157,13 +5039,11 @@ class NodeAppInsightsTelemetryProvider {
5157
5039
  if (!client)
5158
5040
  return;
5159
5041
  const merged = this.mergeProperties(properties);
5160
- logger.debug(`[AppInsights] trackEvent: ${eventName}`, merged ? JSON.stringify(merged) : "");
5161
- try {
5162
- client.trackEvent({
5163
- name: eventName,
5164
- properties: merged
5165
- });
5166
- } catch {
5042
+ const [error] = catchError(() => client.trackEvent({
5043
+ name: eventName,
5044
+ properties: merged
5045
+ }));
5046
+ if (error) {
5167
5047
  logger.debug(`[AppInsights] trackEvent failed for: ${eventName}`);
5168
5048
  }
5169
5049
  }
@@ -5172,13 +5052,11 @@ class NodeAppInsightsTelemetryProvider {
5172
5052
  if (!client)
5173
5053
  return;
5174
5054
  const merged = this.mergeProperties(properties);
5175
- logger.debug(`[AppInsights] trackException: ${error.message}`, merged ?? "");
5176
- try {
5177
- client.trackException({
5178
- exception: error,
5179
- properties: merged
5180
- });
5181
- } catch {
5055
+ const [trackError] = catchError(() => client.trackException({
5056
+ exception: error,
5057
+ properties: merged
5058
+ }));
5059
+ if (trackError) {
5182
5060
  logger.debug(`[AppInsights] trackException failed for: ${error.message}`);
5183
5061
  }
5184
5062
  }
@@ -5187,7 +5065,6 @@ class NodeAppInsightsTelemetryProvider {
5187
5065
  if (!client)
5188
5066
  return;
5189
5067
  const merged = this.mergeProperties(properties);
5190
- logger.debug(`[AppInsights] trackRequest: ${name} duration=${duration}ms success=${success}`, merged ?? "");
5191
5068
  client.trackRequest({
5192
5069
  name,
5193
5070
  url: name,
@@ -5202,14 +5079,12 @@ class NodeAppInsightsTelemetryProvider {
5202
5079
  if (!client)
5203
5080
  return;
5204
5081
  const merged = this.mergeProperties(properties);
5205
- logger.debug(`[AppInsights] trackDependency: ${name} type=${type2} duration=${duration}ms success=${success}`, merged ?? "");
5206
5082
  client.trackDependency({
5207
5083
  name,
5208
5084
  dependencyTypeName: type2,
5209
5085
  duration,
5210
5086
  resultCode: success ? "200" : "500",
5211
5087
  success,
5212
- data: name,
5213
5088
  properties: merged
5214
5089
  });
5215
5090
  }
@@ -5219,7 +5094,6 @@ class NodeAppInsightsTelemetryProvider {
5219
5094
  logger.warn(`[AppInsights] flush error (non-fatal): nil client`);
5220
5095
  return;
5221
5096
  }
5222
- logger.debug("[AppInsights] flush: sending buffered telemetry to cloud");
5223
5097
  const [error] = await catchError(new Promise((resolve, reject) => {
5224
5098
  client.flush({
5225
5099
  callback: (response) => {
@@ -5355,12 +5229,9 @@ async function telemetryInit(defaultProperties) {
5355
5229
  setGlobalTelemetryProperties({ sessionId, ...defaultProperties });
5356
5230
  telemetry.setDefaultProperties({ sessionId, ...defaultProperties });
5357
5231
  const isAppInsights = providerName === "NodeAppInsightsTelemetryProvider";
5358
- if (isAppInsights) {
5359
- logger.debug("[Telemetry] initialized successfully with AppInsights provider");
5360
- } else {
5232
+ if (!isAppInsights) {
5361
5233
  logger.debug(`[Telemetry] initialized with fallback provider (${providerName}). applicationinsights package not available.`);
5362
5234
  }
5363
- logger.debug(`[Telemetry] sessionId=${sessionId}`);
5364
5235
  }
5365
5236
  var FLUSH_SHUTDOWN_TIMEOUT_MS = 5000;
5366
5237
  async function telemetryFlushAndShutdown() {
@@ -5371,13 +5242,7 @@ async function telemetryFlushAndShutdown() {
5371
5242
  timer = setTimeout(() => resolve("timeout"), FLUSH_SHUTDOWN_TIMEOUT_MS);
5372
5243
  });
5373
5244
  const result = await Promise.race([
5374
- provider.flush().then(() => {
5375
- logger.debug("[Telemetry] flush complete");
5376
- return provider.shutdown();
5377
- }).then(() => {
5378
- logger.debug("[Telemetry] shutdown complete");
5379
- return "done";
5380
- }),
5245
+ provider.flush().then(() => provider.shutdown()).then(() => "done"),
5381
5246
  timeout
5382
5247
  ]);
5383
5248
  if (timer)
@@ -5425,7 +5290,7 @@ class FailureOutput {
5425
5290
  }
5426
5291
  }
5427
5292
  }
5428
- function printOutput(data, format = "table", logFn = console.log) {
5293
+ function printOutput(data, format = "table", logFn) {
5429
5294
  if (!data) {
5430
5295
  logFn("Empty response object. No data to display.");
5431
5296
  return;
@@ -5444,8 +5309,6 @@ function printOutput(data, format = "table", logFn = console.log) {
5444
5309
  const values = Object.values(item).map((v) => v ?? "").join("\t");
5445
5310
  logFn(values);
5446
5311
  });
5447
- } else if ("Message" in data && !("Result" in data)) {
5448
- logFn(data.Message);
5449
5312
  } else {
5450
5313
  const values = Object.values(data).map((v) => v ?? "").join("\t");
5451
5314
  logFn(values);
@@ -5454,11 +5317,12 @@ function printOutput(data, format = "table", logFn = console.log) {
5454
5317
  }
5455
5318
  default: {
5456
5319
  if ("Data" in data && data.Data != null) {
5457
- const items = Array.isArray(data.Data) ? data.Data : [data.Data];
5458
- const logValue = "Log" in data ? data.Log : undefined;
5459
- printTable(items, logFn, logValue);
5460
- } else if ("Message" in data && !("Result" in data)) {
5461
- logFn(data.Message);
5320
+ const logValue = data.Log;
5321
+ if (Array.isArray(data.Data)) {
5322
+ printResizableTable(data.Data, logFn, logValue);
5323
+ } else {
5324
+ printVerticalTable(data.Data, logFn, logValue);
5325
+ }
5462
5326
  } else {
5463
5327
  printTable([{ ...data }], logFn);
5464
5328
  }
@@ -5471,11 +5335,22 @@ function logOutput(data, format = "table") {
5471
5335
  printOutput(data, format, (msg) => sink.writeOut(`${msg}
5472
5336
  `));
5473
5337
  }
5474
- function printTable(data, logFn = console.log, externalLogValue) {
5338
+ function cellToString(val) {
5339
+ return val != null && typeof val === "object" ? JSON.stringify(val) : String(val ?? "");
5340
+ }
5341
+ function wrapText(text, width) {
5342
+ if (text.length <= width)
5343
+ return [text];
5344
+ const lines = [];
5345
+ for (let pos = 0;pos < text.length; pos += width) {
5346
+ lines.push(text.substring(pos, pos + width));
5347
+ }
5348
+ return lines;
5349
+ }
5350
+ function printTable(data, logFn, externalLogValue) {
5475
5351
  if (data.length === 0)
5476
5352
  return;
5477
5353
  const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
5478
- const cellToString = (val) => val != null && typeof val === "object" ? JSON.stringify(val) : String(val ?? "");
5479
5354
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
5480
5355
  const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
5481
5356
  logFn(header);
@@ -5489,6 +5364,96 @@ function printTable(data, logFn = console.log, externalLogValue) {
5489
5364
  logFn(`Log: ${externalLogValue}`);
5490
5365
  }
5491
5366
  }
5367
+ function printVerticalTable(data, logFn = console.log, externalLogValue) {
5368
+ const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
5369
+ if (keys.length === 0)
5370
+ return;
5371
+ const maxKeyWidth = Math.max(...keys.map((key) => key.length));
5372
+ keys.forEach((key) => {
5373
+ const keyCol = key.padEnd(maxKeyWidth);
5374
+ logFn(`${keyCol} | ${cellToString(data[key])}`);
5375
+ });
5376
+ if (externalLogValue) {
5377
+ logFn("");
5378
+ logFn(`Log: ${externalLogValue}`);
5379
+ }
5380
+ }
5381
+ function printResizableTable(data, logFn = console.log, externalLogValue) {
5382
+ if (data.length === 0)
5383
+ return;
5384
+ const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
5385
+ if (keys.length === 0)
5386
+ return;
5387
+ if (!process.stdout.isTTY) {
5388
+ printTable(data, logFn, externalLogValue);
5389
+ return;
5390
+ }
5391
+ const naturalWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
5392
+ const separatorTotal = (keys.length - 1) * 3;
5393
+ const totalWidth = naturalWidths.reduce((a, b) => a + b, 0) + separatorTotal;
5394
+ const termWidth = process.stdout.columns || 120;
5395
+ if (totalWidth <= termWidth) {
5396
+ printTable(data, logFn, externalLogValue);
5397
+ return;
5398
+ }
5399
+ const overflow = totalWidth - termWidth;
5400
+ const MIN_COL_WIDTH = 10;
5401
+ const minWidths = keys.map((key) => Math.max(key.length, MIN_COL_WIDTH));
5402
+ let bestCol = -1;
5403
+ let bestCost = Infinity;
5404
+ for (let i2 = 0;i2 < keys.length; i2++) {
5405
+ const maxShrink = naturalWidths[i2] - minWidths[i2];
5406
+ if (maxShrink < overflow)
5407
+ continue;
5408
+ const newWidth = naturalWidths[i2] - overflow;
5409
+ let extraRows = 0;
5410
+ for (const item of data) {
5411
+ const cellLen = cellToString(item[keys[i2]]).length;
5412
+ if (cellLen > newWidth) {
5413
+ extraRows += Math.ceil(cellLen / newWidth) - 1;
5414
+ }
5415
+ }
5416
+ if (extraRows < bestCost) {
5417
+ bestCost = extraRows;
5418
+ bestCol = i2;
5419
+ }
5420
+ }
5421
+ const finalWidths = [...naturalWidths];
5422
+ if (bestCol !== -1) {
5423
+ finalWidths[bestCol] = naturalWidths[bestCol] - overflow;
5424
+ } else {
5425
+ let remaining = overflow;
5426
+ const colsByShrinkPotential = keys.map((_, i2) => ({
5427
+ index: i2,
5428
+ potential: naturalWidths[i2] - minWidths[i2]
5429
+ })).filter((c) => c.potential > 0).sort((a, b) => b.potential - a.potential);
5430
+ for (const col of colsByShrinkPotential) {
5431
+ if (remaining <= 0)
5432
+ break;
5433
+ const shrink = Math.min(remaining, col.potential);
5434
+ finalWidths[col.index] -= shrink;
5435
+ remaining -= shrink;
5436
+ }
5437
+ }
5438
+ const header = keys.map((key, i2) => key.padEnd(finalWidths[i2])).join(" | ");
5439
+ logFn(header);
5440
+ logFn(keys.map((_, i2) => "-".repeat(finalWidths[i2])).join("-|-"));
5441
+ data.forEach((item) => {
5442
+ const cellLines = keys.map((key, i2) => wrapText(cellToString(item[key]), finalWidths[i2]));
5443
+ const lineCount = Math.max(...cellLines.map((l) => l.length));
5444
+ for (let line = 0;line < lineCount; line++) {
5445
+ const row = keys.map((_, i2) => {
5446
+ const val = line < cellLines[i2].length ? cellLines[i2][line] : "";
5447
+ return val.padEnd(finalWidths[i2]);
5448
+ }).join(" | ");
5449
+ logFn(row);
5450
+ }
5451
+ });
5452
+ if (externalLogValue) {
5453
+ logFn("");
5454
+ logFn(`Log: ${externalLogValue}`);
5455
+ }
5456
+ }
5492
5457
  function toYaml(data) {
5493
5458
  return dump(data);
5494
5459
  }
@@ -5530,11 +5495,14 @@ var OutputFormatter;
5530
5495
  OutputFormatter.error = error;
5531
5496
  function log(data) {
5532
5497
  const format = getOutputFormat();
5498
+ const sink = getOutputSink();
5533
5499
  if (format === "json") {
5534
- console.error(JSON.stringify(data));
5500
+ sink.writeErr(`${JSON.stringify(data)}
5501
+ `);
5535
5502
  } else {
5536
5503
  for (const [key, value] of Object.entries(data)) {
5537
- console.error(`${key}: ${value}`);
5504
+ sink.writeErr(`${key}: ${value}
5505
+ `);
5538
5506
  }
5539
5507
  }
5540
5508
  }
@@ -5635,6 +5603,95 @@ function registerHelpAll(command) {
5635
5603
  throw new CommanderError(0, "commander.helpDisplayed", "(outputHelp)");
5636
5604
  });
5637
5605
  }
5606
+ // src/console-guard.ts
5607
+ function format(first, ...rest) {
5608
+ if (typeof first !== "string") {
5609
+ if (first === undefined && rest.length === 0)
5610
+ return "";
5611
+ return [first, ...rest].map(String).join(" ");
5612
+ }
5613
+ let i2 = 0;
5614
+ const result = first.replace(/%[sdifjoO%]/g, (spec) => {
5615
+ if (spec === "%%")
5616
+ return "%";
5617
+ if (i2 >= rest.length)
5618
+ return spec;
5619
+ const arg = rest[i2++];
5620
+ switch (spec) {
5621
+ case "%s":
5622
+ return String(arg);
5623
+ case "%d":
5624
+ case "%i":
5625
+ return String(parseInt(String(arg), 10));
5626
+ case "%f":
5627
+ return String(parseFloat(String(arg)));
5628
+ case "%j":
5629
+ case "%o":
5630
+ case "%O":
5631
+ try {
5632
+ return JSON.stringify(arg);
5633
+ } catch {
5634
+ return String(arg);
5635
+ }
5636
+ default:
5637
+ return spec;
5638
+ }
5639
+ });
5640
+ const extra = rest.slice(i2);
5641
+ if (extra.length > 0) {
5642
+ return result + " " + extra.map(String).join(" ");
5643
+ }
5644
+ return result;
5645
+ }
5646
+ function formatArgs(args) {
5647
+ return `${format(...args)}
5648
+ `;
5649
+ }
5650
+ var guardInstalled = false;
5651
+ var savedOriginals;
5652
+ function installConsoleGuard() {
5653
+ if (guardInstalled)
5654
+ return;
5655
+ const originals = {
5656
+ log: console.log,
5657
+ info: console.info,
5658
+ warn: console.warn,
5659
+ error: console.error,
5660
+ debug: console.debug
5661
+ };
5662
+ savedOriginals = originals;
5663
+ let reentrant = false;
5664
+ function guardedWriter(original) {
5665
+ return (...args) => {
5666
+ if (reentrant) {
5667
+ original.apply(console, args);
5668
+ return;
5669
+ }
5670
+ reentrant = true;
5671
+ try {
5672
+ getOutputSink().writeErr(formatArgs(args));
5673
+ } finally {
5674
+ reentrant = false;
5675
+ }
5676
+ };
5677
+ }
5678
+ console.log = guardedWriter(originals.log);
5679
+ console.info = guardedWriter(originals.info);
5680
+ console.warn = guardedWriter(originals.warn);
5681
+ console.error = guardedWriter(originals.error);
5682
+ console.debug = guardedWriter(originals.debug);
5683
+ guardInstalled = true;
5684
+ }
5685
+ function restoreConsole() {
5686
+ if (!savedOriginals)
5687
+ return;
5688
+ console.log = savedOriginals.log;
5689
+ console.info = savedOriginals.info;
5690
+ console.warn = savedOriginals.warn;
5691
+ console.error = savedOriginals.error;
5692
+ console.debug = savedOriginals.debug;
5693
+ guardInstalled = false;
5694
+ }
5638
5695
  // src/constants.ts
5639
5696
  var UIPATH_HOME_DIR = ".uipath";
5640
5697
  var AUTH_FILENAME = ".auth";
@@ -5645,6 +5702,108 @@ var DEFAULT_PAGE_SIZE = 50;
5645
5702
  var DEFAULT_AUTH_TIMEOUT_MS = 5 * 60 * 1000;
5646
5703
  var DEFAULT_FETCH_TIMEOUT_MS = 30000;
5647
5704
  var DEFAULT_REDIRECT_URI = "http://localhost:8104/oidc/login";
5705
+ // src/error-handler.ts
5706
+ var DEFAULT_401 = "Unauthorized (401). Run `uip login` to authenticate.";
5707
+ var DEFAULT_403 = "Forbidden (403). Ensure the account has the required permissions.";
5708
+ var DEFAULT_405 = "Method Not Allowed (405). The endpoint may not exist or the base URL may be incorrect.";
5709
+ async function extractErrorDetails(error, options) {
5710
+ const err = error !== null && error !== undefined && typeof error === "object" ? error : {};
5711
+ const response = err.response;
5712
+ const status = err.status ?? response?.status;
5713
+ let rawBody;
5714
+ let extractedMessage;
5715
+ let parsedBody;
5716
+ if (response?.text) {
5717
+ const [bodyError, body] = await catchError((async () => response.text())());
5718
+ if (!bodyError && body) {
5719
+ rawBody = body;
5720
+ const [parseError, parsed] = catchError(() => JSON.parse(body));
5721
+ if (!parseError && parsed && typeof parsed === "object") {
5722
+ parsedBody = parsed;
5723
+ if (parsedBody.errors && typeof parsedBody.errors === "object") {
5724
+ for (const field of Object.values(parsedBody.errors)) {
5725
+ if (Array.isArray(field) && field.length > 0) {
5726
+ const first = field[0];
5727
+ if (first && typeof first.message === "string") {
5728
+ extractedMessage = first.message;
5729
+ break;
5730
+ }
5731
+ }
5732
+ }
5733
+ }
5734
+ if (!extractedMessage) {
5735
+ extractedMessage = typeof parsedBody.message === "string" ? parsedBody.message : typeof parsedBody.errorMessage === "string" ? parsedBody.errorMessage : typeof parsedBody.title === "string" ? parsedBody.title : undefined;
5736
+ }
5737
+ if (!extractedMessage) {
5738
+ extractedMessage = body;
5739
+ }
5740
+ } else {
5741
+ extractedMessage = body;
5742
+ }
5743
+ }
5744
+ }
5745
+ const rawMessage = typeof err.message === "string" ? err.message : "Unknown error";
5746
+ let message;
5747
+ if (status === 401) {
5748
+ message = DEFAULT_401;
5749
+ } else if (status === 403) {
5750
+ message = options?.forbiddenMessage ?? DEFAULT_403;
5751
+ } else if (status === 405) {
5752
+ message = DEFAULT_405;
5753
+ } else if (extractedMessage) {
5754
+ message = status ? `HTTP ${status}: ${extractedMessage}` : extractedMessage;
5755
+ } else if (status) {
5756
+ if (rawMessage === "Unknown error" && response) {
5757
+ const statusText = response.statusText;
5758
+ message = statusText ? `HTTP ${status} ${statusText}` : `HTTP ${status} - request failed`;
5759
+ } else {
5760
+ message = `HTTP ${status}: ${rawMessage}`;
5761
+ }
5762
+ } else {
5763
+ message = rawMessage;
5764
+ }
5765
+ let details = rawMessage;
5766
+ if (rawBody) {
5767
+ if (parsedBody) {
5768
+ const extra = {};
5769
+ if (parsedBody.errorCode)
5770
+ extra.errorCode = parsedBody.errorCode;
5771
+ if (parsedBody.details)
5772
+ extra.details = parsedBody.details;
5773
+ if (parsedBody.errors != null)
5774
+ extra.errors = parsedBody.errors;
5775
+ if (parsedBody.data && typeof parsedBody.data === "object" && Object.keys(parsedBody.data).length > 0) {
5776
+ extra.data = parsedBody.data;
5777
+ }
5778
+ details = Object.keys(extra).length > 0 ? JSON.stringify(extra) : rawBody;
5779
+ } else {
5780
+ details = rawBody;
5781
+ }
5782
+ } else if (typeof err.message === "string") {
5783
+ details = err.message;
5784
+ } else {
5785
+ details = String(error);
5786
+ }
5787
+ return { message, details };
5788
+ }
5789
+ async function extractErrorMessage(error, options) {
5790
+ const { message } = await extractErrorDetails(error, options);
5791
+ return message;
5792
+ }
5793
+ function extractErrorMessageSync(error) {
5794
+ if (error instanceof Error) {
5795
+ return error.message;
5796
+ }
5797
+ if (typeof error === "object" && error !== null) {
5798
+ if ("status" in error && error.status === 401) {
5799
+ return DEFAULT_401;
5800
+ }
5801
+ if ("message" in error && typeof error.message === "string") {
5802
+ return error.message;
5803
+ }
5804
+ }
5805
+ return String(error);
5806
+ }
5648
5807
  // ../../node_modules/jsonpath-plus/dist/index-node-esm.js
5649
5808
  import vm from "vm";
5650
5809
 
@@ -7068,6 +7227,477 @@ class JsonPathError extends Error {
7068
7227
  this.name = "JsonPathError";
7069
7228
  }
7070
7229
  }
7230
+ // src/polling/abort-controller.ts
7231
+ var created = false;
7232
+ function createPollAbortController() {
7233
+ const controller = new AbortController;
7234
+ if (typeof process === "undefined" || typeof process.on !== "function") {
7235
+ return controller;
7236
+ }
7237
+ if (created) {
7238
+ logger.warn("[pollUntil] createPollAbortController called more than once — listeners may accumulate");
7239
+ }
7240
+ created = true;
7241
+ const onSignal = () => {
7242
+ cleanup();
7243
+ controller.abort(new Error("Process interrupted (SIGINT/SIGTERM)"));
7244
+ };
7245
+ const cleanup = () => {
7246
+ process.removeListener("SIGINT", onSignal);
7247
+ process.removeListener("SIGTERM", onSignal);
7248
+ process.removeListener("exit", cleanup);
7249
+ };
7250
+ process.on("SIGINT", onSignal);
7251
+ process.on("SIGTERM", onSignal);
7252
+ process.on("exit", cleanup);
7253
+ controller.signal.addEventListener("abort", () => {
7254
+ cleanup();
7255
+ }, { once: true });
7256
+ return controller;
7257
+ }
7258
+ // src/polling/format-utils.ts
7259
+ function msToDuration(ms) {
7260
+ if (!Number.isFinite(ms) || ms < 0) {
7261
+ return "00:00:00";
7262
+ }
7263
+ const totalSec = Math.floor(ms / 1000);
7264
+ const h = Math.floor(totalSec / 3600);
7265
+ const m = Math.floor(totalSec % 3600 / 60);
7266
+ const s = totalSec % 60;
7267
+ return [h, m, s].map((v) => String(v).padStart(2, "0")).join(":");
7268
+ }
7269
+ // src/polling/types.ts
7270
+ var PollOutcome = {
7271
+ Completed: "completed",
7272
+ Timeout: "timeout",
7273
+ Interrupted: "interrupted",
7274
+ Aborted: "aborted",
7275
+ Failed: "failed"
7276
+ };
7277
+ var ErrorDecision = {
7278
+ Abort: "abort"
7279
+ };
7280
+ var POLL_DEFAULTS = {
7281
+ intervalMs: 5000,
7282
+ timeoutMs: 1800000,
7283
+ maxConsecutiveErrors: 3,
7284
+ logIntervalMs: 30000,
7285
+ logPrefix: "wait"
7286
+ };
7287
+ var BACKOFF_DEFAULTS = {
7288
+ initialMs: 1000,
7289
+ multiplier: 2,
7290
+ maxMs: 30000,
7291
+ jitter: 0.5
7292
+ };
7293
+ var MIN_INTERVAL_MS = 100;
7294
+
7295
+ // src/polling/poll-until.ts
7296
+ function resolveIntervalFn(options) {
7297
+ if (typeof options.intervalMs === "function") {
7298
+ return options.intervalMs;
7299
+ }
7300
+ const staticInterval = options.intervalMs ?? POLL_DEFAULTS.intervalMs;
7301
+ return () => staticInterval;
7302
+ }
7303
+ function resolveBackoffFn(options) {
7304
+ if (!options.backoff)
7305
+ return;
7306
+ const config = options.backoff === true ? { ...BACKOFF_DEFAULTS } : {
7307
+ initialMs: options.backoff.initialMs ?? BACKOFF_DEFAULTS.initialMs,
7308
+ multiplier: options.backoff.multiplier ?? BACKOFF_DEFAULTS.multiplier,
7309
+ maxMs: options.backoff.maxMs ?? BACKOFF_DEFAULTS.maxMs,
7310
+ jitter: Math.min(1, Math.max(0, options.backoff.jitter ?? BACKOFF_DEFAULTS.jitter))
7311
+ };
7312
+ return (errorCount) => {
7313
+ const exponent = Math.min(errorCount - 1, 30);
7314
+ const raw = Math.min(config.initialMs * config.multiplier ** exponent, config.maxMs);
7315
+ if (config.jitter > 0) {
7316
+ const jitterAmount = raw * config.jitter;
7317
+ return raw - jitterAmount * Math.random();
7318
+ }
7319
+ return raw;
7320
+ };
7321
+ }
7322
+ function clampInterval(raw, label, prefix) {
7323
+ if (!Number.isFinite(raw) || Number.isNaN(raw)) {
7324
+ if (label) {
7325
+ logger.warn(`[${prefix}] ${label} — intervalMs returned ${raw}, falling back to ${POLL_DEFAULTS.intervalMs}ms`);
7326
+ }
7327
+ return POLL_DEFAULTS.intervalMs;
7328
+ }
7329
+ if (raw < MIN_INTERVAL_MS) {
7330
+ if (label) {
7331
+ logger.warn(`[${prefix}] ${label} — intervalMs ${raw}ms clamped to minimum ${MIN_INTERVAL_MS}ms`);
7332
+ }
7333
+ return MIN_INTERVAL_MS;
7334
+ }
7335
+ return raw;
7336
+ }
7337
+ function abortError(signal) {
7338
+ const reason = signal.reason;
7339
+ if (reason instanceof Error && reason.name === "AbortError") {
7340
+ return reason;
7341
+ }
7342
+ const msg = reason instanceof Error ? reason.message : typeof reason === "string" || typeof reason === "number" ? String(reason) : "Aborted";
7343
+ const err = new Error(msg);
7344
+ err.name = "AbortError";
7345
+ return err;
7346
+ }
7347
+ function interruptibleSleep(ms, signal) {
7348
+ return new Promise((resolve, reject) => {
7349
+ if (signal?.aborted) {
7350
+ reject(abortError(signal));
7351
+ return;
7352
+ }
7353
+ let onAbort;
7354
+ const cleanup = () => {
7355
+ if (onAbort) {
7356
+ signal?.removeEventListener("abort", onAbort);
7357
+ }
7358
+ };
7359
+ const timer = setTimeout(() => {
7360
+ cleanup();
7361
+ resolve();
7362
+ }, ms);
7363
+ if (signal) {
7364
+ onAbort = () => {
7365
+ clearTimeout(timer);
7366
+ cleanup();
7367
+ reject(abortError(signal));
7368
+ };
7369
+ signal.addEventListener("abort", onAbort, { once: true });
7370
+ }
7371
+ });
7372
+ }
7373
+ function sanitizeMaxErrors(value) {
7374
+ if (value === undefined)
7375
+ return POLL_DEFAULTS.maxConsecutiveErrors;
7376
+ if (!Number.isFinite(value) || value < 0)
7377
+ return 0;
7378
+ return Math.floor(value);
7379
+ }
7380
+ function resolveConfig(options) {
7381
+ const timeoutMs = Math.max(0, options.timeoutMs ?? POLL_DEFAULTS.timeoutMs);
7382
+ const startTime = Date.now();
7383
+ return {
7384
+ fn: options.fn,
7385
+ until: options.until,
7386
+ getStatus: options.getStatus,
7387
+ signal: options.signal,
7388
+ label: options.label,
7389
+ beforePoll: options.beforePoll,
7390
+ onPoll: options.onPoll,
7391
+ onStatusChange: options.onStatusChange,
7392
+ onError: options.onError,
7393
+ onComplete: options.onComplete,
7394
+ onTimeout: options.onTimeout,
7395
+ onInterrupt: options.onInterrupt,
7396
+ timeoutMs,
7397
+ maxConsecutiveErrors: sanitizeMaxErrors(options.maxConsecutiveErrors),
7398
+ logIntervalMs: options.logIntervalMs ?? POLL_DEFAULTS.logIntervalMs,
7399
+ logPrefix: options.logPrefix ?? POLL_DEFAULTS.logPrefix,
7400
+ getInterval: resolveIntervalFn(options),
7401
+ getErrorInterval: resolveBackoffFn(options),
7402
+ startTime,
7403
+ deadline: timeoutMs > 0 ? startTime + timeoutMs : 0
7404
+ };
7405
+ }
7406
+ function elapsed(cfg) {
7407
+ return Date.now() - cfg.startTime;
7408
+ }
7409
+ function isPastDeadline(cfg) {
7410
+ return cfg.deadline > 0 && Date.now() >= cfg.deadline;
7411
+ }
7412
+ function buildContext(cfg, state) {
7413
+ return {
7414
+ pollCount: state.pollCount,
7415
+ elapsedMs: elapsed(cfg),
7416
+ lastResult: state.lastResult,
7417
+ lastStatus: state.lastStatus
7418
+ };
7419
+ }
7420
+ function truncateMessage(msg, maxLen = 500) {
7421
+ return msg.length > maxLen ? `${msg.slice(0, maxLen)}...` : msg;
7422
+ }
7423
+ async function handlePollError(error, errorSource, cfg, state) {
7424
+ state.consecutiveErrors++;
7425
+ if (cfg.onError) {
7426
+ const [callbackErr, decision] = await catchError(Promise.resolve().then(() => cfg.onError(error, state.consecutiveErrors)));
7427
+ if (callbackErr) {
7428
+ if (cfg.label) {
7429
+ logger.warn(`[${cfg.logPrefix}] ${cfg.label} — onError callback threw: ${callbackErr.message}`);
7430
+ }
7431
+ } else if (decision === ErrorDecision.Abort) {
7432
+ return "abort";
7433
+ }
7434
+ }
7435
+ if (cfg.label) {
7436
+ const maxLabel = cfg.maxConsecutiveErrors === 0 ? "unlimited" : String(cfg.maxConsecutiveErrors);
7437
+ logger.warn(`[${cfg.logPrefix}] ${cfg.label} — ${errorSource} error (${state.consecutiveErrors}/${maxLabel}): ${error.message}, retrying...`);
7438
+ }
7439
+ if (cfg.maxConsecutiveErrors > 0 && state.consecutiveErrors >= cfg.maxConsecutiveErrors) {
7440
+ return "failed";
7441
+ }
7442
+ return;
7443
+ }
7444
+ function boundToDeadline(interval, deadline) {
7445
+ if (deadline > 0) {
7446
+ return Math.min(interval, Math.max(0, deadline - Date.now()));
7447
+ }
7448
+ return interval;
7449
+ }
7450
+ function computeSleepMs(cfg, ctx) {
7451
+ const interval = clampInterval(cfg.getInterval(ctx), cfg.label, cfg.logPrefix);
7452
+ return boundToDeadline(interval, cfg.deadline);
7453
+ }
7454
+ function computeErrorSleepMs(cfg, state, ctx) {
7455
+ if (cfg.getErrorInterval) {
7456
+ const interval = clampInterval(cfg.getErrorInterval(state.consecutiveErrors), cfg.label, cfg.logPrefix);
7457
+ return boundToDeadline(interval, cfg.deadline);
7458
+ }
7459
+ return computeSleepMs(cfg, ctx);
7460
+ }
7461
+ async function doSleep(ms, cfg) {
7462
+ if (ms > 0) {
7463
+ const [err] = await catchError(interruptibleSleep(ms, cfg.signal));
7464
+ if (err) {
7465
+ if (isAbortError(err))
7466
+ return;
7467
+ throw err;
7468
+ }
7469
+ }
7470
+ }
7471
+ function isAbortError(err) {
7472
+ if (!(err instanceof Error))
7473
+ return false;
7474
+ return err.name === "AbortError";
7475
+ }
7476
+ async function safeCallback(label, name, fn, prefix) {
7477
+ const [err] = await catchError(Promise.resolve().then(() => fn()));
7478
+ if (err && label) {
7479
+ logger.warn(`[${prefix}] ${label} — ${name} callback threw: ${err.message}`);
7480
+ }
7481
+ }
7482
+ async function processSuccessfulPoll(result, cfg, state) {
7483
+ state.consecutiveErrors = 0;
7484
+ if (cfg.onPoll) {
7485
+ await safeCallback(cfg.label, "onPoll", () => cfg.onPoll?.(result, elapsed(cfg)), cfg.logPrefix);
7486
+ }
7487
+ if (cfg.getStatus) {
7488
+ const getStatus = cfg.getStatus;
7489
+ const [statusErr, newStatus] = catchError(() => getStatus(result));
7490
+ if (statusErr) {
7491
+ if (cfg.label) {
7492
+ logger.warn(`[${cfg.logPrefix}] ${cfg.label} — getStatus threw: ${statusErr.message}`);
7493
+ }
7494
+ } else {
7495
+ if (state.lastStatus !== undefined && newStatus !== state.lastStatus) {
7496
+ const oldStatus = state.lastStatus ?? "";
7497
+ await safeCallback(cfg.label, "onStatusChange", () => cfg.onStatusChange?.(newStatus, oldStatus, result), cfg.logPrefix);
7498
+ if (cfg.label) {
7499
+ logger.info(`[${cfg.logPrefix}] ${cfg.label} — status changed: ${state.lastStatus} → ${newStatus}`);
7500
+ }
7501
+ }
7502
+ state.lastStatus = newStatus;
7503
+ }
7504
+ }
7505
+ logProgress(cfg, state);
7506
+ state.lastResult = result;
7507
+ state.pollCount++;
7508
+ }
7509
+ function logProgress(cfg, state) {
7510
+ if (!cfg.label || cfg.logIntervalMs <= 0)
7511
+ return;
7512
+ const now = elapsed(cfg);
7513
+ if (now - state.lastLogAt >= cfg.logIntervalMs) {
7514
+ const statusStr = state.lastStatus ? `status: ${state.lastStatus}, ` : "";
7515
+ logger.info(`[${cfg.logPrefix}] ${cfg.label} — ${statusStr}elapsed: ${msToDuration(now)}`);
7516
+ state.lastLogAt = now;
7517
+ }
7518
+ }
7519
+ function buildResult(data, outcome, cfg) {
7520
+ return { data, outcome, elapsedMs: elapsed(cfg) };
7521
+ }
7522
+ async function handleCompleted(result, cfg) {
7523
+ await safeCallback(cfg.label, "onComplete", () => cfg.onComplete?.(result, elapsed(cfg)), cfg.logPrefix);
7524
+ if (cfg.label) {
7525
+ let statusStr = "";
7526
+ if (cfg.getStatus) {
7527
+ const getStatus = cfg.getStatus;
7528
+ const [, status] = catchError(() => getStatus(result));
7529
+ if (status != null)
7530
+ statusStr = ` ${status}`;
7531
+ }
7532
+ logger.info(`[${cfg.logPrefix}] ${cfg.label} — reached terminal status:${statusStr} (took ${msToDuration(elapsed(cfg))})`);
7533
+ }
7534
+ return buildResult(result, PollOutcome.Completed, cfg);
7535
+ }
7536
+ async function handleTimeout(cfg, state) {
7537
+ await safeCallback(cfg.label, "onTimeout", () => cfg.onTimeout?.(state.lastResult, elapsed(cfg)), cfg.logPrefix);
7538
+ if (cfg.label) {
7539
+ const statusStr = state.lastStatus ? ` Last status: ${state.lastStatus}` : "";
7540
+ logger.info(`[${cfg.logPrefix}] ${cfg.label} — timed out after ${msToDuration(elapsed(cfg))}.${statusStr}`);
7541
+ }
7542
+ return buildResult(state.lastResult, PollOutcome.Timeout, cfg);
7543
+ }
7544
+ async function handleInterrupted(cfg, state) {
7545
+ await safeCallback(cfg.label, "onInterrupt", () => cfg.onInterrupt?.(state.lastResult, elapsed(cfg)), cfg.logPrefix);
7546
+ if (cfg.label) {
7547
+ const statusStr = state.lastStatus ? ` Last status: ${state.lastStatus}` : "";
7548
+ logger.info(`[${cfg.logPrefix}] ${cfg.label} — interrupted.${statusStr}`);
7549
+ }
7550
+ return buildResult(state.lastResult, PollOutcome.Interrupted, cfg);
7551
+ }
7552
+ function handleAborted(cfg, state, error) {
7553
+ const result = buildResult(state.lastResult, PollOutcome.Aborted, cfg);
7554
+ if (error) {
7555
+ result.error = error;
7556
+ }
7557
+ return result;
7558
+ }
7559
+ function handleFailed(cfg, state, error) {
7560
+ if (cfg.label) {
7561
+ logger.warn(`[${cfg.logPrefix}] ${cfg.label} — polling failed after ${state.consecutiveErrors} consecutive errors. Last error: ${truncateMessage(error.message)}`);
7562
+ }
7563
+ const result = buildResult(state.lastResult, PollOutcome.Failed, cfg);
7564
+ result.error = error;
7565
+ return result;
7566
+ }
7567
+ function setupSignalGuard(cfg, state) {
7568
+ const onAbort = () => {
7569
+ state.interrupted = true;
7570
+ };
7571
+ if (cfg.signal) {
7572
+ if (cfg.signal.aborted) {
7573
+ state.interrupted = true;
7574
+ } else {
7575
+ cfg.signal.addEventListener("abort", onAbort, { once: true });
7576
+ }
7577
+ }
7578
+ return {
7579
+ cleanup: () => {
7580
+ cfg.signal?.removeEventListener("abort", onAbort);
7581
+ }
7582
+ };
7583
+ }
7584
+ function logStart(options, cfg) {
7585
+ if (!cfg.label)
7586
+ return;
7587
+ let intervalDesc;
7588
+ if (typeof options.intervalMs === "function") {
7589
+ intervalDesc = "dynamic";
7590
+ } else {
7591
+ const [intervalErr, intervalVal] = catchError(() => cfg.getInterval({ pollCount: 0, elapsedMs: 0 }));
7592
+ intervalDesc = intervalErr ? "dynamic" : `${intervalVal}ms`;
7593
+ }
7594
+ const backoffDesc = options.backoff ? ", error backoff enabled" : "";
7595
+ const timeoutDesc = cfg.timeoutMs === 0 ? "none" : `${cfg.timeoutMs}ms`;
7596
+ logger.info(`[${cfg.logPrefix}] Waiting for ${cfg.label} — polling every ${intervalDesc}${backoffDesc}, timeout ${timeoutDesc}`);
7597
+ }
7598
+ function validateConfig(cfg) {
7599
+ if (cfg.maxConsecutiveErrors === 0 && cfg.timeoutMs === 0 && !cfg.signal) {
7600
+ logger.warn(`[${cfg.logPrefix}] Warning: no timeout, no error limit, and no abort signal — polling will continue indefinitely until terminal state.`);
7601
+ }
7602
+ }
7603
+ async function pollUntil(options) {
7604
+ const cfg = resolveConfig(options);
7605
+ const state = {
7606
+ pollCount: 0,
7607
+ consecutiveErrors: 0,
7608
+ lastResult: undefined,
7609
+ lastStatus: undefined,
7610
+ lastLogAt: 0,
7611
+ interrupted: false
7612
+ };
7613
+ validateConfig(cfg);
7614
+ const guard = setupSignalGuard(cfg, state);
7615
+ logStart(options, cfg);
7616
+ try {
7617
+ return await runPollLoop(cfg, state);
7618
+ } finally {
7619
+ guard.cleanup();
7620
+ }
7621
+ }
7622
+ async function runPollLoop(cfg, state) {
7623
+ while (!state.interrupted && !cfg.signal?.aborted) {
7624
+ if (isPastDeadline(cfg)) {
7625
+ return handleTimeout(cfg, state);
7626
+ }
7627
+ const ctx = buildContext(cfg, state);
7628
+ if (cfg.beforePoll) {
7629
+ const [beforePollErr] = await catchError(Promise.resolve().then(() => cfg.beforePoll?.(ctx)));
7630
+ if (beforePollErr) {
7631
+ const outcome = await handleErrorAndSleep(beforePollErr, "beforePoll", cfg, state, ctx);
7632
+ if (outcome)
7633
+ return outcome;
7634
+ continue;
7635
+ }
7636
+ }
7637
+ const [pollErr, result] = await catchError(cfg.fn());
7638
+ if (pollErr) {
7639
+ const outcome = await handleErrorAndSleep(pollErr, "poll", cfg, state, ctx);
7640
+ if (outcome)
7641
+ return outcome;
7642
+ continue;
7643
+ }
7644
+ await processSuccessfulPoll(result, cfg, state);
7645
+ const [untilErr, isTerminal] = catchError(() => cfg.until(result));
7646
+ if (untilErr) {
7647
+ const outcome = await handleErrorAndSleep(untilErr, "until", cfg, state, ctx);
7648
+ if (outcome)
7649
+ return outcome;
7650
+ continue;
7651
+ }
7652
+ if (isTerminal) {
7653
+ return handleCompleted(result, cfg);
7654
+ }
7655
+ const sleepCtx = buildContext(cfg, state);
7656
+ await doSleep(computeSleepMs(cfg, sleepCtx), cfg);
7657
+ }
7658
+ return handleInterrupted(cfg, state);
7659
+ }
7660
+ async function handleErrorAndSleep(error, source, cfg, state, ctx) {
7661
+ const decision = await handlePollError(error, source, cfg, state);
7662
+ if (decision === "abort") {
7663
+ return handleAborted(cfg, state, error);
7664
+ }
7665
+ if (decision === "failed") {
7666
+ return handleFailed(cfg, state, error);
7667
+ }
7668
+ if (isPastDeadline(cfg)) {
7669
+ return handleTimeout(cfg, state);
7670
+ }
7671
+ await doSleep(computeErrorSleepMs(cfg, state, ctx), cfg);
7672
+ return;
7673
+ }
7674
+ // src/polling/terminal-statuses.ts
7675
+ var TERMINAL_STATUSES = new Set([
7676
+ "completed",
7677
+ "successful",
7678
+ "faulted",
7679
+ "failed",
7680
+ "cancelled",
7681
+ "canceled",
7682
+ "stopped",
7683
+ "finished"
7684
+ ]);
7685
+ var FAILURE_STATUSES = new Set([
7686
+ "faulted",
7687
+ "failed",
7688
+ "cancelled",
7689
+ "canceled",
7690
+ "stopped"
7691
+ ]);
7692
+ function isTerminalStatus(status) {
7693
+ return TERMINAL_STATUSES.has(status.toLowerCase());
7694
+ }
7695
+ function isFailureStatus(status) {
7696
+ return FAILURE_STATUSES.has(status.toLowerCase());
7697
+ }
7698
+ function isSuccessStatus(status) {
7699
+ return isTerminalStatus(status) && !isFailureStatus(status);
7700
+ }
7071
7701
  // src/tool-provider.ts
7072
7702
  var toolProvider;
7073
7703
  function setToolProvider(provider) {
@@ -7081,11 +7711,18 @@ async function ensureToolAvailable(verb) {
7081
7711
  }
7082
7712
  // src/trackedAction.ts
7083
7713
  import { Command } from "commander";
7714
+ var POLL_SIGNAL_KEY = Symbol.for("@uipath/common/poll-signal");
7084
7715
  var processContext = {
7085
7716
  exit: (code) => {
7086
7717
  process.exitCode = code;
7718
+ },
7719
+ get pollSignal() {
7720
+ return globalThis[POLL_SIGNAL_KEY];
7087
7721
  }
7088
7722
  };
7723
+ function setProcessContextPollSignal(signal) {
7724
+ globalThis[POLL_SIGNAL_KEY] = signal;
7725
+ }
7089
7726
  function deriveCommandPath(cmd) {
7090
7727
  const parts = [];
7091
7728
  let current = cmd;
@@ -7143,6 +7780,7 @@ export {
7143
7780
  telemetryFlushAndShutdown,
7144
7781
  telemetry,
7145
7782
  setToolProvider,
7783
+ setProcessContextPollSignal,
7146
7784
  setOutputFormat,
7147
7785
  setOutputFilter,
7148
7786
  setGlobalTelemetryProperties,
@@ -7150,11 +7788,18 @@ export {
7150
7788
  setGlobalLogFilePath,
7151
7789
  sessionId,
7152
7790
  runWithSink,
7791
+ restoreConsole,
7153
7792
  registerHelpAll,
7154
7793
  readRegistryValue,
7155
7794
  processContext,
7795
+ pollUntil,
7796
+ msToDuration,
7156
7797
  logger,
7798
+ isTerminalStatus,
7157
7799
  isTelemetryDisabled,
7800
+ isSuccessStatus,
7801
+ isFailureStatus,
7802
+ installConsoleGuard,
7158
7803
  getOutputSink,
7159
7804
  getOutputFormat,
7160
7805
  getOutputFilter,
@@ -7162,22 +7807,30 @@ export {
7162
7807
  getGlobalLogFilePath,
7163
7808
  formatHelpAll,
7164
7809
  extractFormatFromArgs,
7810
+ extractErrorMessageSync,
7811
+ extractErrorMessage,
7812
+ extractErrorDetails,
7165
7813
  extractCommandHelp,
7166
7814
  evaluateJsonPath,
7167
7815
  ensureToolAvailable,
7168
7816
  deriveCommandPath,
7169
7817
  createTelemetryProvider,
7818
+ createPollAbortController,
7170
7819
  createAppInsightsProvider,
7171
7820
  configureLogger,
7172
7821
  collectCommands,
7173
7822
  catchError,
7174
7823
  UIPATH_HOME_DIR,
7175
7824
  SuccessOutput,
7825
+ PollOutcome,
7826
+ POLL_DEFAULTS,
7176
7827
  OutputFormatter,
7828
+ MIN_INTERVAL_MS,
7177
7829
  LogLevel,
7178
7830
  LOCAL_CONFIG_FILENAME,
7179
7831
  JsonPathError,
7180
7832
  FailureOutput,
7833
+ ErrorDecision,
7181
7834
  DEFAULT_REDIRECT_URI,
7182
7835
  DEFAULT_PAGE_SIZE,
7183
7836
  DEFAULT_LOG_LEVEL,
@@ -7186,5 +7839,6 @@ export {
7186
7839
  DEFAULT_AUTH_TIMEOUT_MS,
7187
7840
  CommonTelemetryEvents,
7188
7841
  CONFIG_FILENAME,
7842
+ BACKOFF_DEFAULTS,
7189
7843
  AUTH_FILENAME
7190
7844
  };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@uipath/common",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Common infrastructure needed by uipcli tools.",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/UiPath/uipcli.git",
7
+ "url": "https://github.com/UiPath/cli.git",
8
8
  "directory": "packages/common"
9
9
  },
10
10
  "publishConfig": {
@@ -24,23 +24,24 @@
24
24
  "vlad-uipath"
25
25
  ],
26
26
  "scripts": {
27
- "build": "bun build ./src/index.ts --outdir dist --format esm --target node --external commander --external applicationinsights",
27
+ "build": "bun build ./src/index.ts --outdir dist --format esm --target node --external commander --external applicationinsights --external @uipath/telemetry",
28
28
  "lint": "biome check .",
29
29
  "test": "vitest run",
30
30
  "test:coverage": "vitest run --coverage"
31
31
  },
32
32
  "dependencies": {
33
33
  "@jmespath-community/jmespath": "^1.3.0",
34
- "@uipath/telemetry": "0.0.5",
35
34
  "js-yaml": "^4.1.0",
36
35
  "jsonpath-plus": "^10.4.0"
37
36
  },
38
37
  "devDependencies": {
38
+ "@uipath/telemetry": "workspace:*",
39
39
  "@types/js-yaml": "^4.0.9",
40
40
  "@types/node": "^25.2.3",
41
41
  "typescript": "^5"
42
42
  },
43
43
  "peerDependencies": {
44
+ "@uipath/telemetry": "^0.0.6",
44
45
  "commander": "^14.0.3"
45
46
  }
46
47
  }