@uipath/apms-tool 1.1.0 → 1.195.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +655 -151
  2. package/dist/tool.js +655 -151
  3. package/package.json +28 -36
package/dist/index.js CHANGED
@@ -2800,6 +2800,7 @@ var init_open = __esm(() => {
2800
2800
  });
2801
2801
 
2802
2802
  // ../../filesystem/src/node.ts
2803
+ import { randomUUID } from "node:crypto";
2803
2804
  import { existsSync } from "node:fs";
2804
2805
  import * as fs6 from "node:fs/promises";
2805
2806
  import * as os2 from "node:os";
@@ -2881,6 +2882,90 @@ class NodeFileSystem {
2881
2882
  async mkdir(dirPath) {
2882
2883
  await fs6.mkdir(dirPath, { recursive: true });
2883
2884
  }
2885
+ async acquireLock(lockPath) {
2886
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
2887
+ const lockFile = `${canonicalPath}.lock`;
2888
+ const ownerId = randomUUID();
2889
+ const start = Date.now();
2890
+ while (true) {
2891
+ try {
2892
+ await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
2893
+ return this.createLockRelease(lockFile, ownerId);
2894
+ } catch (error) {
2895
+ if (!this.hasErrnoCode(error, "EEXIST")) {
2896
+ throw error;
2897
+ }
2898
+ const stats = await fs6.stat(lockFile).catch(() => null);
2899
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
2900
+ const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
2901
+ if (reclaimed)
2902
+ continue;
2903
+ }
2904
+ if (Date.now() - start > LOCK_MAX_WAIT_MS) {
2905
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
2906
+ }
2907
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
2908
+ }
2909
+ }
2910
+ }
2911
+ async canonicalizeLockTarget(lockPath) {
2912
+ const absolute = path2.resolve(lockPath);
2913
+ const fullReal = await fs6.realpath(absolute).catch(() => null);
2914
+ if (fullReal)
2915
+ return fullReal;
2916
+ const parent = path2.dirname(absolute);
2917
+ const base = path2.basename(absolute);
2918
+ const canonicalParent = await fs6.realpath(parent).catch(() => parent);
2919
+ return path2.join(canonicalParent, base);
2920
+ }
2921
+ createLockRelease(lockFile, ownerId) {
2922
+ const heartbeatStart = Date.now();
2923
+ let heartbeatTimer;
2924
+ let stopped = false;
2925
+ const stopHeartbeat = () => {
2926
+ stopped = true;
2927
+ if (heartbeatTimer)
2928
+ clearTimeout(heartbeatTimer);
2929
+ };
2930
+ const scheduleNextHeartbeat = () => {
2931
+ if (stopped)
2932
+ return;
2933
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
2934
+ stopped = true;
2935
+ return;
2936
+ }
2937
+ heartbeatTimer = setTimeout(() => {
2938
+ runHeartbeat();
2939
+ }, LOCK_HEARTBEAT_MS);
2940
+ heartbeatTimer.unref?.();
2941
+ };
2942
+ const runHeartbeat = async () => {
2943
+ if (stopped)
2944
+ return;
2945
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2946
+ if (stopped)
2947
+ return;
2948
+ if (current !== ownerId) {
2949
+ stopped = true;
2950
+ return;
2951
+ }
2952
+ const now = Date.now() / 1000;
2953
+ await fs6.utimes(lockFile, now, now).catch(() => {});
2954
+ scheduleNextHeartbeat();
2955
+ };
2956
+ scheduleNextHeartbeat();
2957
+ let released = false;
2958
+ return async () => {
2959
+ if (released)
2960
+ return;
2961
+ released = true;
2962
+ stopHeartbeat();
2963
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2964
+ if (current === ownerId) {
2965
+ await fs6.rm(lockFile, { force: true });
2966
+ }
2967
+ };
2968
+ }
2884
2969
  async rm(filePath) {
2885
2970
  await fs6.rm(filePath, { recursive: true, force: true });
2886
2971
  }
@@ -2926,9 +3011,13 @@ class NodeFileSystem {
2926
3011
  }
2927
3012
  }
2928
3013
  isEnoent(error) {
2929
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3014
+ return this.hasErrnoCode(error, "ENOENT");
3015
+ }
3016
+ hasErrnoCode(error, code) {
3017
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
2930
3018
  }
2931
3019
  }
3020
+ var LOCK_HEARTBEAT_MS = 5000, LOCK_STALE_MS = 15000, LOCK_MAX_WAIT_MS = 20000, LOCK_MAX_HOLD_MS = 60000, LOCK_RETRY_MIN_MS = 100, LOCK_RETRY_JITTER_MS = 200;
2932
3021
  var init_node = __esm(() => {
2933
3022
  init_open();
2934
3023
  });
