@uipath/agent-sdk 1.195.0 → 1.197.0-preview.59
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/index.js +539 -281
- package/dist/src/governance.d.ts +9 -2
- package/dist/src/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -19164,6 +19164,9 @@ function singleton(ctorOrName) {
|
|
|
19164
19164
|
};
|
|
19165
19165
|
}
|
|
19166
19166
|
|
|
19167
|
+
// ../common/src/telemetry/global-telemetry-properties.ts
|
|
19168
|
+
var telemetryPropsSlot = singleton("TelemetryDefaultProps");
|
|
19169
|
+
|
|
19167
19170
|
// ../common/src/sdk-user-agent.ts
|
|
19168
19171
|
var USER_AGENT_HEADER = "User-Agent";
|
|
19169
19172
|
var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
|
|
@@ -19187,8 +19190,8 @@ function appendUserAgentToken(value, userAgent) {
|
|
|
19187
19190
|
function getEffectiveUserAgent(userAgent) {
|
|
19188
19191
|
return appendUserAgentToken(sdkUserAgentHostToken.get(), userAgent);
|
|
19189
19192
|
}
|
|
19190
|
-
function
|
|
19191
|
-
return
|
|
19193
|
+
function getHeaderName(headers, headerName) {
|
|
19194
|
+
return Object.keys(headers).find((key) => key.toLowerCase() === headerName.toLowerCase());
|
|
19192
19195
|
}
|
|
19193
19196
|
function getSdkUserAgentToken(pkg) {
|
|
19194
19197
|
const packageName = pkg.name.replace(/^@uipath\//, "");
|
|
@@ -19196,59 +19199,31 @@ function getSdkUserAgentToken(pkg) {
|
|
|
19196
19199
|
}
|
|
19197
19200
|
function addSdkUserAgentHeader(headers, userAgent) {
|
|
19198
19201
|
const result = { ...headers ?? {} };
|
|
19199
|
-
const
|
|
19200
|
-
|
|
19201
|
-
if (headerName) {
|
|
19202
|
-
result[headerName] = appendUserAgentToken(result[headerName], effectiveUserAgent);
|
|
19203
|
-
} else {
|
|
19204
|
-
result[USER_AGENT_HEADER] = effectiveUserAgent;
|
|
19205
|
-
}
|
|
19202
|
+
const headerName = getHeaderName(result, USER_AGENT_HEADER);
|
|
19203
|
+
result[headerName ?? USER_AGENT_HEADER] = appendUserAgentToken(headerName ? result[headerName] : undefined, getEffectiveUserAgent(userAgent));
|
|
19206
19204
|
return result;
|
|
19207
19205
|
}
|
|
19208
|
-
function
|
|
19209
|
-
|
|
19210
|
-
if (isHeadersLike(headers)) {
|
|
19211
|
-
headers.set(USER_AGENT_HEADER, appendUserAgentToken(headers.get(USER_AGENT_HEADER), effectiveUserAgent));
|
|
19212
|
-
return headers;
|
|
19213
|
-
}
|
|
19214
|
-
if (Array.isArray(headers)) {
|
|
19215
|
-
const result = headers.map((entry) => {
|
|
19216
|
-
const [key, value] = entry;
|
|
19217
|
-
return [key, value];
|
|
19218
|
-
});
|
|
19219
|
-
const headerIndex = result.findIndex(([key]) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
|
|
19220
|
-
if (headerIndex >= 0) {
|
|
19221
|
-
const [key, value] = result[headerIndex];
|
|
19222
|
-
result[headerIndex] = [
|
|
19223
|
-
key,
|
|
19224
|
-
appendUserAgentToken(value, effectiveUserAgent)
|
|
19225
|
-
];
|
|
19226
|
-
} else {
|
|
19227
|
-
result.push([USER_AGENT_HEADER, effectiveUserAgent]);
|
|
19228
|
-
}
|
|
19229
|
-
return result;
|
|
19230
|
-
}
|
|
19231
|
-
return addSdkUserAgentHeader(typeof headers === "object" && headers !== null ? { ...headers } : {}, effectiveUserAgent);
|
|
19206
|
+
function asHeaderRecord(headers) {
|
|
19207
|
+
return typeof headers === "object" && headers !== null ? { ...headers } : {};
|
|
19232
19208
|
}
|
|
19233
|
-
function
|
|
19209
|
+
function withForwardedHeadersInitOverride(initOverrides, forward) {
|
|
19234
19210
|
return async (requestContext) => {
|
|
19235
|
-
const
|
|
19211
|
+
const initWithHeaders = {
|
|
19236
19212
|
...requestContext.init,
|
|
19237
|
-
headers:
|
|
19213
|
+
headers: forward(asHeaderRecord(requestContext.init.headers))
|
|
19238
19214
|
};
|
|
19239
19215
|
const override = typeof initOverrides === "function" ? await initOverrides({
|
|
19240
19216
|
...requestContext,
|
|
19241
|
-
init:
|
|
19217
|
+
init: initWithHeaders
|
|
19242
19218
|
}) : initOverrides;
|
|
19243
19219
|
return {
|
|
19244
19220
|
...override ?? {},
|
|
19245
|
-
headers:
|
|
19221
|
+
headers: forward(asHeaderRecord(override?.headers ?? initWithHeaders.headers))
|
|
19246
19222
|
};
|
|
19247
19223
|
};
|
|
19248
19224
|
}
|
|
19249
|
-
function
|
|
19225
|
+
function installRequestHeaderForwarding(BaseApiClass, patchKey, forward) {
|
|
19250
19226
|
const prototype = BaseApiClass.prototype;
|
|
19251
|
-
const patchKey = userAgentPatchKey(userAgent);
|
|
19252
19227
|
if (prototype[patchKey]) {
|
|
19253
19228
|
return;
|
|
19254
19229
|
}
|
|
@@ -19256,13 +19231,16 @@ function installSdkUserAgentHeader(BaseApiClass, userAgent) {
|
|
|
19256
19231
|
throw new Error("Generated BaseAPI request function not found.");
|
|
19257
19232
|
}
|
|
19258
19233
|
const originalRequest = prototype.request;
|
|
19259
|
-
prototype.request = function
|
|
19260
|
-
return originalRequest.call(this, context,
|
|
19234
|
+
prototype.request = function requestWithForwardedHeaders(context, initOverrides) {
|
|
19235
|
+
return originalRequest.call(this, context, withForwardedHeadersInitOverride(initOverrides, forward));
|
|
19261
19236
|
};
|
|
19262
19237
|
Object.defineProperty(prototype, patchKey, {
|
|
19263
19238
|
value: true
|
|
19264
19239
|
});
|
|
19265
19240
|
}
|
|
19241
|
+
function installSdkUserAgentHeader(BaseApiClass, userAgent) {
|
|
19242
|
+
installRequestHeaderForwarding(BaseApiClass, userAgentPatchKey(userAgent), (headers) => addSdkUserAgentHeader(headers, userAgent));
|
|
19243
|
+
}
|
|
19266
19244
|
|
|
19267
19245
|
// generated/src/runtime.ts
|
|
19268
19246
|
var BASE_PATH = "http://localhost".replace(/\/+$/, "");
|
|
@@ -19575,7 +19553,7 @@ class TextApiResponse {
|
|
|
19575
19553
|
var package_default = {
|
|
19576
19554
|
name: "@uipath/agent-sdk",
|
|
19577
19555
|
license: "MIT",
|
|
19578
|
-
version: "1.
|
|
19556
|
+
version: "1.197.0-preview.59",
|
|
19579
19557
|
description: "SDK for the UiPath Agent Runtime API — evaluation execution and debug sessions.",
|
|
19580
19558
|
repository: {
|
|
19581
19559
|
type: "git",
|
|
@@ -19604,7 +19582,7 @@ var package_default = {
|
|
|
19604
19582
|
"dist"
|
|
19605
19583
|
],
|
|
19606
19584
|
scripts: {
|
|
19607
|
-
build: "bun build ./src/index.ts --outdir dist --format esm --target node && tsc -p tsconfig.build.json --noCheck",
|
|
19585
|
+
build: "bun build ./src/index.ts --outdir dist --format esm --target node --sourcemap=linked && tsc -p tsconfig.build.json --noCheck",
|
|
19608
19586
|
generate: "bun run src/scripts/generate-sdk.ts",
|
|
19609
19587
|
test: "vitest run",
|
|
19610
19588
|
"test:coverage": "vitest run --coverage",
|
|
@@ -22607,6 +22585,12 @@ var normalizeAndValidateBaseUrl = (rawUrl) => {
|
|
|
22607
22585
|
}
|
|
22608
22586
|
return url.pathname.length > 1 ? url.origin : baseUrl;
|
|
22609
22587
|
};
|
|
22588
|
+
var resolveScopes = (isExternalAppAuth, customScopes, fileScopes) => {
|
|
22589
|
+
const requestedScopes = customScopes?.length ? customScopes : fileScopes ?? [];
|
|
22590
|
+
if (isExternalAppAuth)
|
|
22591
|
+
return requestedScopes;
|
|
22592
|
+
return [...new Set([...DEFAULT_SCOPES, ...requestedScopes])];
|
|
22593
|
+
};
|
|
22610
22594
|
var resolveConfigAsync = async ({
|
|
22611
22595
|
customAuthority,
|
|
22612
22596
|
customClientId,
|
|
@@ -22637,7 +22621,7 @@ var resolveConfigAsync = async ({
|
|
|
22637
22621
|
clientSecret = fileAuth.clientSecret;
|
|
22638
22622
|
}
|
|
22639
22623
|
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
|
|
22640
|
-
const scopes =
|
|
22624
|
+
const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
|
|
22641
22625
|
return {
|
|
22642
22626
|
clientId,
|
|
22643
22627
|
clientSecret,
|
|
@@ -22652,6 +22636,76 @@ var resolveConfigAsync = async ({
|
|
|
22652
22636
|
init_constants();
|
|
22653
22637
|
// ../auth/src/loginStatus.ts
|
|
22654
22638
|
init_src();
|
|
22639
|
+
|
|
22640
|
+
// ../auth/src/authProfile.ts
|
|
22641
|
+
init_src();
|
|
22642
|
+
init_constants();
|
|
22643
|
+
var DEFAULT_AUTH_PROFILE = "default";
|
|
22644
|
+
var PROFILE_DIR = "profiles";
|
|
22645
|
+
var PROFILE_NAME_RE = /^[A-Za-z0-9._-]+$/;
|
|
22646
|
+
var ACTIVE_AUTH_PROFILE_KEY = Symbol.for("@uipath/auth/ActiveAuthProfile");
|
|
22647
|
+
var AUTH_PROFILE_STORAGE_KEY = Symbol.for("@uipath/auth/ProfileStorage");
|
|
22648
|
+
var globalSlot2 = globalThis;
|
|
22649
|
+
function isAuthProfileStorage(value) {
|
|
22650
|
+
return value !== null && typeof value === "object" && "getStore" in value && "run" in value;
|
|
22651
|
+
}
|
|
22652
|
+
function createProfileStorage() {
|
|
22653
|
+
const [error, mod] = catchError(() => __require("node:async_hooks"));
|
|
22654
|
+
if (error || typeof mod?.AsyncLocalStorage !== "function") {
|
|
22655
|
+
return {
|
|
22656
|
+
getStore: () => {
|
|
22657
|
+
return;
|
|
22658
|
+
},
|
|
22659
|
+
run: (_store, fn) => fn()
|
|
22660
|
+
};
|
|
22661
|
+
}
|
|
22662
|
+
return new mod.AsyncLocalStorage;
|
|
22663
|
+
}
|
|
22664
|
+
function getProfileStorage() {
|
|
22665
|
+
const existing = globalSlot2[AUTH_PROFILE_STORAGE_KEY];
|
|
22666
|
+
if (isAuthProfileStorage(existing)) {
|
|
22667
|
+
return existing;
|
|
22668
|
+
}
|
|
22669
|
+
const storage = createProfileStorage();
|
|
22670
|
+
globalSlot2[AUTH_PROFILE_STORAGE_KEY] = storage;
|
|
22671
|
+
return storage;
|
|
22672
|
+
}
|
|
22673
|
+
var profileStorage = getProfileStorage();
|
|
22674
|
+
|
|
22675
|
+
class AuthProfileValidationError extends Error {
|
|
22676
|
+
constructor(message) {
|
|
22677
|
+
super(message);
|
|
22678
|
+
this.name = "AuthProfileValidationError";
|
|
22679
|
+
}
|
|
22680
|
+
}
|
|
22681
|
+
function normalizeAuthProfileName(profile) {
|
|
22682
|
+
if (profile === undefined || profile === DEFAULT_AUTH_PROFILE) {
|
|
22683
|
+
return;
|
|
22684
|
+
}
|
|
22685
|
+
if (profile.length === 0 || profile === "." || profile === ".." || !PROFILE_NAME_RE.test(profile)) {
|
|
22686
|
+
throw new AuthProfileValidationError(`Invalid profile name "${profile}". Profile names may contain only letters, numbers, '.', '_', and '-'.`);
|
|
22687
|
+
}
|
|
22688
|
+
return profile;
|
|
22689
|
+
}
|
|
22690
|
+
function getActiveAuthProfile() {
|
|
22691
|
+
const scopedState = profileStorage.getStore();
|
|
22692
|
+
if (scopedState !== undefined) {
|
|
22693
|
+
return scopedState.profile;
|
|
22694
|
+
}
|
|
22695
|
+
return globalSlot2[ACTIVE_AUTH_PROFILE_KEY]?.profile;
|
|
22696
|
+
}
|
|
22697
|
+
function resolveAuthProfileFilePath(profile) {
|
|
22698
|
+
const normalized = normalizeAuthProfileName(profile);
|
|
22699
|
+
if (normalized === undefined) {
|
|
22700
|
+
throw new AuthProfileValidationError(`"${DEFAULT_AUTH_PROFILE}" is the built-in profile and does not have a profile file path.`);
|
|
22701
|
+
}
|
|
22702
|
+
const fs7 = getFileSystem();
|
|
22703
|
+
return fs7.path.join(fs7.env.homedir(), UIPATH_HOME_DIR, PROFILE_DIR, normalized, AUTH_FILENAME);
|
|
22704
|
+
}
|
|
22705
|
+
function getActiveAuthProfileFilePath() {
|
|
22706
|
+
const profile = getActiveAuthProfile();
|
|
22707
|
+
return profile ? resolveAuthProfileFilePath(profile) : undefined;
|
|
22708
|
+
}
|
|
22655
22709
|
// ../auth/src/utils/jwt.ts
|
|
22656
22710
|
class InvalidIssuerError extends Error {
|
|
22657
22711
|
expected;
|
|
@@ -22780,23 +22834,74 @@ var readAuthFromEnv = () => {
|
|
|
22780
22834
|
organizationId,
|
|
22781
22835
|
tenantName,
|
|
22782
22836
|
tenantId,
|
|
22783
|
-
expiration
|
|
22837
|
+
expiration,
|
|
22838
|
+
source: "env" /* Env */
|
|
22784
22839
|
};
|
|
22785
22840
|
};
|
|
22786
22841
|
|
|
22842
|
+
// ../auth/src/refreshCircuitBreaker.ts
|
|
22843
|
+
init_src();
|
|
22844
|
+
var BREAKER_SUFFIX = ".refresh-state";
|
|
22845
|
+
var BACKOFF_BASE_MS = 60000;
|
|
22846
|
+
var BACKOFF_CAP_MS = 60 * 60 * 1000;
|
|
22847
|
+
var SURFACE_WINDOW_MS = 60 * 60 * 1000;
|
|
22848
|
+
async function refreshTokenFingerprint(refreshToken) {
|
|
22849
|
+
const bytes = new TextEncoder().encode(refreshToken);
|
|
22850
|
+
if (globalThis.crypto?.subtle) {
|
|
22851
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
22852
|
+
return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("").slice(0, 16);
|
|
22853
|
+
}
|
|
22854
|
+
const { createHash } = await import("node:crypto");
|
|
22855
|
+
return createHash("sha256").update(refreshToken).digest("hex").slice(0, 16);
|
|
22856
|
+
}
|
|
22857
|
+
function breakerPathFor(authPath) {
|
|
22858
|
+
return `${authPath}${BREAKER_SUFFIX}`;
|
|
22859
|
+
}
|
|
22860
|
+
async function loadRefreshBreaker(authPath) {
|
|
22861
|
+
const fs7 = getFileSystem();
|
|
22862
|
+
try {
|
|
22863
|
+
const content = await fs7.readFile(breakerPathFor(authPath), "utf-8");
|
|
22864
|
+
if (!content)
|
|
22865
|
+
return {};
|
|
22866
|
+
const parsed = JSON.parse(content);
|
|
22867
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
22868
|
+
} catch {
|
|
22869
|
+
return {};
|
|
22870
|
+
}
|
|
22871
|
+
}
|
|
22872
|
+
async function saveRefreshBreaker(authPath, state) {
|
|
22873
|
+
try {
|
|
22874
|
+
const fs7 = getFileSystem();
|
|
22875
|
+
const path3 = breakerPathFor(authPath);
|
|
22876
|
+
await fs7.mkdir(fs7.path.dirname(path3));
|
|
22877
|
+
const tempPath = `${path3}.tmp`;
|
|
22878
|
+
await fs7.writeFile(tempPath, JSON.stringify(state));
|
|
22879
|
+
await fs7.rename(tempPath, path3);
|
|
22880
|
+
} catch {}
|
|
22881
|
+
}
|
|
22882
|
+
async function clearRefreshBreaker(authPath) {
|
|
22883
|
+
const fs7 = getFileSystem();
|
|
22884
|
+
const path3 = breakerPathFor(authPath);
|
|
22885
|
+
try {
|
|
22886
|
+
if (await fs7.exists(path3)) {
|
|
22887
|
+
await fs7.rm(path3);
|
|
22888
|
+
}
|
|
22889
|
+
} catch {}
|
|
22890
|
+
}
|
|
22891
|
+
function nextBackoffMs(attempts) {
|
|
22892
|
+
const shift = Math.max(0, attempts - 1);
|
|
22893
|
+
return Math.min(BACKOFF_BASE_MS * 2 ** shift, BACKOFF_CAP_MS);
|
|
22894
|
+
}
|
|
22895
|
+
function shouldSurface(state, nowMs) {
|
|
22896
|
+
if (state.lastSurfacedAtMs === undefined)
|
|
22897
|
+
return true;
|
|
22898
|
+
return nowMs - state.lastSurfacedAtMs >= SURFACE_WINDOW_MS;
|
|
22899
|
+
}
|
|
22900
|
+
|
|
22787
22901
|
// ../auth/src/robotClientFallback.ts
|
|
22788
22902
|
init_src();
|
|
22789
22903
|
var DEFAULT_TIMEOUT_MS = 1000;
|
|
22790
22904
|
var CLOSE_TIMEOUT_MS = 500;
|
|
22791
|
-
var NOTICE_SENTINEL = Symbol.for("@uipath/auth/robotFallbackNoticePrinted");
|
|
22792
|
-
var printNoticeOnce = () => {
|
|
22793
|
-
const slot = globalThis;
|
|
22794
|
-
if (slot[NOTICE_SENTINEL])
|
|
22795
|
-
return;
|
|
22796
|
-
slot[NOTICE_SENTINEL] = true;
|
|
22797
|
-
catchError(() => process.stderr.write(`Using UiPath Robot credentials. Run 'uip login' for a dedicated session.
|
|
22798
|
-
`));
|
|
22799
|
-
};
|
|
22800
22905
|
var ROBOT_USER_SERVICES_PIPE = "UiPathUserServices";
|
|
22801
22906
|
var ROBOT_USER_SERVICES_ALTERNATE_PIPE = `${ROBOT_USER_SERVICES_PIPE}Alternate`;
|
|
22802
22907
|
var PIPE_NAME_MAX_LENGTH = 103;
|
|
@@ -22841,11 +22946,11 @@ var parseResourceUrl = (url) => {
|
|
|
22841
22946
|
if (error || !parsed)
|
|
22842
22947
|
return;
|
|
22843
22948
|
const segments = parsed.pathname.split("/").filter(Boolean);
|
|
22844
|
-
|
|
22845
|
-
|
|
22846
|
-
|
|
22847
|
-
|
|
22848
|
-
|
|
22949
|
+
return {
|
|
22950
|
+
baseUrl: parsed.origin,
|
|
22951
|
+
organizationName: segments[0],
|
|
22952
|
+
tenantName: segments[1]
|
|
22953
|
+
};
|
|
22849
22954
|
};
|
|
22850
22955
|
var defaultLoadModule = async () => {
|
|
22851
22956
|
const [error, mod] = await catchError(() => Promise.resolve().then(() => __toESM(require_dist(), 1)));
|
|
@@ -22896,6 +23001,7 @@ var tryRobotClientFallback = async (options = {}) => {
|
|
|
22896
23001
|
}
|
|
22897
23002
|
let organizationIdFromToken;
|
|
22898
23003
|
let tenantIdFromToken;
|
|
23004
|
+
let issuerFromToken;
|
|
22899
23005
|
const [jwtError, claims] = catchError(() => parseJWT(accessToken));
|
|
22900
23006
|
if (!jwtError && claims) {
|
|
22901
23007
|
const rawOrgId = claims.prtId ?? claims.organizationId ?? claims.prt_id;
|
|
@@ -22906,15 +23012,19 @@ var tryRobotClientFallback = async (options = {}) => {
|
|
|
22906
23012
|
if (typeof tenantClaim === "string" && tenantClaim.length > 0) {
|
|
22907
23013
|
tenantIdFromToken = tenantClaim;
|
|
22908
23014
|
}
|
|
23015
|
+
const issClaim = claims.iss;
|
|
23016
|
+
if (typeof issClaim === "string" && issClaim.length > 0) {
|
|
23017
|
+
issuerFromToken = issClaim;
|
|
23018
|
+
}
|
|
22909
23019
|
}
|
|
22910
|
-
printNoticeOnce();
|
|
22911
23020
|
return {
|
|
22912
23021
|
accessToken,
|
|
22913
23022
|
baseUrl: parsedUrl.baseUrl,
|
|
22914
23023
|
organizationName: parsedUrl.organizationName,
|
|
22915
23024
|
organizationId: organizationIdFromToken ?? parsedUrl.organizationName,
|
|
22916
23025
|
tenantName: parsedUrl.tenantName,
|
|
22917
|
-
tenantId: tenantIdFromToken
|
|
23026
|
+
tenantId: tenantIdFromToken,
|
|
23027
|
+
issuer: issuerFromToken
|
|
22918
23028
|
};
|
|
22919
23029
|
} catch {
|
|
22920
23030
|
return;
|
|
@@ -23016,7 +23126,7 @@ var probeAsync = async (fs7, candidate) => {
|
|
|
23016
23126
|
};
|
|
23017
23127
|
}
|
|
23018
23128
|
};
|
|
23019
|
-
var resolveEnvFileLocationAsync = async (envFilePath = DEFAULT_ENV_FILENAME) => {
|
|
23129
|
+
var resolveEnvFileLocationAsync = async (envFilePath = DEFAULT_ENV_FILENAME, opts) => {
|
|
23020
23130
|
const fs7 = getFileSystem();
|
|
23021
23131
|
if (fs7.path.isAbsolute(envFilePath)) {
|
|
23022
23132
|
const probe2 = await probeAsync(fs7, envFilePath);
|
|
@@ -23027,7 +23137,7 @@ var resolveEnvFileLocationAsync = async (envFilePath = DEFAULT_ENV_FILENAME) =>
|
|
|
23027
23137
|
...probe2.unusable ? { unusable: probe2.unusable } : {}
|
|
23028
23138
|
};
|
|
23029
23139
|
}
|
|
23030
|
-
const cwd = fs7.env.cwd();
|
|
23140
|
+
const cwd = opts?.cwd ?? fs7.env.cwd();
|
|
23031
23141
|
let searchDir = cwd;
|
|
23032
23142
|
while (true) {
|
|
23033
23143
|
const candidate = fs7.path.join(searchDir, envFilePath);
|
|
@@ -23057,8 +23167,8 @@ var resolveEnvFileLocationAsync = async (envFilePath = DEFAULT_ENV_FILENAME) =>
|
|
|
23057
23167
|
...probe.unusable ? { unusable: probe.unusable } : {}
|
|
23058
23168
|
};
|
|
23059
23169
|
};
|
|
23060
|
-
var resolveEnvFilePathAsync = async (envFilePath = DEFAULT_ENV_FILENAME) => {
|
|
23061
|
-
const location = await resolveEnvFileLocationAsync(envFilePath);
|
|
23170
|
+
var resolveEnvFilePathAsync = async (envFilePath = DEFAULT_ENV_FILENAME, opts) => {
|
|
23171
|
+
const location = await resolveEnvFileLocationAsync(envFilePath, opts);
|
|
23062
23172
|
if (location.exists) {
|
|
23063
23173
|
return { absolutePath: location.absolutePath };
|
|
23064
23174
|
}
|
|
@@ -23131,18 +23241,327 @@ var saveEnvFileAsync = async ({
|
|
|
23131
23241
|
};
|
|
23132
23242
|
|
|
23133
23243
|
// ../auth/src/loginStatus.ts
|
|
23134
|
-
|
|
23135
|
-
return
|
|
23244
|
+
var getLoginStatusAsync = async (options = {}) => {
|
|
23245
|
+
return getLoginStatusWithDeps(options);
|
|
23246
|
+
};
|
|
23247
|
+
var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
23248
|
+
const {
|
|
23249
|
+
resolveEnvFilePath = resolveEnvFilePathAsync,
|
|
23250
|
+
loadEnvFile = loadEnvFileAsync,
|
|
23251
|
+
saveEnvFile = saveEnvFileAsync,
|
|
23252
|
+
getFs = getFileSystem,
|
|
23253
|
+
refreshToken: refreshTokenFn = refreshAccessToken,
|
|
23254
|
+
resolveConfig = resolveConfigAsync,
|
|
23255
|
+
robotFallback = tryRobotClientFallback,
|
|
23256
|
+
loadBreaker = loadRefreshBreaker,
|
|
23257
|
+
saveBreaker = saveRefreshBreaker,
|
|
23258
|
+
clearBreaker = clearRefreshBreaker
|
|
23259
|
+
} = deps;
|
|
23260
|
+
if (isRobotAuthEnforced()) {
|
|
23261
|
+
return resolveRobotEnforcedStatus(robotFallback);
|
|
23262
|
+
}
|
|
23263
|
+
if (isEnvAuthEnabled()) {
|
|
23264
|
+
return readAuthFromEnv();
|
|
23265
|
+
}
|
|
23266
|
+
const activeProfile = getActiveAuthProfile();
|
|
23267
|
+
const activeProfileFilePath = getActiveAuthProfileFilePath();
|
|
23268
|
+
const usingActiveProfile = activeProfile !== undefined && (options.envFilePath === undefined || options.envFilePath === activeProfileFilePath);
|
|
23269
|
+
const envFilePath = options.envFilePath ?? activeProfileFilePath ?? DEFAULT_ENV_FILENAME;
|
|
23270
|
+
const { ensureTokenValidityMinutes } = options;
|
|
23271
|
+
const { absolutePath } = await resolveEnvFilePath(envFilePath);
|
|
23272
|
+
if (absolutePath === undefined) {
|
|
23273
|
+
if (usingActiveProfile) {
|
|
23274
|
+
return {
|
|
23275
|
+
loginStatus: "Not logged in",
|
|
23276
|
+
hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
|
|
23277
|
+
};
|
|
23278
|
+
}
|
|
23279
|
+
return resolveBorrowedRobotStatus(robotFallback);
|
|
23280
|
+
}
|
|
23281
|
+
const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
|
|
23282
|
+
if ("status" in loaded) {
|
|
23283
|
+
return loaded.status;
|
|
23284
|
+
}
|
|
23285
|
+
const { credentials } = loaded;
|
|
23286
|
+
const globalHint = () => usingActiveProfile ? Promise.resolve(undefined) : getGlobalCredsHint(getFs, loadEnvFile, absolutePath, envFilePath);
|
|
23287
|
+
const expiration = getTokenExpiration(credentials.UIPATH_ACCESS_TOKEN);
|
|
23288
|
+
const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
23289
|
+
let tokens = {
|
|
23290
|
+
accessToken: credentials.UIPATH_ACCESS_TOKEN,
|
|
23291
|
+
refreshToken: credentials.UIPATH_REFRESH_TOKEN,
|
|
23292
|
+
expiration,
|
|
23293
|
+
lockReleaseFailed: false
|
|
23294
|
+
};
|
|
23295
|
+
const refreshToken = credentials.UIPATH_REFRESH_TOKEN;
|
|
23296
|
+
if (expiration && expiration <= outerThreshold && refreshToken) {
|
|
23297
|
+
const refreshed = await attemptRefresh({
|
|
23298
|
+
absolutePath,
|
|
23299
|
+
credentials,
|
|
23300
|
+
accessToken: credentials.UIPATH_ACCESS_TOKEN,
|
|
23301
|
+
refreshToken,
|
|
23302
|
+
expiration,
|
|
23303
|
+
ensureTokenValidityMinutes,
|
|
23304
|
+
getFs,
|
|
23305
|
+
loadEnvFile,
|
|
23306
|
+
saveEnvFile,
|
|
23307
|
+
refreshFn: refreshTokenFn,
|
|
23308
|
+
resolveConfig,
|
|
23309
|
+
loadBreaker,
|
|
23310
|
+
saveBreaker,
|
|
23311
|
+
clearBreaker,
|
|
23312
|
+
globalHint
|
|
23313
|
+
});
|
|
23314
|
+
if (refreshed.kind === "terminal") {
|
|
23315
|
+
return refreshed.status;
|
|
23316
|
+
}
|
|
23317
|
+
tokens = refreshed.tokens;
|
|
23318
|
+
}
|
|
23319
|
+
return buildFileStatus(tokens, credentials, globalHint);
|
|
23320
|
+
};
|
|
23321
|
+
async function resolveRobotEnforcedStatus(robotFallback) {
|
|
23322
|
+
if (isEnvAuthEnabled()) {
|
|
23323
|
+
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
23324
|
+
}
|
|
23325
|
+
const robotCreds = await robotFallback({ force: true });
|
|
23326
|
+
if (!robotCreds) {
|
|
23327
|
+
return {
|
|
23328
|
+
loginStatus: "Not logged in",
|
|
23329
|
+
hint: `${ENFORCE_ROBOT_AUTH_VAR}=true but the UiPath Robot ` + `session is unavailable. Start and sign in to the Assistant, ` + `or unset ${ENFORCE_ROBOT_AUTH_VAR} to fall back to file or ` + `env-var authentication.`
|
|
23330
|
+
};
|
|
23331
|
+
}
|
|
23332
|
+
return buildRobotStatus(robotCreds);
|
|
23136
23333
|
}
|
|
23137
|
-
function
|
|
23138
|
-
|
|
23334
|
+
async function resolveBorrowedRobotStatus(robotFallback) {
|
|
23335
|
+
const robotCreds = await robotFallback();
|
|
23336
|
+
return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
|
|
23139
23337
|
}
|
|
23140
|
-
function
|
|
23141
|
-
|
|
23338
|
+
async function loadFileCredentials(loadEnvFile, absolutePath) {
|
|
23339
|
+
let credentials;
|
|
23340
|
+
try {
|
|
23341
|
+
credentials = await loadEnvFile({ envPath: absolutePath });
|
|
23342
|
+
} catch (error) {
|
|
23343
|
+
if (isFileNotFoundError(error)) {
|
|
23344
|
+
return { status: { loginStatus: "Not logged in" } };
|
|
23345
|
+
}
|
|
23346
|
+
throw error;
|
|
23347
|
+
}
|
|
23348
|
+
if (!credentials.UIPATH_ACCESS_TOKEN) {
|
|
23349
|
+
return { status: { loginStatus: "Not logged in" } };
|
|
23350
|
+
}
|
|
23351
|
+
return { credentials };
|
|
23352
|
+
}
|
|
23353
|
+
async function getGlobalCredsHint(getFs, loadEnvFile, absolutePath, envFilePath) {
|
|
23354
|
+
const fs7 = getFs();
|
|
23355
|
+
const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
|
|
23356
|
+
if (absolutePath === globalPath)
|
|
23357
|
+
return;
|
|
23358
|
+
if (!await fs7.exists(globalPath))
|
|
23359
|
+
return;
|
|
23360
|
+
try {
|
|
23361
|
+
const globalCreds = await loadEnvFile({ envPath: globalPath });
|
|
23362
|
+
if (!globalCreds.UIPATH_ACCESS_TOKEN)
|
|
23363
|
+
return;
|
|
23364
|
+
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
23365
|
+
if (globalExp && globalExp <= new Date)
|
|
23366
|
+
return;
|
|
23367
|
+
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.`;
|
|
23368
|
+
} catch {
|
|
23369
|
+
return;
|
|
23370
|
+
}
|
|
23142
23371
|
}
|
|
23143
23372
|
function computeExpirationThreshold(ensureTokenValidityMinutes) {
|
|
23144
23373
|
return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
|
|
23145
23374
|
}
|
|
23375
|
+
async function attemptRefresh(ctx) {
|
|
23376
|
+
const shortCircuit = await circuitBreakerShortCircuit(ctx);
|
|
23377
|
+
if (shortCircuit) {
|
|
23378
|
+
return { kind: "terminal", status: shortCircuit };
|
|
23379
|
+
}
|
|
23380
|
+
let release;
|
|
23381
|
+
try {
|
|
23382
|
+
release = await ctx.getFs().acquireLock(ctx.absolutePath);
|
|
23383
|
+
} catch (error) {
|
|
23384
|
+
return {
|
|
23385
|
+
kind: "terminal",
|
|
23386
|
+
status: await lockAcquireFailureStatus(ctx, error)
|
|
23387
|
+
};
|
|
23388
|
+
}
|
|
23389
|
+
let lockedFailure;
|
|
23390
|
+
let lockReleaseFailed = false;
|
|
23391
|
+
let success;
|
|
23392
|
+
try {
|
|
23393
|
+
const outcome = await runRefreshLocked({
|
|
23394
|
+
absolutePath: ctx.absolutePath,
|
|
23395
|
+
refreshToken: ctx.refreshToken,
|
|
23396
|
+
customAuthority: ctx.credentials.UIPATH_URL,
|
|
23397
|
+
ensureTokenValidityMinutes: ctx.ensureTokenValidityMinutes,
|
|
23398
|
+
loadEnvFile: ctx.loadEnvFile,
|
|
23399
|
+
saveEnvFile: ctx.saveEnvFile,
|
|
23400
|
+
refreshFn: ctx.refreshFn,
|
|
23401
|
+
resolveConfig: ctx.resolveConfig,
|
|
23402
|
+
loadBreaker: ctx.loadBreaker,
|
|
23403
|
+
saveBreaker: ctx.saveBreaker,
|
|
23404
|
+
clearBreaker: ctx.clearBreaker
|
|
23405
|
+
});
|
|
23406
|
+
if (outcome.kind === "fail") {
|
|
23407
|
+
lockedFailure = outcome.status;
|
|
23408
|
+
} else {
|
|
23409
|
+
success = outcome;
|
|
23410
|
+
}
|
|
23411
|
+
} finally {
|
|
23412
|
+
try {
|
|
23413
|
+
await release();
|
|
23414
|
+
} catch {
|
|
23415
|
+
lockReleaseFailed = true;
|
|
23416
|
+
}
|
|
23417
|
+
}
|
|
23418
|
+
if (lockedFailure) {
|
|
23419
|
+
const globalHint = await ctx.globalHint();
|
|
23420
|
+
const base = globalHint ? { ...lockedFailure, loginStatus: "Expired", hint: globalHint } : lockedFailure;
|
|
23421
|
+
return {
|
|
23422
|
+
kind: "terminal",
|
|
23423
|
+
status: lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base
|
|
23424
|
+
};
|
|
23425
|
+
}
|
|
23426
|
+
return {
|
|
23427
|
+
kind: "refreshed",
|
|
23428
|
+
tokens: {
|
|
23429
|
+
accessToken: success?.accessToken,
|
|
23430
|
+
refreshToken: success?.refreshToken,
|
|
23431
|
+
expiration: success?.expiration,
|
|
23432
|
+
tokenRefresh: success?.tokenRefresh,
|
|
23433
|
+
persistenceWarning: success?.persistenceWarning,
|
|
23434
|
+
lockReleaseFailed
|
|
23435
|
+
}
|
|
23436
|
+
};
|
|
23437
|
+
}
|
|
23438
|
+
async function buildFileStatus(tokens, credentials, globalHint) {
|
|
23439
|
+
const result = {
|
|
23440
|
+
loginStatus: tokens.expiration && tokens.expiration <= new Date ? "Expired" : "Logged in",
|
|
23441
|
+
accessToken: tokens.accessToken,
|
|
23442
|
+
refreshToken: tokens.refreshToken,
|
|
23443
|
+
baseUrl: credentials.UIPATH_URL,
|
|
23444
|
+
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
23445
|
+
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
23446
|
+
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
23447
|
+
tenantId: credentials.UIPATH_TENANT_ID,
|
|
23448
|
+
expiration: tokens.expiration,
|
|
23449
|
+
source: "file" /* File */,
|
|
23450
|
+
...tokens.persistenceWarning ? { hint: tokens.persistenceWarning, persistenceFailed: true } : {},
|
|
23451
|
+
...tokens.lockReleaseFailed ? { lockReleaseFailed: true } : {},
|
|
23452
|
+
...tokens.tokenRefresh ? { tokenRefresh: tokens.tokenRefresh } : {}
|
|
23453
|
+
};
|
|
23454
|
+
if (result.loginStatus === "Expired") {
|
|
23455
|
+
const hint = await globalHint();
|
|
23456
|
+
if (hint) {
|
|
23457
|
+
result.hint = hint;
|
|
23458
|
+
}
|
|
23459
|
+
}
|
|
23460
|
+
return result;
|
|
23461
|
+
}
|
|
23462
|
+
function buildRobotStatus(robotCreds) {
|
|
23463
|
+
return {
|
|
23464
|
+
loginStatus: "Logged in",
|
|
23465
|
+
accessToken: robotCreds.accessToken,
|
|
23466
|
+
baseUrl: robotCreds.baseUrl,
|
|
23467
|
+
organizationName: robotCreds.organizationName,
|
|
23468
|
+
organizationId: robotCreds.organizationId,
|
|
23469
|
+
tenantName: robotCreds.tenantName,
|
|
23470
|
+
tenantId: robotCreds.tenantId,
|
|
23471
|
+
issuer: robotCreds.issuer,
|
|
23472
|
+
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
23473
|
+
source: "robot" /* Robot */
|
|
23474
|
+
};
|
|
23475
|
+
}
|
|
23476
|
+
var isFileNotFoundError = (error) => {
|
|
23477
|
+
if (!(error instanceof Object))
|
|
23478
|
+
return false;
|
|
23479
|
+
return error.code === "ENOENT";
|
|
23480
|
+
};
|
|
23481
|
+
async function circuitBreakerShortCircuit(ctx) {
|
|
23482
|
+
const {
|
|
23483
|
+
absolutePath,
|
|
23484
|
+
refreshToken,
|
|
23485
|
+
accessToken,
|
|
23486
|
+
credentials,
|
|
23487
|
+
expiration,
|
|
23488
|
+
loadBreaker,
|
|
23489
|
+
saveBreaker,
|
|
23490
|
+
clearBreaker
|
|
23491
|
+
} = ctx;
|
|
23492
|
+
const fingerprint = await refreshTokenFingerprint(refreshToken);
|
|
23493
|
+
const breaker = await loadBreaker(absolutePath).catch(() => ({}));
|
|
23494
|
+
if (breaker.deadTokenFp && breaker.deadTokenFp !== fingerprint) {
|
|
23495
|
+
await clearBreaker(absolutePath);
|
|
23496
|
+
breaker.deadTokenFp = undefined;
|
|
23497
|
+
}
|
|
23498
|
+
const nowMs = Date.now();
|
|
23499
|
+
const tokenIsDead = breaker.deadTokenFp === fingerprint;
|
|
23500
|
+
const inBackoff = breaker.backoffUntilMs !== undefined && nowMs < breaker.backoffUntilMs;
|
|
23501
|
+
if (!tokenIsDead && !inBackoff)
|
|
23502
|
+
return;
|
|
23503
|
+
const globalHint = await ctx.globalHint();
|
|
23504
|
+
const suppressed = !shouldSurface(breaker, nowMs);
|
|
23505
|
+
if (!suppressed) {
|
|
23506
|
+
await saveBreaker(absolutePath, {
|
|
23507
|
+
...breaker,
|
|
23508
|
+
lastSurfacedAtMs: nowMs
|
|
23509
|
+
});
|
|
23510
|
+
}
|
|
23511
|
+
const deadHint = "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired. In a non-interactive context, authenticate with: uip login --client-id <id> --client-secret <secret> -t <tenant>.";
|
|
23512
|
+
const backoffHint = "Token refresh is temporarily backed off after a recent network error and will retry automatically once the backoff window elapses.";
|
|
23513
|
+
return {
|
|
23514
|
+
loginStatus: globalHint ? "Expired" : "Refresh Failed",
|
|
23515
|
+
...globalHint ? {
|
|
23516
|
+
accessToken,
|
|
23517
|
+
refreshToken,
|
|
23518
|
+
baseUrl: credentials.UIPATH_URL,
|
|
23519
|
+
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
23520
|
+
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
23521
|
+
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
23522
|
+
tenantId: credentials.UIPATH_TENANT_ID,
|
|
23523
|
+
expiration,
|
|
23524
|
+
source: "file" /* File */
|
|
23525
|
+
} : {},
|
|
23526
|
+
hint: globalHint ?? (tokenIsDead ? deadHint : backoffHint),
|
|
23527
|
+
refreshCircuitOpen: true,
|
|
23528
|
+
refreshTelemetrySuppressed: suppressed,
|
|
23529
|
+
tokenRefresh: { attempted: false, success: false }
|
|
23530
|
+
};
|
|
23531
|
+
}
|
|
23532
|
+
async function lockAcquireFailureStatus(ctx, error) {
|
|
23533
|
+
const msg = errorMessage(error);
|
|
23534
|
+
const globalHint = await ctx.globalHint();
|
|
23535
|
+
if (globalHint) {
|
|
23536
|
+
return {
|
|
23537
|
+
loginStatus: "Expired",
|
|
23538
|
+
accessToken: ctx.accessToken,
|
|
23539
|
+
refreshToken: ctx.refreshToken,
|
|
23540
|
+
baseUrl: ctx.credentials.UIPATH_URL,
|
|
23541
|
+
organizationName: ctx.credentials.UIPATH_ORGANIZATION_NAME,
|
|
23542
|
+
organizationId: ctx.credentials.UIPATH_ORGANIZATION_ID,
|
|
23543
|
+
tenantName: ctx.credentials.UIPATH_TENANT_NAME,
|
|
23544
|
+
tenantId: ctx.credentials.UIPATH_TENANT_ID,
|
|
23545
|
+
expiration: ctx.expiration,
|
|
23546
|
+
source: "file" /* File */,
|
|
23547
|
+
hint: globalHint,
|
|
23548
|
+
tokenRefresh: {
|
|
23549
|
+
attempted: false,
|
|
23550
|
+
success: false,
|
|
23551
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
23552
|
+
}
|
|
23553
|
+
};
|
|
23554
|
+
}
|
|
23555
|
+
return {
|
|
23556
|
+
loginStatus: "Refresh Failed",
|
|
23557
|
+
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.",
|
|
23558
|
+
tokenRefresh: {
|
|
23559
|
+
attempted: false,
|
|
23560
|
+
success: false,
|
|
23561
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
23562
|
+
}
|
|
23563
|
+
};
|
|
23564
|
+
}
|
|
23146
23565
|
async function runRefreshLocked(inputs) {
|
|
23147
23566
|
const {
|
|
23148
23567
|
absolutePath,
|
|
@@ -23152,7 +23571,10 @@ async function runRefreshLocked(inputs) {
|
|
|
23152
23571
|
loadEnvFile,
|
|
23153
23572
|
saveEnvFile,
|
|
23154
23573
|
refreshFn,
|
|
23155
|
-
resolveConfig
|
|
23574
|
+
resolveConfig,
|
|
23575
|
+
loadBreaker,
|
|
23576
|
+
saveBreaker,
|
|
23577
|
+
clearBreaker
|
|
23156
23578
|
} = inputs;
|
|
23157
23579
|
const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
23158
23580
|
let fresh;
|
|
@@ -23175,6 +23597,7 @@ async function runRefreshLocked(inputs) {
|
|
|
23175
23597
|
const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
|
|
23176
23598
|
const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
|
|
23177
23599
|
if (freshAccess && freshExp && freshExp > expirationThreshold) {
|
|
23600
|
+
await clearBreaker(absolutePath);
|
|
23178
23601
|
return {
|
|
23179
23602
|
kind: "ok",
|
|
23180
23603
|
accessToken: freshAccess,
|
|
@@ -23198,8 +23621,21 @@ async function runRefreshLocked(inputs) {
|
|
|
23198
23621
|
refreshedRefresh = refreshed.refreshToken;
|
|
23199
23622
|
} catch (error) {
|
|
23200
23623
|
const isOAuthFailure = isTokenRefreshOAuthFailure(error);
|
|
23201
|
-
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.";
|
|
23624
|
+
const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired. In a non-interactive context, authenticate with: uip login --client-id <id> --client-secret <secret> -t <tenant>." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
|
|
23202
23625
|
const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
|
|
23626
|
+
const fp = await refreshTokenFingerprint(tokenForIdP);
|
|
23627
|
+
if (isOAuthFailure) {
|
|
23628
|
+
await saveBreaker(absolutePath, { deadTokenFp: fp });
|
|
23629
|
+
} else {
|
|
23630
|
+
const prior = await loadBreaker(absolutePath).catch(() => ({}));
|
|
23631
|
+
const attempts = (prior.attempts ?? 0) + 1;
|
|
23632
|
+
await saveBreaker(absolutePath, {
|
|
23633
|
+
...prior,
|
|
23634
|
+
deadTokenFp: undefined,
|
|
23635
|
+
attempts,
|
|
23636
|
+
backoffUntilMs: Date.now() + nextBackoffMs(attempts)
|
|
23637
|
+
});
|
|
23638
|
+
}
|
|
23203
23639
|
return {
|
|
23204
23640
|
kind: "fail",
|
|
23205
23641
|
status: {
|
|
@@ -23228,6 +23664,7 @@ async function runRefreshLocked(inputs) {
|
|
|
23228
23664
|
}
|
|
23229
23665
|
};
|
|
23230
23666
|
}
|
|
23667
|
+
await clearBreaker(absolutePath);
|
|
23231
23668
|
try {
|
|
23232
23669
|
await saveEnvFile({
|
|
23233
23670
|
envPath: absolutePath,
|
|
@@ -23260,215 +23697,21 @@ async function runRefreshLocked(inputs) {
|
|
|
23260
23697
|
};
|
|
23261
23698
|
}
|
|
23262
23699
|
}
|
|
23263
|
-
|
|
23264
|
-
|
|
23265
|
-
|
|
23266
|
-
|
|
23267
|
-
|
|
23268
|
-
|
|
23269
|
-
|
|
23270
|
-
|
|
23271
|
-
|
|
23272
|
-
} = deps;
|
|
23273
|
-
if (isRobotAuthEnforced()) {
|
|
23274
|
-
if (isEnvAuthEnabled()) {
|
|
23275
|
-
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
23276
|
-
}
|
|
23277
|
-
const robotCreds = await robotFallback({ force: true });
|
|
23278
|
-
if (!robotCreds) {
|
|
23279
|
-
return {
|
|
23280
|
-
loginStatus: "Not logged in",
|
|
23281
|
-
hint: `${ENFORCE_ROBOT_AUTH_VAR}=true but the UiPath Robot ` + `session is unavailable. Start and sign in to the Assistant, ` + `or unset ${ENFORCE_ROBOT_AUTH_VAR} to fall back to file or ` + `env-var authentication.`
|
|
23282
|
-
};
|
|
23283
|
-
}
|
|
23284
|
-
const expiration2 = getTokenExpiration(robotCreds.accessToken);
|
|
23285
|
-
return {
|
|
23286
|
-
loginStatus: "Logged in",
|
|
23287
|
-
accessToken: robotCreds.accessToken,
|
|
23288
|
-
baseUrl: robotCreds.baseUrl,
|
|
23289
|
-
organizationName: robotCreds.organizationName,
|
|
23290
|
-
organizationId: robotCreds.organizationId,
|
|
23291
|
-
tenantName: robotCreds.tenantName,
|
|
23292
|
-
tenantId: robotCreds.tenantId,
|
|
23293
|
-
expiration: expiration2,
|
|
23294
|
-
source: "robot" /* Robot */
|
|
23295
|
-
};
|
|
23296
|
-
}
|
|
23297
|
-
if (isEnvAuthEnabled()) {
|
|
23298
|
-
return readAuthFromEnv();
|
|
23299
|
-
}
|
|
23300
|
-
const { envFilePath = DEFAULT_ENV_FILENAME, ensureTokenValidityMinutes } = options;
|
|
23301
|
-
const { absolutePath } = await resolveEnvFilePath(envFilePath);
|
|
23302
|
-
if (absolutePath === undefined) {
|
|
23303
|
-
const robotCreds = await robotFallback();
|
|
23304
|
-
if (robotCreds) {
|
|
23305
|
-
const expiration2 = getTokenExpiration(robotCreds.accessToken);
|
|
23306
|
-
const status = {
|
|
23307
|
-
loginStatus: "Logged in",
|
|
23308
|
-
accessToken: robotCreds.accessToken,
|
|
23309
|
-
baseUrl: robotCreds.baseUrl,
|
|
23310
|
-
organizationName: robotCreds.organizationName,
|
|
23311
|
-
organizationId: robotCreds.organizationId,
|
|
23312
|
-
tenantName: robotCreds.tenantName,
|
|
23313
|
-
tenantId: robotCreds.tenantId,
|
|
23314
|
-
expiration: expiration2,
|
|
23315
|
-
source: "robot" /* Robot */
|
|
23316
|
-
};
|
|
23317
|
-
return status;
|
|
23318
|
-
}
|
|
23319
|
-
return { loginStatus: "Not logged in" };
|
|
23320
|
-
}
|
|
23321
|
-
let credentials;
|
|
23322
|
-
try {
|
|
23323
|
-
credentials = await loadEnvFile({ envPath: absolutePath });
|
|
23324
|
-
} catch (error) {
|
|
23325
|
-
if (isFileNotFoundError(error)) {
|
|
23326
|
-
return { loginStatus: "Not logged in" };
|
|
23327
|
-
}
|
|
23328
|
-
throw error;
|
|
23329
|
-
}
|
|
23330
|
-
if (!credentials.UIPATH_ACCESS_TOKEN) {
|
|
23331
|
-
return { loginStatus: "Not logged in" };
|
|
23332
|
-
}
|
|
23333
|
-
let accessToken = credentials.UIPATH_ACCESS_TOKEN;
|
|
23334
|
-
let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
|
|
23335
|
-
let expiration = getTokenExpiration(accessToken);
|
|
23336
|
-
let persistenceWarning;
|
|
23337
|
-
let lockReleaseFailed = false;
|
|
23338
|
-
let tokenRefresh;
|
|
23339
|
-
const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
23340
|
-
const tryGlobalCredsHint = async () => {
|
|
23341
|
-
const fs7 = getFs();
|
|
23342
|
-
const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
|
|
23343
|
-
if (absolutePath === globalPath)
|
|
23344
|
-
return;
|
|
23345
|
-
if (!await fs7.exists(globalPath))
|
|
23346
|
-
return;
|
|
23347
|
-
try {
|
|
23348
|
-
const globalCreds = await loadEnvFile({ envPath: globalPath });
|
|
23349
|
-
if (!globalCreds.UIPATH_ACCESS_TOKEN)
|
|
23350
|
-
return;
|
|
23351
|
-
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
23352
|
-
if (globalExp && globalExp <= new Date)
|
|
23353
|
-
return;
|
|
23354
|
-
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.`;
|
|
23355
|
-
} catch {
|
|
23356
|
-
return;
|
|
23357
|
-
}
|
|
23358
|
-
};
|
|
23359
|
-
if (expiration && expiration <= outerThreshold && refreshToken) {
|
|
23360
|
-
let release;
|
|
23361
|
-
try {
|
|
23362
|
-
release = await getFs().acquireLock(absolutePath);
|
|
23363
|
-
} catch (error) {
|
|
23364
|
-
const msg = errorMessage(error);
|
|
23365
|
-
const globalHint = await tryGlobalCredsHint();
|
|
23366
|
-
if (globalHint) {
|
|
23367
|
-
return {
|
|
23368
|
-
loginStatus: "Expired",
|
|
23369
|
-
accessToken,
|
|
23370
|
-
refreshToken,
|
|
23371
|
-
baseUrl: credentials.UIPATH_URL,
|
|
23372
|
-
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
23373
|
-
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
23374
|
-
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
23375
|
-
tenantId: credentials.UIPATH_TENANT_ID,
|
|
23376
|
-
expiration,
|
|
23377
|
-
source: "file" /* File */,
|
|
23378
|
-
hint: globalHint,
|
|
23379
|
-
tokenRefresh: {
|
|
23380
|
-
attempted: false,
|
|
23381
|
-
success: false,
|
|
23382
|
-
errorMessage: `lock acquisition failed: ${msg}`
|
|
23383
|
-
}
|
|
23384
|
-
};
|
|
23385
|
-
}
|
|
23386
|
-
return {
|
|
23387
|
-
loginStatus: "Refresh Failed",
|
|
23388
|
-
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.",
|
|
23389
|
-
tokenRefresh: {
|
|
23390
|
-
attempted: false,
|
|
23391
|
-
success: false,
|
|
23392
|
-
errorMessage: `lock acquisition failed: ${msg}`
|
|
23393
|
-
}
|
|
23394
|
-
};
|
|
23395
|
-
}
|
|
23396
|
-
let lockedFailure;
|
|
23397
|
-
try {
|
|
23398
|
-
const outcome = await runRefreshLocked({
|
|
23399
|
-
absolutePath,
|
|
23400
|
-
refreshToken,
|
|
23401
|
-
customAuthority: credentials.UIPATH_URL,
|
|
23402
|
-
ensureTokenValidityMinutes,
|
|
23403
|
-
loadEnvFile,
|
|
23404
|
-
saveEnvFile,
|
|
23405
|
-
refreshFn: refreshTokenFn,
|
|
23406
|
-
resolveConfig
|
|
23407
|
-
});
|
|
23408
|
-
if (outcome.kind === "fail") {
|
|
23409
|
-
lockedFailure = outcome.status;
|
|
23410
|
-
} else {
|
|
23411
|
-
accessToken = outcome.accessToken;
|
|
23412
|
-
refreshToken = outcome.refreshToken;
|
|
23413
|
-
expiration = outcome.expiration;
|
|
23414
|
-
tokenRefresh = outcome.tokenRefresh;
|
|
23415
|
-
if (outcome.persistenceWarning) {
|
|
23416
|
-
persistenceWarning = outcome.persistenceWarning;
|
|
23417
|
-
}
|
|
23418
|
-
}
|
|
23419
|
-
} finally {
|
|
23420
|
-
try {
|
|
23421
|
-
await release();
|
|
23422
|
-
} catch {
|
|
23423
|
-
lockReleaseFailed = true;
|
|
23424
|
-
}
|
|
23425
|
-
}
|
|
23426
|
-
if (lockedFailure) {
|
|
23427
|
-
const globalHint = await tryGlobalCredsHint();
|
|
23428
|
-
const base = globalHint ? {
|
|
23429
|
-
...lockedFailure,
|
|
23430
|
-
loginStatus: "Expired",
|
|
23431
|
-
hint: globalHint
|
|
23432
|
-
} : lockedFailure;
|
|
23433
|
-
return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
|
|
23434
|
-
}
|
|
23435
|
-
}
|
|
23436
|
-
const result = {
|
|
23437
|
-
loginStatus: expiration && expiration <= new Date ? "Expired" : "Logged in",
|
|
23438
|
-
accessToken,
|
|
23439
|
-
refreshToken,
|
|
23440
|
-
baseUrl: credentials.UIPATH_URL,
|
|
23441
|
-
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
23442
|
-
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
23443
|
-
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
23444
|
-
tenantId: credentials.UIPATH_TENANT_ID,
|
|
23445
|
-
expiration,
|
|
23446
|
-
source: "file" /* File */,
|
|
23447
|
-
...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
|
|
23448
|
-
...lockReleaseFailed ? { lockReleaseFailed: true } : {},
|
|
23449
|
-
...tokenRefresh ? { tokenRefresh } : {}
|
|
23450
|
-
};
|
|
23451
|
-
if (result.loginStatus === "Expired") {
|
|
23452
|
-
const globalHint = await tryGlobalCredsHint();
|
|
23453
|
-
if (globalHint) {
|
|
23454
|
-
result.hint = globalHint;
|
|
23455
|
-
}
|
|
23456
|
-
}
|
|
23457
|
-
return result;
|
|
23458
|
-
};
|
|
23459
|
-
var isFileNotFoundError = (error) => {
|
|
23460
|
-
if (!(error instanceof Object))
|
|
23461
|
-
return false;
|
|
23462
|
-
return error.code === "ENOENT";
|
|
23463
|
-
};
|
|
23464
|
-
var getLoginStatusAsync = async (options = {}) => {
|
|
23465
|
-
return getLoginStatusWithDeps(options);
|
|
23466
|
-
};
|
|
23700
|
+
function normalizeTokenRefreshFailure() {
|
|
23701
|
+
return "stored refresh token is invalid or expired";
|
|
23702
|
+
}
|
|
23703
|
+
function normalizeTokenRefreshUnavailableFailure() {
|
|
23704
|
+
return "token refresh failed before authentication completed";
|
|
23705
|
+
}
|
|
23706
|
+
function errorMessage(error) {
|
|
23707
|
+
return error instanceof Error ? error.message : String(error);
|
|
23708
|
+
}
|
|
23467
23709
|
|
|
23468
23710
|
// ../auth/src/authContext.ts
|
|
23469
23711
|
var getAuthContext = async (options = {}) => {
|
|
23470
23712
|
const status = await getLoginStatusAsync({
|
|
23471
|
-
ensureTokenValidityMinutes: options.ensureTokenValidityMinutes
|
|
23713
|
+
ensureTokenValidityMinutes: options.ensureTokenValidityMinutes,
|
|
23714
|
+
envFilePath: options.envFilePath
|
|
23472
23715
|
});
|
|
23473
23716
|
if (status.loginStatus !== "Logged in" || !status.baseUrl || !status.accessToken) {
|
|
23474
23717
|
throw new Error(status.hint ? `Not logged in. ${status.hint}` : "Not logged in. Run 'uip login' first.");
|
|
@@ -23497,6 +23740,14 @@ var getAuthContext = async (options = {}) => {
|
|
|
23497
23740
|
};
|
|
23498
23741
|
// ../auth/src/interactive.ts
|
|
23499
23742
|
init_src();
|
|
23743
|
+
|
|
23744
|
+
// ../auth/src/selectTenant.ts
|
|
23745
|
+
var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
|
|
23746
|
+
var INVALID_TENANT_CODE = "INVALID_TENANT";
|
|
23747
|
+
var TENANT_SELECTION_CODES = new Set([
|
|
23748
|
+
TENANT_SELECTION_REQUIRED_CODE,
|
|
23749
|
+
INVALID_TENANT_CODE
|
|
23750
|
+
]);
|
|
23500
23751
|
// ../auth/src/logout.ts
|
|
23501
23752
|
init_src();
|
|
23502
23753
|
|
|
@@ -23540,7 +23791,7 @@ async function getAgentEnforcements(options) {
|
|
|
23540
23791
|
}
|
|
23541
23792
|
return await response.json();
|
|
23542
23793
|
}
|
|
23543
|
-
async function
|
|
23794
|
+
async function getAvailableModels(options) {
|
|
23544
23795
|
const config = await createAgentRuntimeConfig(options);
|
|
23545
23796
|
const tenantId = extractTenantId(config);
|
|
23546
23797
|
const url = `${config.basePath}/api/designer/${encodeURIComponent(tenantId)}/resources/models`;
|
|
@@ -23552,7 +23803,11 @@ async function getAvailableModelNames(options) {
|
|
|
23552
23803
|
throw new Error(`Failed to fetch available models: ${String(response.status)} ${response.statusText}`);
|
|
23553
23804
|
}
|
|
23554
23805
|
const body = await response.json();
|
|
23555
|
-
const
|
|
23806
|
+
const raw = Array.isArray(body) ? body : body.value ?? [];
|
|
23807
|
+
return raw.map((item) => LlmModelFromJSON(item));
|
|
23808
|
+
}
|
|
23809
|
+
async function getAvailableModelNames(options) {
|
|
23810
|
+
const models2 = await getAvailableModels(options);
|
|
23556
23811
|
return models2.map((m) => m.name).filter((n) => n != null);
|
|
23557
23812
|
}
|
|
23558
23813
|
async function getGuardrailDefinitions(options) {
|
|
@@ -23683,6 +23938,7 @@ export {
|
|
|
23683
23938
|
instanceOfAgentAppearance,
|
|
23684
23939
|
getGuardrailDefinitions,
|
|
23685
23940
|
getGuardrailCatalog,
|
|
23941
|
+
getAvailableModels,
|
|
23686
23942
|
getAvailableModelNames,
|
|
23687
23943
|
getAgentEnforcements,
|
|
23688
23944
|
exists,
|
|
@@ -24028,3 +24284,5 @@ export {
|
|
|
24028
24284
|
AgentAppearanceFromJSONTyped,
|
|
24029
24285
|
AgentAppearanceFromJSON
|
|
24030
24286
|
};
|
|
24287
|
+
|
|
24288
|
+
//# debugId=DDC3689ECCE6BAF664756E2164756E21
|
package/dist/src/governance.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LlmModel } from "../generated/src/models/LlmModel.js";
|
|
1
2
|
import { type CreateApiClientOptions } from "./client-factory.js";
|
|
2
3
|
/**
|
|
3
4
|
* Governance enforcement data returned by the platform API.
|
|
@@ -16,11 +17,17 @@ export interface AgentEnforcements {
|
|
|
16
17
|
* (same base URL as all other agent-sdk calls: `agentsruntime_`).
|
|
17
18
|
*/
|
|
18
19
|
export declare function getAgentEnforcements(options?: CreateApiClientOptions): Promise<AgentEnforcements>;
|
|
20
|
+
/**
|
|
21
|
+
* Fetch available models for the authenticated tenant.
|
|
22
|
+
*
|
|
23
|
+
* Endpoint: `GET /api/designer/{tenantId}/resources/models`
|
|
24
|
+
* Returns full `LlmModel[]` objects with provider, token limits, preview status, etc.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getAvailableModels(options?: CreateApiClientOptions): Promise<LlmModel[]>;
|
|
19
27
|
/**
|
|
20
28
|
* Fetch available model names for the authenticated tenant.
|
|
21
29
|
*
|
|
22
|
-
*
|
|
23
|
-
* just the model name strings (the shape consumers need for validation).
|
|
30
|
+
* Delegates to `getAvailableModels()` and extracts just the name strings.
|
|
24
31
|
*/
|
|
25
32
|
export declare function getAvailableModelNames(options?: CreateApiClientOptions): Promise<string[]>;
|
|
26
33
|
export interface GuardrailParameterDefinition {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./user-agent.js";
|
|
2
2
|
export * from "../generated/src/index.js";
|
|
3
3
|
export { type CreateApiClientOptions, createAgentRuntimeConfig, createApiClient, } from "./client-factory.js";
|
|
4
|
-
export { type AgentEnforcements, type GuardrailCatalogEntry, GuardrailCatalogUnavailableError, type GuardrailDefinition, type GuardrailParameterDefinition, type GuardrailsCatalogResponse, getAgentEnforcements, getAvailableModelNames, getGuardrailCatalog, getGuardrailDefinitions, } from "./governance.js";
|
|
4
|
+
export { type AgentEnforcements, type GuardrailCatalogEntry, GuardrailCatalogUnavailableError, type GuardrailDefinition, type GuardrailParameterDefinition, type GuardrailsCatalogResponse, getAgentEnforcements, getAvailableModelNames, getAvailableModels, getGuardrailCatalog, getGuardrailDefinitions, } from "./governance.js";
|
|
5
5
|
export { ProjectFilesSource } from "./types.js";
|
|
6
6
|
export { SDK_USER_AGENT } from "./user-agent.js";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/agent-sdk",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.197.0-preview.59",
|
|
5
5
|
"description": "SDK for the UiPath Agent Runtime API — evaluation execution and debug sessions.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"files": [
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "df0e2b8140cced13f463b487214927c82bc0f85b"
|
|
33
33
|
}
|