@uipath/functions-tool 1.1.0 → 1.195.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/tool.js +497 -105
  2. package/package.json +32 -40
package/dist/tool.js CHANGED
@@ -3,7 +3,8 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@uipath/functions-tool",
6
- version: "1.1.0",
6
+ license: "MIT",
7
+ version: "1.195.0",
7
8
  description: "UiPath CLI tool for JS/TS and Python Functions — thin passthrough to uipath-functions / uipath",
8
9
  keywords: [
9
10
  "uipcli-tool",
@@ -52,6 +53,7 @@ var package_default = {
52
53
 
53
54
  // ../common/dist/index.js
54
55
  import { createRequire as createRequire2 } from "node:module";
56
+ import { randomUUID } from "node:crypto";
55
57
  import { existsSync } from "node:fs";
56
58
  import * as fs6 from "node:fs/promises";
57
59
  import * as os2 from "node:os";
@@ -2743,6 +2745,12 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
2743
2745
  darwin: "Safari"
2744
2746
  }));
2745
2747
  var open_default = open;
2748
+ var LOCK_HEARTBEAT_MS = 5000;
2749
+ var LOCK_STALE_MS = 15000;
2750
+ var LOCK_MAX_WAIT_MS = 20000;
2751
+ var LOCK_MAX_HOLD_MS = 60000;
2752
+ var LOCK_RETRY_MIN_MS = 100;
2753
+ var LOCK_RETRY_JITTER_MS = 200;
2746
2754
 
2747
2755
  class NodeFileSystem {
2748
2756
  path = {
@@ -2820,6 +2828,90 @@ class NodeFileSystem {
2820
2828
  async mkdir(dirPath) {
2821
2829
  await fs6.mkdir(dirPath, { recursive: true });
2822
2830
  }
2831
+ async acquireLock(lockPath) {
2832
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
2833
+ const lockFile = `${canonicalPath}.lock`;
2834
+ const ownerId = randomUUID();
2835
+ const start = Date.now();
2836
+ while (true) {
2837
+ try {
2838
+ await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
2839
+ return this.createLockRelease(lockFile, ownerId);
2840
+ } catch (error) {
2841
+ if (!this.hasErrnoCode(error, "EEXIST")) {
2842
+ throw error;
2843
+ }
2844
+ const stats = await fs6.stat(lockFile).catch(() => null);
2845
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
2846
+ const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
2847
+ if (reclaimed)
2848
+ continue;
2849
+ }
2850
+ if (Date.now() - start > LOCK_MAX_WAIT_MS) {
2851
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
2852
+ }
2853
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
2854
+ }
2855
+ }
2856
+ }
2857
+ async canonicalizeLockTarget(lockPath) {
2858
+ const absolute = path2.resolve(lockPath);
2859
+ const fullReal = await fs6.realpath(absolute).catch(() => null);
2860
+ if (fullReal)
2861
+ return fullReal;
2862
+ const parent = path2.dirname(absolute);
2863
+ const base = path2.basename(absolute);
2864
+ const canonicalParent = await fs6.realpath(parent).catch(() => parent);
2865
+ return path2.join(canonicalParent, base);
2866
+ }
2867
+ createLockRelease(lockFile, ownerId) {
2868
+ const heartbeatStart = Date.now();
2869
+ let heartbeatTimer;
2870
+ let stopped = false;
2871
+ const stopHeartbeat = () => {
2872
+ stopped = true;
2873
+ if (heartbeatTimer)
2874
+ clearTimeout(heartbeatTimer);
2875
+ };
2876
+ const scheduleNextHeartbeat = () => {
2877
+ if (stopped)
2878
+ return;
2879
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
2880
+ stopped = true;
2881
+ return;
2882
+ }
2883
+ heartbeatTimer = setTimeout(() => {
2884
+ runHeartbeat();
2885
+ }, LOCK_HEARTBEAT_MS);
2886
+ heartbeatTimer.unref?.();
2887
+ };
2888
+ const runHeartbeat = async () => {
2889
+ if (stopped)
2890
+ return;
2891
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2892
+ if (stopped)
2893
+ return;
2894
+ if (current !== ownerId) {
2895
+ stopped = true;
2896
+ return;
2897
+ }
2898
+ const now = Date.now() / 1000;
2899
+ await fs6.utimes(lockFile, now, now).catch(() => {});
2900
+ scheduleNextHeartbeat();
2901
+ };
2902
+ scheduleNextHeartbeat();
2903
+ let released = false;
2904
+ return async () => {
2905
+ if (released)
2906
+ return;
2907
+ released = true;
2908
+ stopHeartbeat();
2909
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2910
+ if (current === ownerId) {
2911
+ await fs6.rm(lockFile, { force: true });
2912
+ }
2913
+ };
2914
+ }
2823
2915
  async rm(filePath) {
2824
2916
  await fs6.rm(filePath, { recursive: true, force: true });
2825
2917
  }
@@ -2865,7 +2957,10 @@ class NodeFileSystem {
2865
2957
  }
2866
2958
  }
2867
2959
  isEnoent(error) {
2868
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
2960
+ return this.hasErrnoCode(error, "ENOENT");
2961
+ }
2962
+ hasErrnoCode(error, code) {
2963
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
2869
2964
  }
2870
2965
  }
2871
2966
  var fsInstance = new NodeFileSystem;
