@uipath/llmgw-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.
- package/dist/tool.js +574 -120
- package/package.json +25 -31
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/llmgw-tool",
|
|
6
|
-
|
|
6
|
+
license: "MIT",
|
|
7
|
+
version: "1.195.0",
|
|
7
8
|
description: "CLI plugin for UiPath AI Trust Layer Bring-Your-Own LLM connections.",
|
|
8
9
|
private: false,
|
|
9
10
|
repository: {
|
|
@@ -14,13 +15,17 @@ var package_default = {
|
|
|
14
15
|
publishConfig: {
|
|
15
16
|
registry: "https://npm.pkg.github.com/@uipath"
|
|
16
17
|
},
|
|
17
|
-
keywords: [
|
|
18
|
+
keywords: [
|
|
19
|
+
"cli-tool"
|
|
20
|
+
],
|
|
18
21
|
type: "module",
|
|
19
22
|
main: "./dist/tool.js",
|
|
20
23
|
exports: {
|
|
21
24
|
".": "./dist/tool.js"
|
|
22
25
|
},
|
|
23
|
-
files: [
|
|
26
|
+
files: [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
24
29
|
scripts: {
|
|
25
30
|
build: "bun build ./src/tool.ts --outdir dist --format esm --target node --external commander",
|
|
26
31
|
package: "bun run build && bun pm pack",
|
|
@@ -39,6 +44,7 @@ var package_default = {
|
|
|
39
44
|
};
|
|
40
45
|
|
|
41
46
|
// ../../filesystem/src/node.ts
|
|
47
|
+
import { randomUUID } from "node:crypto";
|
|
42
48
|
import { existsSync } from "node:fs";
|
|
43
49
|
import * as fs6 from "node:fs/promises";
|
|
44
50
|
import * as os2 from "node:os";
|
|
@@ -655,6 +661,13 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
|
655
661
|
var open_default = open;
|
|
656
662
|
|
|
657
663
|
// ../../filesystem/src/node.ts
|
|
664
|
+
var LOCK_HEARTBEAT_MS = 5000;
|
|
665
|
+
var LOCK_STALE_MS = 15000;
|
|
666
|
+
var LOCK_MAX_WAIT_MS = 20000;
|
|
667
|
+
var LOCK_MAX_HOLD_MS = 60000;
|
|
668
|
+
var LOCK_RETRY_MIN_MS = 100;
|
|
669
|
+
var LOCK_RETRY_JITTER_MS = 200;
|
|
670
|
+
|
|
658
671
|
class NodeFileSystem {
|
|
659
672
|
path = {
|
|
660
673
|
join: path2.join,
|
|
@@ -731,6 +744,90 @@ class NodeFileSystem {
|
|
|
731
744
|
async mkdir(dirPath) {
|
|
732
745
|
await fs6.mkdir(dirPath, { recursive: true });
|
|
733
746
|
}
|
|
747
|
+
async acquireLock(lockPath) {
|
|
748
|
+
const canonicalPath = await this.canonicalizeLockTarget(lockPath);
|
|
749
|
+
const lockFile = `${canonicalPath}.lock`;
|
|
750
|
+
const ownerId = randomUUID();
|
|
751
|
+
const start = Date.now();
|
|
752
|
+
while (true) {
|
|
753
|
+
try {
|
|
754
|
+
await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
|
|
755
|
+
return this.createLockRelease(lockFile, ownerId);
|
|
756
|
+
} catch (error) {
|
|
757
|
+
if (!this.hasErrnoCode(error, "EEXIST")) {
|
|
758
|
+
throw error;
|
|
759
|
+
}
|
|
760
|
+
const stats = await fs6.stat(lockFile).catch(() => null);
|
|
761
|
+
if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
|
|
762
|
+
const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
|
|
763
|
+
if (reclaimed)
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
if (Date.now() - start > LOCK_MAX_WAIT_MS) {
|
|
767
|
+
throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
|
|
768
|
+
}
|
|
769
|
+
await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
async canonicalizeLockTarget(lockPath) {
|
|
774
|
+
const absolute = path2.resolve(lockPath);
|
|
775
|
+
const fullReal = await fs6.realpath(absolute).catch(() => null);
|
|
776
|
+
if (fullReal)
|
|
777
|
+
return fullReal;
|
|
778
|
+
const parent = path2.dirname(absolute);
|
|
779
|
+
const base = path2.basename(absolute);
|
|
780
|
+
const canonicalParent = await fs6.realpath(parent).catch(() => parent);
|
|
781
|
+
return path2.join(canonicalParent, base);
|
|
782
|
+
}
|
|
783
|
+
createLockRelease(lockFile, ownerId) {
|
|
784
|
+
const heartbeatStart = Date.now();
|
|
785
|
+
let heartbeatTimer;
|
|
786
|
+
let stopped = false;
|
|
787
|
+
const stopHeartbeat = () => {
|
|
788
|
+
stopped = true;
|
|
789
|
+
if (heartbeatTimer)
|
|
790
|
+
clearTimeout(heartbeatTimer);
|
|
791
|
+
};
|
|
792
|
+
const scheduleNextHeartbeat = () => {
|
|
793
|
+
if (stopped)
|
|
794
|
+
return;
|
|
795
|
+
if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
|
|
796
|
+
stopped = true;
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
heartbeatTimer = setTimeout(() => {
|
|
800
|
+
runHeartbeat();
|
|
801
|
+
}, LOCK_HEARTBEAT_MS);
|
|
802
|
+
heartbeatTimer.unref?.();
|
|
803
|
+
};
|
|
804
|
+
const runHeartbeat = async () => {
|
|
805
|
+
if (stopped)
|
|
806
|
+
return;
|
|
807
|
+
const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
|
|
808
|
+
if (stopped)
|
|
809
|
+
return;
|
|
810
|
+
if (current !== ownerId) {
|
|
811
|
+
stopped = true;
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
const now = Date.now() / 1000;
|
|
815
|
+
await fs6.utimes(lockFile, now, now).catch(() => {});
|
|
816
|
+
scheduleNextHeartbeat();
|
|
817
|
+
};
|
|
818
|
+
scheduleNextHeartbeat();
|
|
819
|
+
let released = false;
|
|
820
|
+
return async () => {
|
|
821
|
+
if (released)
|
|
822
|
+
return;
|
|
823
|
+
released = true;
|
|
824
|
+
stopHeartbeat();
|
|
825
|
+
const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
|
|
826
|
+
if (current === ownerId) {
|
|
827
|
+
await fs6.rm(lockFile, { force: true });
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
}
|
|
734
831
|
async rm(filePath) {
|
|
735
832
|
await fs6.rm(filePath, { recursive: true, force: true });
|
|
736
833
|
}
|
|
@@ -776,7 +873,10 @@ class NodeFileSystem {
|
|
|
776
873
|
}
|
|
777
874
|
}
|
|
778
875
|
isEnoent(error) {
|
|
779
|
-
return
|
|
876
|
+
return this.hasErrnoCode(error, "ENOENT");
|
|
877
|
+
}
|
|
878
|
+
hasErrnoCode(error, code) {
|
|
879
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
780
880
|
}
|
|
781
881
|
}
|
|
782
882
|
|
|
@@ -918,10 +1018,15 @@ async function extractErrorDetails(error, options) {
|
|
|
918
1018
|
}
|
|
919
1019
|
if (parsedBody?.errorCode && typeof parsedBody.errorCode === "string") {
|
|
920
1020
|
context.errorCode = parsedBody.errorCode;
|
|
1021
|
+
} else if (parsedBody?.code && typeof parsedBody.code === "string") {
|
|
1022
|
+
context.errorCode = parsedBody.code;
|
|
921
1023
|
}
|
|
922
1024
|
if (parsedBody?.requestId && typeof parsedBody.requestId === "string") {
|
|
923
1025
|
context.requestId = parsedBody.requestId;
|
|
924
1026
|
}
|
|
1027
|
+
if (parsedBody?.traceId && typeof parsedBody.traceId === "string") {
|
|
1028
|
+
context.traceId = parsedBody.traceId;
|
|
1029
|
+
}
|
|
925
1030
|
if (status === 429) {
|
|
926
1031
|
const resp = response;
|
|
927
1032
|
const headersObj = resp?.headers;
|
|
@@ -941,7 +1046,35 @@ async function extractErrorDetails(error, options) {
|
|
|
941
1046
|
}
|
|
942
1047
|
}
|
|
943
1048
|
const hasContext = Object.keys(context).length > 0;
|
|
944
|
-
|
|
1049
|
+
let parsedErrors;
|
|
1050
|
+
if (parsedBody?.errors && typeof parsedBody.errors === "object") {
|
|
1051
|
+
const errors = {};
|
|
1052
|
+
for (const [field, raw] of Object.entries(parsedBody.errors)) {
|
|
1053
|
+
if (Array.isArray(raw)) {
|
|
1054
|
+
const messages = raw.map((entry) => {
|
|
1055
|
+
if (typeof entry === "string")
|
|
1056
|
+
return entry;
|
|
1057
|
+
if (entry && typeof entry === "object" && typeof entry.message === "string") {
|
|
1058
|
+
return entry.message;
|
|
1059
|
+
}
|
|
1060
|
+
return String(entry);
|
|
1061
|
+
}).filter(Boolean);
|
|
1062
|
+
if (messages.length > 0)
|
|
1063
|
+
errors[field] = messages;
|
|
1064
|
+
} else if (typeof raw === "string") {
|
|
1065
|
+
errors[field] = [raw];
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
if (Object.keys(errors).length > 0)
|
|
1069
|
+
parsedErrors = errors;
|
|
1070
|
+
}
|
|
1071
|
+
return {
|
|
1072
|
+
result,
|
|
1073
|
+
message,
|
|
1074
|
+
details,
|
|
1075
|
+
...hasContext ? { context } : {},
|
|
1076
|
+
...parsedErrors ? { parsedErrors } : {}
|
|
1077
|
+
};
|
|
945
1078
|
}
|
|
946
1079
|
async function extractErrorMessage(error, options) {
|
|
947
1080
|
const { message } = await extractErrorDetails(error, options);
|
|
@@ -6072,6 +6205,60 @@ function escapeNonAscii(jsonText) {
|
|
|
6072
6205
|
function needsAsciiSafeJson(sink) {
|
|
6073
6206
|
return process.platform === "win32" && !sink.capabilities.isInteractive;
|
|
6074
6207
|
}
|
|
6208
|
+
function isPlainRecord(value) {
|
|
6209
|
+
if (value === null || typeof value !== "object")
|
|
6210
|
+
return false;
|
|
6211
|
+
const prototype = Object.getPrototypeOf(value);
|
|
6212
|
+
return prototype === Object.prototype || prototype === null;
|
|
6213
|
+
}
|
|
6214
|
+
function toLowerCamelCaseKey(key) {
|
|
6215
|
+
if (!key)
|
|
6216
|
+
return key;
|
|
6217
|
+
if (/[_\-\s]/.test(key)) {
|
|
6218
|
+
const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
|
|
6219
|
+
if (!firstPart)
|
|
6220
|
+
return key;
|
|
6221
|
+
return [
|
|
6222
|
+
toLowerCamelCaseSimpleKey(firstPart),
|
|
6223
|
+
...restParts.map((part) => {
|
|
6224
|
+
const normalized = toLowerCamelCaseSimpleKey(part);
|
|
6225
|
+
return normalized.charAt(0).toUpperCase() + normalized.slice(1);
|
|
6226
|
+
})
|
|
6227
|
+
].join("");
|
|
6228
|
+
}
|
|
6229
|
+
return toLowerCamelCaseSimpleKey(key);
|
|
6230
|
+
}
|
|
6231
|
+
function toLowerCamelCaseSimpleKey(key) {
|
|
6232
|
+
if (/^[A-Z0-9]+$/.test(key))
|
|
6233
|
+
return key.toLowerCase();
|
|
6234
|
+
return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
|
|
6235
|
+
}
|
|
6236
|
+
function toPascalCaseKey(key) {
|
|
6237
|
+
const lowerCamelKey = toLowerCamelCaseKey(key);
|
|
6238
|
+
return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
|
|
6239
|
+
}
|
|
6240
|
+
function toPascalCaseData(value) {
|
|
6241
|
+
if (Array.isArray(value))
|
|
6242
|
+
return value.map(toPascalCaseData);
|
|
6243
|
+
if (!isPlainRecord(value))
|
|
6244
|
+
return value;
|
|
6245
|
+
const result = {};
|
|
6246
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
6247
|
+
result[toPascalCaseKey(key)] = toPascalCaseData(nestedValue);
|
|
6248
|
+
}
|
|
6249
|
+
return result;
|
|
6250
|
+
}
|
|
6251
|
+
function normalizeDataKeys(data) {
|
|
6252
|
+
return toPascalCaseData(data);
|
|
6253
|
+
}
|
|
6254
|
+
function normalizeOutputKeys(data) {
|
|
6255
|
+
const result = {};
|
|
6256
|
+
for (const [key, value] of Object.entries(data)) {
|
|
6257
|
+
const pascalKey = toPascalCaseKey(key);
|
|
6258
|
+
result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData(value);
|
|
6259
|
+
}
|
|
6260
|
+
return result;
|
|
6261
|
+
}
|
|
6075
6262
|
function printOutput(data, format = "json", logFn, asciiSafe = false) {
|
|
6076
6263
|
if (!data) {
|
|
6077
6264
|
logFn("Empty response object. No data to display.");
|
|
@@ -6134,7 +6321,7 @@ function wrapText(text, width) {
|
|
|
6134
6321
|
function printTable(data, logFn, externalLogValue) {
|
|
6135
6322
|
if (data.length === 0)
|
|
6136
6323
|
return;
|
|
6137
|
-
const keys = Object.keys(data[0]).filter((key) =>
|
|
6324
|
+
const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
|
|
6138
6325
|
const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
|
|
6139
6326
|
const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
|
|
6140
6327
|
logFn(header);
|
|
@@ -6149,7 +6336,7 @@ function printTable(data, logFn, externalLogValue) {
|
|
|
6149
6336
|
}
|
|
6150
6337
|
}
|
|
6151
6338
|
function printVerticalTable(data, logFn = console.log, externalLogValue) {
|
|
6152
|
-
const keys = Object.keys(data).filter((key) =>
|
|
6339
|
+
const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
|
|
6153
6340
|
if (keys.length === 0)
|
|
6154
6341
|
return;
|
|
6155
6342
|
const maxKeyWidth = Math.max(...keys.map((key) => key.length));
|
|
@@ -6165,7 +6352,7 @@ function printVerticalTable(data, logFn = console.log, externalLogValue) {
|
|
|
6165
6352
|
function printResizableTable(data, logFn = console.log, externalLogValue) {
|
|
6166
6353
|
if (data.length === 0)
|
|
6167
6354
|
return;
|
|
6168
|
-
const keys = Object.keys(data[0]).filter((key) =>
|
|
6355
|
+
const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
|
|
6169
6356
|
if (keys.length === 0)
|
|
6170
6357
|
return;
|
|
6171
6358
|
if (!process.stdout.isTTY) {
|
|
@@ -6241,8 +6428,26 @@ function printResizableTable(data, logFn = console.log, externalLogValue) {
|
|
|
6241
6428
|
function toYaml(data) {
|
|
6242
6429
|
return dump(data);
|
|
6243
6430
|
}
|
|
6431
|
+
class FilterEvaluationError extends Error {
|
|
6432
|
+
__brand = "FilterEvaluationError";
|
|
6433
|
+
filter;
|
|
6434
|
+
instructions;
|
|
6435
|
+
result = RESULTS.ValidationError;
|
|
6436
|
+
constructor(filter, cause) {
|
|
6437
|
+
const underlying = cause instanceof Error ? cause.message : String(cause);
|
|
6438
|
+
super(`Filter '${filter}' failed to evaluate: ${underlying}`);
|
|
6439
|
+
this.name = "FilterEvaluationError";
|
|
6440
|
+
this.filter = filter;
|
|
6441
|
+
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(@)'.";
|
|
6442
|
+
}
|
|
6443
|
+
}
|
|
6244
6444
|
function applyFilter(data, filter) {
|
|
6245
|
-
|
|
6445
|
+
let result;
|
|
6446
|
+
try {
|
|
6447
|
+
result = search(data, filter);
|
|
6448
|
+
} catch (err) {
|
|
6449
|
+
throw new FilterEvaluationError(filter, err);
|
|
6450
|
+
}
|
|
6246
6451
|
if (result == null)
|
|
6247
6452
|
return [];
|
|
6248
6453
|
if (Array.isArray(result)) {
|
|
@@ -6259,13 +6464,18 @@ function applyFilter(data, filter) {
|
|
|
6259
6464
|
}
|
|
6260
6465
|
var OutputFormatter;
|
|
6261
6466
|
((OutputFormatter) => {
|
|
6262
|
-
function success(data) {
|
|
6467
|
+
function success(data, options) {
|
|
6263
6468
|
data.Log ??= getLogFilePath() || undefined;
|
|
6469
|
+
const normalize = !options?.preserveDataKeys;
|
|
6470
|
+
if (normalize) {
|
|
6471
|
+
data.Data = normalizeDataKeys(data.Data);
|
|
6472
|
+
}
|
|
6264
6473
|
const filter = getOutputFilter();
|
|
6265
6474
|
if (filter) {
|
|
6266
|
-
|
|
6475
|
+
const filtered = applyFilter(data.Data, filter);
|
|
6476
|
+
data.Data = normalize ? normalizeDataKeys(filtered) : filtered;
|
|
6267
6477
|
}
|
|
6268
|
-
logOutput(data, getOutputFormat());
|
|
6478
|
+
logOutput(normalizeOutputKeys(data), getOutputFormat());
|
|
6269
6479
|
}
|
|
6270
6480
|
OutputFormatter.success = success;
|
|
6271
6481
|
function error(data) {
|
|
@@ -6275,7 +6485,7 @@ var OutputFormatter;
|
|
|
6275
6485
|
result: data.Result,
|
|
6276
6486
|
message: data.Message
|
|
6277
6487
|
});
|
|
6278
|
-
logOutput(data, getOutputFormat());
|
|
6488
|
+
logOutput(normalizeOutputKeys(data), getOutputFormat());
|
|
6279
6489
|
}
|
|
6280
6490
|
OutputFormatter.error = error;
|
|
6281
6491
|
function emitList(code, items, opts) {
|
|
@@ -6296,13 +6506,14 @@ var OutputFormatter;
|
|
|
6296
6506
|
function log(data) {
|
|
6297
6507
|
const format = getOutputFormat();
|
|
6298
6508
|
const sink = getOutputSink();
|
|
6509
|
+
const normalized = toPascalCaseData(data);
|
|
6299
6510
|
if (format === "json") {
|
|
6300
|
-
const json2 = JSON.stringify(
|
|
6511
|
+
const json2 = JSON.stringify(normalized);
|
|
6301
6512
|
const safe = needsAsciiSafeJson(sink) ? escapeNonAscii(json2) : json2;
|
|
6302
6513
|
sink.writeErr(`${safe}
|
|
6303
6514
|
`);
|
|
6304
6515
|
} else {
|
|
6305
|
-
for (const [key, value] of Object.entries(
|
|
6516
|
+
for (const [key, value] of Object.entries(normalized)) {
|
|
6306
6517
|
sink.writeErr(`${key}: ${value}
|
|
6307
6518
|
`);
|
|
6308
6519
|
}
|
|
@@ -6311,12 +6522,16 @@ var OutputFormatter;
|
|
|
6311
6522
|
OutputFormatter.log = log;
|
|
6312
6523
|
function formatToString(data) {
|
|
6313
6524
|
const filter = getOutputFilter();
|
|
6314
|
-
if (
|
|
6315
|
-
data.Data =
|
|
6525
|
+
if ("Data" in data && data.Data != null) {
|
|
6526
|
+
data.Data = normalizeDataKeys(data.Data);
|
|
6527
|
+
if (filter) {
|
|
6528
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
|
|
6529
|
+
}
|
|
6316
6530
|
}
|
|
6531
|
+
const output = normalizeOutputKeys(data);
|
|
6317
6532
|
const lines = [];
|
|
6318
6533
|
const sink = getOutputSink();
|
|
6319
|
-
printOutput(
|
|
6534
|
+
printOutput(output, getOutputFormat(), (msg) => {
|
|
6320
6535
|
lines.push(msg);
|
|
6321
6536
|
}, needsAsciiSafeJson(sink));
|
|
6322
6537
|
return lines.join(`
|
|
@@ -7731,6 +7946,22 @@ JSONPath.prototype.vm = vm;
|
|
|
7731
7946
|
import { Option } from "commander";
|
|
7732
7947
|
// ../../common/src/option-validators.ts
|
|
7733
7948
|
import { InvalidArgumentError } from "commander";
|
|
7949
|
+
// ../../common/src/polling/types.ts
|
|
7950
|
+
var PollOutcome = {
|
|
7951
|
+
Completed: "completed",
|
|
7952
|
+
Timeout: "timeout",
|
|
7953
|
+
Interrupted: "interrupted",
|
|
7954
|
+
Aborted: "aborted",
|
|
7955
|
+
Failed: "failed"
|
|
7956
|
+
};
|
|
7957
|
+
|
|
7958
|
+
// ../../common/src/polling/poll-failure-mapping.ts
|
|
7959
|
+
var REASON_BY_OUTCOME = {
|
|
7960
|
+
[PollOutcome.Timeout]: "poll_timeout",
|
|
7961
|
+
[PollOutcome.Failed]: "poll_failed",
|
|
7962
|
+
[PollOutcome.Interrupted]: "poll_failed",
|
|
7963
|
+
[PollOutcome.Aborted]: "poll_aborted"
|
|
7964
|
+
};
|
|
7734
7965
|
// ../../common/src/polling/terminal-statuses.ts
|
|
7735
7966
|
var TERMINAL_STATUSES = new Set([
|
|
7736
7967
|
"completed",
|
|
@@ -7758,6 +7989,8 @@ var ScreenLogger;
|
|
|
7758
7989
|
}
|
|
7759
7990
|
ScreenLogger.progress = progress;
|
|
7760
7991
|
})(ScreenLogger ||= {});
|
|
7992
|
+
// ../../common/src/sdk-user-agent.ts
|
|
7993
|
+
var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
|
|
7761
7994
|
// ../../common/src/tool-provider.ts
|
|
7762
7995
|
var factorySlot = singleton("PackagerFactoryProvider");
|
|
7763
7996
|
// ../../common/src/trackedAction.ts
|
|
@@ -7943,13 +8176,17 @@ Command2.prototype.trackedAction = function(context, fn, properties) {
|
|
|
7943
8176
|
const [error] = await catchError(fn(...args));
|
|
7944
8177
|
if (error) {
|
|
7945
8178
|
errorMessage = error instanceof Error ? error.message : String(error);
|
|
7946
|
-
logger.
|
|
8179
|
+
logger.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
|
|
8180
|
+
const typed = error;
|
|
8181
|
+
const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
|
|
8182
|
+
const customResult = typeof typed.result === "string" && typed.result !== RESULTS.Success && Object.values(RESULTS).includes(typed.result) ? typed.result : undefined;
|
|
8183
|
+
const finalResult = customResult ?? RESULTS.Failure;
|
|
7947
8184
|
OutputFormatter.error({
|
|
7948
|
-
Result:
|
|
8185
|
+
Result: finalResult,
|
|
7949
8186
|
Message: errorMessage,
|
|
7950
|
-
Instructions: "An unexpected error occurred. Run with --log-level debug for details."
|
|
8187
|
+
Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
|
|
7951
8188
|
});
|
|
7952
|
-
context.exit(
|
|
8189
|
+
context.exit(EXIT_CODES[finalResult]);
|
|
7953
8190
|
}
|
|
7954
8191
|
const durationMs = performance.now() - startTime;
|
|
7955
8192
|
const success = !error && (process.exitCode === undefined || process.exitCode === 0);
|
|
@@ -7993,6 +8230,7 @@ import path3 from "node:path";
|
|
|
7993
8230
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7994
8231
|
import childProcess32 from "node:child_process";
|
|
7995
8232
|
import fs52, { constants as fsConstants22 } from "node:fs/promises";
|
|
8233
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
7996
8234
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7997
8235
|
import * as fs62 from "node:fs/promises";
|
|
7998
8236
|
import * as os22 from "node:os";
|
|
@@ -8744,6 +8982,90 @@ class NodeFileSystem2 {
|
|
|
8744
8982
|
async mkdir(dirPath) {
|
|
8745
8983
|
await fs62.mkdir(dirPath, { recursive: true });
|
|
8746
8984
|
}
|
|
8985
|
+
async acquireLock(lockPath) {
|
|
8986
|
+
const canonicalPath = await this.canonicalizeLockTarget(lockPath);
|
|
8987
|
+
const lockFile = `${canonicalPath}.lock`;
|
|
8988
|
+
const ownerId = randomUUID2();
|
|
8989
|
+
const start = Date.now();
|
|
8990
|
+
while (true) {
|
|
8991
|
+
try {
|
|
8992
|
+
await fs62.writeFile(lockFile, ownerId, { flag: "wx" });
|
|
8993
|
+
return this.createLockRelease(lockFile, ownerId);
|
|
8994
|
+
} catch (error) {
|
|
8995
|
+
if (!this.hasErrnoCode(error, "EEXIST")) {
|
|
8996
|
+
throw error;
|
|
8997
|
+
}
|
|
8998
|
+
const stats = await fs62.stat(lockFile).catch(() => null);
|
|
8999
|
+
if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS2) {
|
|
9000
|
+
const reclaimed = await fs62.rm(lockFile, { force: true }).then(() => true).catch(() => false);
|
|
9001
|
+
if (reclaimed)
|
|
9002
|
+
continue;
|
|
9003
|
+
}
|
|
9004
|
+
if (Date.now() - start > LOCK_MAX_WAIT_MS2) {
|
|
9005
|
+
throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
|
|
9006
|
+
}
|
|
9007
|
+
await new Promise((resolve22) => setTimeout(resolve22, LOCK_RETRY_MIN_MS2 + Math.random() * LOCK_RETRY_JITTER_MS2));
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
async canonicalizeLockTarget(lockPath) {
|
|
9012
|
+
const absolute = path22.resolve(lockPath);
|
|
9013
|
+
const fullReal = await fs62.realpath(absolute).catch(() => null);
|
|
9014
|
+
if (fullReal)
|
|
9015
|
+
return fullReal;
|
|
9016
|
+
const parent = path22.dirname(absolute);
|
|
9017
|
+
const base = path22.basename(absolute);
|
|
9018
|
+
const canonicalParent = await fs62.realpath(parent).catch(() => parent);
|
|
9019
|
+
return path22.join(canonicalParent, base);
|
|
9020
|
+
}
|
|
9021
|
+
createLockRelease(lockFile, ownerId) {
|
|
9022
|
+
const heartbeatStart = Date.now();
|
|
9023
|
+
let heartbeatTimer;
|
|
9024
|
+
let stopped = false;
|
|
9025
|
+
const stopHeartbeat = () => {
|
|
9026
|
+
stopped = true;
|
|
9027
|
+
if (heartbeatTimer)
|
|
9028
|
+
clearTimeout(heartbeatTimer);
|
|
9029
|
+
};
|
|
9030
|
+
const scheduleNextHeartbeat = () => {
|
|
9031
|
+
if (stopped)
|
|
9032
|
+
return;
|
|
9033
|
+
if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS2) {
|
|
9034
|
+
stopped = true;
|
|
9035
|
+
return;
|
|
9036
|
+
}
|
|
9037
|
+
heartbeatTimer = setTimeout(() => {
|
|
9038
|
+
runHeartbeat();
|
|
9039
|
+
}, LOCK_HEARTBEAT_MS2);
|
|
9040
|
+
heartbeatTimer.unref?.();
|
|
9041
|
+
};
|
|
9042
|
+
const runHeartbeat = async () => {
|
|
9043
|
+
if (stopped)
|
|
9044
|
+
return;
|
|
9045
|
+
const current = await fs62.readFile(lockFile, "utf-8").catch(() => null);
|
|
9046
|
+
if (stopped)
|
|
9047
|
+
return;
|
|
9048
|
+
if (current !== ownerId) {
|
|
9049
|
+
stopped = true;
|
|
9050
|
+
return;
|
|
9051
|
+
}
|
|
9052
|
+
const now = Date.now() / 1000;
|
|
9053
|
+
await fs62.utimes(lockFile, now, now).catch(() => {});
|
|
9054
|
+
scheduleNextHeartbeat();
|
|
9055
|
+
};
|
|
9056
|
+
scheduleNextHeartbeat();
|
|
9057
|
+
let released = false;
|
|
9058
|
+
return async () => {
|
|
9059
|
+
if (released)
|
|
9060
|
+
return;
|
|
9061
|
+
released = true;
|
|
9062
|
+
stopHeartbeat();
|
|
9063
|
+
const current = await fs62.readFile(lockFile, "utf-8").catch(() => null);
|
|
9064
|
+
if (current === ownerId) {
|
|
9065
|
+
await fs62.rm(lockFile, { force: true });
|
|
9066
|
+
}
|
|
9067
|
+
};
|
|
9068
|
+
}
|
|
8747
9069
|
async rm(filePath) {
|
|
8748
9070
|
await fs62.rm(filePath, { recursive: true, force: true });
|
|
8749
9071
|
}
|
|
@@ -8789,9 +9111,18 @@ class NodeFileSystem2 {
|
|
|
8789
9111
|
}
|
|
8790
9112
|
}
|
|
8791
9113
|
isEnoent(error) {
|
|
8792
|
-
return
|
|
9114
|
+
return this.hasErrnoCode(error, "ENOENT");
|
|
9115
|
+
}
|
|
9116
|
+
hasErrnoCode(error, code) {
|
|
9117
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
8793
9118
|
}
|
|
8794
9119
|
}
|
|
9120
|
+
var LOCK_HEARTBEAT_MS2 = 5000;
|
|
9121
|
+
var LOCK_STALE_MS2 = 15000;
|
|
9122
|
+
var LOCK_MAX_WAIT_MS2 = 20000;
|
|
9123
|
+
var LOCK_MAX_HOLD_MS2 = 60000;
|
|
9124
|
+
var LOCK_RETRY_MIN_MS2 = 100;
|
|
9125
|
+
var LOCK_RETRY_JITTER_MS2 = 200;
|
|
8795
9126
|
var init_node = __esm(() => {
|
|
8796
9127
|
init_open();
|
|
8797
9128
|
});
|
|
@@ -8803,7 +9134,7 @@ var init_src = __esm(() => {
|
|
|
8803
9134
|
fsInstance2 = new NodeFileSystem2;
|
|
8804
9135
|
});
|
|
8805
9136
|
var require_coreipc = __commonJS((exports, module) => {
|
|
8806
|
-
var __dirname3 = "/
|
|
9137
|
+
var __dirname3 = "/home/runner/work/cli/cli/node_modules/@uipath/coreipc";
|
|
8807
9138
|
/*! For license information please see index.js.LICENSE.txt */
|
|
8808
9139
|
(function(e, t) {
|
|
8809
9140
|
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();
|
|
@@ -26603,6 +26934,9 @@ var require_dist = __commonJS((exports) => {
|
|
|
26603
26934
|
exports.RobotProxyConstructor = RobotProxyConstructor;
|
|
26604
26935
|
__exportStar(require_agent(), exports);
|
|
26605
26936
|
});
|
|
26937
|
+
var init_server = __esm(() => {
|
|
26938
|
+
init_constants();
|
|
26939
|
+
});
|
|
26606
26940
|
init_constants();
|
|
26607
26941
|
var DEFAULT_CLIENT_ID = "36dea5b8-e8bb-423d-8e7b-c808df8f1c00";
|
|
26608
26942
|
var AUTH_FILE_CONFIG_KEY = Symbol.for("@uipath/auth/AuthFileConfig");
|
|
@@ -26626,32 +26960,7 @@ class InvalidBaseUrlError extends Error {
|
|
|
26626
26960
|
this.name = "InvalidBaseUrlError";
|
|
26627
26961
|
}
|
|
26628
26962
|
}
|
|
26629
|
-
var DEFAULT_SCOPES = [
|
|
26630
|
-
"offline_access",
|
|
26631
|
-
"ProcessMining",
|
|
26632
|
-
"OrchestratorApiUserAccess",
|
|
26633
|
-
"StudioWebBackend",
|
|
26634
|
-
"IdentityServerApi",
|
|
26635
|
-
"ConnectionService",
|
|
26636
|
-
"DataService",
|
|
26637
|
-
"DataServiceApiUserAccess",
|
|
26638
|
-
"DocumentUnderstanding",
|
|
26639
|
-
"EnterpriseContextService",
|
|
26640
|
-
"Directory",
|
|
26641
|
-
"JamJamApi",
|
|
26642
|
-
"LLMGateway",
|
|
26643
|
-
"LLMOps",
|
|
26644
|
-
"OMS",
|
|
26645
|
-
"RCS.FolderAuthorization",
|
|
26646
|
-
"RCS.TagsManagement",
|
|
26647
|
-
"TestmanagerApiUserAccess",
|
|
26648
|
-
"AutomationSolutions",
|
|
26649
|
-
"StudioWebTypeCacheService",
|
|
26650
|
-
"Docs.GPT.Search",
|
|
26651
|
-
"Insights",
|
|
26652
|
-
"ReferenceToken",
|
|
26653
|
-
"Audit.Read"
|
|
26654
|
-
];
|
|
26963
|
+
var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
|
|
26655
26964
|
var normalizeAndValidateBaseUrl = (rawUrl) => {
|
|
26656
26965
|
let baseUrl = rawUrl;
|
|
26657
26966
|
if (baseUrl.endsWith("/identity_/")) {
|
|
@@ -26701,7 +27010,8 @@ var resolveConfigAsync = async ({
|
|
|
26701
27010
|
if (!clientSecret && fileAuth.clientSecret) {
|
|
26702
27011
|
clientSecret = fileAuth.clientSecret;
|
|
26703
27012
|
}
|
|
26704
|
-
const
|
|
27013
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
|
|
27014
|
+
const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES;
|
|
26705
27015
|
return {
|
|
26706
27016
|
clientId,
|
|
26707
27017
|
clientSecret,
|
|
@@ -27188,6 +27498,129 @@ function normalizeTokenRefreshFailure() {
|
|
|
27188
27498
|
function normalizeTokenRefreshUnavailableFailure() {
|
|
27189
27499
|
return "token refresh failed before authentication completed";
|
|
27190
27500
|
}
|
|
27501
|
+
function errorMessage(error) {
|
|
27502
|
+
return error instanceof Error ? error.message : String(error);
|
|
27503
|
+
}
|
|
27504
|
+
function computeExpirationThreshold(ensureTokenValidityMinutes) {
|
|
27505
|
+
return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
|
|
27506
|
+
}
|
|
27507
|
+
async function runRefreshLocked(inputs) {
|
|
27508
|
+
const {
|
|
27509
|
+
absolutePath,
|
|
27510
|
+
refreshToken: callerRefreshToken,
|
|
27511
|
+
customAuthority,
|
|
27512
|
+
ensureTokenValidityMinutes,
|
|
27513
|
+
loadEnvFile,
|
|
27514
|
+
saveEnvFile,
|
|
27515
|
+
refreshFn,
|
|
27516
|
+
resolveConfig
|
|
27517
|
+
} = inputs;
|
|
27518
|
+
const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
27519
|
+
let fresh;
|
|
27520
|
+
try {
|
|
27521
|
+
fresh = await loadEnvFile({ envPath: absolutePath });
|
|
27522
|
+
} catch (error) {
|
|
27523
|
+
return {
|
|
27524
|
+
kind: "fail",
|
|
27525
|
+
status: {
|
|
27526
|
+
loginStatus: "Refresh Failed",
|
|
27527
|
+
hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
|
|
27528
|
+
tokenRefresh: {
|
|
27529
|
+
attempted: false,
|
|
27530
|
+
success: false,
|
|
27531
|
+
errorMessage: `auth file read failed: ${errorMessage(error)}`
|
|
27532
|
+
}
|
|
27533
|
+
}
|
|
27534
|
+
};
|
|
27535
|
+
}
|
|
27536
|
+
const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
|
|
27537
|
+
const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
|
|
27538
|
+
if (freshAccess && freshExp && freshExp > expirationThreshold) {
|
|
27539
|
+
return {
|
|
27540
|
+
kind: "ok",
|
|
27541
|
+
accessToken: freshAccess,
|
|
27542
|
+
refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
|
|
27543
|
+
expiration: freshExp,
|
|
27544
|
+
tokenRefresh: { attempted: false, success: true }
|
|
27545
|
+
};
|
|
27546
|
+
}
|
|
27547
|
+
const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
|
|
27548
|
+
let refreshedAccess;
|
|
27549
|
+
let refreshedRefresh;
|
|
27550
|
+
try {
|
|
27551
|
+
const config = await resolveConfig({ customAuthority });
|
|
27552
|
+
const refreshed = await refreshFn({
|
|
27553
|
+
refreshToken: tokenForIdP,
|
|
27554
|
+
tokenEndpoint: config.tokenEndpoint,
|
|
27555
|
+
clientId: config.clientId,
|
|
27556
|
+
expectedAuthority: customAuthority
|
|
27557
|
+
});
|
|
27558
|
+
refreshedAccess = refreshed.accessToken;
|
|
27559
|
+
refreshedRefresh = refreshed.refreshToken;
|
|
27560
|
+
} catch (error) {
|
|
27561
|
+
const isOAuthFailure = isTokenRefreshOAuthFailure(error);
|
|
27562
|
+
const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
|
|
27563
|
+
const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
|
|
27564
|
+
return {
|
|
27565
|
+
kind: "fail",
|
|
27566
|
+
status: {
|
|
27567
|
+
loginStatus: "Refresh Failed",
|
|
27568
|
+
hint,
|
|
27569
|
+
tokenRefresh: {
|
|
27570
|
+
attempted: true,
|
|
27571
|
+
success: false,
|
|
27572
|
+
errorMessage: message
|
|
27573
|
+
}
|
|
27574
|
+
}
|
|
27575
|
+
};
|
|
27576
|
+
}
|
|
27577
|
+
const refreshedExp = getTokenExpiration(refreshedAccess);
|
|
27578
|
+
if (!refreshedExp || refreshedExp <= new Date) {
|
|
27579
|
+
return {
|
|
27580
|
+
kind: "fail",
|
|
27581
|
+
status: {
|
|
27582
|
+
loginStatus: "Refresh Failed",
|
|
27583
|
+
hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
|
|
27584
|
+
tokenRefresh: {
|
|
27585
|
+
attempted: true,
|
|
27586
|
+
success: false,
|
|
27587
|
+
errorMessage: "refreshed token has no valid expiration claim"
|
|
27588
|
+
}
|
|
27589
|
+
}
|
|
27590
|
+
};
|
|
27591
|
+
}
|
|
27592
|
+
try {
|
|
27593
|
+
await saveEnvFile({
|
|
27594
|
+
envPath: absolutePath,
|
|
27595
|
+
data: {
|
|
27596
|
+
UIPATH_ACCESS_TOKEN: refreshedAccess,
|
|
27597
|
+
UIPATH_REFRESH_TOKEN: refreshedRefresh
|
|
27598
|
+
},
|
|
27599
|
+
merge: true
|
|
27600
|
+
});
|
|
27601
|
+
return {
|
|
27602
|
+
kind: "ok",
|
|
27603
|
+
accessToken: refreshedAccess,
|
|
27604
|
+
refreshToken: refreshedRefresh,
|
|
27605
|
+
expiration: refreshedExp,
|
|
27606
|
+
tokenRefresh: { attempted: true, success: true }
|
|
27607
|
+
};
|
|
27608
|
+
} catch (error) {
|
|
27609
|
+
const msg = errorMessage(error);
|
|
27610
|
+
return {
|
|
27611
|
+
kind: "ok",
|
|
27612
|
+
accessToken: refreshedAccess,
|
|
27613
|
+
refreshToken: refreshedRefresh,
|
|
27614
|
+
expiration: refreshedExp,
|
|
27615
|
+
persistenceWarning: `Access token refreshed in memory but could not be written to ${absolutePath}: ${msg}. The next CLI invocation will fail until the file can be updated — run 'uip login' to re-authenticate.`,
|
|
27616
|
+
tokenRefresh: {
|
|
27617
|
+
attempted: true,
|
|
27618
|
+
success: true,
|
|
27619
|
+
errorMessage: `persistence failed: ${msg}`
|
|
27620
|
+
}
|
|
27621
|
+
};
|
|
27622
|
+
}
|
|
27623
|
+
}
|
|
27191
27624
|
var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
27192
27625
|
const {
|
|
27193
27626
|
resolveEnvFilePath = resolveEnvFilePathAsync,
|
|
@@ -27262,73 +27695,103 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
27262
27695
|
let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
|
|
27263
27696
|
let expiration = getTokenExpiration(accessToken);
|
|
27264
27697
|
let persistenceWarning;
|
|
27698
|
+
let lockReleaseFailed = false;
|
|
27265
27699
|
let tokenRefresh;
|
|
27266
|
-
const
|
|
27267
|
-
|
|
27268
|
-
|
|
27269
|
-
|
|
27700
|
+
const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
27701
|
+
const tryGlobalCredsHint = async () => {
|
|
27702
|
+
const fs72 = getFs();
|
|
27703
|
+
const globalPath = fs72.path.join(fs72.env.homedir(), envFilePath);
|
|
27704
|
+
if (absolutePath === globalPath)
|
|
27705
|
+
return;
|
|
27706
|
+
if (!await fs72.exists(globalPath))
|
|
27707
|
+
return;
|
|
27270
27708
|
try {
|
|
27271
|
-
const
|
|
27272
|
-
|
|
27273
|
-
|
|
27274
|
-
const
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27278
|
-
|
|
27279
|
-
|
|
27280
|
-
|
|
27281
|
-
|
|
27709
|
+
const globalCreds = await loadEnvFile({ envPath: globalPath });
|
|
27710
|
+
if (!globalCreds.UIPATH_ACCESS_TOKEN)
|
|
27711
|
+
return;
|
|
27712
|
+
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
27713
|
+
if (globalExp && globalExp <= new Date)
|
|
27714
|
+
return;
|
|
27715
|
+
return `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
|
|
27716
|
+
} catch {
|
|
27717
|
+
return;
|
|
27718
|
+
}
|
|
27719
|
+
};
|
|
27720
|
+
if (expiration && expiration <= outerThreshold && refreshToken) {
|
|
27721
|
+
let release;
|
|
27722
|
+
try {
|
|
27723
|
+
release = await getFs().acquireLock(absolutePath);
|
|
27282
27724
|
} catch (error) {
|
|
27283
|
-
const
|
|
27284
|
-
const
|
|
27285
|
-
|
|
27725
|
+
const msg = errorMessage(error);
|
|
27726
|
+
const globalHint = await tryGlobalCredsHint();
|
|
27727
|
+
if (globalHint) {
|
|
27728
|
+
return {
|
|
27729
|
+
loginStatus: "Expired",
|
|
27730
|
+
accessToken,
|
|
27731
|
+
refreshToken,
|
|
27732
|
+
baseUrl: credentials.UIPATH_URL,
|
|
27733
|
+
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
27734
|
+
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
27735
|
+
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
27736
|
+
tenantId: credentials.UIPATH_TENANT_ID,
|
|
27737
|
+
expiration,
|
|
27738
|
+
source: "file",
|
|
27739
|
+
hint: globalHint,
|
|
27740
|
+
tokenRefresh: {
|
|
27741
|
+
attempted: false,
|
|
27742
|
+
success: false,
|
|
27743
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
27744
|
+
}
|
|
27745
|
+
};
|
|
27746
|
+
}
|
|
27286
27747
|
return {
|
|
27287
27748
|
loginStatus: "Refresh Failed",
|
|
27288
|
-
hint,
|
|
27749
|
+
hint: "Could not acquire the auth-file lock — too many concurrent `uip` processes, or a permission issue on the auth directory. Retry, or run 'uip login' to re-authenticate.",
|
|
27289
27750
|
tokenRefresh: {
|
|
27290
|
-
attempted:
|
|
27751
|
+
attempted: false,
|
|
27291
27752
|
success: false,
|
|
27292
|
-
errorMessage
|
|
27753
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
27293
27754
|
}
|
|
27294
27755
|
};
|
|
27295
27756
|
}
|
|
27296
|
-
|
|
27297
|
-
if (!refreshedExp || refreshedExp <= new Date) {
|
|
27298
|
-
return {
|
|
27299
|
-
loginStatus: "Refresh Failed",
|
|
27300
|
-
hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
|
|
27301
|
-
tokenRefresh: {
|
|
27302
|
-
attempted: true,
|
|
27303
|
-
success: false,
|
|
27304
|
-
errorMessage: "refreshed token has no valid expiration claim"
|
|
27305
|
-
}
|
|
27306
|
-
};
|
|
27307
|
-
}
|
|
27308
|
-
accessToken = refreshedAccess;
|
|
27309
|
-
refreshToken = refreshedRefresh;
|
|
27310
|
-
expiration = refreshedExp;
|
|
27757
|
+
let lockedFailure;
|
|
27311
27758
|
try {
|
|
27312
|
-
await
|
|
27313
|
-
|
|
27314
|
-
|
|
27315
|
-
|
|
27316
|
-
|
|
27317
|
-
|
|
27318
|
-
|
|
27759
|
+
const outcome = await runRefreshLocked({
|
|
27760
|
+
absolutePath,
|
|
27761
|
+
refreshToken,
|
|
27762
|
+
customAuthority: credentials.UIPATH_URL,
|
|
27763
|
+
ensureTokenValidityMinutes,
|
|
27764
|
+
loadEnvFile,
|
|
27765
|
+
saveEnvFile,
|
|
27766
|
+
refreshFn: refreshTokenFn,
|
|
27767
|
+
resolveConfig
|
|
27319
27768
|
});
|
|
27320
|
-
|
|
27321
|
-
|
|
27322
|
-
|
|
27323
|
-
|
|
27324
|
-
|
|
27325
|
-
|
|
27326
|
-
|
|
27327
|
-
|
|
27328
|
-
|
|
27329
|
-
|
|
27330
|
-
|
|
27331
|
-
|
|
27769
|
+
if (outcome.kind === "fail") {
|
|
27770
|
+
lockedFailure = outcome.status;
|
|
27771
|
+
} else {
|
|
27772
|
+
accessToken = outcome.accessToken;
|
|
27773
|
+
refreshToken = outcome.refreshToken;
|
|
27774
|
+
expiration = outcome.expiration;
|
|
27775
|
+
tokenRefresh = outcome.tokenRefresh;
|
|
27776
|
+
if (outcome.persistenceWarning) {
|
|
27777
|
+
persistenceWarning = outcome.persistenceWarning;
|
|
27778
|
+
}
|
|
27779
|
+
}
|
|
27780
|
+
} finally {
|
|
27781
|
+
try {
|
|
27782
|
+
await release();
|
|
27783
|
+
} catch {
|
|
27784
|
+
lockReleaseFailed = true;
|
|
27785
|
+
}
|
|
27786
|
+
}
|
|
27787
|
+
if (lockedFailure) {
|
|
27788
|
+
const globalHint = await tryGlobalCredsHint();
|
|
27789
|
+
const base = globalHint ? {
|
|
27790
|
+
...lockedFailure,
|
|
27791
|
+
loginStatus: "Expired",
|
|
27792
|
+
hint: globalHint
|
|
27793
|
+
} : lockedFailure;
|
|
27794
|
+
return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
|
|
27332
27795
|
}
|
|
27333
27796
|
}
|
|
27334
27797
|
const result = {
|
|
@@ -27343,23 +27806,13 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
27343
27806
|
expiration,
|
|
27344
27807
|
source: "file",
|
|
27345
27808
|
...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
|
|
27809
|
+
...lockReleaseFailed ? { lockReleaseFailed: true } : {},
|
|
27346
27810
|
...tokenRefresh ? { tokenRefresh } : {}
|
|
27347
27811
|
};
|
|
27348
27812
|
if (result.loginStatus === "Expired") {
|
|
27349
|
-
const
|
|
27350
|
-
|
|
27351
|
-
|
|
27352
|
-
try {
|
|
27353
|
-
const globalCreds = await loadEnvFile({
|
|
27354
|
-
envPath: globalPath
|
|
27355
|
-
});
|
|
27356
|
-
if (globalCreds.UIPATH_ACCESS_TOKEN) {
|
|
27357
|
-
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
27358
|
-
if (!globalExp || globalExp > new Date) {
|
|
27359
|
-
result.hint = `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
|
|
27360
|
-
}
|
|
27361
|
-
}
|
|
27362
|
-
} catch {}
|
|
27813
|
+
const globalHint = await tryGlobalCredsHint();
|
|
27814
|
+
if (globalHint) {
|
|
27815
|
+
result.hint = globalHint;
|
|
27363
27816
|
}
|
|
27364
27817
|
}
|
|
27365
27818
|
return result;
|
|
@@ -27374,6 +27827,7 @@ var getLoginStatusAsync = async (options = {}) => {
|
|
|
27374
27827
|
};
|
|
27375
27828
|
init_src();
|
|
27376
27829
|
init_src();
|
|
27830
|
+
init_server();
|
|
27377
27831
|
var SERVICE_PATH = {
|
|
27378
27832
|
"llm-gateway": "llmgateway_"
|
|
27379
27833
|
};
|
package/package.json
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"@uipath/llmgw-sdk": "1.1.0",
|
|
28
|
-
"@uipath/common": "1.1.0",
|
|
29
|
-
"commander": "^14.0.3",
|
|
30
|
-
"typescript": "^6.0.2"
|
|
31
|
-
},
|
|
32
|
-
"gitHead": "06e8c8f566df4b87da4a008635483c62f64f33f0"
|
|
2
|
+
"name": "@uipath/llmgw-tool",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "1.195.0",
|
|
5
|
+
"description": "CLI plugin for UiPath AI Trust Layer Bring-Your-Own LLM connections.",
|
|
6
|
+
"private": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/UiPath/cli.git",
|
|
10
|
+
"directory": "packages/admin/llmgw-tool"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"registry": "https://registry.npmjs.org/"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"cli-tool"
|
|
17
|
+
],
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "./dist/tool.js",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./dist/tool.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"gitHead": "eecf5713cd579b15783c770d1923e44e730271ea"
|
|
33
27
|
}
|