@@ -2942,7 +3031,7 @@ var init_src = __esm(() => {
2942
3031
 
2943
3032
  // ../../../node_modules/@uipath/coreipc/index.js
2944
3033
  var require_coreipc = __commonJS((exports, module) => {
2945
- var __dirname = "/Users/alexandru.oltean/github/cli/node_modules/@uipath/coreipc";
3034
+ var __dirname = "/home/runner/work/cli/cli/node_modules/@uipath/coreipc";
2946
3035
  /*! For license information please see index.js.LICENSE.txt */
2947
3036
  (function(e, t) {
2948
3037
  typeof exports == "object" && typeof module == "object" ? module.exports = t() : typeof define == "function" && define.amd ? define([], t) : typeof exports == "object" ? exports.ipc = t() : e.ipc = t();
@@ -21134,6 +21223,10 @@ var require_dist = __commonJS((exports) => {
21134
21223
  exports.RobotProxyConstructor = RobotProxyConstructor;
21135
21224
  __exportStar(require_agent(), exports);
21136
21225
  });
21226
+ // ../../auth/src/server.ts
21227
+ var init_server = __esm(() => {
21228
+ init_constants();
21229
+ });
21137
21230
 
21138
21231
  // ../../../node_modules/commander/esm.mjs
21139
21232
  var import__ = __toESM(require_commander(), 1);
@@ -21153,7 +21246,8 @@ var {
21153
21246
  // package.json
21154
21247
  var package_default = {
21155
21248
  name: "@uipath/apms-tool",
21156
- version: "1.1.0",
21249
+ license: "MIT",
21250
+ version: "1.195.0",
21157
21251
  description: "CLI plugin for the UiPath Access Policy Management Service.",
21158
21252
  private: false,
21159
21253
  repository: {
@@ -21197,6 +21291,136 @@ var package_default = {
21197
21291
  }
21198
21292
  };
21199
21293
 
21294
+ // ../../common/src/singleton.ts
21295
+ var PREFIX = "@uipath/common/";
21296
+ var _g = globalThis;
21297
+ function singleton(ctorOrName) {
21298
+ const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
21299
+ const key = Symbol.for(PREFIX + name);
21300
+ return {
21301
+ get(fallback) {
21302
+ return _g[key] ?? fallback;
21303
+ },
21304
+ set(value) {
21305
+ _g[key] = value;
21306
+ },
21307
+ clear() {
21308
+ delete _g[key];
21309
+ },
21310
+ getOrInit(factory, guard) {
21311
+ const existing = _g[key];
21312
+ if (existing != null && typeof existing === "object") {
21313
+ if (!guard || guard(existing)) {
21314
+ return existing;
21315
+ }
21316
+ }
21317
+ const instance = factory();
21318
+ _g[key] = instance;
21319
+ return instance;
21320
+ }
21321
+ };
21322
+ }
21323
+
21324
+ // ../../common/src/sdk-user-agent.ts
21325
+ var USER_AGENT_HEADER = "User-Agent";
21326
+ var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
21327
+ function userAgentPatchKey(userAgent) {
21328
+ return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
21329
+ }
21330
+ function splitUserAgentTokens(value) {
21331
+ return value?.trim().split(/\s+/).filter(Boolean) ?? [];
21332
+ }
21333
+ function appendUserAgentToken(value, userAgent) {
21334
+ const tokens = splitUserAgentTokens(value);
21335
+ const seen = new Set(tokens);
21336
+ for (const token of splitUserAgentTokens(userAgent)) {
21337
+ if (!seen.has(token)) {
21338
+ tokens.push(token);
21339
+ seen.add(token);
21340
+ }
21341
+ }
21342
+ return tokens.join(" ");
21343
+ }
21344
+ function getEffectiveUserAgent(userAgent) {
21345
+ return appendUserAgentToken(sdkUserAgentHostToken.get(), userAgent);
21346
+ }
21347
+ function isHeadersLike(headers) {
21348
+ return typeof headers === "object" && headers !== null && "get" in headers && typeof headers.get === "function" && "set" in headers && typeof headers.set === "function";
21349
+ }
21350
+ function getSdkUserAgentToken(pkg) {
21351
+ const packageName = pkg.name.replace(/^@uipath\//, "");
21352
+ return getEffectiveUserAgent(`${packageName}/${pkg.version}`);
21353
+ }
21354
+ function addSdkUserAgentHeader(headers, userAgent) {
21355
+ const result = { ...headers ?? {} };
21356
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
21357
+ const headerName = Object.keys(result).find((key) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
21358
+ if (headerName) {
21359
+ result[headerName] = appendUserAgentToken(result[headerName], effectiveUserAgent);
21360
+ } else {
21361
+ result[USER_AGENT_HEADER] = effectiveUserAgent;
21362
+ }
21363
+ return result;
21364
+ }
21365
+ function withSdkUserAgentHeader(headers, userAgent) {
21366
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
21367
+ if (isHeadersLike(headers)) {
21368
+ headers.set(USER_AGENT_HEADER, appendUserAgentToken(headers.get(USER_AGENT_HEADER), effectiveUserAgent));
21369
+ return headers;
21370
+ }
21371
+ if (Array.isArray(headers)) {
21372
+ const result = headers.map((entry) => {
21373
+ const [key, value] = entry;
21374
+ return [key, value];
21375
+ });
21376
+ const headerIndex = result.findIndex(([key]) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
21377
+ if (headerIndex >= 0) {
21378
+ const [key, value] = result[headerIndex];
21379
+ result[headerIndex] = [
21380
+ key,
21381
+ appendUserAgentToken(value, effectiveUserAgent)
21382
+ ];
21383
+ } else {
21384
+ result.push([USER_AGENT_HEADER, effectiveUserAgent]);
21385
+ }
21386
+ return result;
21387
+ }
21388
+ return addSdkUserAgentHeader(typeof headers === "object" && headers !== null ? { ...headers } : {}, effectiveUserAgent);
21389
+ }
21390
+ function withUserAgentInitOverride(initOverrides, userAgent) {
21391
+ return async (requestContext) => {
21392
+ const initWithUserAgent = {
21393
+ ...requestContext.init,
21394
+ headers: withSdkUserAgentHeader(requestContext.init.headers, userAgent)
21395
+ };
21396
+ const override = typeof initOverrides === "function" ? await initOverrides({
21397
+ ...requestContext,
21398
+ init: initWithUserAgent
21399
+ }) : initOverrides;
21400
+ return {
21401
+ ...override ?? {},
21402
+ headers: withSdkUserAgentHeader(override?.headers ?? initWithUserAgent.headers, userAgent)
21403
+ };
21404
+ };
21405
+ }
21406
+ function installSdkUserAgentHeader(BaseApiClass, userAgent) {
21407
+ const prototype = BaseApiClass.prototype;
21408
+ const patchKey = userAgentPatchKey(userAgent);
21409
+ if (prototype[patchKey]) {
21410
+ return;
21411
+ }
21412
+ if (typeof prototype.request !== "function") {
21413
+ throw new Error("Generated BaseAPI request function not found.");
21414
+ }
21415
+ const originalRequest = prototype.request;
21416
+ prototype.request = function requestWithUserAgent(context, initOverrides) {
21417
+ return originalRequest.call(this, context, withUserAgentInitOverride(initOverrides, userAgent));
21418
+ };
21419
+ Object.defineProperty(prototype, patchKey, {
21420
+ value: true
21421
+ });
21422
+ }
21423
+
21200
21424
  // ../apms-sdk/generated/src/runtime.ts
21201
21425
  var BASE_PATH = "http://localhost:35599".replace(/\/+$/, "");
21202
21426
 
@@ -21446,6 +21670,57 @@ class VoidApiResponse {
21446
21670
  return;
21447
21671
  }
21448
21672
  }
21673
+ // ../apms-sdk/package.json
21674
+ var package_default2 = {
21675
+ name: "@uipath/apms-sdk",
21676
+ license: "MIT",
21677
+ version: "1.195.0",
21678
+ description: "SDK for the UiPath Access Policy Management Service API.",
21679
+ repository: {
21680
+ type: "git",
21681
+ url: "https://github.com/UiPath/cli.git",
21682
+ directory: "packages/admin/apms-sdk"
21683
+ },
21684
+ publishConfig: {
21685
+ registry: "https://npm.pkg.github.com/@uipath"
21686
+ },
21687
+ keywords: [
21688
+ "uipath",
21689
+ "access-policy-management",
21690
+ "apms",
21691
+ "sdk"
21692
+ ],
21693
+ type: "module",
21694
+ main: "./dist/index.js",
21695
+ types: "./dist/src/index.d.ts",
21696
+ exports: {
21697
+ ".": {
21698
+ types: "./dist/src/index.d.ts",
21699
+ default: "./dist/index.js"
21700
+ }
21701
+ },
21702
+ files: [
21703
+ "dist"
21704
+ ],
21705
+ private: true,
21706
+ scripts: {
21707
+ build: "bun build ./src/index.ts --outdir dist --format esm --target node && tsc -p tsconfig.build.json --noCheck",
21708
+ generate: "bun run src/scripts/generate-sdk.ts",
21709
+ lint: "biome check ."
21710
+ },
21711
+ devDependencies: {
21712
+ "@openapitools/openapi-generator-cli": "^2.31.1",
21713
+ "@types/node": "^25.5.2",
21714
+ "@uipath/auth": "workspace:*",
21715
+ "@uipath/common": "workspace:*",
21716
+ "@uipath/filesystem": "workspace:*",
21717
+ typescript: "^6.0.2"
21718
+ }
21719
+ };
21720
+
21721
+ // ../apms-sdk/src/user-agent.ts
21722
+ var SDK_USER_AGENT = getSdkUserAgentToken(package_default2);
21723
+ installSdkUserAgentHeader(BaseAPI, SDK_USER_AGENT);
21449
21724
 
21450
21725
  // ../apms-sdk/generated/src/models/UiPathPlatformServiceAccessPolicyManagementDomainDataStatus.ts
21451
21726
  function UiPathPlatformServiceAccessPolicyManagementDomainDataStatusToJSON(value) {
@@ -22449,32 +22724,7 @@ class InvalidBaseUrlError extends Error {
22449
22724
  this.name = "InvalidBaseUrlError";
22450
22725
  }
22451
22726
  }
22452
- var DEFAULT_SCOPES = [
22453
- "offline_access",
22454
- "ProcessMining",
22455
- "OrchestratorApiUserAccess",
22456
- "StudioWebBackend",
22457
- "IdentityServerApi",
22458
- "ConnectionService",
22459
- "DataService",
22460
- "DataServiceApiUserAccess",
22461
- "DocumentUnderstanding",
22462
- "EnterpriseContextService",
22463
- "Directory",
22464
- "JamJamApi",
22465
- "LLMGateway",
22466
- "LLMOps",
22467
- "OMS",
22468
- "RCS.FolderAuthorization",
22469
- "RCS.TagsManagement",
22470
- "TestmanagerApiUserAccess",
22471
- "AutomationSolutions",
22472
- "StudioWebTypeCacheService",
22473
- "Docs.GPT.Search",
22474
- "Insights",
22475
- "ReferenceToken",
22476
- "Audit.Read"
22477
- ];
22727
+ var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
22478
22728
  var normalizeAndValidateBaseUrl = (rawUrl) => {
22479
22729
  let baseUrl = rawUrl;
22480
22730
  if (baseUrl.endsWith("/identity_/")) {
@@ -22524,7 +22774,8 @@ var resolveConfigAsync = async ({
22524
22774
  if (!clientSecret && fileAuth.clientSecret) {
22525
22775
  clientSecret = fileAuth.clientSecret;
22526
22776
  }
22527
- const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : DEFAULT_SCOPES;
22777
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
22778
+ const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES;
22528
22779
  return {
22529
22780
  clientId,
22530
22781
  clientSecret,
@@ -23024,6 +23275,129 @@ function normalizeTokenRefreshFailure() {
23024
23275
  function normalizeTokenRefreshUnavailableFailure() {
23025
23276
  return "token refresh failed before authentication completed";
23026
23277
  }
23278
+ function errorMessage(error) {
23279
+ return error instanceof Error ? error.message : String(error);
23280
+ }
23281
+ function computeExpirationThreshold(ensureTokenValidityMinutes) {
23282
+ return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
23283
+ }
23284
+ async function runRefreshLocked(inputs) {
23285
+ const {
23286
+ absolutePath,
23287
+ refreshToken: callerRefreshToken,
23288
+ customAuthority,
23289
+ ensureTokenValidityMinutes,
23290
+ loadEnvFile,
23291
+ saveEnvFile,
23292
+ refreshFn,
23293
+ resolveConfig
23294
+ } = inputs;
23295
+ const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
23296
+ let fresh;
23297
+ try {
23298
+ fresh = await loadEnvFile({ envPath: absolutePath });
23299
+ } catch (error) {
23300
+ return {
23301
+ kind: "fail",
23302
+ status: {
23303
+ loginStatus: "Refresh Failed",
23304
+ hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
23305
+ tokenRefresh: {
23306
+ attempted: false,
23307
+ success: false,
23308
+ errorMessage: `auth file read failed: ${errorMessage(error)}`
23309
+ }
23310
+ }
23311
+ };
23312
+ }
23313
+ const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
23314
+ const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
23315
+ if (freshAccess && freshExp && freshExp > expirationThreshold) {
23316
+ return {
23317
+ kind: "ok",
23318
+ accessToken: freshAccess,
23319
+ refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
23320
+ expiration: freshExp,
23321
+ tokenRefresh: { attempted: false, success: true }
23322
+ };
23323
+ }
23324
+ const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
23325
+ let refreshedAccess;
23326
+ let refreshedRefresh;
23327
+ try {
23328
+ const config = await resolveConfig({ customAuthority });
23329
+ const refreshed = await refreshFn({
23330
+ refreshToken: tokenForIdP,
23331
+ tokenEndpoint: config.tokenEndpoint,
23332
+ clientId: config.clientId,
23333
+ expectedAuthority: customAuthority
23334
+ });
23335
+ refreshedAccess = refreshed.accessToken;
23336
+ refreshedRefresh = refreshed.refreshToken;
23337
+ } catch (error) {
23338
+ const isOAuthFailure = isTokenRefreshOAuthFailure(error);
23339
+ 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.";
23340
+ const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
23341
+ return {
23342
+ kind: "fail",
23343
+ status: {
23344
+ loginStatus: "Refresh Failed",
23345
+ hint,
23346
+ tokenRefresh: {
23347
+ attempted: true,
23348
+ success: false,
23349
+ errorMessage: message
23350
+ }
23351
+ }
23352
+ };
23353
+ }
23354
+ const refreshedExp = getTokenExpiration(refreshedAccess);
23355
+ if (!refreshedExp || refreshedExp <= new Date) {
23356
+ return {
23357
+ kind: "fail",
23358
+ status: {
23359
+ loginStatus: "Refresh Failed",
23360
+ hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
23361
+ tokenRefresh: {
23362
+ attempted: true,
23363
+ success: false,
23364
+ errorMessage: "refreshed token has no valid expiration claim"
23365
+ }
23366
+ }
23367
+ };
23368
+ }
23369
+ try {
23370
+ await saveEnvFile({
23371
+ envPath: absolutePath,
23372
+ data: {
23373
+ UIPATH_ACCESS_TOKEN: refreshedAccess,
23374
+ UIPATH_REFRESH_TOKEN: refreshedRefresh
23375
+ },
23376
+ merge: true
23377
+ });
23378
+ return {
23379
+ kind: "ok",
23380
+ accessToken: refreshedAccess,
23381
+ refreshToken: refreshedRefresh,
23382
+ expiration: refreshedExp,
23383
+ tokenRefresh: { attempted: true, success: true }
23384
+ };
23385
+ } catch (error) {
23386
+ const msg = errorMessage(error);
23387
+ return {
23388
+ kind: "ok",
23389
+ accessToken: refreshedAccess,
23390
+ refreshToken: refreshedRefresh,
23391
+ expiration: refreshedExp,
23392
+ persistenceWarning: `Access token refreshed in memory but could not be written to ${absolutePath}: ${msg}. The next CLI invocation will fail until the file can be updated — run 'uip login' to re-authenticate.`,
23393
+ tokenRefresh: {
23394
+ attempted: true,
23395
+ success: true,
23396
+ errorMessage: `persistence failed: ${msg}`
23397
+ }
23398
+ };
23399
+ }
23400
+ }
23027
23401
  var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
23028
23402
  const {
23029
23403
  resolveEnvFilePath = resolveEnvFilePathAsync,
@@ -23098,73 +23472,103 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
23098
23472
  let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
23099
23473
  let expiration = getTokenExpiration(accessToken);
23100
23474
  let persistenceWarning;
23475
+ let lockReleaseFailed = false;
23101
23476
  let tokenRefresh;
23102
- const expirationThreshold = new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
23103
- if (expiration && expiration <= expirationThreshold && refreshToken) {
23104
- let refreshedAccess;
23105
- let refreshedRefresh;
23477
+ const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
23478
+ const tryGlobalCredsHint = async () => {
23479
+ const fs7 = getFs();
23480
+ const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
23481
+ if (absolutePath === globalPath)
23482
+ return;
23483
+ if (!await fs7.exists(globalPath))
23484
+ return;
23106
23485
  try {
23107
- const config = await resolveConfig({
23108
- customAuthority: credentials.UIPATH_URL
23109
- });
23110
- const refreshed = await refreshTokenFn({
23111
- refreshToken,
23112
- tokenEndpoint: config.tokenEndpoint,
23113
- clientId: config.clientId,
23114
- expectedAuthority: credentials.UIPATH_URL
23115
- });
23116
- refreshedAccess = refreshed.accessToken;
23117
- refreshedRefresh = refreshed.refreshToken;
23118
- } catch (error) {
23119
- const isOAuthFailure = isTokenRefreshOAuthFailure(error);
23120
- 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.";
23121
- const errorMessage = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
23122
- return {
23123
- loginStatus: "Refresh Failed",
23124
- hint,
23125
- tokenRefresh: {
23126
- attempted: true,
23127
- success: false,
23128
- errorMessage
23129
- }
23130
- };
23486
+ const globalCreds = await loadEnvFile({ envPath: globalPath });
23487
+ if (!globalCreds.UIPATH_ACCESS_TOKEN)
23488
+ return;
23489
+ const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
23490
+ if (globalExp && globalExp <= new Date)
23491
+ return;
23492
+ 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.`;
23493
+ } catch {
23494
+ return;
23131
23495
  }
23132
- const refreshedExp = getTokenExpiration(refreshedAccess);
23133
- if (!refreshedExp || refreshedExp <= new Date) {
23496
+ };
23497
+ if (expiration && expiration <= outerThreshold && refreshToken) {
23498
+ let release;
23499
+ try {
23500
+ release = await getFs().acquireLock(absolutePath);
23501
+ } catch (error) {
23502
+ const msg = errorMessage(error);
23503
+ const globalHint = await tryGlobalCredsHint();
23504
+ if (globalHint) {
23505
+ return {
23506
+ loginStatus: "Expired",
23507
+ accessToken,
23508
+ refreshToken,
23509
+ baseUrl: credentials.UIPATH_URL,
23510
+ organizationName: credentials.UIPATH_ORGANIZATION_NAME,
23511
+ organizationId: credentials.UIPATH_ORGANIZATION_ID,
23512
+ tenantName: credentials.UIPATH_TENANT_NAME,
23513
+ tenantId: credentials.UIPATH_TENANT_ID,
23514
+ expiration,
23515
+ source: "file" /* File */,
23516
+ hint: globalHint,
23517
+ tokenRefresh: {
23518
+ attempted: false,
23519
+ success: false,
23520
+ errorMessage: `lock acquisition failed: ${msg}`
23521
+ }
23522
+ };
23523
+ }
23134
23524
  return {
23135
23525
  loginStatus: "Refresh Failed",
23136
- hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
23526
+ 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.",
23137
23527
  tokenRefresh: {
23138
- attempted: true,
23528
+ attempted: false,
23139
23529
  success: false,
23140
- errorMessage: "refreshed token has no valid expiration claim"
23530
+ errorMessage: `lock acquisition failed: ${msg}`
23141
23531
  }
23142
23532
  };
23143
23533
  }
23144
- accessToken = refreshedAccess;
23145
- refreshToken = refreshedRefresh;
23146
- expiration = refreshedExp;
23534
+ let lockedFailure;
23147
23535
  try {
23148
- await saveEnvFile({
23149
- envPath: absolutePath,
23150
- data: {
23151
- UIPATH_ACCESS_TOKEN: accessToken,
23152
- UIPATH_REFRESH_TOKEN: refreshToken
23153
- },
23154
- merge: true
23536
+ const outcome = await runRefreshLocked({
23537
+ absolutePath,
23538
+ refreshToken,
23539
+ customAuthority: credentials.UIPATH_URL,
23540
+ ensureTokenValidityMinutes,
23541
+ loadEnvFile,
23542
+ saveEnvFile,
23543
+ refreshFn: refreshTokenFn,
23544
+ resolveConfig
23155
23545
  });
23156
- tokenRefresh = {
23157
- attempted: true,
23158
- success: true
23159
- };
23160
- } catch (error) {
23161
- const msg = error instanceof Error ? error.message : String(error);
23162
- persistenceWarning = `Access token refreshed in memory but could not be written to ${absolutePath}: ${msg}. The next CLI invocation will fail until the file can be updated — run 'uip login' to re-authenticate.`;
23163
- tokenRefresh = {
23164
- attempted: true,
23165
- success: true,
23166
- errorMessage: `persistence failed: ${msg}`
23167
- };
23546
+ if (outcome.kind === "fail") {
23547
+ lockedFailure = outcome.status;
23548
+ } else {
23549
+ accessToken = outcome.accessToken;
23550
+ refreshToken = outcome.refreshToken;
23551
+ expiration = outcome.expiration;
23552
+ tokenRefresh = outcome.tokenRefresh;
23553
+ if (outcome.persistenceWarning) {
23554
+ persistenceWarning = outcome.persistenceWarning;
23555
+ }
23556
+ }
23557
+ } finally {
23558
+ try {
23559
+ await release();
23560
+ } catch {
23561
+ lockReleaseFailed = true;
23562
+ }
23563
+ }
23564
+ if (lockedFailure) {
23565
+ const globalHint = await tryGlobalCredsHint();
23566
+ const base = globalHint ? {
23567
+ ...lockedFailure,
23568
+ loginStatus: "Expired",
23569
+ hint: globalHint
23570
+ } : lockedFailure;
23571
+ return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
23168
23572
  }
23169
23573
  }
23170
23574
  const result = {
@@ -23179,23 +23583,13 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
23179
23583
  expiration,
23180
23584
  source: "file" /* File */,
23181
23585
  ...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
23586
+ ...lockReleaseFailed ? { lockReleaseFailed: true } : {},
23182
23587
  ...tokenRefresh ? { tokenRefresh } : {}
23183
23588
  };
23184
23589
  if (result.loginStatus === "Expired") {
23185
- const fs7 = getFs();
23186
- const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
23187
- if (absolutePath !== globalPath && await fs7.exists(globalPath)) {
23188
- try {
23189
- const globalCreds = await loadEnvFile({
23190
- envPath: globalPath
23191
- });
23192
- if (globalCreds.UIPATH_ACCESS_TOKEN) {
23193
- const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
23194
- if (!globalExp || globalExp > new Date) {
23195
- result.hint = `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
23196
- }
23197
- }
23198
- } catch {}
23590
+ const globalHint = await tryGlobalCredsHint();
23591
+ if (globalHint) {
23592
+ result.hint = globalHint;
23199
23593
  }
23200
23594
  }
23201
23595
  return result;
@@ -23212,6 +23606,10 @@ var getLoginStatusAsync = async (options = {}) => {
23212
23606
  init_src();
23213
23607
  // ../../auth/src/logout.ts
23214
23608
  init_src();
23609
+
23610
+ // ../../auth/src/index.ts
23611
+ init_server();
23612
+
23215
23613
  // ../apms-sdk/src/client-factory.ts
23216
23614
  var STRIP_PREFIX_RE = /\/accesspolicy_\/api\/(?:accessPolicy\/)?organization\/[^/]+/;
23217
23615
  function rewriteApmsUrl(url) {
@@ -23242,6 +23640,7 @@ async function resolveConfig(options) {
23242
23640
  config: new Configuration({
23243
23641
  basePath,
23244
23642
  accessToken: async () => bearerToken,
23643
+ headers: addSdkUserAgentHeader(undefined, SDK_USER_AGENT),
23245
23644
  fetchApi
23246
23645
  }),
23247
23646
  organizationId: status.organizationId
@@ -23391,10 +23790,15 @@ async function extractErrorDetails(error, options) {
23391
23790
  }
23392
23791
  if (parsedBody?.errorCode && typeof parsedBody.errorCode === "string") {
23393
23792
  context.errorCode = parsedBody.errorCode;
23793
+ } else if (parsedBody?.code && typeof parsedBody.code === "string") {
23794
+ context.errorCode = parsedBody.code;
23394
23795
  }
23395
23796
  if (parsedBody?.requestId && typeof parsedBody.requestId === "string") {
23396
23797
  context.requestId = parsedBody.requestId;
23397
23798
  }
23799
+ if (parsedBody?.traceId && typeof parsedBody.traceId === "string") {
23800
+ context.traceId = parsedBody.traceId;
23801
+ }
23398
23802
  if (status === 429) {
23399
23803
  const resp = response;
23400
23804
  const headersObj = resp?.headers;
@@ -23414,7 +23818,35 @@ async function extractErrorDetails(error, options) {
23414
23818
  }
23415
23819
  }
23416
23820
  const hasContext = Object.keys(context).length > 0;
23417
- return { result, message, details, ...hasContext ? { context } : {} };
23821
+ let parsedErrors;
23822
+ if (parsedBody?.errors && typeof parsedBody.errors === "object") {
23823
+ const errors = {};
23824
+ for (const [field, raw] of Object.entries(parsedBody.errors)) {
23825
+ if (Array.isArray(raw)) {
23826
+ const messages = raw.map((entry) => {
23827
+ if (typeof entry === "string")
23828
+ return entry;
23829
+ if (entry && typeof entry === "object" && typeof entry.message === "string") {
23830
+ return entry.message;
23831
+ }
23832
+ return String(entry);
23833
+ }).filter(Boolean);
23834
+ if (messages.length > 0)
23835
+ errors[field] = messages;
23836
+ } else if (typeof raw === "string") {
23837
+ errors[field] = [raw];
23838
+ }
23839
+ }
23840
+ if (Object.keys(errors).length > 0)
23841
+ parsedErrors = errors;
23842
+ }
23843
+ return {
23844
+ result,
23845
+ message,
23846
+ details,
23847
+ ...hasContext ? { context } : {},
23848
+ ...parsedErrors ? { parsedErrors } : {}
23849
+ };
23418
23850
  }
23419
23851
  async function extractErrorMessage(error, options) {
23420
23852
  const { message } = await extractErrorDetails(error, options);
@@ -23426,36 +23858,6 @@ Command.prototype.examples = function(examples) {
23426
23858
  examplesByCommand.set(this, examples);
23427
23859
  return this;
23428
23860
  };
23429
- // ../../common/src/singleton.ts
23430
- var PREFIX = "@uipath/common/";
23431
- var _g = globalThis;
23432
- function singleton(ctorOrName) {
23433
- const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
23434
- const key = Symbol.for(PREFIX + name);
23435
- return {
23436
- get(fallback) {
23437
- return _g[key] ?? fallback;
23438
- },
23439
- set(value) {
23440
- _g[key] = value;
23441
- },
23442
- clear() {
23443
- delete _g[key];
23444
- },
23445
- getOrInit(factory, guard) {
23446
- const existing = _g[key];
23447
- if (existing != null && typeof existing === "object") {
23448
- if (!guard || guard(existing)) {
23449
- return existing;
23450
- }
23451
- }
23452
- const instance = factory();
23453
- _g[key] = instance;
23454
- return instance;
23455
- }
23456
- };
23457
- }
23458
-
23459
23861
  // ../../common/src/output-context.ts
23460
23862
  function createStorage() {
23461
23863
  const [error, mod] = catchError2(() => __require("node:async_hooks"));
@@ -28545,6 +28947,60 @@ function escapeNonAscii(jsonText) {
28545
28947
  function needsAsciiSafeJson(sink) {
28546
28948
  return process.platform === "win32" && !sink.capabilities.isInteractive;
28547
28949
  }
28950
+ function isPlainRecord(value) {
28951
+ if (value === null || typeof value !== "object")
28952
+ return false;
28953
+ const prototype = Object.getPrototypeOf(value);
28954
+ return prototype === Object.prototype || prototype === null;
28955
+ }
28956
+ function toLowerCamelCaseKey(key) {
28957
+ if (!key)
28958
+ return key;
28959
+ if (/[_\-\s]/.test(key)) {
28960
+ const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
28961
+ if (!firstPart)
28962
+ return key;
28963
+ return [
28964
+ toLowerCamelCaseSimpleKey(firstPart),
28965
+ ...restParts.map((part) => {
28966
+ const normalized = toLowerCamelCaseSimpleKey(part);
28967
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
28968
+ })
28969
+ ].join("");
28970
+ }
28971
+ return toLowerCamelCaseSimpleKey(key);
28972
+ }
28973
+ function toLowerCamelCaseSimpleKey(key) {
28974
+ if (/^[A-Z0-9]+$/.test(key))
28975
+ return key.toLowerCase();
28976
+ return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
28977
+ }
28978
+ function toPascalCaseKey(key) {
28979
+ const lowerCamelKey = toLowerCamelCaseKey(key);
28980
+ return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
28981
+ }
28982
+ function toPascalCaseData(value) {
28983
+ if (Array.isArray(value))
28984
+ return value.map(toPascalCaseData);
28985
+ if (!isPlainRecord(value))
28986
+ return value;
28987
+ const result = {};
28988
+ for (const [key, nestedValue] of Object.entries(value)) {
28989
+ result[toPascalCaseKey(key)] = toPascalCaseData(nestedValue);
28990
+ }
28991
+ return result;
28992
+ }
28993
+ function normalizeDataKeys(data) {
28994
+ return toPascalCaseData(data);
28995
+ }
28996
+ function normalizeOutputKeys(data) {
28997
+ const result = {};
28998
+ for (const [key, value] of Object.entries(data)) {
28999
+ const pascalKey = toPascalCaseKey(key);
29000
+ result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData(value);
29001
+ }
29002
+ return result;
29003
+ }
28548
29004
  function printOutput(data, format = "json", logFn, asciiSafe = false) {
28549
29005
  if (!data) {
28550
29006
  logFn("Empty response object. No data to display.");
@@ -28607,7 +29063,7 @@ function wrapText(text, width) {
28607
29063
  function printTable(data, logFn, externalLogValue) {
28608
29064
  if (data.length === 0)
28609
29065
  return;
28610
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
29066
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
28611
29067
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
28612
29068
  const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
28613
29069
  logFn(header);
@@ -28622,7 +29078,7 @@ function printTable(data, logFn, externalLogValue) {
28622
29078
  }
28623
29079
  }
28624
29080
  function printVerticalTable(data, logFn = console.log, externalLogValue) {
28625
- const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
29081
+ const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
28626
29082
  if (keys.length === 0)
28627
29083
  return;
28628
29084
  const maxKeyWidth = Math.max(...keys.map((key) => key.length));
@@ -28638,7 +29094,7 @@ function printVerticalTable(data, logFn = console.log, externalLogValue) {
28638
29094
  function printResizableTable(data, logFn = console.log, externalLogValue) {
28639
29095
  if (data.length === 0)
28640
29096
  return;
28641
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
29097
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
28642
29098
  if (keys.length === 0)
28643
29099
  return;
28644
29100
  if (!process.stdout.isTTY) {
@@ -28714,8 +29170,26 @@ function printResizableTable(data, logFn = console.log, externalLogValue) {
28714
29170
  function toYaml(data) {
28715
29171
  return dump(data);
28716
29172
  }
29173
+ class FilterEvaluationError extends Error {
29174
+ __brand = "FilterEvaluationError";
29175
+ filter;
29176
+ instructions;
29177
+ result = RESULTS.ValidationError;
29178
+ constructor(filter, cause) {
29179
+ const underlying = cause instanceof Error ? cause.message : String(cause);
29180
+ super(`Filter '${filter}' failed to evaluate: ${underlying}`);
29181
+ this.name = "FilterEvaluationError";
29182
+ this.filter = filter;
29183
+ this.instructions = `The --output-filter expression '${filter}' failed at evaluation time. ` + "Note that --output-filter operates on the 'Data' field of the envelope, not the full object. " + "For example, on a list result use 'length(@)' instead of 'Data | length(@)'.";
29184
+ }
29185
+ }
28717
29186
  function applyFilter(data, filter) {
28718
- const result = search(data, filter);
29187
+ let result;
29188
+ try {
29189
+ result = search(data, filter);
29190
+ } catch (err) {
29191
+ throw new FilterEvaluationError(filter, err);
29192
+ }
28719
29193
  if (result == null)
28720
29194
  return [];
28721
29195
  if (Array.isArray(result)) {
@@ -28732,13 +29206,18 @@ function applyFilter(data, filter) {
28732
29206
  }
28733
29207
  var OutputFormatter;
28734
29208
  ((OutputFormatter) => {
28735
- function success(data) {
29209
+ function success(data, options) {
28736
29210
  data.Log ??= getLogFilePath() || undefined;
29211
+ const normalize = !options?.preserveDataKeys;
29212
+ if (normalize) {
29213
+ data.Data = normalizeDataKeys(data.Data);
29214
+ }
28737
29215
  const filter = getOutputFilter();
28738
29216
  if (filter) {
28739
- data.Data = applyFilter(data.Data, filter);
29217
+ const filtered = applyFilter(data.Data, filter);
29218
+ data.Data = normalize ? normalizeDataKeys(filtered) : filtered;
28740
29219
  }
28741
- logOutput(data, getOutputFormat());
29220
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
28742
29221
  }
28743
29222
  OutputFormatter.success = success;
28744
29223
  function error(data) {
@@ -28748,7 +29227,7 @@ var OutputFormatter;
28748
29227
  result: data.Result,
28749
29228
  message: data.Message
28750
29229
  });
28751
- logOutput(data, getOutputFormat());
29230
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
28752
29231
  }
28753
29232
  OutputFormatter.error = error;
28754
29233
  function emitList(code, items, opts) {
@@ -28769,13 +29248,14 @@ var OutputFormatter;
28769
29248
  function log(data) {
28770
29249
  const format = getOutputFormat();
28771
29250
  const sink = getOutputSink();
29251
+ const normalized = toPascalCaseData(data);
28772
29252
  if (format === "json") {
28773
- const json2 = JSON.stringify(data);
29253
+ const json2 = JSON.stringify(normalized);
28774
29254
  const safe = needsAsciiSafeJson(sink) ? escapeNonAscii(json2) : json2;
28775
29255
  sink.writeErr(`${safe}
28776
29256
  `);
28777
29257
  } else {
28778
- for (const [key, value] of Object.entries(data)) {
29258
+ for (const [key, value] of Object.entries(normalized)) {
28779
29259
  sink.writeErr(`${key}: ${value}
28780
29260
  `);
28781
29261
  }
@@ -28784,12 +29264,16 @@ var OutputFormatter;
28784
29264
  OutputFormatter.log = log;
28785
29265
  function formatToString(data) {
28786
29266
  const filter = getOutputFilter();
28787
- if (filter && "Data" in data && data.Data != null) {
28788
- data.Data = applyFilter(data.Data, filter);
29267
+ if ("Data" in data && data.Data != null) {
29268
+ data.Data = normalizeDataKeys(data.Data);
29269
+ if (filter) {
29270
+ data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
29271
+ }
28789
29272
  }
29273
+ const output = normalizeOutputKeys(data);
28790
29274
  const lines = [];
28791
29275
  const sink = getOutputSink();
28792
- printOutput(data, getOutputFormat(), (msg) => {
29276
+ printOutput(output, getOutputFormat(), (msg) => {
28793
29277
  lines.push(msg);
28794
29278
  }, needsAsciiSafeJson(sink));
28795
29279
  return lines.join(`
@@ -30200,6 +30684,22 @@ JSONPath.prototype.safeVm = {
30200
30684
  Script: SafeScript
30201
30685
  };
30202
30686
  JSONPath.prototype.vm = vm;
30687
+ // ../../common/src/polling/types.ts
30688
+ var PollOutcome = {
30689
+ Completed: "completed",
30690
+ Timeout: "timeout",
30691
+ Interrupted: "interrupted",
30692
+ Aborted: "aborted",
30693
+ Failed: "failed"
30694
+ };
30695
+
30696
+ // ../../common/src/polling/poll-failure-mapping.ts
30697
+ var REASON_BY_OUTCOME = {
30698
+ [PollOutcome.Timeout]: "poll_timeout",
30699
+ [PollOutcome.Failed]: "poll_failed",
30700
+ [PollOutcome.Interrupted]: "poll_failed",
30701
+ [PollOutcome.Aborted]: "poll_aborted"
30702
+ };
30203
30703
  // ../../common/src/polling/terminal-statuses.ts
30204
30704
  var TERMINAL_STATUSES = new Set([
30205
30705
  "completed",
@@ -30405,17 +30905,21 @@ Command.prototype.trackedAction = function(context, fn, properties) {
30405
30905
  const telemetryName = deriveCommandPath(command);
30406
30906
  const props = typeof properties === "function" ? properties(...args) : properties;
30407
30907
  const startTime = performance.now();
30408
- let errorMessage;
30908
+ let errorMessage2;
30409
30909
  const [error] = await catchError2(fn(...args));
30410
30910
  if (error) {
30411
- errorMessage = error instanceof Error ? error.message : String(error);
30412
- logger.error(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
30911
+ errorMessage2 = error instanceof Error ? error.message : String(error);
30912
+ logger.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage2}`);
30913
+ const typed = error;
30914
+ const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
30915
+ const customResult = typeof typed.result === "string" && typed.result !== RESULTS.Success && Object.values(RESULTS).includes(typed.result) ? typed.result : undefined;
30916
+ const finalResult = customResult ?? RESULTS.Failure;
30413
30917
  OutputFormatter.error({
30414
- Result: RESULTS.Failure,
30415
- Message: errorMessage,
30416
- Instructions: "An unexpected error occurred. Run with --log-level debug for details."
30918
+ Result: finalResult,
30919
+ Message: errorMessage2,
30920
+ Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
30417
30921
  });
30418
- context.exit(1);
30922
+ context.exit(EXIT_CODES[finalResult]);
30419
30923
  }
30420
30924
  const durationMs = performance.now() - startTime;
30421
30925
  const success = !error && (process.exitCode === undefined || process.exitCode === 0);
@@ -30424,7 +30928,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
30424
30928
  ...props,
30425
30929
  duration: String(durationMs),
30426
30930
  success: String(success),
30427
- ...errorMessage ? { errorMessage } : {}
30931
+ ...errorMessage2 ? { errorMessage: errorMessage2 } : {}
30428
30932
  }));
30429
30933
  });
30430
30934
  };