@@ -8013,6 +8108,60 @@ function escapeNonAscii(jsonText) {
8013
8108
  function needsAsciiSafeJson(sink) {
8014
8109
  return process.platform === "win32" && !sink.capabilities.isInteractive;
8015
8110
  }
8111
+ function isPlainRecord(value) {
8112
+ if (value === null || typeof value !== "object")
8113
+ return false;
8114
+ const prototype = Object.getPrototypeOf(value);
8115
+ return prototype === Object.prototype || prototype === null;
8116
+ }
8117
+ function toLowerCamelCaseKey(key) {
8118
+ if (!key)
8119
+ return key;
8120
+ if (/[_\-\s]/.test(key)) {
8121
+ const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
8122
+ if (!firstPart)
8123
+ return key;
8124
+ return [
8125
+ toLowerCamelCaseSimpleKey(firstPart),
8126
+ ...restParts.map((part) => {
8127
+ const normalized = toLowerCamelCaseSimpleKey(part);
8128
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
8129
+ })
8130
+ ].join("");
8131
+ }
8132
+ return toLowerCamelCaseSimpleKey(key);
8133
+ }
8134
+ function toLowerCamelCaseSimpleKey(key) {
8135
+ if (/^[A-Z0-9]+$/.test(key))
8136
+ return key.toLowerCase();
8137
+ return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
8138
+ }
8139
+ function toPascalCaseKey(key) {
8140
+ const lowerCamelKey = toLowerCamelCaseKey(key);
8141
+ return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
8142
+ }
8143
+ function toPascalCaseData(value) {
8144
+ if (Array.isArray(value))
8145
+ return value.map(toPascalCaseData);
8146
+ if (!isPlainRecord(value))
8147
+ return value;
8148
+ const result = {};
8149
+ for (const [key, nestedValue] of Object.entries(value)) {
8150
+ result[toPascalCaseKey(key)] = toPascalCaseData(nestedValue);
8151
+ }
8152
+ return result;
8153
+ }
8154
+ function normalizeDataKeys(data) {
8155
+ return toPascalCaseData(data);
8156
+ }
8157
+ function normalizeOutputKeys(data) {
8158
+ const result = {};
8159
+ for (const [key, value] of Object.entries(data)) {
8160
+ const pascalKey = toPascalCaseKey(key);
8161
+ result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData(value);
8162
+ }
8163
+ return result;
8164
+ }
8016
8165
  function printOutput(data, format2 = "json", logFn, asciiSafe = false) {
8017
8166
  if (!data) {
8018
8167
  logFn("Empty response object. No data to display.");
@@ -8075,7 +8224,7 @@ function wrapText(text, width) {
8075
8224
  function printTable(data, logFn, externalLogValue) {
8076
8225
  if (data.length === 0)
8077
8226
  return;
8078
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
8227
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
8079
8228
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
8080
8229
  const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
8081
8230
  logFn(header);
@@ -8090,7 +8239,7 @@ function printTable(data, logFn, externalLogValue) {
8090
8239
  }
8091
8240
  }
8092
8241
  function printVerticalTable(data, logFn = console.log, externalLogValue) {
8093
- const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
8242
+ const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
8094
8243
  if (keys.length === 0)
8095
8244
  return;
8096
8245
  const maxKeyWidth = Math.max(...keys.map((key) => key.length));
@@ -8106,7 +8255,7 @@ function printVerticalTable(data, logFn = console.log, externalLogValue) {
8106
8255
  function printResizableTable(data, logFn = console.log, externalLogValue) {
8107
8256
  if (data.length === 0)
8108
8257
  return;
8109
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
8258
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
8110
8259
  if (keys.length === 0)
8111
8260
  return;
8112
8261
  if (!process.stdout.isTTY) {
@@ -8182,8 +8331,26 @@ function printResizableTable(data, logFn = console.log, externalLogValue) {
8182
8331
  function toYaml(data) {
8183
8332
  return dump(data);
8184
8333
  }
8334
+ class FilterEvaluationError extends Error {
8335
+ __brand = "FilterEvaluationError";
8336
+ filter;
8337
+ instructions;
8338
+ result = RESULTS.ValidationError;
8339
+ constructor(filter, cause) {
8340
+ const underlying = cause instanceof Error ? cause.message : String(cause);
8341
+ super(`Filter '${filter}' failed to evaluate: ${underlying}`);
8342
+ this.name = "FilterEvaluationError";
8343
+ this.filter = filter;
8344
+ this.instructions = `The --output-filter expression '${filter}' failed at evaluation time. ` + "Note that --output-filter operates on the 'Data' field of the envelope, not the full object. " + "For example, on a list result use 'length(@)' instead of 'Data | length(@)'.";
8345
+ }
8346
+ }
8185
8347
  function applyFilter(data, filter) {
8186
- const result = search(data, filter);
8348
+ let result;
8349
+ try {
8350
+ result = search(data, filter);
8351
+ } catch (err) {
8352
+ throw new FilterEvaluationError(filter, err);
8353
+ }
8187
8354
  if (result == null)
8188
8355
  return [];
8189
8356
  if (Array.isArray(result)) {
@@ -8200,13 +8367,18 @@ function applyFilter(data, filter) {
8200
8367
  }
8201
8368
  var OutputFormatter;
8202
8369
  ((OutputFormatter2) => {
8203
- function success(data) {
8370
+ function success(data, options) {
8204
8371
  data.Log ??= getLogFilePath() || undefined;
8372
+ const normalize = !options?.preserveDataKeys;
8373
+ if (normalize) {
8374
+ data.Data = normalizeDataKeys(data.Data);
8375
+ }
8205
8376
  const filter = getOutputFilter();
8206
8377
  if (filter) {
8207
- data.Data = applyFilter(data.Data, filter);
8378
+ const filtered = applyFilter(data.Data, filter);
8379
+ data.Data = normalize ? normalizeDataKeys(filtered) : filtered;
8208
8380
  }
8209
- logOutput(data, getOutputFormat());
8381
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
8210
8382
  }
8211
8383
  OutputFormatter2.success = success;
8212
8384
  function error(data) {
@@ -8216,7 +8388,7 @@ var OutputFormatter;
8216
8388
  result: data.Result,
8217
8389
  message: data.Message
8218
8390
  });
8219
- logOutput(data, getOutputFormat());
8391
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
8220
8392
  }
8221
8393
  OutputFormatter2.error = error;
8222
8394
  function emitList(code, items, opts) {
@@ -8237,13 +8409,14 @@ var OutputFormatter;
8237
8409
  function log(data) {
8238
8410
  const format2 = getOutputFormat();
8239
8411
  const sink = getOutputSink();
8412
+ const normalized = toPascalCaseData(data);
8240
8413
  if (format2 === "json") {
8241
- const json2 = JSON.stringify(data);
8414
+ const json2 = JSON.stringify(normalized);
8242
8415
  const safe = needsAsciiSafeJson(sink) ? escapeNonAscii(json2) : json2;
8243
8416
  sink.writeErr(`${safe}
8244
8417
  `);
8245
8418
  } else {
8246
- for (const [key, value] of Object.entries(data)) {
8419
+ for (const [key, value] of Object.entries(normalized)) {
8247
8420
  sink.writeErr(`${key}: ${value}
8248
8421
  `);
8249
8422
  }
@@ -8252,12 +8425,16 @@ var OutputFormatter;
8252
8425
  OutputFormatter2.log = log;
8253
8426
  function formatToString(data) {
8254
8427
  const filter = getOutputFilter();
8255
- if (filter && "Data" in data && data.Data != null) {
8256
- data.Data = applyFilter(data.Data, filter);
8428
+ if ("Data" in data && data.Data != null) {
8429
+ data.Data = normalizeDataKeys(data.Data);
8430
+ if (filter) {
8431
+ data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
8432
+ }
8257
8433
  }
8434
+ const output = normalizeOutputKeys(data);
8258
8435
  const lines = [];
8259
8436
  const sink = getOutputSink();
8260
- printOutput(data, getOutputFormat(), (msg) => {
8437
+ printOutput(output, getOutputFormat(), (msg) => {
8261
8438
  lines.push(msg);
8262
8439
  }, needsAsciiSafeJson(sink));
8263
8440
  return lines.join(`
@@ -9681,6 +9858,19 @@ function warnDeprecatedTenantOption(tenant) {
9681
9858
  return;
9682
9859
  warnDeprecatedOptionAlias("--tenant", TENANT_SWITCH_COMMAND);
9683
9860
  }
9861
+ var PollOutcome = {
9862
+ Completed: "completed",
9863
+ Timeout: "timeout",
9864
+ Interrupted: "interrupted",
9865
+ Aborted: "aborted",
9866
+ Failed: "failed"
9867
+ };
9868
+ var REASON_BY_OUTCOME = {
9869
+ [PollOutcome.Timeout]: "poll_timeout",
9870
+ [PollOutcome.Failed]: "poll_failed",
9871
+ [PollOutcome.Interrupted]: "poll_failed",
9872
+ [PollOutcome.Aborted]: "poll_aborted"
9873
+ };
9684
9874
  var TERMINAL_STATUSES = new Set([
9685
9875
  "completed",
9686
9876
  "successful",
@@ -9706,6 +9896,7 @@ var ScreenLogger;
9706
9896
  }
9707
9897
  ScreenLogger2.progress = progress;
9708
9898
  })(ScreenLogger ||= {});
9899
+ var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
9709
9900
  var factorySlot = singleton("PackagerFactoryProvider");
9710
9901
  var REDACTED = "[REDACTED]";
9711
9902
  var MAX_VALUE_LENGTH = 200;
@@ -9884,13 +10075,17 @@ Command.prototype.trackedAction = function(context, fn, properties) {
9884
10075
  const [error] = await catchError(fn(...args));
9885
10076
  if (error) {
9886
10077
  errorMessage = error instanceof Error ? error.message : String(error);
9887
- logger.error(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
10078
+ logger.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
10079
+ const typed = error;
10080
+ const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
10081
+ const customResult = typeof typed.result === "string" && typed.result !== RESULTS.Success && Object.values(RESULTS).includes(typed.result) ? typed.result : undefined;
10082
+ const finalResult = customResult ?? RESULTS.Failure;
9888
10083
  OutputFormatter.error({
9889
- Result: RESULTS.Failure,
10084
+ Result: finalResult,
9890
10085
  Message: errorMessage,
9891
- Instructions: "An unexpected error occurred. Run with --log-level debug for details."
10086
+ Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
9892
10087
  });
9893
- context.exit(1);
10088
+ context.exit(EXIT_CODES[finalResult]);
9894
10089
  }
9895
10090
  const durationMs = performance.now() - startTime;
9896
10091
  const success = !error && (process.exitCode === undefined || process.exitCode === 0);
@@ -9905,6 +10100,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
9905
10100
  };
9906
10101
 
9907
10102
  // ../filesystem/dist/index.js
10103
+ import { randomUUID as randomUUID2 } from "node:crypto";
9908
10104
  import { existsSync as existsSync2 } from "node:fs";
9909
10105
  import * as fs62 from "node:fs/promises";
9910
10106
  import * as os22 from "node:os";
@@ -10481,6 +10677,12 @@ defineLazyProperty2(apps2, "safari", () => detectPlatformBinary2({
10481
10677
  darwin: "Safari"
10482
10678
  }));
10483
10679
  var open_default2 = open2;
10680
+ var LOCK_HEARTBEAT_MS2 = 5000;
10681
+ var LOCK_STALE_MS2 = 15000;
10682
+ var LOCK_MAX_WAIT_MS2 = 20000;
10683
+ var LOCK_MAX_HOLD_MS2 = 60000;
10684
+ var LOCK_RETRY_MIN_MS2 = 100;
10685
+ var LOCK_RETRY_JITTER_MS2 = 200;
10484
10686
 
10485
10687
  class NodeFileSystem2 {
10486
10688
  path = {
@@ -10558,6 +10760,90 @@ class NodeFileSystem2 {
10558
10760
  async mkdir(dirPath) {
10559
10761
  await fs62.mkdir(dirPath, { recursive: true });
10560
10762
  }
10763
+ async acquireLock(lockPath) {
10764
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
10765
+ const lockFile = `${canonicalPath}.lock`;
10766
+ const ownerId = randomUUID2();
10767
+ const start = Date.now();
10768
+ while (true) {
10769
+ try {
10770
+ await fs62.writeFile(lockFile, ownerId, { flag: "wx" });
10771
+ return this.createLockRelease(lockFile, ownerId);
10772
+ } catch (error) {
10773
+ if (!this.hasErrnoCode(error, "EEXIST")) {
10774
+ throw error;
10775
+ }
10776
+ const stats = await fs62.stat(lockFile).catch(() => null);
10777
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS2) {
10778
+ const reclaimed = await fs62.rm(lockFile, { force: true }).then(() => true).catch(() => false);
10779
+ if (reclaimed)
10780
+ continue;
10781
+ }
10782
+ if (Date.now() - start > LOCK_MAX_WAIT_MS2) {
10783
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
10784
+ }
10785
+ await new Promise((resolve22) => setTimeout(resolve22, LOCK_RETRY_MIN_MS2 + Math.random() * LOCK_RETRY_JITTER_MS2));
10786
+ }
10787
+ }
10788
+ }
10789
+ async canonicalizeLockTarget(lockPath) {
10790
+ const absolute = path22.resolve(lockPath);
10791
+ const fullReal = await fs62.realpath(absolute).catch(() => null);
10792
+ if (fullReal)
10793
+ return fullReal;
10794
+ const parent = path22.dirname(absolute);
10795
+ const base = path22.basename(absolute);
10796
+ const canonicalParent = await fs62.realpath(parent).catch(() => parent);
10797
+ return path22.join(canonicalParent, base);
10798
+ }
10799
+ createLockRelease(lockFile, ownerId) {
10800
+ const heartbeatStart = Date.now();
10801
+ let heartbeatTimer;
10802
+ let stopped = false;
10803
+ const stopHeartbeat = () => {
10804
+ stopped = true;
10805
+ if (heartbeatTimer)
10806
+ clearTimeout(heartbeatTimer);
10807
+ };
10808
+ const scheduleNextHeartbeat = () => {
10809
+ if (stopped)
10810
+ return;
10811
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS2) {
10812
+ stopped = true;
10813
+ return;
10814
+ }
10815
+ heartbeatTimer = setTimeout(() => {
10816
+ runHeartbeat();
10817
+ }, LOCK_HEARTBEAT_MS2);
10818
+ heartbeatTimer.unref?.();
10819
+ };
10820
+ const runHeartbeat = async () => {
10821
+ if (stopped)
10822
+ return;
10823
+ const current = await fs62.readFile(lockFile, "utf-8").catch(() => null);
10824
+ if (stopped)
10825
+ return;
10826
+ if (current !== ownerId) {
10827
+ stopped = true;
10828
+ return;
10829
+ }
10830
+ const now = Date.now() / 1000;
10831
+ await fs62.utimes(lockFile, now, now).catch(() => {});
10832
+ scheduleNextHeartbeat();
10833
+ };
10834
+ scheduleNextHeartbeat();
10835
+ let released = false;
10836
+ return async () => {
10837
+ if (released)
10838
+ return;
10839
+ released = true;
10840
+ stopHeartbeat();
10841
+ const current = await fs62.readFile(lockFile, "utf-8").catch(() => null);
10842
+ if (current === ownerId) {
10843
+ await fs62.rm(lockFile, { force: true });
10844
+ }
10845
+ };
10846
+ }
10561
10847
  async rm(filePath) {
10562
10848
  await fs62.rm(filePath, { recursive: true, force: true });
10563
10849
  }
@@ -10603,7 +10889,10 @@ class NodeFileSystem2 {
10603
10889
  }
10604
10890
  }
10605
10891
  isEnoent(error) {
10606
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
10892
+ return this.hasErrnoCode(error, "ENOENT");
10893
+ }
10894
+ hasErrnoCode(error, code) {
10895
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
10607
10896
  }
10608
10897
  }
10609
10898
  var fsInstance2 = new NodeFileSystem2;
@@ -10701,7 +10990,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
10701
10990
  import { execSync as execSync22 } from "node:child_process";
10702
10991
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync5, readdirSync as readdirSync2, rmSync, statSync, writeFileSync as writeFileSync8 } from "node:fs";
10703
10992
  import { join as join9, resolve as resolve4 } from "node:path";
10704
- import { randomUUID as randomUUID2 } from "node:crypto";
10993
+ import { randomUUID as randomUUID22 } from "node:crypto";
10705
10994
  import { createRequire as createRequire32 } from "module";
10706
10995
  import { existsSync as existsSync5 } from "node:fs";
10707
10996
  import * as fs63 from "node:fs/promises";
@@ -10738,7 +11027,7 @@ import { execFile as execFile53 } from "node:child_process";
10738
11027
  import process73 from "node:process";
10739
11028
  import { createRequire as createRequire4 } from "node:module";
10740
11029
  import { register } from "node:module";
10741
- import { randomUUID } from "node:crypto";
11030
+ import { randomUUID as randomUUID3 } from "node:crypto";
10742
11031
  import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync7 } from "node:fs";
10743
11032
  import { join as join8 } from "node:path";
10744
11033
  import { pathToFileURL } from "node:url";
@@ -14646,7 +14935,7 @@ ${msg}`);
14646
14935
  $id: "entry-points.json",
14647
14936
  entryPoints: manifest.endpoints.map((ep) => ({
14648
14937
  filePath: "content/" + ep.functionPath,
14649
- uniqueId: existingIds.get("content/" + ep.functionPath) ?? randomUUID(),
14938
+ uniqueId: existingIds.get("content/" + ep.functionPath) ?? randomUUID3(),
14650
14939
  type: "function",
14651
14940
  input: ep.inputSchema ?? { type: "object" },
14652
14941
  output: ep.outputSchema ?? { type: "object" }
@@ -14676,8 +14965,8 @@ ${msg}`);
14676
14965
  version: "2.0",
14677
14966
  resources: manifest.endpoints.map((ep) => {
14678
14967
  const existing = existingBindings.get(`${ep.method}:${ep.path}`);
14679
- const bindingKey = existing?.key ?? randomUUID();
14680
- const bindingId = existing?.id ?? randomUUID();
14968
+ const bindingKey = existing?.key ?? randomUUID3();
14969
+ const bindingId = existing?.id ?? randomUUID3();
14681
14970
  const entryPointUniqueId = entryPointIdByPath.get("content/" + ep.functionPath);
14682
14971
  if (!entryPointUniqueId) {
14683
14972
  throw new Error(`Internal error: binding for "${ep.method} ${ep.path}" references entry point "content/${ep.functionPath}", which is missing from entry-points.json.`);
@@ -14723,7 +15012,7 @@ function registerPackCommand(program22) {
14723
15012
  const packageId = (packageJson.name ?? "functions").replace(/[^a-zA-Z0-9._-]/g, "") || "functions";
14724
15013
  const version = packageJson.version ?? "1.0.0";
14725
15014
  if (!uipathJson.projectId) {
14726
- uipathJson.projectId = randomUUID2();
15015
+ uipathJson.projectId = randomUUID22();
14727
15016
  writeFileSync8(uipathJsonPath, JSON.stringify(uipathJson, null, 2), "utf-8");
14728
15017
  }
14729
15018
  setupRunDependencies(cwd);
@@ -15409,6 +15698,7 @@ import path6 from "node:path";
15409
15698
  import { fileURLToPath as fileURLToPath4 } from "node:url";
15410
15699
  import childProcess34 from "node:child_process";
15411
15700
  import fs54, { constants as fsConstants24 } from "node:fs/promises";
15701
+ import { randomUUID as randomUUID4 } from "node:crypto";
15412
15702
  import { existsSync as existsSync11 } from "node:fs";
15413
15703
  import * as fs64 from "node:fs/promises";
15414
15704
  import * as os24 from "node:os";
@@ -16146,6 +16436,90 @@ class NodeFileSystem4 {
16146
16436
  async mkdir(dirPath) {
16147
16437
  await fs64.mkdir(dirPath, { recursive: true });
16148
16438
  }
16439
+ async acquireLock(lockPath) {
16440
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
16441
+ const lockFile = `${canonicalPath}.lock`;
16442
+ const ownerId = randomUUID4();
16443
+ const start = Date.now();
16444
+ while (true) {
16445
+ try {
16446
+ await fs64.writeFile(lockFile, ownerId, { flag: "wx" });
16447
+ return this.createLockRelease(lockFile, ownerId);
16448
+ } catch (error) {
16449
+ if (!this.hasErrnoCode(error, "EEXIST")) {
16450
+ throw error;
16451
+ }
16452
+ const stats = await fs64.stat(lockFile).catch(() => null);
16453
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS3) {
16454
+ const reclaimed = await fs64.rm(lockFile, { force: true }).then(() => true).catch(() => false);
16455
+ if (reclaimed)
16456
+ continue;
16457
+ }
16458
+ if (Date.now() - start > LOCK_MAX_WAIT_MS3) {
16459
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
16460
+ }
16461
+ await new Promise((resolve23) => setTimeout(resolve23, LOCK_RETRY_MIN_MS3 + Math.random() * LOCK_RETRY_JITTER_MS3));
16462
+ }
16463
+ }
16464
+ }
16465
+ async canonicalizeLockTarget(lockPath) {
16466
+ const absolute = path24.resolve(lockPath);
16467
+ const fullReal = await fs64.realpath(absolute).catch(() => null);
16468
+ if (fullReal)
16469
+ return fullReal;
16470
+ const parent = path24.dirname(absolute);
16471
+ const base = path24.basename(absolute);
16472
+ const canonicalParent = await fs64.realpath(parent).catch(() => parent);
16473
+ return path24.join(canonicalParent, base);
16474
+ }
16475
+ createLockRelease(lockFile, ownerId) {
16476
+ const heartbeatStart = Date.now();
16477
+ let heartbeatTimer;
16478
+ let stopped = false;
16479
+ const stopHeartbeat = () => {
16480
+ stopped = true;
16481
+ if (heartbeatTimer)
16482
+ clearTimeout(heartbeatTimer);
16483
+ };
16484
+ const scheduleNextHeartbeat = () => {
16485
+ if (stopped)
16486
+ return;
16487
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS3) {
16488
+ stopped = true;
16489
+ return;
16490
+ }
16491
+ heartbeatTimer = setTimeout(() => {
16492
+ runHeartbeat();
16493
+ }, LOCK_HEARTBEAT_MS3);
16494
+ heartbeatTimer.unref?.();
16495
+ };
16496
+ const runHeartbeat = async () => {
16497
+ if (stopped)
16498
+ return;
16499
+ const current = await fs64.readFile(lockFile, "utf-8").catch(() => null);
16500
+ if (stopped)
16501
+ return;
16502
+ if (current !== ownerId) {
16503
+ stopped = true;
16504
+ return;
16505
+ }
16506
+ const now = Date.now() / 1000;
16507
+ await fs64.utimes(lockFile, now, now).catch(() => {});
16508
+ scheduleNextHeartbeat();
16509
+ };
16510
+ scheduleNextHeartbeat();
16511
+ let released = false;
16512
+ return async () => {
16513
+ if (released)
16514
+ return;
16515
+ released = true;
16516
+ stopHeartbeat();
16517
+ const current = await fs64.readFile(lockFile, "utf-8").catch(() => null);
16518
+ if (current === ownerId) {
16519
+ await fs64.rm(lockFile, { force: true });
16520
+ }
16521
+ };
16522
+ }
16149
16523
  async rm(filePath) {
16150
16524
  await fs64.rm(filePath, { recursive: true, force: true });
16151
16525
  }
@@ -16191,9 +16565,18 @@ class NodeFileSystem4 {
16191
16565
  }
16192
16566
  }
16193
16567
  isEnoent(error) {
16194
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
16568
+ return this.hasErrnoCode(error, "ENOENT");
16569
+ }
16570
+ hasErrnoCode(error, code) {
16571
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
16195
16572
  }
16196
16573
  }
16574
+ var LOCK_HEARTBEAT_MS3 = 5000;
16575
+ var LOCK_STALE_MS3 = 15000;
16576
+ var LOCK_MAX_WAIT_MS3 = 20000;
16577
+ var LOCK_MAX_HOLD_MS3 = 60000;
16578
+ var LOCK_RETRY_MIN_MS3 = 100;
16579
+ var LOCK_RETRY_JITTER_MS3 = 200;
16197
16580
  var init_node = __esm(() => {
16198
16581
  init_open();
16199
16582
  });
@@ -16205,7 +16588,7 @@ var init_src = __esm(() => {
16205
16588
  fsInstance4 = new NodeFileSystem4;
16206
16589
  });
16207
16590
  var require_coreipc = __commonJS3((exports, module) => {
16208
- var __dirname4 = "/Users/alexandru.oltean/github/cli/node_modules/@uipath/coreipc";
16591
+ var __dirname4 = "/home/runner/work/cli/cli/node_modules/@uipath/coreipc";
16209
16592
  /*! For license information please see index.js.LICENSE.txt */
16210
16593
  (function(e, t) {
16211
16594
  typeof exports == "object" && typeof module == "object" ? module.exports = t() : typeof define == "function" && define.amd ? define([], t) : typeof exports == "object" ? exports.ipc = t() : e.ipc = t();
@@ -34005,78 +34388,6 @@ var require_dist = __commonJS3((exports) => {
34005
34388
  exports.RobotProxyConstructor = RobotProxyConstructor;
34006
34389
  __exportStar(require_agent(), exports);
34007
34390
  });
34008
- var exports_browser_strategy = {};
34009
- __export(exports_browser_strategy, {
34010
- BrowserAuthStrategy: () => BrowserAuthStrategy
34011
- });
34012
-
34013
- class BrowserAuthStrategy {
34014
- async execute(url, _redirectUri, expectedState) {
34015
- const global2 = getGlobalThis();
34016
- if (!global2?.window) {
34017
- throw new Error("Browser environment required for authentication");
34018
- }
34019
- const screenWidth = global2.window.screen?.width ?? 1024;
34020
- const screenHeight = global2.window.screen?.height ?? 768;
34021
- const width = 600;
34022
- const height = 700;
34023
- const left = screenWidth / 2 - width / 2;
34024
- const top = screenHeight / 2 - height / 2;
34025
- if (!global2.window.open) {
34026
- throw new Error("window.open is not available");
34027
- }
34028
- const popupResult = global2.window.open(url, "uip_auth", `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=yes`);
34029
- const popup = popupResult;
34030
- if (!popup) {
34031
- throw new Error(`Authentication popup was blocked by your browser.
34032
-
34033
- ` + `To continue:
34034
- ` + `1. Look for a popup blocker icon in your address bar
34035
- ` + `2. Allow popups for this site
34036
- ` + `3. Try logging in again
34037
-
34038
- ` + "If using an ad blocker, you may need to temporarily disable it.");
34039
- }
34040
- return new Promise((resolve23, reject) => {
34041
- const messageHandler = (event) => {
34042
- if (event.data?.type === "UIP_AUTH_CODE" && event.data.code) {
34043
- if (event.data.state !== expectedState) {
34044
- cleanup();
34045
- reject(new Error("OAuth state mismatch — the callback state does not match the expected value. " + "This may indicate a CSRF attack. Please try signing in again."));
34046
- popup.close();
34047
- return;
34048
- }
34049
- cleanup();
34050
- resolve23(event.data.code);
34051
- popup.close();
34052
- } else if (event.data?.type === "UIP_AUTH_ERROR") {
34053
- cleanup();
34054
- const errorMsg = event.data.error || "Authentication failed";
34055
- reject(new Error(`Authentication failed: ${errorMsg}
34056
-
34057
- ` + "Please check your credentials and try again. " + "If the problem persists, verify your UiPath account is active."));
34058
- popup.close();
34059
- }
34060
- };
34061
- const cleanup = () => {
34062
- global2.window?.removeEventListener?.("message", messageHandler);
34063
- if (timer)
34064
- clearInterval(timer);
34065
- };
34066
- if (global2.window?.addEventListener) {
34067
- global2.window.addEventListener("message", messageHandler);
34068
- }
34069
- const timer = setInterval(() => {
34070
- if (popup.closed) {
34071
- cleanup();
34072
- reject(new Error(`Authentication was cancelled.
34073
-
34074
- ` + "The authentication popup was closed before completing the login process. " + "Please try again and complete the authentication flow."));
34075
- }
34076
- }, 1000);
34077
- });
34078
- }
34079
- }
34080
34391
  var getBaseHtml = ({ title, message, type: type2 }) => {
34081
34392
  const icon = type2 === "success" ? "✓" : "✕";
34082
34393
  const iconClass = type2 === "success" ? "icon-success" : "icon-error";
@@ -34220,6 +34531,7 @@ var getBaseHtml = ({ title, message, type: type2 }) => {
34220
34531
  </body>
34221
34532
  </html>`;
34222
34533
  };
34534
+ var AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT";
34223
34535
  var startServer = async ({
34224
34536
  redirectUri,
34225
34537
  timeoutMs = DEFAULT_AUTH_TIMEOUT_MS2,
@@ -34291,7 +34603,18 @@ var startServer = async ({
34291
34603
  reject(new Error("No authorization code received"));
34292
34604
  return;
34293
34605
  });
34294
- server.listen(Number(redirectUri.port), redirectUri.hostname, () => {
34606
+ const timeoutHandle = setTimeout(() => {
34607
+ server.close();
34608
+ const err2 = new Error("Authentication timeout");
34609
+ err2.code = AUTH_TIMEOUT_ERROR_CODE;
34610
+ reject(err2);
34611
+ }, timeoutMs);
34612
+ const bindHost = redirectUri.hostname === "localhost" ? "127.0.0.1" : redirectUri.hostname;
34613
+ server.on("error", (err2) => {
34614
+ clearTimeout(timeoutHandle);
34615
+ reject(err2);
34616
+ });
34617
+ server.listen(Number(redirectUri.port), bindHost, () => {
34295
34618
  if (onListening) {
34296
34619
  Promise.resolve(onListening()).catch((err2) => {
34297
34620
  server.close();
@@ -34300,10 +34623,6 @@ var startServer = async ({
34300
34623
  });
34301
34624
  }
34302
34625
  });
34303
- const timeoutHandle = setTimeout(() => {
34304
- server.close();
34305
- reject(new Error("Authentication timeout"));
34306
- }, timeoutMs);
34307
34626
  server.on("close", () => {
34308
34627
  clearTimeout(timeoutHandle);
34309
34628
  });
@@ -34312,6 +34631,78 @@ var startServer = async ({
34312
34631
  var init_server = __esm(() => {
34313
34632
  init_constants();
34314
34633
  });
34634
+ var exports_browser_strategy = {};
34635
+ __export(exports_browser_strategy, {
34636
+ BrowserAuthStrategy: () => BrowserAuthStrategy
34637
+ });
34638
+
34639
+ class BrowserAuthStrategy {
34640
+ async execute(url, _redirectUri, expectedState) {
34641
+ const global2 = getGlobalThis();
34642
+ if (!global2?.window) {
34643
+ throw new Error("Browser environment required for authentication");
34644
+ }
34645
+ const screenWidth = global2.window.screen?.width ?? 1024;
34646
+ const screenHeight = global2.window.screen?.height ?? 768;
34647
+ const width = 600;
34648
+ const height = 700;
34649
+ const left = screenWidth / 2 - width / 2;
34650
+ const top = screenHeight / 2 - height / 2;
34651
+ if (!global2.window.open) {
34652
+ throw new Error("window.open is not available");
34653
+ }
34654
+ const popupResult = global2.window.open(url, "uip_auth", `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=yes`);
34655
+ const popup = popupResult;
34656
+ if (!popup) {
34657
+ throw new Error(`Authentication popup was blocked by your browser.
34658
+
34659
+ To continue:
34660
+ 1. Look for a popup blocker icon in your address bar
34661
+ 2. Allow popups for this site
34662
+ 3. Try logging in again
34663
+
34664
+ If using an ad blocker, you may need to temporarily disable it.`);
34665
+ }
34666
+ return new Promise((resolve23, reject) => {
34667
+ const messageHandler = (event) => {
34668
+ if (event.data?.type === "UIP_AUTH_CODE" && event.data.code) {
34669
+ if (event.data.state !== expectedState) {
34670
+ cleanup();
34671
+ reject(new Error("OAuth state mismatch — the callback state does not match the expected value. " + "This may indicate a CSRF attack. Please try signing in again."));
34672
+ popup.close();
34673
+ return;
34674
+ }
34675
+ cleanup();
34676
+ resolve23(event.data.code);
34677
+ popup.close();
34678
+ } else if (event.data?.type === "UIP_AUTH_ERROR") {
34679
+ cleanup();
34680
+ const errorMsg = event.data.error || "Authentication failed";
34681
+ reject(new Error(`Authentication failed: ${errorMsg}
34682
+
34683
+ Please check your credentials and try again. If the problem persists, verify your UiPath account is active.`));
34684
+ popup.close();
34685
+ }
34686
+ };
34687
+ const cleanup = () => {
34688
+ global2.window?.removeEventListener?.("message", messageHandler);
34689
+ if (timer)
34690
+ clearInterval(timer);
34691
+ };
34692
+ if (global2.window?.addEventListener) {
34693
+ global2.window.addEventListener("message", messageHandler);
34694
+ }
34695
+ const timer = setInterval(() => {
34696
+ if (popup.closed) {
34697
+ cleanup();
34698
+ reject(new Error(`Authentication was cancelled.
34699
+
34700
+ The authentication popup was closed before completing the login process. Please try again and complete the authentication flow.`));
34701
+ }
34702
+ }, 1000);
34703
+ });
34704
+ }
34705
+ }
34315
34706
  var exports_node_strategy = {};
34316
34707
  __export(exports_node_strategy, {
34317
34708
  NodeAuthStrategy: () => NodeAuthStrategy
@@ -35062,6 +35453,7 @@ var LoginStatusSource;
35062
35453
  })(LoginStatusSource ||= {});
35063
35454
  init_src();
35064
35455
  init_src();
35456
+ init_server();
35065
35457
 
35066
35458
  // src/services/utils.ts
35067
35459
  async function loadGlobalAuthEnv() {
package/package.json CHANGED
@@ -1,42 +1,34 @@
1
1
  {
2
- "name": "@uipath/functions-tool",
3
- "version": "1.1.0",
4
- "description": "UiPath CLI tool for JS/TS and Python Functions — thin passthrough to uipath-functions / uipath",
5
- "keywords": [
6
- "uipcli-tool",
7
- "functions",
8
- "wrapper"
9
- ],
10
- "type": "module",
11
- "main": "./dist/tool.js",
12
- "exports": {
13
- ".": "./dist/tool.js"
14
- },
15
- "private": false,
16
- "maintainers": [
17
- "aoltean16",
18
- "mihaigirleanu",
19
- "vlad-uipath"
20
- ],
21
- "files": [
22
- "dist"
23
- ],
24
- "repository": {
25
- "type": "git",
26
- "url": "https://github.com/UiPath/cli.git",
27
- "directory": "packages/functions-tool"
28
- },
29
- "publishConfig": {
30
- "registry": "https://registry.npmjs.org/"
31
- },
32
- "devDependencies": {
33
- "@uipath/auth": "1.1.0",
34
- "@uipath/coded-functions-js-cli": "^0.1.54",
35
- "@uipath/common": "1.1.0",
36
- "@uipath/filesystem": "1.1.0",
37
- "commander": "^14.0.3",
38
- "@types/bun": "^1.3.11",
39
- "typescript": "^6.0.2"
40
- },
41
- "gitHead": "06e8c8f566df4b87da4a008635483c62f64f33f0"
2
+ "name": "@uipath/functions-tool",
3
+ "license": "MIT",
4
+ "version": "1.195.0",
5
+ "description": "UiPath CLI tool for JS/TS and Python Functions — thin passthrough to uipath-functions / uipath",
6
+ "keywords": [
7
+ "uipcli-tool",
8
+ "functions",
9
+ "wrapper"
10
+ ],
11
+ "type": "module",
12
+ "main": "./dist/tool.js",
13
+ "exports": {
14
+ ".": "./dist/tool.js"
15
+ },
16
+ "private": false,
17
+ "maintainers": [
18
+ "aoltean16",
19
+ "mihaigirleanu",
20
+ "vlad-uipath"
21
+ ],
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/UiPath/cli.git",
28
+ "directory": "packages/functions-tool"
29
+ },
30
+ "publishConfig": {
31
+ "registry": "https://registry.npmjs.org/"
32
+ },
33
+ "gitHead": "65fabb84552758b2710d8ca68470e70a9b1d19bc"
42
34
  }