@uipath/admin-vpngateway-tool 1.1.0 → 1.2.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 +767 -150
  2. package/dist/tool.js +767 -150
  3. package/package.json +28 -34
package/dist/index.js CHANGED
@@ -2144,7 +2144,8 @@ var {
2144
2144
  // package.json
2145
2145
  var package_default = {
2146
2146
  name: "@uipath/admin-vpngateway-tool",
2147
- version: "1.1.0",
2147
+ license: "MIT",
2148
+ version: "1.2.0",
2148
2149
  description: "CLI plugin for UiPath VPN Gateway management (Hypervisor service).",
2149
2150
  private: false,
2150
2151
  repository: {
@@ -2213,6 +2214,7 @@ import path from "node:path";
2213
2214
  import { fileURLToPath } from "node:url";
2214
2215
  import childProcess3 from "node:child_process";
2215
2216
  import fs5, { constants as fsConstants2 } from "node:fs/promises";
2217
+ import { randomUUID } from "node:crypto";
2216
2218
  import { existsSync } from "node:fs";
2217
2219
  import * as fs6 from "node:fs/promises";
2218
2220
  import * as os2 from "node:os";
@@ -2964,6 +2966,90 @@ class NodeFileSystem {
2964
2966
  async mkdir(dirPath) {
2965
2967
  await fs6.mkdir(dirPath, { recursive: true });
2966
2968
  }
2969
+ async acquireLock(lockPath) {
2970
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
2971
+ const lockFile = `${canonicalPath}.lock`;
2972
+ const ownerId = randomUUID();
2973
+ const start = Date.now();
2974
+ while (true) {
2975
+ try {
2976
+ await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
2977
+ return this.createLockRelease(lockFile, ownerId);
2978
+ } catch (error) {
2979
+ if (!this.hasErrnoCode(error, "EEXIST")) {
2980
+ throw error;
2981
+ }
2982
+ const stats = await fs6.stat(lockFile).catch(() => null);
2983
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
2984
+ const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
2985
+ if (reclaimed)
2986
+ continue;
2987
+ }
2988
+ if (Date.now() - start > LOCK_MAX_WAIT_MS) {
2989
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
2990
+ }
2991
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
2992
+ }
2993
+ }
2994
+ }
2995
+ async canonicalizeLockTarget(lockPath) {
2996
+ const absolute = path2.resolve(lockPath);
2997
+ const fullReal = await fs6.realpath(absolute).catch(() => null);
2998
+ if (fullReal)
2999
+ return fullReal;
3000
+ const parent = path2.dirname(absolute);
3001
+ const base = path2.basename(absolute);
3002
+ const canonicalParent = await fs6.realpath(parent).catch(() => parent);
3003
+ return path2.join(canonicalParent, base);
3004
+ }
3005
+ createLockRelease(lockFile, ownerId) {
3006
+ const heartbeatStart = Date.now();
3007
+ let heartbeatTimer;
3008
+ let stopped = false;
3009
+ const stopHeartbeat = () => {
3010
+ stopped = true;
3011
+ if (heartbeatTimer)
3012
+ clearTimeout(heartbeatTimer);
3013
+ };
3014
+ const scheduleNextHeartbeat = () => {
3015
+ if (stopped)
3016
+ return;
3017
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
3018
+ stopped = true;
3019
+ return;
3020
+ }
3021
+ heartbeatTimer = setTimeout(() => {
3022
+ runHeartbeat();
3023
+ }, LOCK_HEARTBEAT_MS);
3024
+ heartbeatTimer.unref?.();
3025
+ };
3026
+ const runHeartbeat = async () => {
3027
+ if (stopped)
3028
+ return;
3029
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
3030
+ if (stopped)
3031
+ return;
3032
+ if (current !== ownerId) {
3033
+ stopped = true;
3034
+ return;
3035
+ }
3036
+ const now = Date.now() / 1000;
3037
+ await fs6.utimes(lockFile, now, now).catch(() => {});
3038
+ scheduleNextHeartbeat();
3039
+ };
3040
+ scheduleNextHeartbeat();
3041
+ let released = false;
3042
+ return async () => {
3043
+ if (released)
3044
+ return;
3045
+ released = true;
3046
+ stopHeartbeat();
3047
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
3048
+ if (current === ownerId) {
3049
+ await fs6.rm(lockFile, { force: true });
3050
+ }
3051
+ };
3052
+ }
2967
3053
  async rm(filePath) {
2968
3054
  await fs6.rm(filePath, { recursive: true, force: true });
2969
3055
  }
@@ -3009,9 +3095,18 @@ class NodeFileSystem {
3009
3095
  }
3010
3096
  }
3011
3097
  isEnoent(error) {
3012
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3098
+ return this.hasErrnoCode(error, "ENOENT");
3099
+ }
3100
+ hasErrnoCode(error, code) {
3101
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
3013
3102
  }
3014
3103
  }
3104
+ var LOCK_HEARTBEAT_MS = 5000;
3105
+ var LOCK_STALE_MS = 15000;
3106
+ var LOCK_MAX_WAIT_MS = 20000;
3107
+ var LOCK_MAX_HOLD_MS = 60000;
3108
+ var LOCK_RETRY_MIN_MS = 100;
3109
+ var LOCK_RETRY_JITTER_MS = 200;
3015
3110
  var init_node = __esm(() => {
3016
3111
  init_open();
3017
3112
  });
@@ -3023,7 +3118,7 @@ var init_src = __esm(() => {
3023
3118
  fsInstance = new NodeFileSystem;
3024
3119
  });
