@uipath/ixp-sdk 1.204.0-preview.254 → 1.205.0-preview.256
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 +135 -26
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -883,6 +883,16 @@ class NodeFileSystem {
|
|
|
883
883
|
async rename(oldPath, newPath) {
|
|
884
884
|
await fs6.rename(oldPath, newPath);
|
|
885
885
|
}
|
|
886
|
+
async isSymbolicLink(filePath) {
|
|
887
|
+
try {
|
|
888
|
+
return (await fs6.lstat(filePath)).isSymbolicLink();
|
|
889
|
+
} catch (error) {
|
|
890
|
+
if (this.isEnoent(error) || this.hasErrnoCode(error, "ENOTDIR")) {
|
|
891
|
+
return false;
|
|
892
|
+
}
|
|
893
|
+
throw error;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
886
896
|
async realpath(filePath) {
|
|
887
897
|
try {
|
|
888
898
|
return await fs6.realpath(filePath);
|
|
@@ -1014,22 +1024,12 @@ var resolveConfigAsync = async ({
|
|
|
1014
1024
|
baseUrl = DEFAULT_BASE_URL;
|
|
1015
1025
|
}
|
|
1016
1026
|
baseUrl = normalizeAndValidateBaseUrl(baseUrl);
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
clientId = fileAuth.clientId;
|
|
1020
|
-
}
|
|
1021
|
-
if (!clientId) {
|
|
1022
|
-
clientId = DEFAULT_CLIENT_ID;
|
|
1023
|
-
}
|
|
1024
|
-
let clientSecret = customClientSecret;
|
|
1025
|
-
if (!clientSecret && fileAuth.clientSecret) {
|
|
1026
|
-
clientSecret = fileAuth.clientSecret;
|
|
1027
|
-
}
|
|
1028
|
-
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
|
|
1027
|
+
const clientId = customClientId || DEFAULT_CLIENT_ID;
|
|
1028
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(customClientSecret) || Boolean(customClientAssertion));
|
|
1029
1029
|
const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
|
|
1030
1030
|
return {
|
|
1031
1031
|
clientId,
|
|
1032
|
-
clientSecret,
|
|
1032
|
+
clientSecret: customClientSecret,
|
|
1033
1033
|
scopes,
|
|
1034
1034
|
baseUrl,
|
|
1035
1035
|
authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
|
|
@@ -1204,6 +1204,16 @@ var resolveIdentityType = (claims, authFlow, email) => {
|
|
|
1204
1204
|
}
|
|
1205
1205
|
return;
|
|
1206
1206
|
};
|
|
1207
|
+
var resolveApplicationSubtype = (claims, authFlow) => {
|
|
1208
|
+
switch (asString(claims?.sub_type)) {
|
|
1209
|
+
case "service.external":
|
|
1210
|
+
return "External";
|
|
1211
|
+
case "service.internal":
|
|
1212
|
+
return "Internal";
|
|
1213
|
+
default:
|
|
1214
|
+
return authFlow === "client_credentials" || authFlow === "federated_credentials" ? "External" : undefined;
|
|
1215
|
+
}
|
|
1216
|
+
};
|
|
1207
1217
|
var looksLikeEmail = (value) => value?.includes("@") ?? false;
|
|
1208
1218
|
var pickEmail = (claims) => {
|
|
1209
1219
|
for (const candidate of [claims?.email, claims?.preferred_username]) {
|
|
@@ -1245,6 +1255,12 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
|
1245
1255
|
const clientId = asString(claims?.client_id);
|
|
1246
1256
|
if (clientId)
|
|
1247
1257
|
identity.clientId = clientId;
|
|
1258
|
+
const subType = asString(claims?.sub_type);
|
|
1259
|
+
if (subType)
|
|
1260
|
+
identity.subType = subType;
|
|
1261
|
+
const applicationSubtype = resolveApplicationSubtype(claims, authFlow);
|
|
1262
|
+
if (applicationSubtype)
|
|
1263
|
+
identity.applicationSubtype = applicationSubtype;
|
|
1248
1264
|
return identity;
|
|
1249
1265
|
};
|
|
1250
1266
|
var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
|
|
@@ -1539,6 +1555,40 @@ var tryRobotClientFallback = async (options = {}) => {
|
|
|
1539
1555
|
}
|
|
1540
1556
|
};
|
|
1541
1557
|
|
|
1558
|
+
// ../auth/src/tenantSelection.ts
|
|
1559
|
+
var LOGIN_STATUS_HINT = "Run 'uip login status' to see the organization the CLI is signed in to.";
|
|
1560
|
+
var organizationHint = (organizationId) => `The request used '${organizationId}' as the organization. ${LOGIN_STATUS_HINT}`;
|
|
1561
|
+
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
1562
|
+
var describeNonJsonResponse = (organizationId, response, parseError) => {
|
|
1563
|
+
if (response.redirected) {
|
|
1564
|
+
return `Could not find organization '${organizationId}': the request was ` + `redirected to a sign-in page instead of the organization's tenant ` + `list. ${LOGIN_STATUS_HINT}`;
|
|
1565
|
+
}
|
|
1566
|
+
const contentType = response.headers.get("content-type") ?? "unknown";
|
|
1567
|
+
return `The organization service returned a '${contentType}' response instead ` + `of JSON: ${parseError.message}. ${organizationHint(organizationId)}`;
|
|
1568
|
+
};
|
|
1569
|
+
var fetchTenantsAndOrganizations = async (baseUrl, accessToken, organizationId, signal) => {
|
|
1570
|
+
const url = `${baseUrl}/${organizationId}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo`;
|
|
1571
|
+
const response = await fetch(url, {
|
|
1572
|
+
headers: {
|
|
1573
|
+
Authorization: `Bearer ${accessToken}`
|
|
1574
|
+
},
|
|
1575
|
+
...signal ? { signal } : {}
|
|
1576
|
+
});
|
|
1577
|
+
if (!response.ok) {
|
|
1578
|
+
if (response.status === 401) {
|
|
1579
|
+
throw new Error(`Unauthorized: the access token was rejected, it was not ` + `issued for organization '${organizationId}', or ` + `'${organizationId}' was not accepted as an organization ` + `URL segment in this environment. ` + LOGIN_STATUS_HINT);
|
|
1580
|
+
}
|
|
1581
|
+
const errorText = await response.text();
|
|
1582
|
+
const message = `Failed to get tenants and organizations: ${response.status} ${errorText}`;
|
|
1583
|
+
throw new Error(IDENTIFIER_STATUSES.has(response.status) ? `${message}. ${organizationHint(organizationId)}` : message);
|
|
1584
|
+
}
|
|
1585
|
+
const [parseError, data] = await catchError(response.json());
|
|
1586
|
+
if (parseError) {
|
|
1587
|
+
throw new Error(describeNonJsonResponse(organizationId, response, parseError));
|
|
1588
|
+
}
|
|
1589
|
+
return data;
|
|
1590
|
+
};
|
|
1591
|
+
|
|
1542
1592
|
// ../auth/src/tokenRefresh.ts
|
|
1543
1593
|
var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
|
|
1544
1594
|
|
|
@@ -1753,6 +1803,8 @@ var saveEnvFileAsync = async ({
|
|
|
1753
1803
|
};
|
|
1754
1804
|
|
|
1755
1805
|
// ../auth/src/loginStatus.ts
|
|
1806
|
+
var defaultRobotTenantIdCache = new Map;
|
|
1807
|
+
var ROBOT_TENANT_LOOKUP_TIMEOUT_MS = 5000;
|
|
1756
1808
|
var getLoginStatusAsync = async (options = {}) => {
|
|
1757
1809
|
return getLoginStatusWithDeps(options);
|
|
1758
1810
|
};
|
|
@@ -1765,12 +1817,20 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
1765
1817
|
refreshToken: refreshTokenFn = refreshAccessToken,
|
|
1766
1818
|
resolveConfig = resolveConfigAsync,
|
|
1767
1819
|
robotFallback = tryRobotClientFallback,
|
|
1820
|
+
fetchTenantsAndOrgs = fetchTenantsAndOrganizations,
|
|
1821
|
+
robotTenantIdCache = defaultRobotTenantIdCache,
|
|
1822
|
+
robotTenantLookupTimeoutMs = ROBOT_TENANT_LOOKUP_TIMEOUT_MS,
|
|
1768
1823
|
loadBreaker = loadRefreshBreaker,
|
|
1769
1824
|
saveBreaker = saveRefreshBreaker,
|
|
1770
1825
|
clearBreaker = clearRefreshBreaker
|
|
1771
1826
|
} = deps;
|
|
1827
|
+
const robotDeps = {
|
|
1828
|
+
fetchTenantsAndOrgs,
|
|
1829
|
+
cache: robotTenantIdCache,
|
|
1830
|
+
lookupTimeoutMs: robotTenantLookupTimeoutMs
|
|
1831
|
+
};
|
|
1772
1832
|
if (isRobotAuthEnforced()) {
|
|
1773
|
-
return resolveRobotEnforcedStatus(robotFallback);
|
|
1833
|
+
return resolveRobotEnforcedStatus(robotFallback, robotDeps);
|
|
1774
1834
|
}
|
|
1775
1835
|
if (isEnvAuthEnabled()) {
|
|
1776
1836
|
return readAuthFromEnv();
|
|
@@ -1788,7 +1848,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
1788
1848
|
hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
|
|
1789
1849
|
};
|
|
1790
1850
|
}
|
|
1791
|
-
return resolveBorrowedRobotStatus(robotFallback);
|
|
1851
|
+
return resolveBorrowedRobotStatus(robotFallback, robotDeps);
|
|
1792
1852
|
}
|
|
1793
1853
|
const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
|
|
1794
1854
|
if ("status" in loaded) {
|
|
@@ -1830,7 +1890,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
1830
1890
|
}
|
|
1831
1891
|
return buildFileStatus(tokens, credentials, globalHint);
|
|
1832
1892
|
};
|
|
1833
|
-
async function resolveRobotEnforcedStatus(robotFallback) {
|
|
1893
|
+
async function resolveRobotEnforcedStatus(robotFallback, deps) {
|
|
1834
1894
|
if (isEnvAuthEnabled()) {
|
|
1835
1895
|
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
1836
1896
|
}
|
|
@@ -1841,11 +1901,11 @@ async function resolveRobotEnforcedStatus(robotFallback) {
|
|
|
1841
1901
|
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.`
|
|
1842
1902
|
};
|
|
1843
1903
|
}
|
|
1844
|
-
return buildRobotStatus(robotCreds);
|
|
1904
|
+
return buildRobotStatus(robotCreds, deps);
|
|
1845
1905
|
}
|
|
1846
|
-
async function resolveBorrowedRobotStatus(robotFallback) {
|
|
1906
|
+
async function resolveBorrowedRobotStatus(robotFallback, deps) {
|
|
1847
1907
|
const robotCreds = await robotFallback();
|
|
1848
|
-
return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
|
|
1908
|
+
return robotCreds ? buildRobotStatus(robotCreds, deps) : { loginStatus: "Not logged in" };
|
|
1849
1909
|
}
|
|
1850
1910
|
async function loadFileCredentials(loadEnvFile, absolutePath) {
|
|
1851
1911
|
let credentials;
|
|
@@ -1980,9 +2040,10 @@ function identityFields(accessToken, credentials) {
|
|
|
1980
2040
|
...scopes ? { scopes } : {}
|
|
1981
2041
|
};
|
|
1982
2042
|
}
|
|
1983
|
-
function buildRobotStatus(robotCreds) {
|
|
2043
|
+
async function buildRobotStatus(robotCreds, deps) {
|
|
1984
2044
|
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
1985
2045
|
const scopes = readTokenScopes(robotCreds.accessToken);
|
|
2046
|
+
const tenant = robotCreds.tenantId ? { tenantId: robotCreds.tenantId } : await resolveRobotTenantId(robotCreds, deps);
|
|
1986
2047
|
return {
|
|
1987
2048
|
loginStatus: "Logged in",
|
|
1988
2049
|
accessToken: robotCreds.accessToken,
|
|
@@ -1990,14 +2051,62 @@ function buildRobotStatus(robotCreds) {
|
|
|
1990
2051
|
organizationName: robotCreds.organizationName,
|
|
1991
2052
|
organizationId: robotCreds.organizationId,
|
|
1992
2053
|
tenantName: robotCreds.tenantName,
|
|
1993
|
-
tenantId:
|
|
2054
|
+
tenantId: tenant.tenantId,
|
|
1994
2055
|
issuer: robotCreds.issuer,
|
|
1995
2056
|
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
1996
2057
|
source: "robot" /* Robot */,
|
|
2058
|
+
...tenant.hint ? { hint: tenant.hint } : {},
|
|
1997
2059
|
...identity ? { identity } : {},
|
|
1998
2060
|
...scopes ? { scopes } : {}
|
|
1999
2061
|
};
|
|
2000
2062
|
}
|
|
2063
|
+
async function resolveRobotTenantId(robotCreds, deps) {
|
|
2064
|
+
const { baseUrl, accessToken, tenantName } = robotCreds;
|
|
2065
|
+
const organization = robotCreds.organizationName ?? robotCreds.organizationId;
|
|
2066
|
+
if (!tenantName || !organization) {
|
|
2067
|
+
return {};
|
|
2068
|
+
}
|
|
2069
|
+
const key = `${baseUrl}|${organization}|${tenantName}|${accessToken}`;
|
|
2070
|
+
let pending = deps.cache.get(key);
|
|
2071
|
+
if (!pending) {
|
|
2072
|
+
pending = catchError(lookupRobotTenantId({ baseUrl, accessToken, organization, tenantName }, deps)).then(([error, resolution]) => {
|
|
2073
|
+
const settled = error ? { hint: tenantLookupFailureHint(tenantName, error.message) } : resolution;
|
|
2074
|
+
if (!settled.tenantId) {
|
|
2075
|
+
deps.cache.delete(key);
|
|
2076
|
+
}
|
|
2077
|
+
return settled;
|
|
2078
|
+
});
|
|
2079
|
+
deps.cache.set(key, pending);
|
|
2080
|
+
}
|
|
2081
|
+
return pending;
|
|
2082
|
+
}
|
|
2083
|
+
async function lookupRobotTenantId(target, deps) {
|
|
2084
|
+
const { baseUrl, accessToken, organization, tenantName } = target;
|
|
2085
|
+
const [error, data] = await catchError(deps.fetchTenantsAndOrgs(baseUrl, accessToken, organization, AbortSignal.timeout(deps.lookupTimeoutMs)));
|
|
2086
|
+
if (error) {
|
|
2087
|
+
const reason = error.name === "TimeoutError" ? `the tenant list did not answer within ${deps.lookupTimeoutMs} ms.` : error.message;
|
|
2088
|
+
return { hint: tenantLookupFailureHint(tenantName, reason) };
|
|
2089
|
+
}
|
|
2090
|
+
const rows = data?.tenants;
|
|
2091
|
+
const tenants = Array.isArray(rows) ? rows.filter((tenant) => typeof tenant?.id === "string" && typeof tenant?.name === "string") : [];
|
|
2092
|
+
const wantedName = decodePathSegment(tenantName);
|
|
2093
|
+
const wanted = wantedName.toLowerCase();
|
|
2094
|
+
const match = tenants.find((tenant) => tenant.name === wantedName) ?? tenants.find((tenant) => tenant.name.toLowerCase() === wanted);
|
|
2095
|
+
if (!match) {
|
|
2096
|
+
const names = tenants.map((tenant) => tenant.name).join(", ");
|
|
2097
|
+
return {
|
|
2098
|
+
hint: `The Robot session targets tenant '${tenantName}', but ` + `organization '${organization}' lists no tenant of that name` + `${names ? ` (available: ${names})` : ""}. Commands that need ` + `the tenant id will fail until it can be resolved.`
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
return { tenantId: match.id };
|
|
2102
|
+
}
|
|
2103
|
+
function tenantLookupFailureHint(tenantName, reason) {
|
|
2104
|
+
return `Could not resolve the id of tenant '${tenantName}' from the ` + `Robot session: ${reason} Commands that need the tenant id will ` + `fail until it can be resolved.`;
|
|
2105
|
+
}
|
|
2106
|
+
function decodePathSegment(segment) {
|
|
2107
|
+
const [error, decoded] = catchError(() => decodeURIComponent(segment));
|
|
2108
|
+
return error ? segment : decoded;
|
|
2109
|
+
}
|
|
2001
2110
|
var isFileNotFoundError = (error) => {
|
|
2002
2111
|
if (!(error instanceof Object))
|
|
2003
2112
|
return false;
|
|
@@ -2241,8 +2350,6 @@ init_constants();
|
|
|
2241
2350
|
// ../auth/src/interactive.ts
|
|
2242
2351
|
init_src();
|
|
2243
2352
|
init_constants();
|
|
2244
|
-
// ../auth/src/tenantSelection.ts
|
|
2245
|
-
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
2246
2353
|
|
|
2247
2354
|
// ../auth/src/selectTenant.ts
|
|
2248
2355
|
var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
|
|
@@ -2348,7 +2455,9 @@ var ErrorDimensions = {
|
|
|
2348
2455
|
Result: "Result",
|
|
2349
2456
|
ErrorCode: "ErrorCode",
|
|
2350
2457
|
Retry: "Retry",
|
|
2351
|
-
ErrorMessage: "ErrorMessage"
|
|
2458
|
+
ErrorMessage: "ErrorMessage",
|
|
2459
|
+
HttpStatus: "HttpStatus",
|
|
2460
|
+
UpstreamErrorCode: "UpstreamErrorCode"
|
|
2352
2461
|
};
|
|
2353
2462
|
var AuthDimensions = {
|
|
2354
2463
|
AuthenticationMethod: "AuthenticationMethod",
|
|
@@ -2475,7 +2584,7 @@ var package_default = {
|
|
|
2475
2584
|
name: "@uipath/ixp-sdk",
|
|
2476
2585
|
author: "UiPath",
|
|
2477
2586
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
2478
|
-
version: "1.
|
|
2587
|
+
version: "1.205.0-preview.256",
|
|
2479
2588
|
description: "SDK for the UiPath IXP (Intelligent eXtraction Platform) API — projects, taxonomies, prompts, predictions, and model publishing.",
|
|
2480
2589
|
repository: {
|
|
2481
2590
|
type: "git",
|
|
@@ -2907,4 +3016,4 @@ export {
|
|
|
2907
3016
|
uploadDocument
|
|
2908
3017
|
};
|
|
2909
3018
|
|
|
2910
|
-
//# debugId=
|
|
3019
|
+
//# debugId=5E2A702605D20B6164756E2164756E21
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/ixp-sdk",
|
|
3
3
|
"author": "UiPath",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.205.0-preview.256",
|
|
6
6
|
"description": "SDK for the UiPath IXP (Intelligent eXtraction Platform) API — projects, taxonomies, prompts, predictions, and model publishing.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "63740c6cbb7ff282fa9118cc16a148eb030b245f"
|
|
29
29
|
}
|