@uipath/agent-sdk 1.204.0-preview.255 → 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.
Files changed (2) hide show
  1. package/dist/index.js +135 -26
  2. 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);
@@ -1024,7 +1034,9 @@ var ErrorDimensions = {
1024
1034
  Result: "Result",
1025
1035
  ErrorCode: "ErrorCode",
1026
1036
  Retry: "Retry",
1027
- ErrorMessage: "ErrorMessage"
1037
+ ErrorMessage: "ErrorMessage",
1038
+ HttpStatus: "HttpStatus",
1039
+ UpstreamErrorCode: "UpstreamErrorCode"
1028
1040
  };
1029
1041
  var AuthDimensions = {
1030
1042
  AuthenticationMethod: "AuthenticationMethod",
@@ -1487,7 +1499,7 @@ var package_default = {
1487
1499
  name: "@uipath/agent-sdk",
1488
1500
  author: "UiPath",
1489
1501
  license: "SEE LICENSE IN LICENSE.txt",
1490
- version: "1.204.0-preview.255",
1502
+ version: "1.205.0-preview.256",
1491
1503
  description: "SDK for the UiPath Agent Runtime API — evaluation execution and debug sessions.",
1492
1504
  repository: {
1493
1505
  type: "git",
@@ -4551,22 +4563,12 @@ var resolveConfigAsync = async ({
4551
4563
  baseUrl = DEFAULT_BASE_URL;
4552
4564
  }
4553
4565
  baseUrl = normalizeAndValidateBaseUrl(baseUrl);
4554
- let clientId = customClientId;
4555
- if (!clientId && fileAuth.clientId) {
4556
- clientId = fileAuth.clientId;
4557
- }
4558
- if (!clientId) {
4559
- clientId = DEFAULT_CLIENT_ID;
4560
- }
4561
- let clientSecret = customClientSecret;
4562
- if (!clientSecret && fileAuth.clientSecret) {
4563
- clientSecret = fileAuth.clientSecret;
4564
- }
4565
- const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
4566
+ const clientId = customClientId || DEFAULT_CLIENT_ID;
4567
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(customClientSecret) || Boolean(customClientAssertion));
4566
4568
  const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
4567
4569
  return {
4568
4570
  clientId,
4569
- clientSecret,
4571
+ clientSecret: customClientSecret,
4570
4572
  scopes,
4571
4573
  baseUrl,
4572
4574
  authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
@@ -4741,6 +4743,16 @@ var resolveIdentityType = (claims, authFlow, email) => {
4741
4743
  }
4742
4744
  return;
4743
4745
  };
4746
+ var resolveApplicationSubtype = (claims, authFlow) => {
4747
+ switch (asString(claims?.sub_type)) {
4748
+ case "service.external":
4749
+ return "External";
4750
+ case "service.internal":
4751
+ return "Internal";
4752
+ default:
4753
+ return authFlow === "client_credentials" || authFlow === "federated_credentials" ? "External" : undefined;
4754
+ }
4755
+ };
4744
4756
  var looksLikeEmail = (value) => value?.includes("@") ?? false;
4745
4757
  var pickEmail = (claims) => {
4746
4758
  for (const candidate of [claims?.email, claims?.preferred_username]) {
@@ -4782,6 +4794,12 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
4782
4794
  const clientId = asString(claims?.client_id);
4783
4795
  if (clientId)
4784
4796
  identity.clientId = clientId;
4797
+ const subType = asString(claims?.sub_type);
4798
+ if (subType)
4799
+ identity.subType = subType;
4800
+ const applicationSubtype = resolveApplicationSubtype(claims, authFlow);
4801
+ if (applicationSubtype)
4802
+ identity.applicationSubtype = applicationSubtype;
4785
4803
  return identity;
4786
4804
  };
4787
4805
  var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
@@ -5076,6 +5094,40 @@ var tryRobotClientFallback = async (options = {}) => {
5076
5094
  }
5077
5095
  };
5078
5096
 
5097
+ // ../auth/src/tenantSelection.ts
5098
+ var LOGIN_STATUS_HINT = "Run 'uip login status' to see the organization the CLI is signed in to.";
5099
+ var organizationHint = (organizationId) => `The request used '${organizationId}' as the organization. ${LOGIN_STATUS_HINT}`;
5100
+ var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
5101
+ var describeNonJsonResponse = (organizationId, response, parseError) => {
5102
+ if (response.redirected) {
5103
+ 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}`;
5104
+ }
5105
+ const contentType = response.headers.get("content-type") ?? "unknown";
5106
+ return `The organization service returned a '${contentType}' response instead ` + `of JSON: ${parseError.message}. ${organizationHint(organizationId)}`;
5107
+ };
5108
+ var fetchTenantsAndOrganizations = async (baseUrl, accessToken, organizationId, signal) => {
5109
+ const url = `${baseUrl}/${organizationId}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo`;
5110
+ const response = await fetch(url, {
5111
+ headers: {
5112
+ Authorization: `Bearer ${accessToken}`
5113
+ },
5114
+ ...signal ? { signal } : {}
5115
+ });
5116
+ if (!response.ok) {
5117
+ if (response.status === 401) {
5118
+ 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);
5119
+ }
5120
+ const errorText = await response.text();
5121
+ const message = `Failed to get tenants and organizations: ${response.status} ${errorText}`;
5122
+ throw new Error(IDENTIFIER_STATUSES.has(response.status) ? `${message}. ${organizationHint(organizationId)}` : message);
5123
+ }
5124
+ const [parseError, data] = await catchError(response.json());
5125
+ if (parseError) {
5126
+ throw new Error(describeNonJsonResponse(organizationId, response, parseError));
5127
+ }
5128
+ return data;
5129
+ };
5130
+
5079
5131
  // ../auth/src/tokenRefresh.ts
5080
5132
  var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
5081
5133
 
@@ -5290,6 +5342,8 @@ var saveEnvFileAsync = async ({
5290
5342
  };
5291
5343
 
5292
5344
  // ../auth/src/loginStatus.ts
5345
+ var defaultRobotTenantIdCache = new Map;
5346
+ var ROBOT_TENANT_LOOKUP_TIMEOUT_MS = 5000;
5293
5347
  var getLoginStatusAsync = async (options = {}) => {
5294
5348
  return getLoginStatusWithDeps(options);
5295
5349
  };
@@ -5302,12 +5356,20 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
5302
5356
  refreshToken: refreshTokenFn = refreshAccessToken,
5303
5357
  resolveConfig = resolveConfigAsync,
5304
5358
  robotFallback = tryRobotClientFallback,
5359
+ fetchTenantsAndOrgs = fetchTenantsAndOrganizations,
5360
+ robotTenantIdCache = defaultRobotTenantIdCache,
5361
+ robotTenantLookupTimeoutMs = ROBOT_TENANT_LOOKUP_TIMEOUT_MS,
5305
5362
  loadBreaker = loadRefreshBreaker,
5306
5363
  saveBreaker = saveRefreshBreaker,
5307
5364
  clearBreaker = clearRefreshBreaker
5308
5365
  } = deps;
5366
+ const robotDeps = {
5367
+ fetchTenantsAndOrgs,
5368
+ cache: robotTenantIdCache,
5369
+ lookupTimeoutMs: robotTenantLookupTimeoutMs
5370
+ };
5309
5371
  if (isRobotAuthEnforced()) {
5310
- return resolveRobotEnforcedStatus(robotFallback);
5372
+ return resolveRobotEnforcedStatus(robotFallback, robotDeps);
5311
5373
  }
5312
5374
  if (isEnvAuthEnabled()) {
5313
5375
  return readAuthFromEnv();
@@ -5325,7 +5387,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
5325
5387
  hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
5326
5388
  };
5327
5389
  }
5328
- return resolveBorrowedRobotStatus(robotFallback);
5390
+ return resolveBorrowedRobotStatus(robotFallback, robotDeps);
5329
5391
  }
5330
5392
  const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
5331
5393
  if ("status" in loaded) {
@@ -5367,7 +5429,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
5367
5429
  }
5368
5430
  return buildFileStatus(tokens, credentials, globalHint);
5369
5431
  };
5370
- async function resolveRobotEnforcedStatus(robotFallback) {
5432
+ async function resolveRobotEnforcedStatus(robotFallback, deps) {
5371
5433
  if (isEnvAuthEnabled()) {
5372
5434
  throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
5373
5435
  }
@@ -5378,11 +5440,11 @@ async function resolveRobotEnforcedStatus(robotFallback) {
5378
5440
  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.`
5379
5441
  };
5380
5442
  }
5381
- return buildRobotStatus(robotCreds);
5443
+ return buildRobotStatus(robotCreds, deps);
5382
5444
  }
5383
- async function resolveBorrowedRobotStatus(robotFallback) {
5445
+ async function resolveBorrowedRobotStatus(robotFallback, deps) {
5384
5446
  const robotCreds = await robotFallback();
5385
- return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
5447
+ return robotCreds ? buildRobotStatus(robotCreds, deps) : { loginStatus: "Not logged in" };
5386
5448
  }
5387
5449
  async function loadFileCredentials(loadEnvFile, absolutePath) {
5388
5450
  let credentials;
@@ -5517,9 +5579,10 @@ function identityFields(accessToken, credentials) {
5517
5579
  ...scopes ? { scopes } : {}
5518
5580
  };
5519
5581
  }
5520
- function buildRobotStatus(robotCreds) {
5582
+ async function buildRobotStatus(robotCreds, deps) {
5521
5583
  const identity = resolveSessionIdentity(robotCreds.accessToken);
5522
5584
  const scopes = readTokenScopes(robotCreds.accessToken);
5585
+ const tenant = robotCreds.tenantId ? { tenantId: robotCreds.tenantId } : await resolveRobotTenantId(robotCreds, deps);
5523
5586
  return {
5524
5587
  loginStatus: "Logged in",
5525
5588
  accessToken: robotCreds.accessToken,
@@ -5527,14 +5590,62 @@ function buildRobotStatus(robotCreds) {
5527
5590
  organizationName: robotCreds.organizationName,
5528
5591
  organizationId: robotCreds.organizationId,
5529
5592
  tenantName: robotCreds.tenantName,
5530
- tenantId: robotCreds.tenantId,
5593
+ tenantId: tenant.tenantId,
5531
5594
  issuer: robotCreds.issuer,
5532
5595
  expiration: getTokenExpiration(robotCreds.accessToken),
5533
5596
  source: "robot" /* Robot */,
5597
+ ...tenant.hint ? { hint: tenant.hint } : {},
5534
5598
  ...identity ? { identity } : {},
5535
5599
  ...scopes ? { scopes } : {}
5536
5600
  };
5537
5601
  }
5602
+ async function resolveRobotTenantId(robotCreds, deps) {
5603
+ const { baseUrl, accessToken, tenantName } = robotCreds;
5604
+ const organization = robotCreds.organizationName ?? robotCreds.organizationId;
5605
+ if (!tenantName || !organization) {
5606
+ return {};
5607
+ }
5608
+ const key = `${baseUrl}|${organization}|${tenantName}|${accessToken}`;
5609
+ let pending = deps.cache.get(key);
5610
+ if (!pending) {
5611
+ pending = catchError(lookupRobotTenantId({ baseUrl, accessToken, organization, tenantName }, deps)).then(([error, resolution]) => {
5612
+ const settled = error ? { hint: tenantLookupFailureHint(tenantName, error.message) } : resolution;
5613
+ if (!settled.tenantId) {
5614
+ deps.cache.delete(key);
5615
+ }
5616
+ return settled;
5617
+ });
5618
+ deps.cache.set(key, pending);
5619
+ }
5620
+ return pending;
5621
+ }
5622
+ async function lookupRobotTenantId(target, deps) {
5623
+ const { baseUrl, accessToken, organization, tenantName } = target;
5624
+ const [error, data] = await catchError(deps.fetchTenantsAndOrgs(baseUrl, accessToken, organization, AbortSignal.timeout(deps.lookupTimeoutMs)));
5625
+ if (error) {
5626
+ const reason = error.name === "TimeoutError" ? `the tenant list did not answer within ${deps.lookupTimeoutMs} ms.` : error.message;
5627
+ return { hint: tenantLookupFailureHint(tenantName, reason) };
5628
+ }
5629
+ const rows = data?.tenants;
5630
+ const tenants = Array.isArray(rows) ? rows.filter((tenant) => typeof tenant?.id === "string" && typeof tenant?.name === "string") : [];
5631
+ const wantedName = decodePathSegment(tenantName);
5632
+ const wanted = wantedName.toLowerCase();
5633
+ const match = tenants.find((tenant) => tenant.name === wantedName) ?? tenants.find((tenant) => tenant.name.toLowerCase() === wanted);
5634
+ if (!match) {
5635
+ const names = tenants.map((tenant) => tenant.name).join(", ");
5636
+ return {
5637
+ 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.`
5638
+ };
5639
+ }
5640
+ return { tenantId: match.id };
5641
+ }
5642
+ function tenantLookupFailureHint(tenantName, reason) {
5643
+ 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.`;
5644
+ }
5645
+ function decodePathSegment(segment) {
5646
+ const [error, decoded] = catchError(() => decodeURIComponent(segment));
5647
+ return error ? segment : decoded;
5648
+ }
5538
5649
  var isFileNotFoundError = (error) => {
5539
5650
  if (!(error instanceof Object))
5540
5651
  return false;
@@ -5811,8 +5922,6 @@ init_constants();
5811
5922
  // ../auth/src/interactive.ts
5812
5923
  init_src();
5813
5924
  init_constants();
5814
- // ../auth/src/tenantSelection.ts
5815
- var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
5816
5925
 
5817
5926
  // ../auth/src/selectTenant.ts
5818
5927
  var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
@@ -6354,4 +6463,4 @@ export {
6354
6463
  querystring
6355
6464
  };
6356
6465
 
6357
- //# debugId=546889A894D1EE0564756E2164756E21
6466
+ //# debugId=6D65DDD5D47D59AE64756E2164756E21
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@uipath/agent-sdk",
3
3
  "author": "UiPath",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
- "version": "1.204.0-preview.255",
5
+ "version": "1.205.0-preview.256",
6
6
  "description": "SDK for the UiPath Agent Runtime API — evaluation execution and debug sessions.",
7
7
  "repository": {
8
8
  "type": "git",
@@ -30,5 +30,5 @@
30
30
  "files": [
31
31
  "dist"
32
32
  ],
33
- "gitHead": "699c58dabb59414557755a8933bcbe40aa420df3"
33
+ "gitHead": "63740c6cbb7ff282fa9118cc16a148eb030b245f"
34
34
  }