3025
3120
  var require_coreipc = __commonJS2((exports, module) => {
3026
- var __dirname3 = "/Users/alexandru.oltean/github/cli/node_modules/@uipath/coreipc";
3121
+ var __dirname3 = "/home/runner/work/cli/cli/node_modules/@uipath/coreipc";
3027
3122
  /*! For license information please see index.js.LICENSE.txt */
3028
3123
  (function(e, t) {
3029
3124
  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();
@@ -20823,6 +20918,135 @@ var require_dist = __commonJS2((exports) => {
20823
20918
  exports.RobotProxyConstructor = RobotProxyConstructor;
20824
20919
  __exportStar(require_agent(), exports);
20825
20920
  });
20921
+ var init_server = __esm(() => {
20922
+ init_constants();
20923
+ });
20924
+ var PREFIX = "@uipath/common/";
20925
+ var _g = globalThis;
20926
+ function singleton(ctorOrName) {
20927
+ const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
20928
+ const key = Symbol.for(PREFIX + name);
20929
+ return {
20930
+ get(fallback) {
20931
+ return _g[key] ?? fallback;
20932
+ },
20933
+ set(value) {
20934
+ _g[key] = value;
20935
+ },
20936
+ clear() {
20937
+ delete _g[key];
20938
+ },
20939
+ getOrInit(factory, guard) {
20940
+ const existing = _g[key];
20941
+ if (existing != null && typeof existing === "object") {
20942
+ if (!guard || guard(existing)) {
20943
+ return existing;
20944
+ }
20945
+ }
20946
+ const instance = factory();
20947
+ _g[key] = instance;
20948
+ return instance;
20949
+ }
20950
+ };
20951
+ }
20952
+ var USER_AGENT_HEADER = "User-Agent";
20953
+ var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
20954
+ function userAgentPatchKey(userAgent) {
20955
+ return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
20956
+ }
20957
+ function splitUserAgentTokens(value) {
20958
+ return value?.trim().split(/\s+/).filter(Boolean) ?? [];
20959
+ }
20960
+ function appendUserAgentToken(value, userAgent) {
20961
+ const tokens = splitUserAgentTokens(value);
20962
+ const seen = new Set(tokens);
20963
+ for (const token of splitUserAgentTokens(userAgent)) {
20964
+ if (!seen.has(token)) {
20965
+ tokens.push(token);
20966
+ seen.add(token);
20967
+ }
20968
+ }
20969
+ return tokens.join(" ");
20970
+ }
20971
+ function getEffectiveUserAgent(userAgent) {
20972
+ return appendUserAgentToken(sdkUserAgentHostToken.get(), userAgent);
20973
+ }
20974
+ function isHeadersLike(headers) {
20975
+ return typeof headers === "object" && headers !== null && "get" in headers && typeof headers.get === "function" && "set" in headers && typeof headers.set === "function";
20976
+ }
20977
+ function getSdkUserAgentToken(pkg) {
20978
+ const packageName = pkg.name.replace(/^@uipath\//, "");
20979
+ return getEffectiveUserAgent(`${packageName}/${pkg.version}`);
20980
+ }
20981
+ function addSdkUserAgentHeader(headers, userAgent) {
20982
+ const result = { ...headers ?? {} };
20983
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
20984
+ const headerName = Object.keys(result).find((key) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
20985
+ if (headerName) {
20986
+ result[headerName] = appendUserAgentToken(result[headerName], effectiveUserAgent);
20987
+ } else {
20988
+ result[USER_AGENT_HEADER] = effectiveUserAgent;
20989
+ }
20990
+ return result;
20991
+ }
20992
+ function withSdkUserAgentHeader(headers, userAgent) {
20993
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
20994
+ if (isHeadersLike(headers)) {
20995
+ headers.set(USER_AGENT_HEADER, appendUserAgentToken(headers.get(USER_AGENT_HEADER), effectiveUserAgent));
20996
+ return headers;
20997
+ }
20998
+ if (Array.isArray(headers)) {
20999
+ const result = headers.map((entry) => {
21000
+ const [key, value] = entry;
21001
+ return [key, value];
21002
+ });
21003
+ const headerIndex = result.findIndex(([key]) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
21004
+ if (headerIndex >= 0) {
21005
+ const [key, value] = result[headerIndex];
21006
+ result[headerIndex] = [
21007
+ key,
21008
+ appendUserAgentToken(value, effectiveUserAgent)
21009
+ ];
21010
+ } else {
21011
+ result.push([USER_AGENT_HEADER, effectiveUserAgent]);
21012
+ }
21013
+ return result;
21014
+ }
21015
+ return addSdkUserAgentHeader(typeof headers === "object" && headers !== null ? { ...headers } : {}, effectiveUserAgent);
21016
+ }
21017
+ function withUserAgentInitOverride(initOverrides, userAgent) {
21018
+ return async (requestContext) => {
21019
+ const initWithUserAgent = {
21020
+ ...requestContext.init,
21021
+ headers: withSdkUserAgentHeader(requestContext.init.headers, userAgent)
21022
+ };
21023
+ const override = typeof initOverrides === "function" ? await initOverrides({
21024
+ ...requestContext,
21025
+ init: initWithUserAgent
21026
+ }) : initOverrides;
21027
+ return {
21028
+ ...override ?? {},
21029
+ headers: withSdkUserAgentHeader(override?.headers ?? initWithUserAgent.headers, userAgent)
21030
+ };
21031
+ };
21032
+ }
21033
+ function installSdkUserAgentHeader(BaseApiClass, userAgent) {
21034
+ const prototype = BaseApiClass.prototype;
21035
+ const patchKey = userAgentPatchKey(userAgent);
21036
+ if (prototype[patchKey]) {
21037
+ return;
21038
+ }
21039
+ if (typeof prototype.request !== "function") {
21040
+ throw new Error("Generated BaseAPI request function not found.");
21041
+ }
21042
+ const originalRequest = prototype.request;
21043
+ prototype.request = function requestWithUserAgent(context, initOverrides) {
21044
+ return originalRequest.call(this, context, withUserAgentInitOverride(initOverrides, userAgent));
21045
+ };
21046
+ Object.defineProperty(prototype, patchKey, {
21047
+ value: true
21048
+ });
21049
+ }
20826
21050
  var BASE_PATH = "http://localhost".replace(/\/+$/, "");
20827
21051
 
20828
21052
  class Configuration {
@@ -21071,6 +21295,47 @@ class VoidApiResponse {
21071
21295
  return;
21072
21296
  }
21073
21297
  }
21298
+ var package_default2 = {
21299
+ name: "@uipath/admin-vpngateway-sdk",
21300
+ license: "MIT",
21301
+ version: "1.2.0",
21302
+ description: "SDK for the UiPath Hypervisor VPN Gateway management APIs.",
21303
+ repository: {
21304
+ type: "git",
21305
+ url: "https://github.com/UiPath/cli.git",
21306
+ directory: "packages/admin/vpngateway-sdk"
21307
+ },
21308
+ publishConfig: {
21309
+ registry: "https://npm.pkg.github.com/@uipath"
21310
+ },
21311
+ keywords: ["uipath", "vpn-gateway", "hypervisor", "sdk"],
21312
+ type: "module",
21313
+ main: "./dist/index.js",
21314
+ types: "./dist/src/index.d.ts",
21315
+ exports: {
21316
+ ".": {
21317
+ types: "./dist/src/index.d.ts",
21318
+ default: "./dist/index.js"
21319
+ }
21320
+ },
21321
+ files: ["dist"],
21322
+ private: true,
21323
+ scripts: {
21324
+ build: "bun build ./src/index.ts --outdir dist --format esm --target node && tsc -p tsconfig.build.json --noCheck",
21325
+ generate: "bun run src/scripts/generate-sdk.ts",
21326
+ lint: "biome check ."
21327
+ },
21328
+ devDependencies: {
21329
+ "@openapitools/openapi-generator-cli": "^2.31.1",
21330
+ "@types/node": "^25.5.0",
21331
+ "@uipath/auth": "workspace:*",
21332
+ "@uipath/common": "workspace:*",
21333
+ "@uipath/filesystem": "workspace:*",
21334
+ typescript: "^6.0.2"
21335
+ }
21336
+ };
21337
+ var SDK_USER_AGENT = getSdkUserAgentToken(package_default2);
21338
+ installSdkUserAgentHeader(BaseAPI, SDK_USER_AGENT);
21074
21339
  function FreezingMetadataFromJSON(json) {
21075
21340
  return FreezingMetadataFromJSONTyped(json, false);
21076
21341
  }
@@ -21764,32 +22029,7 @@ class InvalidBaseUrlError extends Error {
21764
22029
  this.name = "InvalidBaseUrlError";
21765
22030
  }
21766
22031
  }
21767
- var DEFAULT_SCOPES = [
21768
- "offline_access",
21769
- "ProcessMining",
21770
- "OrchestratorApiUserAccess",
21771
- "StudioWebBackend",
21772
- "IdentityServerApi",
21773
- "ConnectionService",
21774
- "DataService",
21775
- "DataServiceApiUserAccess",
21776
- "DocumentUnderstanding",
21777
- "EnterpriseContextService",
21778
- "Directory",
21779
- "JamJamApi",
21780
- "LLMGateway",
21781
- "LLMOps",
21782
- "OMS",
21783
- "RCS.FolderAuthorization",
21784
- "RCS.TagsManagement",
21785
- "TestmanagerApiUserAccess",
21786
- "AutomationSolutions",
21787
- "StudioWebTypeCacheService",
21788
- "Docs.GPT.Search",
21789
- "Insights",
21790
- "ReferenceToken",
21791
- "Audit.Read"
21792
- ];
22032
+ var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
21793
22033
  var normalizeAndValidateBaseUrl = (rawUrl) => {
21794
22034
  let baseUrl = rawUrl;
21795
22035
  if (baseUrl.endsWith("/identity_/")) {
@@ -21839,7 +22079,8 @@ var resolveConfigAsync = async ({
21839
22079
  if (!clientSecret && fileAuth.clientSecret) {
21840
22080
  clientSecret = fileAuth.clientSecret;
21841
22081
  }
21842
- const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : DEFAULT_SCOPES;
22082
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
22083
+ const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES;
21843
22084
  return {
21844
22085
  clientId,
21845
22086
  clientSecret,
@@ -22326,6 +22567,129 @@ function normalizeTokenRefreshFailure() {
22326
22567
  function normalizeTokenRefreshUnavailableFailure() {
22327
22568
  return "token refresh failed before authentication completed";
22328
22569
  }
22570
+ function errorMessage(error) {
22571
+ return error instanceof Error ? error.message : String(error);
22572
+ }
22573
+ function computeExpirationThreshold(ensureTokenValidityMinutes) {
22574
+ return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
22575
+ }
22576
+ async function runRefreshLocked(inputs) {
22577
+ const {
22578
+ absolutePath,
22579
+ refreshToken: callerRefreshToken,
22580
+ customAuthority,
22581
+ ensureTokenValidityMinutes,
22582
+ loadEnvFile,
22583
+ saveEnvFile,
22584
+ refreshFn,
22585
+ resolveConfig
22586
+ } = inputs;
22587
+ const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
22588
+ let fresh;
22589
+ try {
22590
+ fresh = await loadEnvFile({ envPath: absolutePath });
22591
+ } catch (error) {
22592
+ return {
22593
+ kind: "fail",
22594
+ status: {
22595
+ loginStatus: "Refresh Failed",
22596
+ hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
22597
+ tokenRefresh: {
22598
+ attempted: false,
22599
+ success: false,
22600
+ errorMessage: `auth file read failed: ${errorMessage(error)}`
22601
+ }
22602
+ }
22603
+ };
22604
+ }
22605
+ const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
22606
+ const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
22607
+ if (freshAccess && freshExp && freshExp > expirationThreshold) {
22608
+ return {
22609
+ kind: "ok",
22610
+ accessToken: freshAccess,
22611
+ refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
22612
+ expiration: freshExp,
22613
+ tokenRefresh: { attempted: false, success: true }
22614
+ };
22615
+ }
22616
+ const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
22617
+ let refreshedAccess;
22618
+ let refreshedRefresh;
22619
+ try {
22620
+ const config = await resolveConfig({ customAuthority });
22621
+ const refreshed = await refreshFn({
22622
+ refreshToken: tokenForIdP,
22623
+ tokenEndpoint: config.tokenEndpoint,
22624
+ clientId: config.clientId,
22625
+ expectedAuthority: customAuthority
22626
+ });
22627
+ refreshedAccess = refreshed.accessToken;
22628
+ refreshedRefresh = refreshed.refreshToken;
22629
+ } catch (error) {
22630
+ const isOAuthFailure = isTokenRefreshOAuthFailure(error);
22631
+ 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.";
22632
+ const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
22633
+ return {
22634
+ kind: "fail",
22635
+ status: {
22636
+ loginStatus: "Refresh Failed",
22637
+ hint,
22638
+ tokenRefresh: {
22639
+ attempted: true,
22640
+ success: false,
22641
+ errorMessage: message
22642
+ }
22643
+ }
22644
+ };
22645
+ }
22646
+ const refreshedExp = getTokenExpiration(refreshedAccess);
22647
+ if (!refreshedExp || refreshedExp <= new Date) {
22648
+ return {
22649
+ kind: "fail",
22650
+ status: {
22651
+ loginStatus: "Refresh Failed",
22652
+ hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
22653
+ tokenRefresh: {
22654
+ attempted: true,
22655
+ success: false,
22656
+ errorMessage: "refreshed token has no valid expiration claim"
22657
+ }
22658
+ }
22659
+ };
22660
+ }
22661
+ try {
22662
+ await saveEnvFile({
22663
+ envPath: absolutePath,
22664
+ data: {
22665
+ UIPATH_ACCESS_TOKEN: refreshedAccess,
22666
+ UIPATH_REFRESH_TOKEN: refreshedRefresh
22667
+ },
22668
+ merge: true
22669
+ });
22670
+ return {
22671
+ kind: "ok",
22672
+ accessToken: refreshedAccess,
22673
+ refreshToken: refreshedRefresh,
22674
+ expiration: refreshedExp,
22675
+ tokenRefresh: { attempted: true, success: true }
22676
+ };
22677
+ } catch (error) {
22678
+ const msg = errorMessage(error);
22679
+ return {
22680
+ kind: "ok",
22681
+ accessToken: refreshedAccess,
22682
+ refreshToken: refreshedRefresh,
22683
+ expiration: refreshedExp,
22684
+ 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.`,
22685
+ tokenRefresh: {
22686
+ attempted: true,
22687
+ success: true,
22688
+ errorMessage: `persistence failed: ${msg}`
22689
+ }
22690
+ };
22691
+ }
22692
+ }
22329
22693
  var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22330
22694
  const {
22331
22695
  resolveEnvFilePath = resolveEnvFilePathAsync,
@@ -22400,73 +22764,103 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22400
22764
  let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
22401
22765
  let expiration = getTokenExpiration(accessToken);
22402
22766
  let persistenceWarning;
22767
+ let lockReleaseFailed = false;
22403
22768
  let tokenRefresh;
22404
- const expirationThreshold = new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
22405
- if (expiration && expiration <= expirationThreshold && refreshToken) {
22406
- let refreshedAccess;
22407
- let refreshedRefresh;
22769
+ const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
22770
+ const tryGlobalCredsHint = async () => {
22771
+ const fs7 = getFs();
22772
+ const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
22773
+ if (absolutePath === globalPath)
22774
+ return;
22775
+ if (!await fs7.exists(globalPath))
22776
+ return;
22408
22777
  try {
22409
- const config = await resolveConfig({
22410
- customAuthority: credentials.UIPATH_URL
22411
- });
22412
- const refreshed = await refreshTokenFn({
22413
- refreshToken,
22414
- tokenEndpoint: config.tokenEndpoint,
22415
- clientId: config.clientId,
22416
- expectedAuthority: credentials.UIPATH_URL
22417
- });
22418
- refreshedAccess = refreshed.accessToken;
22419
- refreshedRefresh = refreshed.refreshToken;
22420
- } catch (error) {
22421
- const isOAuthFailure = isTokenRefreshOAuthFailure(error);
22422
- 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.";
22423
- const errorMessage = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
22424
- return {
22425
- loginStatus: "Refresh Failed",
22426
- hint,
22427
- tokenRefresh: {
22428
- attempted: true,
22429
- success: false,
22430
- errorMessage
22431
- }
22432
- };
22778
+ const globalCreds = await loadEnvFile({ envPath: globalPath });
22779
+ if (!globalCreds.UIPATH_ACCESS_TOKEN)
22780
+ return;
22781
+ const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
22782
+ if (globalExp && globalExp <= new Date)
22783
+ return;
22784
+ 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.`;
22785
+ } catch {
22786
+ return;
22433
22787
  }
22434
- const refreshedExp = getTokenExpiration(refreshedAccess);
22435
- if (!refreshedExp || refreshedExp <= new Date) {
22788
+ };
22789
+ if (expiration && expiration <= outerThreshold && refreshToken) {
22790
+ let release;
22791
+ try {
22792
+ release = await getFs().acquireLock(absolutePath);
22793
+ } catch (error) {
22794
+ const msg = errorMessage(error);
22795
+ const globalHint = await tryGlobalCredsHint();
22796
+ if (globalHint) {
22797
+ return {
22798
+ loginStatus: "Expired",
22799
+ accessToken,
22800
+ refreshToken,
22801
+ baseUrl: credentials.UIPATH_URL,
22802
+ organizationName: credentials.UIPATH_ORGANIZATION_NAME,
22803
+ organizationId: credentials.UIPATH_ORGANIZATION_ID,
22804
+ tenantName: credentials.UIPATH_TENANT_NAME,
22805
+ tenantId: credentials.UIPATH_TENANT_ID,
22806
+ expiration,
22807
+ source: "file",
22808
+ hint: globalHint,
22809
+ tokenRefresh: {
22810
+ attempted: false,
22811
+ success: false,
22812
+ errorMessage: `lock acquisition failed: ${msg}`
22813
+ }
22814
+ };
22815
+ }
22436
22816
  return {
22437
22817
  loginStatus: "Refresh Failed",
22438
- hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
22818
+ 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.",
22439
22819
  tokenRefresh: {
22440
- attempted: true,
22820
+ attempted: false,
22441
22821
  success: false,
22442
- errorMessage: "refreshed token has no valid expiration claim"
22822
+ errorMessage: `lock acquisition failed: ${msg}`
22443
22823
  }
22444
22824
  };
22445
22825
  }
22446
- accessToken = refreshedAccess;
22447
- refreshToken = refreshedRefresh;
22448
- expiration = refreshedExp;
22826
+ let lockedFailure;
22449
22827
  try {
22450
- await saveEnvFile({
22451
- envPath: absolutePath,
22452
- data: {
22453
- UIPATH_ACCESS_TOKEN: accessToken,
22454
- UIPATH_REFRESH_TOKEN: refreshToken
22455
- },
22456
- merge: true
22828
+ const outcome = await runRefreshLocked({
22829
+ absolutePath,
22830
+ refreshToken,
22831
+ customAuthority: credentials.UIPATH_URL,
22832
+ ensureTokenValidityMinutes,
22833
+ loadEnvFile,
22834
+ saveEnvFile,
22835
+ refreshFn: refreshTokenFn,
22836
+ resolveConfig
22457
22837
  });
22458
- tokenRefresh = {
22459
- attempted: true,
22460
- success: true
22461
- };
22462
- } catch (error) {
22463
- const msg = error instanceof Error ? error.message : String(error);
22464
- 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.`;
22465
- tokenRefresh = {
22466
- attempted: true,
22467
- success: true,
22468
- errorMessage: `persistence failed: ${msg}`
22469
- };
22838
+ if (outcome.kind === "fail") {
22839
+ lockedFailure = outcome.status;
22840
+ } else {
22841
+ accessToken = outcome.accessToken;
22842
+ refreshToken = outcome.refreshToken;
22843
+ expiration = outcome.expiration;
22844
+ tokenRefresh = outcome.tokenRefresh;
22845
+ if (outcome.persistenceWarning) {
22846
+ persistenceWarning = outcome.persistenceWarning;
22847
+ }
22848
+ }
22849
+ } finally {
22850
+ try {
22851
+ await release();
22852
+ } catch {
22853
+ lockReleaseFailed = true;
22854
+ }
22855
+ }
22856
+ if (lockedFailure) {
22857
+ const globalHint = await tryGlobalCredsHint();
22858
+ const base = globalHint ? {
22859
+ ...lockedFailure,
22860
+ loginStatus: "Expired",
22861
+ hint: globalHint
22862
+ } : lockedFailure;
22863
+ return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
22470
22864
  }
22471
22865
  }
22472
22866
  const result = {
@@ -22481,23 +22875,13 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22481
22875
  expiration,
22482
22876
  source: "file",
22483
22877
  ...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
22878
+ ...lockReleaseFailed ? { lockReleaseFailed: true } : {},
22484
22879
  ...tokenRefresh ? { tokenRefresh } : {}
22485
22880
  };
22486
22881
  if (result.loginStatus === "Expired") {
22487
- const fs7 = getFs();
22488
- const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
22489
- if (absolutePath !== globalPath && await fs7.exists(globalPath)) {
22490
- try {
22491
- const globalCreds = await loadEnvFile({
22492
- envPath: globalPath
22493
- });
22494
- if (globalCreds.UIPATH_ACCESS_TOKEN) {
22495
- const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
22496
- if (!globalExp || globalExp > new Date) {
22497
- 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.`;
22498
- }
22499
- }
22500
- } catch {}
22882
+ const globalHint = await tryGlobalCredsHint();
22883
+ if (globalHint) {
22884
+ result.hint = globalHint;
22501
22885
  }
22502
22886
  }
22503
22887
  return result;
@@ -22512,6 +22896,7 @@ var getLoginStatusAsync = async (options = {}) => {
22512
22896
  };
22513
22897
  init_src();
22514
22898
  init_src();
22899
+ init_server();
22515
22900
  async function resolveConfig(options) {
22516
22901
  const status = await getLoginStatusAsync();
22517
22902
  if (status.loginStatus !== "Logged in" || !status.baseUrl || !status.accessToken) {
@@ -22529,10 +22914,10 @@ async function resolveConfig(options) {
22529
22914
  return {
22530
22915
  config: new Configuration({
22531
22916
  basePath,
22532
- headers: {
22917
+ headers: addSdkUserAgentHeader({
22533
22918
  Authorization: `Bearer ${bearerToken}`,
22534
22919
  "x-uipath-source": "UiPath.CLI"
22535
- }
22920
+ }, SDK_USER_AGENT)
22536
22921
  }),
22537
22922
  organizationId: status.organizationId,
22538
22923
  tenantName: tenant
@@ -22548,6 +22933,7 @@ async function createApiClient(ApiClass, options) {
22548
22933
  }
22549
22934
 
22550
22935
  // ../../filesystem/src/node.ts
22936
+ import { randomUUID as randomUUID2 } from "node:crypto";
22551
22937
  import { existsSync as existsSync2 } from "node:fs";
22552
22938
  import * as fs13 from "node:fs/promises";
22553
22939
  import * as os5 from "node:os";
@@ -23164,6 +23550,13 @@ defineLazyProperty2(apps2, "safari", () => detectPlatformBinary2({
23164
23550
  var open_default2 = open2;
23165
23551
 
23166
23552
  // ../../filesystem/src/node.ts
23553
+ var LOCK_HEARTBEAT_MS2 = 5000;
23554
+ var LOCK_STALE_MS2 = 15000;
23555
+ var LOCK_MAX_WAIT_MS2 = 20000;
23556
+ var LOCK_MAX_HOLD_MS2 = 60000;
23557
+ var LOCK_RETRY_MIN_MS2 = 100;
23558
+ var LOCK_RETRY_JITTER_MS2 = 200;
23559
+
23167
23560
  class NodeFileSystem2 {
23168
23561
  path = {
23169
23562
  join: path5.join,
@@ -23240,6 +23633,90 @@ class NodeFileSystem2 {
23240
23633
  async mkdir(dirPath) {
23241
23634
  await fs13.mkdir(dirPath, { recursive: true });
23242
23635
  }
23636
+ async acquireLock(lockPath) {
23637
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
23638
+ const lockFile = `${canonicalPath}.lock`;
23639
+ const ownerId = randomUUID2();
23640
+ const start = Date.now();
23641
+ while (true) {
23642
+ try {
23643
+ await fs13.writeFile(lockFile, ownerId, { flag: "wx" });
23644
+ return this.createLockRelease(lockFile, ownerId);
23645
+ } catch (error) {
23646
+ if (!this.hasErrnoCode(error, "EEXIST")) {
23647
+ throw error;
23648
+ }
23649
+ const stats = await fs13.stat(lockFile).catch(() => null);
23650
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS2) {
23651
+ const reclaimed = await fs13.rm(lockFile, { force: true }).then(() => true).catch(() => false);
23652
+ if (reclaimed)
23653
+ continue;
23654
+ }
23655
+ if (Date.now() - start > LOCK_MAX_WAIT_MS2) {
23656
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
23657
+ }
23658
+ await new Promise((resolve3) => setTimeout(resolve3, LOCK_RETRY_MIN_MS2 + Math.random() * LOCK_RETRY_JITTER_MS2));
23659
+ }
23660
+ }
23661
+ }
23662
+ async canonicalizeLockTarget(lockPath) {
23663
+ const absolute = path5.resolve(lockPath);
23664
+ const fullReal = await fs13.realpath(absolute).catch(() => null);
23665
+ if (fullReal)
23666
+ return fullReal;
23667
+ const parent = path5.dirname(absolute);
23668
+ const base = path5.basename(absolute);
23669
+ const canonicalParent = await fs13.realpath(parent).catch(() => parent);
23670
+ return path5.join(canonicalParent, base);
23671
+ }
23672
+ createLockRelease(lockFile, ownerId) {
23673
+ const heartbeatStart = Date.now();
23674
+ let heartbeatTimer;
23675
+ let stopped = false;
23676
+ const stopHeartbeat = () => {
23677
+ stopped = true;
23678
+ if (heartbeatTimer)
23679
+ clearTimeout(heartbeatTimer);
23680
+ };
23681
+ const scheduleNextHeartbeat = () => {
23682
+ if (stopped)
23683
+ return;
23684
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS2) {
23685
+ stopped = true;
23686
+ return;
23687
+ }
23688
+ heartbeatTimer = setTimeout(() => {
23689
+ runHeartbeat();
23690
+ }, LOCK_HEARTBEAT_MS2);
23691
+ heartbeatTimer.unref?.();
23692
+ };
23693
+ const runHeartbeat = async () => {
23694
+ if (stopped)
23695
+ return;
23696
+ const current = await fs13.readFile(lockFile, "utf-8").catch(() => null);
23697
+ if (stopped)
23698
+ return;
23699
+ if (current !== ownerId) {
23700
+ stopped = true;
23701
+ return;
23702
+ }
23703
+ const now = Date.now() / 1000;
23704
+ await fs13.utimes(lockFile, now, now).catch(() => {});
23705
+ scheduleNextHeartbeat();
23706
+ };
23707
+ scheduleNextHeartbeat();
23708
+ let released = false;
23709
+ return async () => {
23710
+ if (released)
23711
+ return;
23712
+ released = true;
23713
+ stopHeartbeat();
23714
+ const current = await fs13.readFile(lockFile, "utf-8").catch(() => null);
23715
+ if (current === ownerId) {
23716
+ await fs13.rm(lockFile, { force: true });
23717
+ }
23718
+ };
23719
+ }
23243
23720
  async rm(filePath) {
23244
23721
  await fs13.rm(filePath, { recursive: true, force: true });
23245
23722
  }
@@ -23285,7 +23762,10 @@ class NodeFileSystem2 {
23285
23762
  }
23286
23763
  }
23287
23764
  isEnoent(error) {
23288
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
23765
+ return this.hasErrnoCode(error, "ENOENT");
23766
+ }
23767
+ hasErrnoCode(error, code) {
23768
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
23289
23769
  }
23290
23770
  }
23291
23771
 
@@ -23427,10 +23907,15 @@ async function extractErrorDetails(error, options) {
23427
23907
  }
23428
23908
  if (parsedBody?.errorCode && typeof parsedBody.errorCode === "string") {
23429
23909
  context.errorCode = parsedBody.errorCode;
23910
+ } else if (parsedBody?.code && typeof parsedBody.code === "string") {
23911
+ context.errorCode = parsedBody.code;
23430
23912
  }
23431
23913
  if (parsedBody?.requestId && typeof parsedBody.requestId === "string") {
23432
23914
  context.requestId = parsedBody.requestId;
23433
23915
  }
23916
+ if (parsedBody?.traceId && typeof parsedBody.traceId === "string") {
23917
+ context.traceId = parsedBody.traceId;
23918
+ }
23434
23919
  if (status === 429) {
23435
23920
  const resp = response;
23436
23921
  const headersObj = resp?.headers;
@@ -23450,7 +23935,35 @@ async function extractErrorDetails(error, options) {
23450
23935
  }
23451
23936
  }
23452
23937
  const hasContext = Object.keys(context).length > 0;
23453
- return { result, message, details, ...hasContext ? { context } : {} };
23938
+ let parsedErrors;
23939
+ if (parsedBody?.errors && typeof parsedBody.errors === "object") {
23940
+ const errors = {};
23941
+ for (const [field, raw] of Object.entries(parsedBody.errors)) {
23942
+ if (Array.isArray(raw)) {
23943
+ const messages = raw.map((entry) => {
23944
+ if (typeof entry === "string")
23945
+ return entry;
23946
+ if (entry && typeof entry === "object" && typeof entry.message === "string") {
23947
+ return entry.message;
23948
+ }
23949
+ return String(entry);
23950
+ }).filter(Boolean);
23951
+ if (messages.length > 0)
23952
+ errors[field] = messages;
23953
+ } else if (typeof raw === "string") {
23954
+ errors[field] = [raw];
23955
+ }
23956
+ }
23957
+ if (Object.keys(errors).length > 0)
23958
+ parsedErrors = errors;
23959
+ }
23960
+ return {
23961
+ result,
23962
+ message,
23963
+ details,
23964
+ ...hasContext ? { context } : {},
23965
+ ...parsedErrors ? { parsedErrors } : {}
23966
+ };
23454
23967
  }
23455
23968
  // ../../common/src/command-examples.ts
23456
23969
  var examplesByCommand = new WeakMap;
@@ -23459,30 +23972,30 @@ Command.prototype.examples = function(examples) {
23459
23972
  return this;
23460
23973
  };
23461
23974
  // ../../common/src/singleton.ts
23462
- var PREFIX = "@uipath/common/";
23463
- var _g = globalThis;
23464
- function singleton(ctorOrName) {
23975
+ var PREFIX2 = "@uipath/common/";
23976
+ var _g2 = globalThis;
23977
+ function singleton2(ctorOrName) {
23465
23978
  const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
23466
- const key = Symbol.for(PREFIX + name);
23979
+ const key = Symbol.for(PREFIX2 + name);
23467
23980
  return {
23468
23981
  get(fallback) {
23469
- return _g[key] ?? fallback;
23982
+ return _g2[key] ?? fallback;
23470
23983
  },
23471
23984
  set(value) {
23472
- _g[key] = value;
23985
+ _g2[key] = value;
23473
23986
  },
23474
23987
  clear() {
23475
- delete _g[key];
23988
+ delete _g2[key];
23476
23989
  },
23477
23990
  getOrInit(factory, guard) {
23478
- const existing = _g[key];
23991
+ const existing = _g2[key];
23479
23992
  if (existing != null && typeof existing === "object") {
23480
23993
  if (!guard || guard(existing)) {
23481
23994
  return existing;
23482
23995
  }
23483
23996
  }
23484
23997
  const instance = factory();
23485
- _g[key] = instance;
23998
+ _g2[key] = instance;
23486
23999
  return instance;
23487
24000
  }
23488
24001
  };
@@ -23501,8 +24014,8 @@ function createStorage() {
23501
24014
  }
23502
24015
  return new mod.AsyncLocalStorage;
23503
24016
  }
23504
- var storageSingleton = singleton("OutputStorage");
23505
- var sinkSlot = singleton("OutputSink");
24017
+ var storageSingleton = singleton2("OutputStorage");
24018
+ var sinkSlot = singleton2("OutputSink");
23506
24019
  var outputStorage = storageSingleton.getOrInit(createStorage, (v) => ("getStore" in v));
23507
24020
  var CONSOLE_FALLBACK = {
23508
24021
  writeOut: (str) => process.stdout.write(str),
@@ -23520,8 +24033,8 @@ function getOutputSink() {
23520
24033
  // ../../common/src/completer.ts
23521
24034
  var COMPLETER_SYMBOL = Symbol.for("@uipath/common/completer");
23522
24035
  // ../../common/src/console-guard.ts
23523
- var guardInstalledSlot = singleton("ConsoleGuardInstalled");
23524
- var savedOriginalsSlot = singleton("ConsoleGuardOriginals");
24036
+ var guardInstalledSlot = singleton2("ConsoleGuardInstalled");
24037
+ var savedOriginalsSlot = singleton2("ConsoleGuardOriginals");
23525
24038
  // ../../common/src/constants.ts
23526
24039
  var DEFAULT_AUTH_TIMEOUT_MS2 = 5 * 60 * 1000;
23527
24040
  // ../../common/src/error-instructions.ts
@@ -28175,7 +28688,7 @@ var safeLoadAll = renamed("safeLoadAll", "loadAll");
28175
28688
  var safeDump = renamed("safeDump", "dump");
28176
28689
 
28177
28690
  // ../../common/src/logger.ts
28178
- var logFilePathSlot = singleton("logFilePath");
28691
+ var logFilePathSlot = singleton2("logFilePath");
28179
28692
  function setGlobalLogFilePath(path4) {
28180
28693
  logFilePathSlot.set(path4);
28181
28694
  }
@@ -28359,16 +28872,16 @@ class SimpleLogger {
28359
28872
  }
28360
28873
  };
28361
28874
  }
28362
- var loggerSingleton = singleton(SimpleLogger);
28875
+ var loggerSingleton = singleton2(SimpleLogger);
28363
28876
  var logger = SimpleLogger.getInstance();
28364
28877
  function getLogFilePath() {
28365
28878
  return logger.getLogFilePath();
28366
28879
  }
28367
28880
 
28368
28881
  // ../../common/src/output-format-context.ts
28369
- var formatSlot = singleton("OutputFormat");
28370
- var formatExplicitSlot = singleton("OutputFormatExplicit");
28371
- var filterSlot = singleton("OutputFilter");
28882
+ var formatSlot = singleton2("OutputFormat");
28883
+ var formatExplicitSlot = singleton2("OutputFormatExplicit");
28884
+ var filterSlot = singleton2("OutputFilter");
28372
28885
  function getOutputFormat() {
28373
28886
  return formatSlot.get("json");
28374
28887
  }
@@ -28546,11 +29059,11 @@ class TelemetryService {
28546
29059
  }
28547
29060
  }
28548
29061
  // ../../common/src/telemetry/node-appinsights-telemetry-provider.ts
28549
- var telemetryPropsSlot = singleton("TelemetryDefaultProps");
28550
- var providerSlot = singleton("TelemetryProvider");
29062
+ var telemetryPropsSlot = singleton2("TelemetryDefaultProps");
29063
+ var providerSlot = singleton2("TelemetryProvider");
28551
29064
 
28552
29065
  // ../../common/src/telemetry/telemetry-init.ts
28553
- var telemetryInstanceSlot = singleton("TelemetryService");
29066
+ var telemetryInstanceSlot = singleton2("TelemetryService");
28554
29067
  var DEFAULT_AI_CONNECTION_STRING = atob("SW5zdHJ1bWVudGF0aW9uS2V5PTliZDM3NDgyLTgxMGUtNDQyYS1hYWE2LWQzOGVmNjVjNjY3NDtJbmdlc3Rpb25FbmRwb2ludD1odHRwczovL3dlc3RldXJvcGUtNS5pbi5hcHBsaWNhdGlvbmluc2lnaHRzLmF6dXJlLmNvbS87TGl2ZUVuZHBvaW50PWh0dHBzOi8vd2VzdGV1cm9wZS5saXZlZGlhZ25vc3RpY3MubW9uaXRvci5henVyZS5jb20vO0FwcGxpY2F0aW9uSWQ9MzU2OTdlZjEtOGJkMC00ZjE5LWEyN2MtZDg3Y2NhYzY2ZDJj");
28555
29068
  function getGlobalTelemetryInstance() {
28556
29069
  const existing = telemetryInstanceSlot.get();
@@ -28619,6 +29132,60 @@ function escapeNonAscii(jsonText) {
28619
29132
  function needsAsciiSafeJson(sink) {
28620
29133
  return process.platform === "win32" && !sink.capabilities.isInteractive;
28621
29134
  }
29135
+ function isPlainRecord(value) {
29136
+ if (value === null || typeof value !== "object")
29137
+ return false;
29138
+ const prototype = Object.getPrototypeOf(value);
29139
+ return prototype === Object.prototype || prototype === null;
29140
+ }
29141
+ function toLowerCamelCaseKey(key) {
29142
+ if (!key)
29143
+ return key;
29144
+ if (/[_\-\s]/.test(key)) {
29145
+ const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
29146
+ if (!firstPart)
29147
+ return key;
29148
+ return [
29149
+ toLowerCamelCaseSimpleKey(firstPart),
29150
+ ...restParts.map((part) => {
29151
+ const normalized = toLowerCamelCaseSimpleKey(part);
29152
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
29153
+ })
29154
+ ].join("");
29155
+ }
29156
+ return toLowerCamelCaseSimpleKey(key);
29157
+ }
29158
+ function toLowerCamelCaseSimpleKey(key) {
29159
+ if (/^[A-Z0-9]+$/.test(key))
29160
+ return key.toLowerCase();
29161
+ return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
29162
+ }
29163
+ function toPascalCaseKey(key) {
29164
+ const lowerCamelKey = toLowerCamelCaseKey(key);
29165
+ return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
29166
+ }
29167
+ function toPascalCaseData(value) {
29168
+ if (Array.isArray(value))
29169
+ return value.map(toPascalCaseData);
29170
+ if (!isPlainRecord(value))
29171
+ return value;
29172
+ const result = {};
29173
+ for (const [key, nestedValue] of Object.entries(value)) {
29174
+ result[toPascalCaseKey(key)] = toPascalCaseData(nestedValue);
29175
+ }
29176
+ return result;
29177
+ }
29178
+ function normalizeDataKeys(data) {
29179
+ return toPascalCaseData(data);
29180
+ }
29181
+ function normalizeOutputKeys(data) {
29182
+ const result = {};
29183
+ for (const [key, value] of Object.entries(data)) {
29184
+ const pascalKey = toPascalCaseKey(key);
29185
+ result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData(value);
29186
+ }
29187
+ return result;
29188
+ }
28622
29189
  function printOutput(data, format = "json", logFn, asciiSafe = false) {
28623
29190
  if (!data) {
28624
29191
  logFn("Empty response object. No data to display.");
@@ -28681,7 +29248,7 @@ function wrapText(text, width) {
28681
29248
  function printTable(data, logFn, externalLogValue) {
28682
29249
  if (data.length === 0)
28683
29250
  return;
28684
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
29251
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
28685
29252
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
28686
29253
  const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
28687
29254
  logFn(header);
@@ -28696,7 +29263,7 @@ function printTable(data, logFn, externalLogValue) {
28696
29263
  }
28697
29264
  }
28698
29265
  function printVerticalTable(data, logFn = console.log, externalLogValue) {
28699
- const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
29266
+ const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
28700
29267
  if (keys.length === 0)
28701
29268
  return;
28702
29269
  const maxKeyWidth = Math.max(...keys.map((key) => key.length));
@@ -28712,7 +29279,7 @@ function printVerticalTable(data, logFn = console.log, externalLogValue) {
28712
29279
  function printResizableTable(data, logFn = console.log, externalLogValue) {
28713
29280
  if (data.length === 0)
28714
29281
  return;
28715
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
29282
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
28716
29283
  if (keys.length === 0)
28717
29284
  return;
28718
29285
  if (!process.stdout.isTTY) {
@@ -28788,8 +29355,26 @@ function printResizableTable(data, logFn = console.log, externalLogValue) {
28788
29355
  function toYaml(data) {
28789
29356
  return dump(data);
28790
29357
  }
29358
+ class FilterEvaluationError extends Error {
29359
+ __brand = "FilterEvaluationError";
29360
+ filter;
29361
+ instructions;
29362
+ result = RESULTS.ValidationError;
29363
+ constructor(filter, cause) {
29364
+ const underlying = cause instanceof Error ? cause.message : String(cause);
29365
+ super(`Filter '${filter}' failed to evaluate: ${underlying}`);
29366
+ this.name = "FilterEvaluationError";
29367
+ this.filter = filter;
29368
+ 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(@)'.";
29369
+ }
29370
+ }
28791
29371
  function applyFilter(data, filter) {
28792
- const result = search(data, filter);
29372
+ let result;
29373
+ try {
29374
+ result = search(data, filter);
29375
+ } catch (err) {
29376
+ throw new FilterEvaluationError(filter, err);
29377
+ }
28793
29378
  if (result == null)
28794
29379
  return [];
28795
29380
  if (Array.isArray(result)) {
@@ -28806,13 +29391,18 @@ function applyFilter(data, filter) {
28806
29391
  }
28807
29392
  var OutputFormatter;
28808
29393
  ((OutputFormatter) => {
28809
- function success(data) {
29394
+ function success(data, options) {
28810
29395
  data.Log ??= getLogFilePath() || undefined;
29396
+ const normalize = !options?.preserveDataKeys;
29397
+ if (normalize) {
29398
+ data.Data = normalizeDataKeys(data.Data);
29399
+ }
28811
29400
  const filter = getOutputFilter();
28812
29401
  if (filter) {
28813
- data.Data = applyFilter(data.Data, filter);
29402
+ const filtered = applyFilter(data.Data, filter);
29403
+ data.Data = normalize ? normalizeDataKeys(filtered) : filtered;
28814
29404
  }
28815
- logOutput(data, getOutputFormat());
29405
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
28816
29406
  }
28817
29407
  OutputFormatter.success = success;
28818
29408
  function error(data) {
@@ -28822,7 +29412,7 @@ var OutputFormatter;
28822
29412
  result: data.Result,
28823
29413
  message: data.Message
28824
29414
  });
28825
- logOutput(data, getOutputFormat());
29415
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
28826
29416
  }
28827
29417
  OutputFormatter.error = error;
28828
29418
  function emitList(code, items, opts) {
@@ -28843,13 +29433,14 @@ var OutputFormatter;
28843
29433
  function log(data) {
28844
29434
  const format = getOutputFormat();
28845
29435
  const sink = getOutputSink();
29436
+ const normalized = toPascalCaseData(data);
28846
29437
  if (format === "json") {
28847
- const json2 = JSON.stringify(data);
29438
+ const json2 = JSON.stringify(normalized);
28848
29439
  const safe = needsAsciiSafeJson(sink) ? escapeNonAscii(json2) : json2;
28849
29440
  sink.writeErr(`${safe}
28850
29441
  `);
28851
29442
  } else {
28852
- for (const [key, value] of Object.entries(data)) {
29443
+ for (const [key, value] of Object.entries(normalized)) {
28853
29444
  sink.writeErr(`${key}: ${value}
28854
29445
  `);
28855
29446
  }
@@ -28858,12 +29449,16 @@ var OutputFormatter;
28858
29449
  OutputFormatter.log = log;
28859
29450
  function formatToString(data) {
28860
29451
  const filter = getOutputFilter();
28861
- if (filter && "Data" in data && data.Data != null) {
28862
- data.Data = applyFilter(data.Data, filter);
29452
+ if ("Data" in data && data.Data != null) {
29453
+ data.Data = normalizeDataKeys(data.Data);
29454
+ if (filter) {
29455
+ data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
29456
+ }
28863
29457
  }
29458
+ const output = normalizeOutputKeys(data);
28864
29459
  const lines = [];
28865
29460
  const sink = getOutputSink();
28866
- printOutput(data, getOutputFormat(), (msg) => {
29461
+ printOutput(output, getOutputFormat(), (msg) => {
28867
29462
  lines.push(msg);
28868
29463
  }, needsAsciiSafeJson(sink));
28869
29464
  return lines.join(`
@@ -30274,6 +30869,22 @@ JSONPath.prototype.safeVm = {
30274
30869
  Script: SafeScript
30275
30870
  };
30276
30871
  JSONPath.prototype.vm = vm;
30872
+ // ../../common/src/polling/types.ts
30873
+ var PollOutcome = {
30874
+ Completed: "completed",
30875
+ Timeout: "timeout",
30876
+ Interrupted: "interrupted",
30877
+ Aborted: "aborted",
30878
+ Failed: "failed"
30879
+ };
30880
+
30881
+ // ../../common/src/polling/poll-failure-mapping.ts
30882
+ var REASON_BY_OUTCOME = {
30883
+ [PollOutcome.Timeout]: "poll_timeout",
30884
+ [PollOutcome.Failed]: "poll_failed",
30885
+ [PollOutcome.Interrupted]: "poll_failed",
30886
+ [PollOutcome.Aborted]: "poll_aborted"
30887
+ };
30277
30888
  // ../../common/src/polling/terminal-statuses.ts
30278
30889
  var TERMINAL_STATUSES = new Set([
30279
30890
  "completed",
@@ -30301,8 +30912,10 @@ var ScreenLogger;
30301
30912
  }
30302
30913
  ScreenLogger.progress = progress;
30303
30914
  })(ScreenLogger ||= {});
30915
+ // ../../common/src/sdk-user-agent.ts
30916
+ var sdkUserAgentHostToken2 = singleton2("SdkUserAgentHostToken");
30304
30917
  // ../../common/src/tool-provider.ts
30305
- var factorySlot = singleton("PackagerFactoryProvider");
30918
+ var factorySlot = singleton2("PackagerFactoryProvider");
30306
30919
  // ../../common/src/telemetry/pii-redactor.ts
30307
30920
  var REDACTED = "[REDACTED]";
30308
30921
  var MAX_VALUE_LENGTH = 200;
@@ -30428,7 +31041,7 @@ function redactProperties(properties) {
30428
31041
  }
30429
31042
 
30430
31043
  // ../../common/src/trackedAction.ts
30431
- var pollSignalSlot = singleton("PollSignal");
31044
+ var pollSignalSlot = singleton2("PollSignal");
30432
31045
  var processContext = {
30433
31046
  exit: (code) => {
30434
31047
  process.exitCode = code;
@@ -30479,17 +31092,21 @@ Command.prototype.trackedAction = function(context, fn, properties) {
30479
31092
  const telemetryName = deriveCommandPath(command);
30480
31093
  const props = typeof properties === "function" ? properties(...args) : properties;
30481
31094
  const startTime = performance.now();
30482
- let errorMessage;
31095
+ let errorMessage2;
30483
31096
  const [error] = await catchError2(fn(...args));
30484
31097
  if (error) {
30485
- errorMessage = error instanceof Error ? error.message : String(error);
30486
- logger.error(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
31098
+ errorMessage2 = error instanceof Error ? error.message : String(error);
31099
+ logger.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage2}`);
31100
+ const typed = error;
31101
+ const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
31102
+ const customResult = typeof typed.result === "string" && typed.result !== RESULTS.Success && Object.values(RESULTS).includes(typed.result) ? typed.result : undefined;
31103
+ const finalResult = customResult ?? RESULTS.Failure;
30487
31104
  OutputFormatter.error({
30488
- Result: RESULTS.Failure,
30489
- Message: errorMessage,
30490
- Instructions: "An unexpected error occurred. Run with --log-level debug for details."
31105
+ Result: finalResult,
31106
+ Message: errorMessage2,
31107
+ Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
30491
31108
  });
30492
- context.exit(1);
31109
+ context.exit(EXIT_CODES[finalResult]);
30493
31110
  }
30494
31111
  const durationMs = performance.now() - startTime;
30495
31112
  const success = !error && (process.exitCode === undefined || process.exitCode === 0);
@@ -30498,7 +31115,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
30498
31115
  ...props,
30499
31116
  duration: String(durationMs),
30500
31117
  success: String(success),
30501
- ...errorMessage ? { errorMessage } : {}
31118
+ ...errorMessage2 ? { errorMessage: errorMessage2 } : {}
30502
31119
  }));
30503
31120
  });
30504
31121
  };
@@ -30519,14 +31136,14 @@ async function reportError(error, loginInstructions) {
30519
31136
 
30520
31137
  // src/helpers/validators.ts
30521
31138
  var IPV4_OCTET = /^(25[0-5]|2[0-4]\d|[01]?\d?\d)$/;
30522
- function errorMessage(err) {
31139
+ function errorMessage2(err) {
30523
31140
  return err instanceof Error ? err.message : String(err);
30524
31141
  }
30525
31142
  function asInvalidArgument(fn) {
30526
31143
  try {
30527
31144
  return fn();
30528
31145
  } catch (err) {
30529
- throw new InvalidArgumentError(errorMessage(err));
31146
+ throw new InvalidArgumentError(errorMessage2(err));
30530
31147
  }
30531
31148
  }
30532
31149
  function assertIpv4(value, label) {
@@ -31200,7 +31817,7 @@ function appendTrustedCert(value, previous) {
31200
31817
  try {
31201
31818
  return [...previous, assertTrustedCertSpec(value)];
31202
31819
  } catch (err) {
31203
- throw new InvalidArgumentError(errorMessage(err));
31820
+ throw new InvalidArgumentError(errorMessage2(err));
31204
31821
  }
31205
31822
  }
31206
31823
  var LOGIN_INSTRUCTIONS2 = "Ensure you are logged in with 'uip login' and that your account has org-admin access to the Hypervisor service. Pass --tenant <name> to target a tenant other than your login context.";