@uipath/uipath-python-bridge 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.
Files changed (2) hide show
  1. package/dist/index.js +142 -27
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -876,6 +876,16 @@ class NodeFileSystem {
876
876
  async rename(oldPath, newPath) {
877
877
  await fs6.rename(oldPath, newPath);
878
878
  }
879
+ async isSymbolicLink(filePath) {
880
+ try {
881
+ return (await fs6.lstat(filePath)).isSymbolicLink();
882
+ } catch (error) {
883
+ if (this.isEnoent(error) || this.hasErrnoCode(error, "ENOTDIR")) {
884
+ return false;
885
+ }
886
+ throw error;
887
+ }
888
+ }
879
889
  async realpath(filePath) {
880
890
  try {
881
891
  return await fs6.realpath(filePath);
@@ -8313,7 +8323,7 @@ function setGlobalLogFilePath(path3) {
8313
8323
  function getGlobalLogFilePath() {
8314
8324
  return logFilePathSlot.get("");
8315
8325
  }
8316
- var DEFAULT_LOG_LEVEL = 3 /* ERROR */;
8326
+ var DEFAULT_LOG_LEVEL = 2 /* WARN */;
8317
8327
 
8318
8328
  class SimpleLogger {
8319
8329
  __brand = "SimpleLogger";
@@ -8583,7 +8593,9 @@ var ErrorDimensions = {
8583
8593
  Result: "Result",
8584
8594
  ErrorCode: "ErrorCode",
8585
8595
  Retry: "Retry",
8586
- ErrorMessage: "ErrorMessage"
8596
+ ErrorMessage: "ErrorMessage",
8597
+ HttpStatus: "HttpStatus",
8598
+ UpstreamErrorCode: "UpstreamErrorCode"
8587
8599
  };
8588
8600
  var AuthDimensions = {
8589
8601
  AuthenticationMethod: "AuthenticationMethod",
@@ -9576,7 +9588,9 @@ var CLI_ERROR_CODES = [
9576
9588
  "timeout",
9577
9589
  "server_error",
9578
9590
  "method_not_allowed",
9591
+ "not_supported",
9579
9592
  "configuration_error",
9593
+ "execution_failed",
9580
9594
  "unknown_error"
9581
9595
  ];
9582
9596
  var RETRY_HINTS = [
@@ -10533,7 +10547,9 @@ var OutputFormatter;
10533
10547
  [ErrorDimensions.Result]: data.Result,
10534
10548
  [ErrorDimensions.ErrorCode]: data.ErrorCode,
10535
10549
  [ErrorDimensions.Retry]: data.Retry,
10536
- [ErrorDimensions.ErrorMessage]: data.Message
10550
+ [ErrorDimensions.ErrorMessage]: data.Message,
10551
+ [ErrorDimensions.HttpStatus]: data.Context?.httpStatus?.toString(),
10552
+ [ErrorDimensions.UpstreamErrorCode]: data.Context?.errorCode
10537
10553
  });
10538
10554
  }
10539
10555
  logOutput(normalizeOutputKeys(envelope), getOutputFormat());
@@ -11294,6 +11310,8 @@ var BOOLEAN_FLAGS = new Set(HOST_GLOBAL_FLAGS);
11294
11310
  // ../common/src/interactivity-context.ts
11295
11311
  var modeSlot = singleton("InteractivityMode");
11296
11312
  var interactiveFlagSlot = singleton("InteractiveFlag");
11313
+ // ../common/src/json-option.ts
11314
+ init_src();
11297
11315
  // ../common/src/mime-types.ts
11298
11316
  var MIME_TYPES_BY_EXTENSION = Object.freeze({
11299
11317
  pdf: "application/pdf",
@@ -11549,22 +11567,12 @@ var resolveConfigAsync = async ({
11549
11567
  baseUrl = DEFAULT_BASE_URL;
11550
11568
  }
11551
11569
  baseUrl = normalizeAndValidateBaseUrl(baseUrl);
11552
- let clientId = customClientId;
11553
- if (!clientId && fileAuth.clientId) {
11554
- clientId = fileAuth.clientId;
11555
- }
11556
- if (!clientId) {
11557
- clientId = DEFAULT_CLIENT_ID;
11558
- }
11559
- let clientSecret = customClientSecret;
11560
- if (!clientSecret && fileAuth.clientSecret) {
11561
- clientSecret = fileAuth.clientSecret;
11562
- }
11563
- const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
11570
+ const clientId = customClientId || DEFAULT_CLIENT_ID;
11571
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(customClientSecret) || Boolean(customClientAssertion));
11564
11572
  const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
11565
11573
  return {
11566
11574
  clientId,
11567
- clientSecret,
11575
+ clientSecret: customClientSecret,
11568
11576
  scopes,
11569
11577
  baseUrl,
11570
11578
  authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
@@ -11739,6 +11747,16 @@ var resolveIdentityType = (claims, authFlow, email) => {
11739
11747
  }
11740
11748
  return;
11741
11749
  };
11750
+ var resolveApplicationSubtype = (claims, authFlow) => {
11751
+ switch (asString(claims?.sub_type)) {
11752
+ case "service.external":
11753
+ return "External";
11754
+ case "service.internal":
11755
+ return "Internal";
11756
+ default:
11757
+ return authFlow === "client_credentials" || authFlow === "federated_credentials" ? "External" : undefined;
11758
+ }
11759
+ };
11742
11760
  var looksLikeEmail = (value) => value?.includes("@") ?? false;
11743
11761
  var pickEmail = (claims) => {
11744
11762
  for (const candidate of [claims?.email, claims?.preferred_username]) {
@@ -11780,6 +11798,12 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
11780
11798
  const clientId = asString(claims?.client_id);
11781
11799
  if (clientId)
11782
11800
  identity.clientId = clientId;
11801
+ const subType = asString(claims?.sub_type);
11802
+ if (subType)
11803
+ identity.subType = subType;
11804
+ const applicationSubtype = resolveApplicationSubtype(claims, authFlow);
11805
+ if (applicationSubtype)
11806
+ identity.applicationSubtype = applicationSubtype;
11783
11807
  return identity;
11784
11808
  };
11785
11809
  var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
@@ -12074,6 +12098,40 @@ var tryRobotClientFallback = async (options = {}) => {
12074
12098
  }
12075
12099
  };
12076
12100
 
12101
+ // ../auth/src/tenantSelection.ts
12102
+ var LOGIN_STATUS_HINT = "Run 'uip login status' to see the organization the CLI is signed in to.";
12103
+ var organizationHint = (organizationId) => `The request used '${organizationId}' as the organization. ${LOGIN_STATUS_HINT}`;
12104
+ var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
12105
+ var describeNonJsonResponse = (organizationId, response, parseError) => {
12106
+ if (response.redirected) {
12107
+ 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}`;
12108
+ }
12109
+ const contentType = response.headers.get("content-type") ?? "unknown";
12110
+ return `The organization service returned a '${contentType}' response instead ` + `of JSON: ${parseError.message}. ${organizationHint(organizationId)}`;
12111
+ };
12112
+ var fetchTenantsAndOrganizations = async (baseUrl, accessToken, organizationId, signal) => {
12113
+ const url = `${baseUrl}/${organizationId}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo`;
12114
+ const response = await fetch(url, {
12115
+ headers: {
12116
+ Authorization: `Bearer ${accessToken}`
12117
+ },
12118
+ ...signal ? { signal } : {}
12119
+ });
12120
+ if (!response.ok) {
12121
+ if (response.status === 401) {
12122
+ 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);
12123
+ }
12124
+ const errorText = await response.text();
12125
+ const message = `Failed to get tenants and organizations: ${response.status} ${errorText}`;
12126
+ throw new Error(IDENTIFIER_STATUSES.has(response.status) ? `${message}. ${organizationHint(organizationId)}` : message);
12127
+ }
12128
+ const [parseError, data] = await catchError2(response.json());
12129
+ if (parseError) {
12130
+ throw new Error(describeNonJsonResponse(organizationId, response, parseError));
12131
+ }
12132
+ return data;
12133
+ };
12134
+
12077
12135
  // ../auth/src/tokenRefresh.ts
12078
12136
  var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
12079
12137
 
@@ -12288,6 +12346,8 @@ var saveEnvFileAsync = async ({
12288
12346
  };
12289
12347
 
12290
12348
  // ../auth/src/loginStatus.ts
12349
+ var defaultRobotTenantIdCache = new Map;
12350
+ var ROBOT_TENANT_LOOKUP_TIMEOUT_MS = 5000;
12291
12351
  var getLoginStatusAsync = async (options = {}) => {
12292
12352
  return getLoginStatusWithDeps(options);
12293
12353
  };
@@ -12300,12 +12360,20 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
12300
12360
  refreshToken: refreshTokenFn = refreshAccessToken,
12301
12361
  resolveConfig = resolveConfigAsync,
12302
12362
  robotFallback = tryRobotClientFallback,
12363
+ fetchTenantsAndOrgs = fetchTenantsAndOrganizations,
12364
+ robotTenantIdCache = defaultRobotTenantIdCache,
12365
+ robotTenantLookupTimeoutMs = ROBOT_TENANT_LOOKUP_TIMEOUT_MS,
12303
12366
  loadBreaker = loadRefreshBreaker,
12304
12367
  saveBreaker = saveRefreshBreaker,
12305
12368
  clearBreaker = clearRefreshBreaker
12306
12369
  } = deps;
12370
+ const robotDeps = {
12371
+ fetchTenantsAndOrgs,
12372
+ cache: robotTenantIdCache,
12373
+ lookupTimeoutMs: robotTenantLookupTimeoutMs
12374
+ };
12307
12375
  if (isRobotAuthEnforced()) {
12308
- return resolveRobotEnforcedStatus(robotFallback);
12376
+ return resolveRobotEnforcedStatus(robotFallback, robotDeps);
12309
12377
  }
12310
12378
  if (isEnvAuthEnabled()) {
12311
12379
  return readAuthFromEnv();
@@ -12323,7 +12391,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
12323
12391
  hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
12324
12392
  };
12325
12393
  }
12326
- return resolveBorrowedRobotStatus(robotFallback);
12394
+ return resolveBorrowedRobotStatus(robotFallback, robotDeps);
12327
12395
  }
12328
12396
  const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
12329
12397
  if ("status" in loaded) {
@@ -12365,7 +12433,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
12365
12433
  }
12366
12434
  return buildFileStatus(tokens, credentials, globalHint);
12367
12435
  };
12368
- async function resolveRobotEnforcedStatus(robotFallback) {
12436
+ async function resolveRobotEnforcedStatus(robotFallback, deps) {
12369
12437
  if (isEnvAuthEnabled()) {
12370
12438
  throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
12371
12439
  }
@@ -12376,11 +12444,11 @@ async function resolveRobotEnforcedStatus(robotFallback) {
12376
12444
  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.`
12377
12445
  };
12378
12446
  }
12379
- return buildRobotStatus(robotCreds);
12447
+ return buildRobotStatus(robotCreds, deps);
12380
12448
  }
12381
- async function resolveBorrowedRobotStatus(robotFallback) {
12449
+ async function resolveBorrowedRobotStatus(robotFallback, deps) {
12382
12450
  const robotCreds = await robotFallback();
12383
- return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
12451
+ return robotCreds ? buildRobotStatus(robotCreds, deps) : { loginStatus: "Not logged in" };
12384
12452
  }
12385
12453
  async function loadFileCredentials(loadEnvFile, absolutePath) {
12386
12454
  let credentials;
@@ -12515,9 +12583,10 @@ function identityFields(accessToken, credentials) {
12515
12583
  ...scopes ? { scopes } : {}
12516
12584
  };
12517
12585
  }
12518
- function buildRobotStatus(robotCreds) {
12586
+ async function buildRobotStatus(robotCreds, deps) {
12519
12587
  const identity = resolveSessionIdentity(robotCreds.accessToken);
12520
12588
  const scopes = readTokenScopes(robotCreds.accessToken);
12589
+ const tenant = robotCreds.tenantId ? { tenantId: robotCreds.tenantId } : await resolveRobotTenantId(robotCreds, deps);
12521
12590
  return {
12522
12591
  loginStatus: "Logged in",
12523
12592
  accessToken: robotCreds.accessToken,
@@ -12525,14 +12594,62 @@ function buildRobotStatus(robotCreds) {
12525
12594
  organizationName: robotCreds.organizationName,
12526
12595
  organizationId: robotCreds.organizationId,
12527
12596
  tenantName: robotCreds.tenantName,
12528
- tenantId: robotCreds.tenantId,
12597
+ tenantId: tenant.tenantId,
12529
12598
  issuer: robotCreds.issuer,
12530
12599
  expiration: getTokenExpiration(robotCreds.accessToken),
12531
12600
  source: "robot" /* Robot */,
12601
+ ...tenant.hint ? { hint: tenant.hint } : {},
12532
12602
  ...identity ? { identity } : {},
12533
12603
  ...scopes ? { scopes } : {}
12534
12604
  };
12535
12605
  }
12606
+ async function resolveRobotTenantId(robotCreds, deps) {
12607
+ const { baseUrl, accessToken, tenantName } = robotCreds;
12608
+ const organization = robotCreds.organizationName ?? robotCreds.organizationId;
12609
+ if (!tenantName || !organization) {
12610
+ return {};
12611
+ }
12612
+ const key = `${baseUrl}|${organization}|${tenantName}|${accessToken}`;
12613
+ let pending = deps.cache.get(key);
12614
+ if (!pending) {
12615
+ pending = catchError2(lookupRobotTenantId({ baseUrl, accessToken, organization, tenantName }, deps)).then(([error, resolution]) => {
12616
+ const settled = error ? { hint: tenantLookupFailureHint(tenantName, error.message) } : resolution;
12617
+ if (!settled.tenantId) {
12618
+ deps.cache.delete(key);
12619
+ }
12620
+ return settled;
12621
+ });
12622
+ deps.cache.set(key, pending);
12623
+ }
12624
+ return pending;
12625
+ }
12626
+ async function lookupRobotTenantId(target, deps) {
12627
+ const { baseUrl, accessToken, organization, tenantName } = target;
12628
+ const [error, data] = await catchError2(deps.fetchTenantsAndOrgs(baseUrl, accessToken, organization, AbortSignal.timeout(deps.lookupTimeoutMs)));
12629
+ if (error) {
12630
+ const reason = error.name === "TimeoutError" ? `the tenant list did not answer within ${deps.lookupTimeoutMs} ms.` : error.message;
12631
+ return { hint: tenantLookupFailureHint(tenantName, reason) };
12632
+ }
12633
+ const rows = data?.tenants;
12634
+ const tenants = Array.isArray(rows) ? rows.filter((tenant) => typeof tenant?.id === "string" && typeof tenant?.name === "string") : [];
12635
+ const wantedName = decodePathSegment(tenantName);
12636
+ const wanted = wantedName.toLowerCase();
12637
+ const match = tenants.find((tenant) => tenant.name === wantedName) ?? tenants.find((tenant) => tenant.name.toLowerCase() === wanted);
12638
+ if (!match) {
12639
+ const names = tenants.map((tenant) => tenant.name).join(", ");
12640
+ return {
12641
+ 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.`
12642
+ };
12643
+ }
12644
+ return { tenantId: match.id };
12645
+ }
12646
+ function tenantLookupFailureHint(tenantName, reason) {
12647
+ 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.`;
12648
+ }
12649
+ function decodePathSegment(segment) {
12650
+ const [error, decoded] = catchError2(() => decodeURIComponent(segment));
12651
+ return error ? segment : decoded;
12652
+ }
12536
12653
  var isFileNotFoundError = (error) => {
12537
12654
  if (!(error instanceof Object))
12538
12655
  return false;
@@ -12806,8 +12923,6 @@ init_constants();
12806
12923
  // ../auth/src/interactive.ts
12807
12924
  init_src();
12808
12925
  init_constants();
12809
- // ../auth/src/tenantSelection.ts
12810
- var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
12811
12926
 
12812
12927
  // ../auth/src/selectTenant.ts
12813
12928
  var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
@@ -13666,4 +13781,4 @@ export {
13666
13781
  supportsNewTypeOption
13667
13782
  };
13668
13783
 
13669
- //# debugId=BB66CB0E81FC803464756E2164756E21
13784
+ //# debugId=D8ED30C5E356723E64756E2164756E21
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@uipath/uipath-python-bridge",
3
3
  "author": "UiPath",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
- "version": "1.204.0-preview.254",
5
+ "version": "1.205.0-preview.256",
6
6
  "description": "Shared Python detection, caching, and CLI bridge for UiPath Python SDK tools.",
7
7
  "keywords": [
8
8
  "uip",
@@ -25,5 +25,5 @@
25
25
  "publishConfig": {
26
26
  "registry": "https://registry.npmjs.org/"
27
27
  },
28
- "gitHead": "3ee79cdec05b36231a8da9e8de6bf0043585526a"
28
+ "gitHead": "63740c6cbb7ff282fa9118cc16a148eb030b245f"
29
29
  }