@uipath/gov-tool 0.3.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 (2) hide show
  1. package/dist/tool.js +1777 -590
  2. package/package.json +25 -39
package/dist/tool.js CHANGED
@@ -1004,7 +1004,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1004
1004
  this._exitCallback = (err) => {
1005
1005
  if (err.code !== "commander.executeSubCommandAsync") {
1006
1006
  throw err;
1007
- } else {}
1007
+ }
1008
1008
  };
1009
1009
  }
1010
1010
  return this;
@@ -2156,6 +2156,7 @@ import path from "node:path";
2156
2156
  import { fileURLToPath } from "node:url";
2157
2157
  import childProcess3 from "node:child_process";
2158
2158
  import fs5, { constants as fsConstants2 } from "node:fs/promises";
2159
+ import { randomUUID } from "node:crypto";
2159
2160
  import { existsSync } from "node:fs";
2160
2161
  import * as fs6 from "node:fs/promises";
2161
2162
  import * as os2 from "node:os";
@@ -2928,6 +2929,90 @@ class NodeFileSystem {
2928
2929
  async mkdir(dirPath) {
2929
2930
  await fs6.mkdir(dirPath, { recursive: true });
2930
2931
  }
2932
+ async acquireLock(lockPath) {
2933
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
2934
+ const lockFile = `${canonicalPath}.lock`;
2935
+ const ownerId = randomUUID();
2936
+ const start = Date.now();
2937
+ while (true) {
2938
+ try {
2939
+ await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
2940
+ return this.createLockRelease(lockFile, ownerId);
2941
+ } catch (error) {
2942
+ if (!this.hasErrnoCode(error, "EEXIST")) {
2943
+ throw error;
2944
+ }
2945
+ const stats = await fs6.stat(lockFile).catch(() => null);
2946
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
2947
+ const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
2948
+ if (reclaimed)
2949
+ continue;
2950
+ }
2951
+ if (Date.now() - start > LOCK_MAX_WAIT_MS) {
2952
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
2953
+ }
2954
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
2955
+ }
2956
+ }
2957
+ }
2958
+ async canonicalizeLockTarget(lockPath) {
2959
+ const absolute = path2.resolve(lockPath);
2960
+ const fullReal = await fs6.realpath(absolute).catch(() => null);
2961
+ if (fullReal)
2962
+ return fullReal;
2963
+ const parent = path2.dirname(absolute);
2964
+ const base = path2.basename(absolute);
2965
+ const canonicalParent = await fs6.realpath(parent).catch(() => parent);
2966
+ return path2.join(canonicalParent, base);
2967
+ }
2968
+ createLockRelease(lockFile, ownerId) {
2969
+ const heartbeatStart = Date.now();
2970
+ let heartbeatTimer;
2971
+ let stopped = false;
2972
+ const stopHeartbeat = () => {
2973
+ stopped = true;
2974
+ if (heartbeatTimer)
2975
+ clearTimeout(heartbeatTimer);
2976
+ };
2977
+ const scheduleNextHeartbeat = () => {
2978
+ if (stopped)
2979
+ return;
2980
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
2981
+ stopped = true;
2982
+ return;
2983
+ }
2984
+ heartbeatTimer = setTimeout(() => {
2985
+ runHeartbeat();
2986
+ }, LOCK_HEARTBEAT_MS);
2987
+ heartbeatTimer.unref?.();
2988
+ };
2989
+ const runHeartbeat = async () => {
2990
+ if (stopped)
2991
+ return;
2992
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2993
+ if (stopped)
2994
+ return;
2995
+ if (current !== ownerId) {
2996
+ stopped = true;
2997
+ return;
2998
+ }
2999
+ const now = Date.now() / 1000;
3000
+ await fs6.utimes(lockFile, now, now).catch(() => {});
3001
+ scheduleNextHeartbeat();
3002
+ };
3003
+ scheduleNextHeartbeat();
3004
+ let released = false;
3005
+ return async () => {
3006
+ if (released)
3007
+ return;
3008
+ released = true;
3009
+ stopHeartbeat();
3010
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
3011
+ if (current === ownerId) {
3012
+ await fs6.rm(lockFile, { force: true });
3013
+ }
3014
+ };
3015
+ }
2931
3016
  async rm(filePath) {
2932
3017
  await fs6.rm(filePath, { recursive: true, force: true });
2933
3018
  }
@@ -2973,16 +3058,23 @@ class NodeFileSystem {
2973
3058
  }
2974
3059
  }
2975
3060
  isEnoent(error) {
2976
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3061
+ return this.hasErrnoCode(error, "ENOENT");
3062
+ }
3063
+ hasErrnoCode(error, code) {
3064
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
2977
3065
  }
2978
3066
  }
3067
+ var LOCK_HEARTBEAT_MS = 5000;
3068
+ var LOCK_STALE_MS = 15000;
3069
+ var LOCK_MAX_WAIT_MS = 20000;
3070
+ var LOCK_MAX_HOLD_MS = 60000;
3071
+ var LOCK_RETRY_MIN_MS = 100;
3072
+ var LOCK_RETRY_JITTER_MS = 200;
2979
3073
  var init_node = __esm(() => {
2980
3074
  init_open();
2981
3075
  });
2982
3076
  var fsInstance;
2983
- var getFileSystem = () => {
2984
- return fsInstance;
2985
- };
3077
+ var getFileSystem = () => fsInstance;
2986
3078
  var init_src = __esm(() => {
2987
3079
  init_node();
2988
3080
  init_node();
@@ -20789,9 +20881,13 @@ var require_dist = __commonJS2((exports) => {
20789
20881
  exports.RobotProxyConstructor = RobotProxyConstructor;
20790
20882
  __exportStar(require_agent(), exports);
20791
20883
  });
20884
+ var init_server = __esm(() => {
20885
+ init_constants();
20886
+ });
20792
20887
  var package_default = {
20793
20888
  name: "@uipath/access-policy-tool",
20794
- version: "0.3.0",
20889
+ license: "MIT",
20890
+ version: "1.2.0",
20795
20891
  description: "Manage UiPath Access Policies, rules, and compliance evaluations.",
20796
20892
  private: false,
20797
20893
  repository: {
@@ -20828,11 +20924,137 @@ var package_default = {
20828
20924
  commander: "^14.0.3",
20829
20925
  "@uipath/common": "workspace:*",
20830
20926
  "@uipath/filesystem": "workspace:*",
20831
- "@uipath/access-policy-sdk": "workspace:*",
20927
+ "@uipath/authz-sdk": "workspace:*",
20832
20928
  "@types/node": "^25.5.2",
20833
20929
  typescript: "^6.0.2"
20834
20930
  }
20835
20931
  };
20932
+ var PREFIX = "@uipath/common/";
20933
+ var _g = globalThis;
20934
+ function singleton(ctorOrName) {
20935
+ const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
20936
+ const key = Symbol.for(PREFIX + name);
20937
+ return {
20938
+ get(fallback) {
20939
+ return _g[key] ?? fallback;
20940
+ },
20941
+ set(value) {
20942
+ _g[key] = value;
20943
+ },
20944
+ clear() {
20945
+ delete _g[key];
20946
+ },
20947
+ getOrInit(factory, guard) {
20948
+ const existing = _g[key];
20949
+ if (existing != null && typeof existing === "object") {
20950
+ if (!guard || guard(existing)) {
20951
+ return existing;
20952
+ }
20953
+ }
20954
+ const instance = factory();
20955
+ _g[key] = instance;
20956
+ return instance;
20957
+ }
20958
+ };
20959
+ }
20960
+ var USER_AGENT_HEADER = "User-Agent";
20961
+ var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
20962
+ function userAgentPatchKey(userAgent) {
20963
+ return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
20964
+ }
20965
+ function splitUserAgentTokens(value) {
20966
+ return value?.trim().split(/\s+/).filter(Boolean) ?? [];
20967
+ }
20968
+ function appendUserAgentToken(value, userAgent) {
20969
+ const tokens = splitUserAgentTokens(value);
20970
+ const seen = new Set(tokens);
20971
+ for (const token of splitUserAgentTokens(userAgent)) {
20972
+ if (!seen.has(token)) {
20973
+ tokens.push(token);
20974
+ seen.add(token);
20975
+ }
20976
+ }
20977
+ return tokens.join(" ");
20978
+ }
20979
+ function getEffectiveUserAgent(userAgent) {
20980
+ return appendUserAgentToken(sdkUserAgentHostToken.get(), userAgent);
20981
+ }
20982
+ function isHeadersLike(headers) {
20983
+ return typeof headers === "object" && headers !== null && "get" in headers && typeof headers.get === "function" && "set" in headers && typeof headers.set === "function";
20984
+ }
20985
+ function getSdkUserAgentToken(pkg) {
20986
+ const packageName = pkg.name.replace(/^@uipath\//, "");
20987
+ return getEffectiveUserAgent(`${packageName}/${pkg.version}`);
20988
+ }
20989
+ function addSdkUserAgentHeader(headers, userAgent) {
20990
+ const result = { ...headers ?? {} };
20991
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
20992
+ const headerName = Object.keys(result).find((key) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
20993
+ if (headerName) {
20994
+ result[headerName] = appendUserAgentToken(result[headerName], effectiveUserAgent);
20995
+ } else {
20996
+ result[USER_AGENT_HEADER] = effectiveUserAgent;
20997
+ }
20998
+ return result;
20999
+ }
21000
+ function withSdkUserAgentHeader(headers, userAgent) {
21001
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
21002
+ if (isHeadersLike(headers)) {
21003
+ headers.set(USER_AGENT_HEADER, appendUserAgentToken(headers.get(USER_AGENT_HEADER), effectiveUserAgent));
21004
+ return headers;
21005
+ }
21006
+ if (Array.isArray(headers)) {
21007
+ const result = headers.map((entry) => {
21008
+ const [key, value] = entry;
21009
+ return [key, value];
21010
+ });
21011
+ const headerIndex = result.findIndex(([key]) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
21012
+ if (headerIndex >= 0) {
21013
+ const [key, value] = result[headerIndex];
21014
+ result[headerIndex] = [
21015
+ key,
21016
+ appendUserAgentToken(value, effectiveUserAgent)
21017
+ ];
21018
+ } else {
21019
+ result.push([USER_AGENT_HEADER, effectiveUserAgent]);
21020
+ }
21021
+ return result;
21022
+ }
21023
+ return addSdkUserAgentHeader(typeof headers === "object" && headers !== null ? { ...headers } : {}, effectiveUserAgent);
21024
+ }
21025
+ function withUserAgentInitOverride(initOverrides, userAgent) {
21026
+ return async (requestContext) => {
21027
+ const initWithUserAgent = {
21028
+ ...requestContext.init,
21029
+ headers: withSdkUserAgentHeader(requestContext.init.headers, userAgent)
21030
+ };
21031
+ const override = typeof initOverrides === "function" ? await initOverrides({
21032
+ ...requestContext,
21033
+ init: initWithUserAgent
21034
+ }) : initOverrides;
21035
+ return {
21036
+ ...override ?? {},
21037
+ headers: withSdkUserAgentHeader(override?.headers ?? initWithUserAgent.headers, userAgent)
21038
+ };
21039
+ };
21040
+ }
21041
+ function installSdkUserAgentHeader(BaseApiClass, userAgent) {
21042
+ const prototype = BaseApiClass.prototype;
21043
+ const patchKey = userAgentPatchKey(userAgent);
21044
+ if (prototype[patchKey]) {
21045
+ return;
21046
+ }
21047
+ if (typeof prototype.request !== "function") {
21048
+ throw new Error("Generated BaseAPI request function not found.");
21049
+ }
21050
+ const originalRequest = prototype.request;
21051
+ prototype.request = function requestWithUserAgent(context, initOverrides) {
21052
+ return originalRequest.call(this, context, withUserAgentInitOverride(initOverrides, userAgent));
21053
+ };
21054
+ Object.defineProperty(prototype, patchKey, {
21055
+ value: true
21056
+ });
21057
+ }
20836
21058
  var BASE_PATH = "http://localhost".replace(/\/+$/, "");
20837
21059
 
20838
21060
  class Configuration {
@@ -21019,10 +21241,6 @@ class ResponseError extends Error {
21019
21241
  constructor(response, msg) {
21020
21242
  super(msg);
21021
21243
  this.response = response;
21022
- const actualProto = new.target.prototype;
21023
- if (Object.setPrototypeOf) {
21024
- Object.setPrototypeOf(this, actualProto);
21025
- }
21026
21244
  }
21027
21245
  }
21028
21246
 
@@ -21032,10 +21250,6 @@ class FetchError extends Error {
21032
21250
  constructor(cause, msg) {
21033
21251
  super(msg);
21034
21252
  this.cause = cause;
21035
- const actualProto = new.target.prototype;
21036
- if (Object.setPrototypeOf) {
21037
- Object.setPrototypeOf(this, actualProto);
21038
- }
21039
21253
  }
21040
21254
  }
21041
21255
 
@@ -21045,10 +21259,6 @@ class RequiredError extends Error {
21045
21259
  constructor(field, msg) {
21046
21260
  super(msg);
21047
21261
  this.field = field;
21048
- const actualProto = new.target.prototype;
21049
- if (Object.setPrototypeOf) {
21050
- Object.setPrototypeOf(this, actualProto);
21051
- }
21052
21262
  }
21053
21263
  }
21054
21264
  function querystring(params, prefix = "") {
@@ -21094,6 +21304,54 @@ class VoidApiResponse {
21094
21304
  return;
21095
21305
  }
21096
21306
  }
21307
+ var package_default2 = {
21308
+ name: "@uipath/authz-sdk",
21309
+ license: "MIT",
21310
+ version: "1.2.0",
21311
+ description: "SDK for the UiPath Authorization Service API.",
21312
+ repository: {
21313
+ type: "git",
21314
+ url: "https://github.com/UiPath/cli.git",
21315
+ directory: "packages/admin/authz-sdk"
21316
+ },
21317
+ publishConfig: {
21318
+ registry: "https://npm.pkg.github.com/@uipath"
21319
+ },
21320
+ keywords: [
21321
+ "uipath",
21322
+ "authorization",
21323
+ "authz",
21324
+ "sdk"
21325
+ ],
21326
+ type: "module",
21327
+ main: "./dist/index.js",
21328
+ types: "./dist/src/index.d.ts",
21329
+ exports: {
21330
+ ".": {
21331
+ types: "./dist/src/index.d.ts",
21332
+ default: "./dist/index.js"
21333
+ }
21334
+ },
21335
+ files: [
21336
+ "dist"
21337
+ ],
21338
+ private: true,
21339
+ scripts: {
21340
+ build: "bun build ./src/index.ts --outdir dist --format esm --target node && tsc -p tsconfig.build.json --noCheck",
21341
+ generate: "bun run src/scripts/generate-sdk.ts",
21342
+ lint: "biome check ."
21343
+ },
21344
+ devDependencies: {
21345
+ "@openapitools/openapi-generator-cli": "^2.31.1",
21346
+ "@types/node": "^25.5.2",
21347
+ "@uipath/auth": "workspace:*",
21348
+ "@uipath/common": "workspace:*",
21349
+ "@uipath/filesystem": "workspace:*",
21350
+ typescript: "^6.0.2"
21351
+ }
21352
+ };
21353
+ var SDK_USER_AGENT = getSdkUserAgentToken(package_default2);
21354
+ installSdkUserAgentHeader(BaseAPI, SDK_USER_AGENT);
21097
21355
  function PolicyOperatorFromJSON(json) {
21098
21356
  return PolicyOperatorFromJSONTyped(json, false);
21099
21357
  }
@@ -21138,30 +21396,6 @@ function PolicyActorTypePolicyEntityRuleToJSONTyped(value, ignoreDiscriminator =
21138
21396
  operator: PolicyOperatorToJSON(value["operator"])
21139
21397
  };
21140
21398
  }
21141
- function PolicyAttributeRuleFromJSON(json) {
21142
- return PolicyAttributeRuleFromJSONTyped(json, false);
21143
- }
21144
- function PolicyAttributeRuleFromJSONTyped(json, ignoreDiscriminator) {
21145
- if (json == null) {
21146
- return json;
21147
- }
21148
- return {
21149
- values: json["values"] == null ? undefined : json["values"],
21150
- operator: json["operator"] == null ? undefined : PolicyOperatorFromJSON(json["operator"])
21151
- };
21152
- }
21153
- function PolicyAttributeRuleToJSON(json) {
21154
- return PolicyAttributeRuleToJSONTyped(json, false);
21155
- }
21156
- function PolicyAttributeRuleToJSONTyped(value, ignoreDiscriminator = false) {
21157
- if (value == null) {
21158
- return value;
21159
- }
21160
- return {
21161
- values: value["values"],
21162
- operator: PolicyOperatorToJSON(value["operator"])
21163
- };
21164
- }
21165
21399
  function ActorRuleFromJSON(json) {
21166
21400
  return ActorRuleFromJSONTyped(json, false);
21167
21401
  }
@@ -21170,8 +21404,7 @@ function ActorRuleFromJSONTyped(json, ignoreDiscriminator) {
21170
21404
  return json;
21171
21405
  }
21172
21406
  return {
21173
- values: json["values"] == null ? undefined : json["values"].map(PolicyActorTypePolicyEntityRuleFromJSON),
21174
- groupMemberships: json["groupMemberships"] == null ? undefined : PolicyAttributeRuleFromJSON(json["groupMemberships"])
21407
+ values: json["values"] == null ? undefined : json["values"].map(PolicyActorTypePolicyEntityRuleFromJSON)
21175
21408
  };
21176
21409
  }
21177
21410
  function ActorRuleToJSON(json) {
@@ -21182,8 +21415,7 @@ function ActorRuleToJSONTyped(value, ignoreDiscriminator = false) {
21182
21415
  return value;
21183
21416
  }
21184
21417
  return {
21185
- values: value["values"] == null ? undefined : value["values"].map(PolicyActorTypePolicyEntityRuleToJSON),
21186
- groupMemberships: PolicyAttributeRuleToJSON(value["groupMemberships"])
21418
+ values: value["values"] == null ? undefined : value["values"].map(PolicyActorTypePolicyEntityRuleToJSON)
21187
21419
  };
21188
21420
  }
21189
21421
  var PolicyExecutableType = {
@@ -21227,6 +21459,30 @@ function PolicyExecutableTypePolicyEntityRuleToJSONTyped(value, ignoreDiscrimina
21227
21459
  operator: PolicyOperatorToJSON(value["operator"])
21228
21460
  };
21229
21461
  }
21462
+ function PolicyAttributeRuleFromJSON(json) {
21463
+ return PolicyAttributeRuleFromJSONTyped(json, false);
21464
+ }
21465
+ function PolicyAttributeRuleFromJSONTyped(json, ignoreDiscriminator) {
21466
+ if (json == null) {
21467
+ return json;
21468
+ }
21469
+ return {
21470
+ values: json["values"] == null ? undefined : json["values"],
21471
+ operator: json["operator"] == null ? undefined : PolicyOperatorFromJSON(json["operator"])
21472
+ };
21473
+ }
21474
+ function PolicyAttributeRuleToJSON(json) {
21475
+ return PolicyAttributeRuleToJSONTyped(json, false);
21476
+ }
21477
+ function PolicyAttributeRuleToJSONTyped(value, ignoreDiscriminator = false) {
21478
+ if (value == null) {
21479
+ return value;
21480
+ }
21481
+ return {
21482
+ values: value["values"],
21483
+ operator: PolicyOperatorToJSON(value["operator"])
21484
+ };
21485
+ }
21230
21486
  function ExecutableRuleFromJSON(json) {
21231
21487
  return ExecutableRuleFromJSONTyped(json, false);
21232
21488
  }
@@ -21403,7 +21659,6 @@ function PolicyEvaluationApiRequestDtoToJSONTyped(value, ignoreDiscriminator = f
21403
21659
  return {
21404
21660
  organizationId: value["organizationId"],
21405
21661
  actorIdentifier: value["actorIdentifier"],
21406
- actorType: PolicyActorTypeToJSON(value["actorType"]),
21407
21662
  executableIdentifier: value["executableIdentifier"],
21408
21663
  executableType: PolicyExecutableTypeToJSON(value["executableType"]),
21409
21664
  resourceIdentifier: value["resourceIdentifier"],
@@ -21453,7 +21708,7 @@ function PolicyUpsertResultDtoFromJSONTyped(json, ignoreDiscriminator) {
21453
21708
  }
21454
21709
 
21455
21710
  class PolicyEvaluationApi extends BaseAPI {
21456
- async apiPolicyEvaluateTenantTenantIdPostRequestOpts(requestParameters) {
21711
+ async apiPolicyEvaluateTenantTenantIdPostRaw(requestParameters, initOverrides) {
21457
21712
  if (requestParameters["tenantId"] == null) {
21458
21713
  throw new RequiredError("tenantId", 'Required parameter "tenantId" was null or undefined when calling apiPolicyEvaluateTenantTenantIdPost().');
21459
21714
  }
@@ -21475,17 +21730,13 @@ class PolicyEvaluationApi extends BaseAPI {
21475
21730
  }
21476
21731
  let urlPath = `/api/policy/evaluate/tenant/{tenantId}`;
21477
21732
  urlPath = urlPath.replace(`{${"tenantId"}}`, encodeURIComponent(String(requestParameters["tenantId"])));
21478
- return {
21733
+ const response = await this.request({
21479
21734
  path: urlPath,
21480
21735
  method: "POST",
21481
21736
  headers: headerParameters,
21482
21737
  query: queryParameters,
21483
21738
  body: PolicyEvaluationApiRequestDtoToJSON(requestParameters["policyEvaluationApiRequestDto"])
21484
- };
21485
- }
21486
- async apiPolicyEvaluateTenantTenantIdPostRaw(requestParameters, initOverrides) {
21487
- const requestOptions = await this.apiPolicyEvaluateTenantTenantIdPostRequestOpts(requestParameters);
21488
- const response = await this.request(requestOptions, initOverrides);
21739
+ }, initOverrides);
21489
21740
  return new JSONApiResponse(response, (jsonValue) => PolicyEvaluationResultDtoFromJSON(jsonValue));
21490
21741
  }
21491
21742
  async apiPolicyEvaluateTenantTenantIdPost(requestParameters, initOverrides) {
@@ -21495,7 +21746,7 @@ class PolicyEvaluationApi extends BaseAPI {
21495
21746
  }
21496
21747
 
21497
21748
  class PolicyManagementApi extends BaseAPI {
21498
- async apiPoliciesDeleteRequestOpts(requestParameters) {
21749
+ async apiPoliciesDeleteRaw(requestParameters, initOverrides) {
21499
21750
  const queryParameters = {};
21500
21751
  if (requestParameters["policyId"] != null) {
21501
21752
  queryParameters["policyId"] = requestParameters["policyId"];
@@ -21512,22 +21763,18 @@ class PolicyManagementApi extends BaseAPI {
21512
21763
  }
21513
21764
  }
21514
21765
  let urlPath = `/api/policies`;
21515
- return {
21766
+ const response = await this.request({
21516
21767
  path: urlPath,
21517
21768
  method: "DELETE",
21518
21769
  headers: headerParameters,
21519
21770
  query: queryParameters
21520
- };
21521
- }
21522
- async apiPoliciesDeleteRaw(requestParameters, initOverrides) {
21523
- const requestOptions = await this.apiPoliciesDeleteRequestOpts(requestParameters);
21524
- const response = await this.request(requestOptions, initOverrides);
21771
+ }, initOverrides);
21525
21772
  return new VoidApiResponse(response);
21526
21773
  }
21527
21774
  async apiPoliciesDelete(requestParameters = {}, initOverrides) {
21528
21775
  await this.apiPoliciesDeleteRaw(requestParameters, initOverrides);
21529
21776
  }
21530
- async apiPoliciesGetRequestOpts(requestParameters) {
21777
+ async apiPoliciesGetRaw(requestParameters, initOverrides) {
21531
21778
  const queryParameters = {};
21532
21779
  if (requestParameters["top"] != null) {
21533
21780
  queryParameters["top"] = requestParameters["top"];
@@ -21553,23 +21800,19 @@ class PolicyManagementApi extends BaseAPI {
21553
21800
  }
21554
21801
  }
21555
21802
  let urlPath = `/api/policies`;
21556
- return {
21803
+ const response = await this.request({
21557
21804
  path: urlPath,
21558
21805
  method: "GET",
21559
21806
  headers: headerParameters,
21560
21807
  query: queryParameters
21561
- };
21562
- }
21563
- async apiPoliciesGetRaw(requestParameters, initOverrides) {
21564
- const requestOptions = await this.apiPoliciesGetRequestOpts(requestParameters);
21565
- const response = await this.request(requestOptions, initOverrides);
21808
+ }, initOverrides);
21566
21809
  return new JSONApiResponse(response, (jsonValue) => PolicyDefinitionPagedResultFromJSON(jsonValue));
21567
21810
  }
21568
21811
  async apiPoliciesGet(requestParameters = {}, initOverrides) {
21569
21812
  const response = await this.apiPoliciesGetRaw(requestParameters, initOverrides);
21570
21813
  return await response.value();
21571
21814
  }
21572
- async apiPoliciesPatchRequestOpts(requestParameters) {
21815
+ async apiPoliciesPatchRaw(requestParameters, initOverrides) {
21573
21816
  const queryParameters = {};
21574
21817
  const headerParameters = {};
21575
21818
  headerParameters["Content-Type"] = "application/json";
@@ -21584,24 +21827,20 @@ class PolicyManagementApi extends BaseAPI {
21584
21827
  }
21585
21828
  }
21586
21829
  let urlPath = `/api/policies`;
21587
- return {
21830
+ const response = await this.request({
21588
21831
  path: urlPath,
21589
21832
  method: "PATCH",
21590
21833
  headers: headerParameters,
21591
21834
  query: queryParameters,
21592
21835
  body: PolicyDefinitionToJSON(requestParameters["policyDefinition"])
21593
- };
21594
- }
21595
- async apiPoliciesPatchRaw(requestParameters, initOverrides) {
21596
- const requestOptions = await this.apiPoliciesPatchRequestOpts(requestParameters);
21597
- const response = await this.request(requestOptions, initOverrides);
21836
+ }, initOverrides);
21598
21837
  return new JSONApiResponse(response, (jsonValue) => PolicyUpsertResultDtoFromJSON(jsonValue));
21599
21838
  }
21600
21839
  async apiPoliciesPatch(requestParameters = {}, initOverrides) {
21601
21840
  const response = await this.apiPoliciesPatchRaw(requestParameters, initOverrides);
21602
21841
  return await response.value();
21603
21842
  }
21604
- async apiPoliciesPolicyIdGetRequestOpts(requestParameters) {
21843
+ async apiPoliciesPolicyIdGetRaw(requestParameters, initOverrides) {
21605
21844
  if (requestParameters["policyId"] == null) {
21606
21845
  throw new RequiredError("policyId", 'Required parameter "policyId" was null or undefined when calling apiPoliciesPolicyIdGet().');
21607
21846
  }
@@ -21619,23 +21858,19 @@ class PolicyManagementApi extends BaseAPI {
21619
21858
  }
21620
21859
  let urlPath = `/api/policies/{policyId}`;
21621
21860
  urlPath = urlPath.replace(`{${"policyId"}}`, encodeURIComponent(String(requestParameters["policyId"])));
21622
- return {
21861
+ const response = await this.request({
21623
21862
  path: urlPath,
21624
21863
  method: "GET",
21625
21864
  headers: headerParameters,
21626
21865
  query: queryParameters
21627
- };
21628
- }
21629
- async apiPoliciesPolicyIdGetRaw(requestParameters, initOverrides) {
21630
- const requestOptions = await this.apiPoliciesPolicyIdGetRequestOpts(requestParameters);
21631
- const response = await this.request(requestOptions, initOverrides);
21866
+ }, initOverrides);
21632
21867
  return new JSONApiResponse(response, (jsonValue) => PolicyDefinitionFromJSON(jsonValue));
21633
21868
  }
21634
21869
  async apiPoliciesPolicyIdGet(requestParameters, initOverrides) {
21635
21870
  const response = await this.apiPoliciesPolicyIdGetRaw(requestParameters, initOverrides);
21636
21871
  return await response.value();
21637
21872
  }
21638
- async apiPoliciesPostRequestOpts(requestParameters) {
21873
+ async apiPoliciesPostRaw(requestParameters, initOverrides) {
21639
21874
  const queryParameters = {};
21640
21875
  const headerParameters = {};
21641
21876
  headerParameters["Content-Type"] = "application/json";
@@ -21650,17 +21885,13 @@ class PolicyManagementApi extends BaseAPI {
21650
21885
  }
21651
21886
  }
21652
21887
  let urlPath = `/api/policies`;
21653
- return {
21888
+ const response = await this.request({
21654
21889
  path: urlPath,
21655
21890
  method: "POST",
21656
21891
  headers: headerParameters,
21657
21892
  query: queryParameters,
21658
21893
  body: PolicyDefinitionToJSON(requestParameters["policyDefinition"])
21659
- };
21660
- }
21661
- async apiPoliciesPostRaw(requestParameters, initOverrides) {
21662
- const requestOptions = await this.apiPoliciesPostRequestOpts(requestParameters);
21663
- const response = await this.request(requestOptions, initOverrides);
21894
+ }, initOverrides);
21664
21895
  return new JSONApiResponse(response, (jsonValue) => PolicyUpsertResultDtoFromJSON(jsonValue));
21665
21896
  }
21666
21897
  async apiPoliciesPost(requestParameters = {}, initOverrides) {
@@ -21691,30 +21922,7 @@ class InvalidBaseUrlError extends Error {
21691
21922
  this.name = "InvalidBaseUrlError";
21692
21923
  }
21693
21924
  }
21694
- var DEFAULT_SCOPES = [
21695
- "offline_access",
21696
- "ProcessMining",
21697
- "OrchestratorApiUserAccess",
21698
- "StudioWebBackend",
21699
- "IdentityServerApi",
21700
- "ConnectionService",
21701
- "DataService",
21702
- "DataServiceApiUserAccess",
21703
- "DocumentUnderstanding",
21704
- "EnterpriseContextService",
21705
- "Directory",
21706
- "JamJamApi",
21707
- "LLMGateway",
21708
- "LLMOps",
21709
- "OMS",
21710
- "RCS.FolderAuthorization",
21711
- "RCS.TagsManagement",
21712
- "TestmanagerApiUserAccess",
21713
- "AutomationSolutions",
21714
- "StudioWebTypeCacheService",
21715
- "Docs.GPT.Search",
21716
- "Insights"
21717
- ];
21925
+ var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
21718
21926
  var normalizeAndValidateBaseUrl = (rawUrl) => {
21719
21927
  let baseUrl = rawUrl;
21720
21928
  if (baseUrl.endsWith("/identity_/")) {
@@ -21764,7 +21972,8 @@ var resolveConfigAsync = async ({
21764
21972
  if (!clientSecret && fileAuth.clientSecret) {
21765
21973
  clientSecret = fileAuth.clientSecret;
21766
21974
  }
21767
- const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : DEFAULT_SCOPES;
21975
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
21976
+ const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES;
21768
21977
  return {
21769
21978
  clientId,
21770
21979
  clientSecret,
@@ -21847,6 +22056,7 @@ var getTokenExpiration = (accessToken) => {
21847
22056
  }
21848
22057
  };
21849
22058
  var ENV_AUTH_ENABLE_VAR = "UIPATH_CLI_ENABLE_ENV_AUTH";
22059
+ var ENFORCE_ROBOT_AUTH_VAR = "UIPATH_CLI_ENFORCE_ROBOT_AUTH";
21850
22060
  var ENV_AUTH_VARS = {
21851
22061
  token: "UIPATH_CLI_AUTH_TOKEN",
21852
22062
  organizationName: "UIPATH_CLI_ORGANIZATION_NAME",
@@ -21862,6 +22072,7 @@ class EnvAuthConfigError extends Error {
21862
22072
  }
21863
22073
  }
21864
22074
  var isEnvAuthEnabled = () => process.env[ENV_AUTH_ENABLE_VAR] === "true";
22075
+ var isRobotAuthEnforced = () => process.env[ENFORCE_ROBOT_AUTH_VAR] === "true";
21865
22076
  var requireEnv = (name) => {
21866
22077
  const value = process.env[name];
21867
22078
  if (!value) {
@@ -21903,6 +22114,7 @@ var readAuthFromEnv = () => {
21903
22114
  expiration
21904
22115
  };
21905
22116
  };
22117
+ init_src();
21906
22118
  var DEFAULT_TIMEOUT_MS = 1000;
21907
22119
  var CLOSE_TIMEOUT_MS = 500;
21908
22120
  var NOTICE_SENTINEL = Symbol.for("@uipath/auth/robotFallbackNoticePrinted");
@@ -21914,6 +22126,35 @@ var printNoticeOnce = () => {
21914
22126
  catchError(() => process.stderr.write(`Using UiPath Robot credentials. Run 'uip login' for a dedicated session.
21915
22127
  `));
21916
22128
  };
22129
+ var ROBOT_USER_SERVICES_PIPE = "UiPathUserServices";
22130
+ var ROBOT_USER_SERVICES_ALTERNATE_PIPE = `${ROBOT_USER_SERVICES_PIPE}Alternate`;
22131
+ var PIPE_NAME_MAX_LENGTH = 103;
22132
+ var getRobotIpcPipeNames = async () => {
22133
+ const fs7 = getFileSystem();
22134
+ const username = fs7.env.getenv("USER") ?? fs7.env.getenv("USERNAME");
22135
+ if (!username) {
22136
+ throw new Error("Unable to determine current username");
22137
+ }
22138
+ const tempPath = fs7.env.getenv("TMPDIR") ?? "/tmp/";
22139
+ return [ROBOT_USER_SERVICES_PIPE, ROBOT_USER_SERVICES_ALTERNATE_PIPE].map((baseName) => fs7.path.join(tempPath, `${baseName}_${username}`).substring(0, PIPE_NAME_MAX_LENGTH));
22140
+ };
22141
+ var defaultIsRobotIpcAvailable = async () => {
22142
+ if (process.platform === "win32") {
22143
+ return true;
22144
+ }
22145
+ const [pipeNamesError, pipeNames] = await catchError(getRobotIpcPipeNames());
22146
+ if (pipeNamesError || !pipeNames) {
22147
+ return false;
22148
+ }
22149
+ const fs7 = getFileSystem();
22150
+ for (const pipeName of pipeNames) {
22151
+ const [existsError, exists] = await catchError(fs7.exists(pipeName));
22152
+ if (!existsError && exists === true) {
22153
+ return true;
22154
+ }
22155
+ }
22156
+ return false;
22157
+ };
21917
22158
  var withTimeout = (promise, timeoutMs) => new Promise((resolve2, reject) => {
21918
22159
  const timer = setTimeout(() => reject(new Error(`Robot IPC call timed out after ${timeoutMs}ms`)), timeoutMs);
21919
22160
  promise.then((value) => {
@@ -21945,14 +22186,20 @@ var defaultLoadModule = async () => {
21945
22186
  var tryRobotClientFallback = async (options = {}) => {
21946
22187
  if (isBrowser())
21947
22188
  return;
21948
- if (process.env.CI || process.env.GITHUB_ACTIONS) {
21949
- return;
21950
- }
21951
- if (process.env.UIPATH_URL) {
21952
- return;
22189
+ if (!options.force) {
22190
+ if (process.env.CI || process.env.GITHUB_ACTIONS) {
22191
+ return;
22192
+ }
22193
+ if (process.env.UIPATH_URL) {
22194
+ return;
22195
+ }
21953
22196
  }
21954
22197
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
22198
+ const isRobotIpcAvailable = options.isRobotIpcAvailable ?? defaultIsRobotIpcAvailable;
21955
22199
  const loadModule = options.loadModule ?? defaultLoadModule;
22200
+ if (!await isRobotIpcAvailable()) {
22201
+ return;
22202
+ }
21956
22203
  const mod = await loadModule();
21957
22204
  if (!mod)
21958
22205
  return;
@@ -22213,11 +22460,130 @@ function normalizeTokenRefreshFailure() {
22213
22460
  function normalizeTokenRefreshUnavailableFailure() {
22214
22461
  return "token refresh failed before authentication completed";
22215
22462
  }
22216
- var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22217
- if (isEnvAuthEnabled()) {
22218
- return readAuthFromEnv();
22463
+ function errorMessage(error) {
22464
+ return error instanceof Error ? error.message : String(error);
22465
+ }
22466
+ function computeExpirationThreshold(ensureTokenValidityMinutes) {
22467
+ return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
22468
+ }
22469
+ async function runRefreshLocked(inputs) {
22470
+ const {
22471
+ absolutePath,
22472
+ refreshToken: callerRefreshToken,
22473
+ customAuthority,
22474
+ ensureTokenValidityMinutes,
22475
+ loadEnvFile,
22476
+ saveEnvFile,
22477
+ refreshFn,
22478
+ resolveConfig
22479
+ } = inputs;
22480
+ const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
22481
+ let fresh;
22482
+ try {
22483
+ fresh = await loadEnvFile({ envPath: absolutePath });
22484
+ } catch (error) {
22485
+ return {
22486
+ kind: "fail",
22487
+ status: {
22488
+ loginStatus: "Refresh Failed",
22489
+ hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
22490
+ tokenRefresh: {
22491
+ attempted: false,
22492
+ success: false,
22493
+ errorMessage: `auth file read failed: ${errorMessage(error)}`
22494
+ }
22495
+ }
22496
+ };
22219
22497
  }
22220
- const { envFilePath = DEFAULT_ENV_FILENAME, ensureTokenValidityMinutes } = options;
22498
+ const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
22499
+ const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
22500
+ if (freshAccess && freshExp && freshExp > expirationThreshold) {
22501
+ return {
22502
+ kind: "ok",
22503
+ accessToken: freshAccess,
22504
+ refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
22505
+ expiration: freshExp,
22506
+ tokenRefresh: { attempted: false, success: true }
22507
+ };
22508
+ }
22509
+ const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
22510
+ let refreshedAccess;
22511
+ let refreshedRefresh;
22512
+ try {
22513
+ const config = await resolveConfig({ customAuthority });
22514
+ const refreshed = await refreshFn({
22515
+ refreshToken: tokenForIdP,
22516
+ tokenEndpoint: config.tokenEndpoint,
22517
+ clientId: config.clientId,
22518
+ expectedAuthority: customAuthority
22519
+ });
22520
+ refreshedAccess = refreshed.accessToken;
22521
+ refreshedRefresh = refreshed.refreshToken;
22522
+ } catch (error) {
22523
+ const isOAuthFailure = isTokenRefreshOAuthFailure(error);
22524
+ 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.";
22525
+ const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
22526
+ return {
22527
+ kind: "fail",
22528
+ status: {
22529
+ loginStatus: "Refresh Failed",
22530
+ hint,
22531
+ tokenRefresh: {
22532
+ attempted: true,
22533
+ success: false,
22534
+ errorMessage: message
22535
+ }
22536
+ }
22537
+ };
22538
+ }
22539
+ const refreshedExp = getTokenExpiration(refreshedAccess);
22540
+ if (!refreshedExp || refreshedExp <= new Date) {
22541
+ return {
22542
+ kind: "fail",
22543
+ status: {
22544
+ loginStatus: "Refresh Failed",
22545
+ hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
22546
+ tokenRefresh: {
22547
+ attempted: true,
22548
+ success: false,
22549
+ errorMessage: "refreshed token has no valid expiration claim"
22550
+ }
22551
+ }
22552
+ };
22553
+ }
22554
+ try {
22555
+ await saveEnvFile({
22556
+ envPath: absolutePath,
22557
+ data: {
22558
+ UIPATH_ACCESS_TOKEN: refreshedAccess,
22559
+ UIPATH_REFRESH_TOKEN: refreshedRefresh
22560
+ },
22561
+ merge: true
22562
+ });
22563
+ return {
22564
+ kind: "ok",
22565
+ accessToken: refreshedAccess,
22566
+ refreshToken: refreshedRefresh,
22567
+ expiration: refreshedExp,
22568
+ tokenRefresh: { attempted: true, success: true }
22569
+ };
22570
+ } catch (error) {
22571
+ const msg = errorMessage(error);
22572
+ return {
22573
+ kind: "ok",
22574
+ accessToken: refreshedAccess,
22575
+ refreshToken: refreshedRefresh,
22576
+ expiration: refreshedExp,
22577
+ 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.`,
22578
+ tokenRefresh: {
22579
+ attempted: true,
22580
+ success: true,
22581
+ errorMessage: `persistence failed: ${msg}`
22582
+ }
22583
+ };
22584
+ }
22585
+ }
22586
+ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22221
22587
  const {
22222
22588
  resolveEnvFilePath = resolveEnvFilePathAsync,
22223
22589
  loadEnvFile = loadEnvFileAsync,
@@ -22227,6 +22593,34 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22227
22593
  resolveConfig = resolveConfigAsync,
22228
22594
  robotFallback = tryRobotClientFallback
22229
22595
  } = deps;
22596
+ if (isRobotAuthEnforced()) {
22597
+ if (isEnvAuthEnabled()) {
22598
+ throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
22599
+ }
22600
+ const robotCreds = await robotFallback({ force: true });
22601
+ if (!robotCreds) {
22602
+ return {
22603
+ loginStatus: "Not logged in",
22604
+ hint: `${ENFORCE_ROBOT_AUTH_VAR}=true but the UiPath Robot ` + `session is unavailable. Start and sign in to the Assistant, ` + `or unset ${ENFORCE_ROBOT_AUTH_VAR} to fall back to file or ` + `env-var authentication.`
22605
+ };
22606
+ }
22607
+ const expiration2 = getTokenExpiration(robotCreds.accessToken);
22608
+ return {
22609
+ loginStatus: "Logged in",
22610
+ accessToken: robotCreds.accessToken,
22611
+ baseUrl: robotCreds.baseUrl,
22612
+ organizationName: robotCreds.organizationName,
22613
+ organizationId: robotCreds.organizationId,
22614
+ tenantName: robotCreds.tenantName,
22615
+ tenantId: robotCreds.tenantId,
22616
+ expiration: expiration2,
22617
+ source: "robot"
22618
+ };
22619
+ }
22620
+ if (isEnvAuthEnabled()) {
22621
+ return readAuthFromEnv();
22622
+ }
22623
+ const { envFilePath = DEFAULT_ENV_FILENAME, ensureTokenValidityMinutes } = options;
22230
22624
  const { absolutePath } = await resolveEnvFilePath(envFilePath);
22231
22625
  if (absolutePath === undefined) {
22232
22626
  const robotCreds = await robotFallback();
@@ -22263,73 +22657,103 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22263
22657
  let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
22264
22658
  let expiration = getTokenExpiration(accessToken);
22265
22659
  let persistenceWarning;
22660
+ let lockReleaseFailed = false;
22266
22661
  let tokenRefresh;
22267
- const expirationThreshold = new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
22268
- if (expiration && expiration <= expirationThreshold && refreshToken) {
22269
- let refreshedAccess;
22270
- let refreshedRefresh;
22662
+ const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
22663
+ const tryGlobalCredsHint = async () => {
22664
+ const fs7 = getFs();
22665
+ const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
22666
+ if (absolutePath === globalPath)
22667
+ return;
22668
+ if (!await fs7.exists(globalPath))
22669
+ return;
22271
22670
  try {
22272
- const config = await resolveConfig({
22273
- customAuthority: credentials.UIPATH_URL
22274
- });
22275
- const refreshed = await refreshTokenFn({
22276
- refreshToken,
22277
- tokenEndpoint: config.tokenEndpoint,
22278
- clientId: config.clientId,
22279
- expectedAuthority: credentials.UIPATH_URL
22280
- });
22281
- refreshedAccess = refreshed.accessToken;
22282
- refreshedRefresh = refreshed.refreshToken;
22671
+ const globalCreds = await loadEnvFile({ envPath: globalPath });
22672
+ if (!globalCreds.UIPATH_ACCESS_TOKEN)
22673
+ return;
22674
+ const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
22675
+ if (globalExp && globalExp <= new Date)
22676
+ return;
22677
+ 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.`;
22678
+ } catch {
22679
+ return;
22680
+ }
22681
+ };
22682
+ if (expiration && expiration <= outerThreshold && refreshToken) {
22683
+ let release;
22684
+ try {
22685
+ release = await getFs().acquireLock(absolutePath);
22283
22686
  } catch (error) {
22284
- const isOAuthFailure = isTokenRefreshOAuthFailure(error);
22285
- 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.";
22286
- const errorMessage = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
22687
+ const msg = errorMessage(error);
22688
+ const globalHint = await tryGlobalCredsHint();
22689
+ if (globalHint) {
22690
+ return {
22691
+ loginStatus: "Expired",
22692
+ accessToken,
22693
+ refreshToken,
22694
+ baseUrl: credentials.UIPATH_URL,
22695
+ organizationName: credentials.UIPATH_ORGANIZATION_NAME,
22696
+ organizationId: credentials.UIPATH_ORGANIZATION_ID,
22697
+ tenantName: credentials.UIPATH_TENANT_NAME,
22698
+ tenantId: credentials.UIPATH_TENANT_ID,
22699
+ expiration,
22700
+ source: "file",
22701
+ hint: globalHint,
22702
+ tokenRefresh: {
22703
+ attempted: false,
22704
+ success: false,
22705
+ errorMessage: `lock acquisition failed: ${msg}`
22706
+ }
22707
+ };
22708
+ }
22287
22709
  return {
22288
22710
  loginStatus: "Refresh Failed",
22289
- hint,
22711
+ 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.",
22290
22712
  tokenRefresh: {
22291
- attempted: true,
22713
+ attempted: false,
22292
22714
  success: false,
22293
- errorMessage
22715
+ errorMessage: `lock acquisition failed: ${msg}`
22294
22716
  }
22295
22717
  };
22296
22718
  }
22297
- const refreshedExp = getTokenExpiration(refreshedAccess);
22298
- if (!refreshedExp || refreshedExp <= new Date) {
22299
- return {
22300
- loginStatus: "Refresh Failed",
22301
- hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
22302
- tokenRefresh: {
22303
- attempted: true,
22304
- success: false,
22305
- errorMessage: "refreshed token has no valid expiration claim"
22719
+ let lockedFailure;
22720
+ try {
22721
+ const outcome = await runRefreshLocked({
22722
+ absolutePath,
22723
+ refreshToken,
22724
+ customAuthority: credentials.UIPATH_URL,
22725
+ ensureTokenValidityMinutes,
22726
+ loadEnvFile,
22727
+ saveEnvFile,
22728
+ refreshFn: refreshTokenFn,
22729
+ resolveConfig
22730
+ });
22731
+ if (outcome.kind === "fail") {
22732
+ lockedFailure = outcome.status;
22733
+ } else {
22734
+ accessToken = outcome.accessToken;
22735
+ refreshToken = outcome.refreshToken;
22736
+ expiration = outcome.expiration;
22737
+ tokenRefresh = outcome.tokenRefresh;
22738
+ if (outcome.persistenceWarning) {
22739
+ persistenceWarning = outcome.persistenceWarning;
22306
22740
  }
22307
- };
22741
+ }
22742
+ } finally {
22743
+ try {
22744
+ await release();
22745
+ } catch {
22746
+ lockReleaseFailed = true;
22747
+ }
22308
22748
  }
22309
- accessToken = refreshedAccess;
22310
- refreshToken = refreshedRefresh;
22311
- expiration = refreshedExp;
22312
- try {
22313
- await saveEnvFile({
22314
- envPath: absolutePath,
22315
- data: {
22316
- UIPATH_ACCESS_TOKEN: accessToken,
22317
- UIPATH_REFRESH_TOKEN: refreshToken
22318
- },
22319
- merge: true
22320
- });
22321
- tokenRefresh = {
22322
- attempted: true,
22323
- success: true
22324
- };
22325
- } catch (error) {
22326
- const msg = error instanceof Error ? error.message : String(error);
22327
- 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.`;
22328
- tokenRefresh = {
22329
- attempted: true,
22330
- success: true,
22331
- errorMessage: `persistence failed: ${msg}`
22332
- };
22749
+ if (lockedFailure) {
22750
+ const globalHint = await tryGlobalCredsHint();
22751
+ const base = globalHint ? {
22752
+ ...lockedFailure,
22753
+ loginStatus: "Expired",
22754
+ hint: globalHint
22755
+ } : lockedFailure;
22756
+ return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
22333
22757
  }
22334
22758
  }
22335
22759
  const result = {
@@ -22344,23 +22768,13 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
22344
22768
  expiration,
22345
22769
  source: "file",
22346
22770
  ...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
22771
+ ...lockReleaseFailed ? { lockReleaseFailed: true } : {},
22347
22772
  ...tokenRefresh ? { tokenRefresh } : {}
22348
22773
  };
22349
22774
  if (result.loginStatus === "Expired") {
22350
- const fs7 = getFs();
22351
- const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
22352
- if (absolutePath !== globalPath && await fs7.exists(globalPath)) {
22353
- try {
22354
- const globalCreds = await loadEnvFile({
22355
- envPath: globalPath
22356
- });
22357
- if (globalCreds.UIPATH_ACCESS_TOKEN) {
22358
- const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
22359
- if (!globalExp || globalExp > new Date) {
22360
- 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.`;
22361
- }
22362
- }
22363
- } catch {}
22775
+ const globalHint = await tryGlobalCredsHint();
22776
+ if (globalHint) {
22777
+ result.hint = globalHint;
22364
22778
  }
22365
22779
  }
22366
22780
  return result;
@@ -22375,7 +22789,8 @@ var getLoginStatusAsync = async (options = {}) => {
22375
22789
  };
22376
22790
  init_src();
22377
22791
  init_src();
22378
- async function resolveConfig(service, options) {
22792
+ init_server();
22793
+ async function resolveConfig(plane, options) {
22379
22794
  const status = await getLoginStatusAsync({
22380
22795
  ensureTokenValidityMinutes: options?.loginValidity
22381
22796
  });
@@ -22385,29 +22800,35 @@ async function resolveConfig(service, options) {
22385
22800
  if (!status.organizationId) {
22386
22801
  throw new Error("Organization ID not available. Ensure you are logged in with an organization context.");
22387
22802
  }
22388
- const basePath = `${status.baseUrl}/${status.organizationId}/${service}_`;
22803
+ const basePath = `${status.baseUrl}/${status.organizationId}/${plane}_`;
22804
+ const bearerToken = options?.s2sToken ?? status.accessToken;
22389
22805
  return {
22390
22806
  config: new Configuration({
22391
22807
  basePath,
22392
- headers: {
22393
- Authorization: `Bearer ${status.accessToken}`
22394
- }
22808
+ accessToken: async () => bearerToken,
22809
+ headers: addSdkUserAgentHeader(undefined, SDK_USER_AGENT)
22395
22810
  }),
22396
- status
22811
+ organizationId: status.organizationId,
22812
+ tenantId: status.tenantId,
22813
+ tenantName: status.tenantName
22397
22814
  };
22398
22815
  }
22399
- async function createPapApiClient(ApiClass, options) {
22400
- const { config } = await resolveConfig("pap", options);
22401
- return new ApiClass(config);
22402
- }
22403
- async function createPdpApiClient(ApiClass, options) {
22404
- const { config, status } = await resolveConfig("pdp", options);
22816
+ async function createApiClient(ApiClass, plane, options) {
22817
+ const { config, organizationId, tenantId, tenantName } = await resolveConfig(plane, options);
22405
22818
  return {
22406
22819
  api: new ApiClass(config),
22407
- organizationId: status.organizationId,
22408
- tenantId: status.tenantId
22820
+ organizationId,
22821
+ tenantId,
22822
+ tenantName
22409
22823
  };
22410
22824
  }
22825
+ async function createPapClient(ApiClass, options) {
22826
+ return createApiClient(ApiClass, "pap", options);
22827
+ }
22828
+ async function createPdpClient(ApiClass, options) {
22829
+ return createApiClient(ApiClass, "pdp", options);
22830
+ }
22831
+ init_src();
22411
22832
  function isPromiseLike2(value) {
22412
22833
  return value !== null && typeof value === "object" && typeof value.then === "function";
22413
22834
  }
@@ -22434,71 +22855,6 @@ function settlePromiseLike2(thenable) {
22434
22855
  undefined
22435
22856
  ]);
22436
22857
  }
22437
- var examplesByCommand = new WeakMap;
22438
- Command.prototype.examples = function(examples) {
22439
- examplesByCommand.set(this, examples);
22440
- return this;
22441
- };
22442
- var PREFIX = "@uipath/common/";
22443
- var _g = globalThis;
22444
- function singleton(ctorOrName) {
22445
- const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
22446
- const key = Symbol.for(PREFIX + name);
22447
- return {
22448
- get(fallback) {
22449
- return _g[key] ?? fallback;
22450
- },
22451
- set(value) {
22452
- _g[key] = value;
22453
- },
22454
- clear() {
22455
- delete _g[key];
22456
- },
22457
- getOrInit(factory, guard) {
22458
- const existing = _g[key];
22459
- if (existing != null && typeof existing === "object") {
22460
- if (!guard || guard(existing)) {
22461
- return existing;
22462
- }
22463
- }
22464
- const instance = factory();
22465
- _g[key] = instance;
22466
- return instance;
22467
- }
22468
- };
22469
- }
22470
- function createStorage() {
22471
- const [error, mod] = catchError2(() => __require2("node:async_hooks"));
22472
- if (error || typeof mod?.AsyncLocalStorage !== "function") {
22473
- return {
22474
- getStore: () => {
22475
- return;
22476
- },
22477
- run: (_store, fn) => fn()
22478
- };
22479
- }
22480
- return new mod.AsyncLocalStorage;
22481
- }
22482
- var storageSingleton = singleton("OutputStorage");
22483
- var sinkSlot = singleton("OutputSink");
22484
- var outputStorage = storageSingleton.getOrInit(createStorage, (v) => ("getStore" in v));
22485
- var CONSOLE_FALLBACK = {
22486
- writeOut: (str) => process.stdout.write(str),
22487
- writeErr: (str) => process.stderr.write(str),
22488
- writeLog: (str) => process.stdout.write(str),
22489
- capabilities: {
22490
- isInteractive: false,
22491
- supportsColor: false,
22492
- outputWidth: 80
22493
- }
22494
- };
22495
- function getOutputSink() {
22496
- return outputStorage.getStore() ?? sinkSlot.get() ?? CONSOLE_FALLBACK;
22497
- }
22498
- var COMPLETER_SYMBOL = Symbol.for("@uipath/common/completer");
22499
- var guardInstalledSlot = singleton("ConsoleGuardInstalled");
22500
- var savedOriginalsSlot = singleton("ConsoleGuardOriginals");
22501
- var DEFAULT_AUTH_TIMEOUT_MS2 = 5 * 60 * 1000;
22502
22858
  var DEFAULT_401 = "Unauthorized (401). Run `uip login` to authenticate.";
22503
22859
  var DEFAULT_403 = "Forbidden (403). Ensure the account has the required permissions.";
22504
22860
  var DEFAULT_405 = "Method Not Allowed (405). The endpoint may not exist or the base URL may be incorrect.";
@@ -22604,10 +22960,15 @@ async function extractErrorDetails(error, options) {
22604
22960
  }
22605
22961
  if (parsedBody?.errorCode && typeof parsedBody.errorCode === "string") {
22606
22962
  context.errorCode = parsedBody.errorCode;
22963
+ } else if (parsedBody?.code && typeof parsedBody.code === "string") {
22964
+ context.errorCode = parsedBody.code;
22607
22965
  }
22608
22966
  if (parsedBody?.requestId && typeof parsedBody.requestId === "string") {
22609
22967
  context.requestId = parsedBody.requestId;
22610
22968
  }
22969
+ if (parsedBody?.traceId && typeof parsedBody.traceId === "string") {
22970
+ context.traceId = parsedBody.traceId;
22971
+ }
22611
22972
  if (status === 429) {
22612
22973
  const resp = response;
22613
22974
  const headersObj = resp?.headers;
@@ -22627,12 +22988,77 @@ async function extractErrorDetails(error, options) {
22627
22988
  }
22628
22989
  }
22629
22990
  const hasContext = Object.keys(context).length > 0;
22630
- return { result, message, details, ...hasContext ? { context } : {} };
22991
+ let parsedErrors;
22992
+ if (parsedBody?.errors && typeof parsedBody.errors === "object") {
22993
+ const errors = {};
22994
+ for (const [field, raw] of Object.entries(parsedBody.errors)) {
22995
+ if (Array.isArray(raw)) {
22996
+ const messages = raw.map((entry) => {
22997
+ if (typeof entry === "string")
22998
+ return entry;
22999
+ if (entry && typeof entry === "object" && typeof entry.message === "string") {
23000
+ return entry.message;
23001
+ }
23002
+ return String(entry);
23003
+ }).filter(Boolean);
23004
+ if (messages.length > 0)
23005
+ errors[field] = messages;
23006
+ } else if (typeof raw === "string") {
23007
+ errors[field] = [raw];
23008
+ }
23009
+ }
23010
+ if (Object.keys(errors).length > 0)
23011
+ parsedErrors = errors;
23012
+ }
23013
+ return {
23014
+ result,
23015
+ message,
23016
+ details,
23017
+ ...hasContext ? { context } : {},
23018
+ ...parsedErrors ? { parsedErrors } : {}
23019
+ };
22631
23020
  }
22632
23021
  async function extractErrorMessage(error, options) {
22633
23022
  const { message } = await extractErrorDetails(error, options);
22634
23023
  return message;
22635
23024
  }
23025
+ var examplesByCommand = new WeakMap;
23026
+ Command.prototype.examples = function(examples) {
23027
+ examplesByCommand.set(this, examples);
23028
+ return this;
23029
+ };
23030
+ function createStorage() {
23031
+ const [error, mod] = catchError2(() => __require2("node:async_hooks"));
23032
+ if (error || typeof mod?.AsyncLocalStorage !== "function") {
23033
+ return {
23034
+ getStore: () => {
23035
+ return;
23036
+ },
23037
+ run: (_store, fn) => fn()
23038
+ };
23039
+ }
23040
+ return new mod.AsyncLocalStorage;
23041
+ }
23042
+ var storageSingleton = singleton("OutputStorage");
23043
+ var sinkSlot = singleton("OutputSink");
23044
+ var outputStorage = storageSingleton.getOrInit(createStorage, (v) => ("getStore" in v));
23045
+ var CONSOLE_FALLBACK = {
23046
+ writeOut: (str) => process.stdout.write(str),
23047
+ writeErr: (str) => process.stderr.write(str),
23048
+ writeLog: (str) => process.stdout.write(str),
23049
+ capabilities: {
23050
+ isInteractive: false,
23051
+ supportsColor: false,
23052
+ outputWidth: 80
23053
+ }
23054
+ };
23055
+ function getOutputSink() {
23056
+ return outputStorage.getStore() ?? sinkSlot.get() ?? CONSOLE_FALLBACK;
23057
+ }
23058
+ var COMPLETER_SYMBOL = Symbol.for("@uipath/common/completer");
23059
+ var guardInstalledSlot = singleton("ConsoleGuardInstalled");
23060
+ var savedOriginalsSlot = singleton("ConsoleGuardOriginals");
23061
+ var DEFAULT_AUTH_TIMEOUT_MS2 = 5 * 60 * 1000;
22636
23062
  var isObject = (obj) => {
22637
23063
  return obj !== null && Object.prototype.toString.call(obj) === "[object Object]";
22638
23064
  };
@@ -27658,15 +28084,80 @@ class SuccessOutput {
27658
28084
  }
27659
28085
  }
27660
28086
  }
27661
- function printOutput(data, format = "json", logFn) {
28087
+ function escapeNonAscii(jsonText) {
28088
+ return jsonText.replace(/[\u0080-\uffff]/g, (c) => {
28089
+ const hex = c.charCodeAt(0).toString(16).padStart(4, "0");
28090
+ return `\\u${hex}`;
28091
+ });
28092
+ }
28093
+ function needsAsciiSafeJson(sink) {
28094
+ return process.platform === "win32" && !sink.capabilities.isInteractive;
28095
+ }
28096
+ function isPlainRecord(value) {
28097
+ if (value === null || typeof value !== "object")
28098
+ return false;
28099
+ const prototype = Object.getPrototypeOf(value);
28100
+ return prototype === Object.prototype || prototype === null;
28101
+ }
28102
+ function toLowerCamelCaseKey(key) {
28103
+ if (!key)
28104
+ return key;
28105
+ if (/[_\-\s]/.test(key)) {
28106
+ const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
28107
+ if (!firstPart)
28108
+ return key;
28109
+ return [
28110
+ toLowerCamelCaseSimpleKey(firstPart),
28111
+ ...restParts.map((part) => {
28112
+ const normalized = toLowerCamelCaseSimpleKey(part);
28113
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
28114
+ })
28115
+ ].join("");
28116
+ }
28117
+ return toLowerCamelCaseSimpleKey(key);
28118
+ }
28119
+ function toLowerCamelCaseSimpleKey(key) {
28120
+ if (/^[A-Z0-9]+$/.test(key))
28121
+ return key.toLowerCase();
28122
+ return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
28123
+ }
28124
+ function toPascalCaseKey(key) {
28125
+ const lowerCamelKey = toLowerCamelCaseKey(key);
28126
+ return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
28127
+ }
28128
+ function toPascalCaseData(value) {
28129
+ if (Array.isArray(value))
28130
+ return value.map(toPascalCaseData);
28131
+ if (!isPlainRecord(value))
28132
+ return value;
28133
+ const result = {};
28134
+ for (const [key, nestedValue] of Object.entries(value)) {
28135
+ result[toPascalCaseKey(key)] = toPascalCaseData(nestedValue);
28136
+ }
28137
+ return result;
28138
+ }
28139
+ function normalizeDataKeys(data) {
28140
+ return toPascalCaseData(data);
28141
+ }
28142
+ function normalizeOutputKeys(data) {
28143
+ const result = {};
28144
+ for (const [key, value] of Object.entries(data)) {
28145
+ const pascalKey = toPascalCaseKey(key);
28146
+ result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData(value);
28147
+ }
28148
+ return result;
28149
+ }
28150
+ function printOutput(data, format = "json", logFn, asciiSafe = false) {
27662
28151
  if (!data) {
27663
28152
  logFn("Empty response object. No data to display.");
27664
28153
  return;
27665
28154
  }
27666
28155
  switch (format) {
27667
- case "json":
27668
- logFn(JSON.stringify(data, null, 2));
28156
+ case "json": {
28157
+ const json2 = JSON.stringify(data, null, 2);
28158
+ logFn(asciiSafe ? escapeNonAscii(json2) : json2);
27669
28159
  break;
28160
+ }
27670
28161
  case "yaml":
27671
28162
  logFn(toYaml(data));
27672
28163
  break;
@@ -27701,7 +28192,7 @@ function printOutput(data, format = "json", logFn) {
27701
28192
  function logOutput(data, format = "json") {
27702
28193
  const sink = getOutputSink();
27703
28194
  printOutput(data, format, (msg) => sink.writeOut(`${msg}
27704
- `));
28195
+ `), needsAsciiSafeJson(sink));
27705
28196
  }
27706
28197
  function cellToString(val) {
27707
28198
  return val != null && typeof val === "object" ? JSON.stringify(val) : String(val ?? "");
@@ -27718,7 +28209,7 @@ function wrapText(text, width) {
27718
28209
  function printTable(data, logFn, externalLogValue) {
27719
28210
  if (data.length === 0)
27720
28211
  return;
27721
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
28212
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
27722
28213
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
27723
28214
  const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
27724
28215
  logFn(header);
@@ -27733,7 +28224,7 @@ function printTable(data, logFn, externalLogValue) {
27733
28224
  }
27734
28225
  }
27735
28226
  function printVerticalTable(data, logFn = console.log, externalLogValue) {
27736
- const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
28227
+ const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
27737
28228
  if (keys.length === 0)
27738
28229
  return;
27739
28230
  const maxKeyWidth = Math.max(...keys.map((key) => key.length));
@@ -27749,7 +28240,7 @@ function printVerticalTable(data, logFn = console.log, externalLogValue) {
27749
28240
  function printResizableTable(data, logFn = console.log, externalLogValue) {
27750
28241
  if (data.length === 0)
27751
28242
  return;
27752
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
28243
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
27753
28244
  if (keys.length === 0)
27754
28245
  return;
27755
28246
  if (!process.stdout.isTTY) {
@@ -27825,8 +28316,27 @@ function printResizableTable(data, logFn = console.log, externalLogValue) {
27825
28316
  function toYaml(data) {
27826
28317
  return dump(data);
27827
28318
  }
28319
+
28320
+ class FilterEvaluationError extends Error {
28321
+ __brand = "FilterEvaluationError";
28322
+ filter;
28323
+ instructions;
28324
+ result = RESULTS.ValidationError;
28325
+ constructor(filter, cause) {
28326
+ const underlying = cause instanceof Error ? cause.message : String(cause);
28327
+ super(`Filter '${filter}' failed to evaluate: ${underlying}`);
28328
+ this.name = "FilterEvaluationError";
28329
+ this.filter = filter;
28330
+ 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(@)'.";
28331
+ }
28332
+ }
27828
28333
  function applyFilter(data, filter) {
27829
- const result = search(data, filter);
28334
+ let result;
28335
+ try {
28336
+ result = search(data, filter);
28337
+ } catch (err) {
28338
+ throw new FilterEvaluationError(filter, err);
28339
+ }
27830
28340
  if (result == null)
27831
28341
  return [];
27832
28342
  if (Array.isArray(result)) {
@@ -27843,13 +28353,18 @@ function applyFilter(data, filter) {
27843
28353
  }
27844
28354
  var OutputFormatter;
27845
28355
  ((OutputFormatter2) => {
27846
- function success(data) {
28356
+ function success(data, options) {
27847
28357
  data.Log ??= getLogFilePath() || undefined;
28358
+ const normalize = !options?.preserveDataKeys;
28359
+ if (normalize) {
28360
+ data.Data = normalizeDataKeys(data.Data);
28361
+ }
27848
28362
  const filter = getOutputFilter();
27849
28363
  if (filter) {
27850
- data.Data = applyFilter(data.Data, filter);
28364
+ const filtered = applyFilter(data.Data, filter);
28365
+ data.Data = normalize ? normalizeDataKeys(filtered) : filtered;
27851
28366
  }
27852
- logOutput(data, getOutputFormat());
28367
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
27853
28368
  }
27854
28369
  OutputFormatter2.success = success;
27855
28370
  function error(data) {
@@ -27859,7 +28374,7 @@ var OutputFormatter;
27859
28374
  result: data.Result,
27860
28375
  message: data.Message
27861
28376
  });
27862
- logOutput(data, getOutputFormat());
28377
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
27863
28378
  }
27864
28379
  OutputFormatter2.error = error;
27865
28380
  function emitList(code, items, opts) {
@@ -27880,11 +28395,14 @@ var OutputFormatter;
27880
28395
  function log(data) {
27881
28396
  const format = getOutputFormat();
27882
28397
  const sink = getOutputSink();
28398
+ const normalized = toPascalCaseData(data);
27883
28399
  if (format === "json") {
27884
- sink.writeErr(`${JSON.stringify(data)}
28400
+ const json2 = JSON.stringify(normalized);
28401
+ const safe = needsAsciiSafeJson(sink) ? escapeNonAscii(json2) : json2;
28402
+ sink.writeErr(`${safe}
27885
28403
  `);
27886
28404
  } else {
27887
- for (const [key, value] of Object.entries(data)) {
28405
+ for (const [key, value] of Object.entries(normalized)) {
27888
28406
  sink.writeErr(`${key}: ${value}
27889
28407
  `);
27890
28408
  }
@@ -27893,13 +28411,18 @@ var OutputFormatter;
27893
28411
  OutputFormatter2.log = log;
27894
28412
  function formatToString(data) {
27895
28413
  const filter = getOutputFilter();
27896
- if (filter && "Data" in data && data.Data != null) {
27897
- data.Data = applyFilter(data.Data, filter);
28414
+ if ("Data" in data && data.Data != null) {
28415
+ data.Data = normalizeDataKeys(data.Data);
28416
+ if (filter) {
28417
+ data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
28418
+ }
27898
28419
  }
28420
+ const output = normalizeOutputKeys(data);
27899
28421
  const lines = [];
27900
- printOutput(data, getOutputFormat(), (msg) => {
28422
+ const sink = getOutputSink();
28423
+ printOutput(output, getOutputFormat(), (msg) => {
27901
28424
  lines.push(msg);
27902
- });
28425
+ }, needsAsciiSafeJson(sink));
27903
28426
  return lines.join(`
27904
28427
  `);
27905
28428
  }
@@ -29320,6 +29843,19 @@ function parseSafeInteger(raw, min) {
29320
29843
  }
29321
29844
  return parsed;
29322
29845
  }
29846
+ var PollOutcome = {
29847
+ Completed: "completed",
29848
+ Timeout: "timeout",
29849
+ Interrupted: "interrupted",
29850
+ Aborted: "aborted",
29851
+ Failed: "failed"
29852
+ };
29853
+ var REASON_BY_OUTCOME = {
29854
+ [PollOutcome.Timeout]: "poll_timeout",
29855
+ [PollOutcome.Failed]: "poll_failed",
29856
+ [PollOutcome.Interrupted]: "poll_failed",
29857
+ [PollOutcome.Aborted]: "poll_aborted"
29858
+ };
29323
29859
  var TERMINAL_STATUSES = new Set([
29324
29860
  "completed",
29325
29861
  "successful",
@@ -29519,17 +30055,21 @@ Command.prototype.trackedAction = function(context, fn, properties) {
29519
30055
  const telemetryName = deriveCommandPath(command);
29520
30056
  const props = typeof properties === "function" ? properties(...args) : properties;
29521
30057
  const startTime = performance.now();
29522
- let errorMessage;
30058
+ let errorMessage2;
29523
30059
  const [error] = await catchError2(fn(...args));
29524
30060
  if (error) {
29525
- errorMessage = error instanceof Error ? error.message : String(error);
29526
- logger.error(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
30061
+ errorMessage2 = error instanceof Error ? error.message : String(error);
30062
+ logger.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage2}`);
30063
+ const typed = error;
30064
+ const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
30065
+ const customResult = typeof typed.result === "string" && typed.result !== RESULTS.Success && Object.values(RESULTS).includes(typed.result) ? typed.result : undefined;
30066
+ const finalResult = customResult ?? RESULTS.Failure;
29527
30067
  OutputFormatter.error({
29528
- Result: RESULTS.Failure,
29529
- Message: errorMessage,
29530
- Instructions: "An unexpected error occurred. Run with --log-level debug for details."
30068
+ Result: finalResult,
30069
+ Message: errorMessage2,
30070
+ Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
29531
30071
  });
29532
- context.exit(1);
30072
+ context.exit(EXIT_CODES[finalResult]);
29533
30073
  }
29534
30074
  const durationMs = performance.now() - startTime;
29535
30075
  const success = !error && (process.exitCode === undefined || process.exitCode === 0);
@@ -29538,7 +30078,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
29538
30078
  ...props,
29539
30079
  duration: String(durationMs),
29540
30080
  success: String(success),
29541
- ...errorMessage ? { errorMessage } : {}
30081
+ ...errorMessage2 ? { errorMessage: errorMessage2 } : {}
29542
30082
  }));
29543
30083
  });
29544
30084
  };
@@ -29559,7 +30099,7 @@ var withLoginValidity = (cmd) => {
29559
30099
  return cmd;
29560
30100
  };
29561
30101
  async function getPapApi(options) {
29562
- const [err, api] = await catchError2(createPapApiClient(PolicyManagementApi, {
30102
+ const [err, client] = await catchError2(createPapClient(PolicyManagementApi, {
29563
30103
  loginValidity: options.loginValidity
29564
30104
  }));
29565
30105
  if (err) {
@@ -29571,7 +30111,7 @@ async function getPapApi(options) {
29571
30111
  processContext.exit(1);
29572
30112
  return null;
29573
30113
  }
29574
- return api;
30114
+ return client.api;
29575
30115
  }
29576
30116
  async function loadPolicyDefinition(file) {
29577
30117
  const fs7 = getFileSystem();
@@ -29627,7 +30167,7 @@ var LIST_EXAMPLES = [
29627
30167
  },
29628
30168
  {
29629
30169
  Description: "Filter active policies, sorted by name",
29630
- Command: `uip gov access-policy list --filter "status in ('Active')" --order-by "Name asc"`,
30170
+ Command: `uip gov access-policy list --filter "status in ('Active')" --sort-by "Name asc"`,
29631
30171
  Output: {
29632
30172
  Code: "PolicyList",
29633
30173
  Data: {
@@ -29731,11 +30271,11 @@ var registerAccessPolicyCommand = (program2) => {
29731
30271
  "Search for policies matching optional filters, with pagination.",
29732
30272
  "Returns a paged list (totalCount + results) of policy metadata.",
29733
30273
  "",
29734
- "Filters use OData syntax (e.g. `status in ('Active')`). Sort with --order-by using",
30274
+ "Filters use OData syntax (e.g. `status in ('Active')`). Sort with --sort-by using",
29735
30275
  "`<Field> asc|desc` (e.g. `Name asc`, `CreatedOn desc`).",
29736
30276
  "Use the returned `id` with `access-policy get|update|delete|evaluate`."
29737
30277
  ].join(`
29738
- `)).option("--limit <n>", "Page size — maximum number of policies to return. Defaults to 20.", parseNonNegativeInt, 20).option("--offset <n>", "Number of records to skip before the returned page (zero-based).", parseNonNegativeInt, 0).option("--filter <filter>", `OData-style filter expression (e.g. "status in ('Active')").`).option("--order-by <order>", "Sort expression — '<Field> asc|desc' (e.g. 'Name asc', 'CreatedOn desc').").examples(LIST_EXAMPLES)).trackedAction(processContext, async (options) => {
30278
+ `)).option("--limit <n>", "Page size — maximum number of policies to return. Defaults to 20.", parseNonNegativeInt, 20).option("--offset <n>", "Number of records to skip before the returned page (zero-based).", parseNonNegativeInt, 0).option("--filter <filter>", `OData-style filter expression (e.g. "status in ('Active')").`).option("--sort-by <order>", "Sort expression — '<Field> asc|desc' (e.g. 'Name asc', 'CreatedOn desc').").examples(LIST_EXAMPLES)).trackedAction(processContext, async (options) => {
29739
30279
  const api = await getPapApi(options);
29740
30280
  if (!api)
29741
30281
  return;
@@ -29743,13 +30283,13 @@ var registerAccessPolicyCommand = (program2) => {
29743
30283
  top: options.limit,
29744
30284
  skip: options.offset,
29745
30285
  filter: options.filter,
29746
- orderBy: options.orderBy
30286
+ orderBy: options.sortBy
29747
30287
  }));
29748
30288
  if (error) {
29749
30289
  OutputFormatter.error({
29750
30290
  Result: RESULTS.Failure,
29751
30291
  Message: await extractErrorMessage(error),
29752
- Instructions: "Verify --filter uses OData syntax and --order-by is '<Field> asc|desc'. Ensure you have access to the access-policy service."
30292
+ Instructions: "Verify --filter uses OData syntax and --sort-by is '<Field> asc|desc'. Ensure you have access to the access-policy service."
29753
30293
  });
29754
30294
  processContext.exit(1);
29755
30295
  return;
@@ -29885,7 +30425,7 @@ var registerAccessPolicyCommand = (program2) => {
29885
30425
  "why a production request was allowed/denied."
29886
30426
  ].join(`
29887
30427
  `)).addOption(new Option("--resource-type <type>", "The protected asset being accessed (e.g. the Agent being invoked).").choices(RESOURCE_TYPES).makeOptionMandatory(true)).option("--resource-id <id>", "Identifier of the specific resource instance (e.g. an Agent UUID).").option("--actor-identity-id <id>", "Identifier of the actor — only required when calling with an S2S token. With a user token the actor is inferred from the bearer.").addOption(new Option("--actor-process-type <type>", "The workflow/agent being executed on behalf of the actor, if any.").choices(EXECUTABLE_TYPES)).option("--actor-process-id <id>", "Identifier of the executable (e.g. a Flow UUID).").option("--folder-key <key>", "Folder key (UUID) scoping the request to a specific folder.").option("--trace-parent-id <id>", "W3C traceparent header value to correlate this evaluation with upstream traces.").examples(EVALUATE_EXAMPLES)).trackedAction(processContext, async (options) => {
29888
- const [apiErr, client] = await catchError2(createPdpApiClient(PolicyEvaluationApi, {
30428
+ const [apiErr, client] = await catchError2(createPdpClient(PolicyEvaluationApi, {
29889
30429
  loginValidity: options.loginValidity
29890
30430
  }));
29891
30431
  if (apiErr) {
@@ -29977,6 +30517,7 @@ import path3 from "node:path";
29977
30517
  import { fileURLToPath as fileURLToPath2 } from "node:url";
29978
30518
  import childProcess32 from "node:child_process";
29979
30519
  import fs52, { constants as fsConstants22 } from "node:fs/promises";
30520
+ import { randomUUID as randomUUID2 } from "node:crypto";
29980
30521
  import { existsSync as existsSync2 } from "node:fs";
29981
30522
  import * as fs62 from "node:fs/promises";
29982
30523
  import * as os22 from "node:os";
@@ -30731,6 +31272,90 @@ class NodeFileSystem2 {
30731
31272
  async mkdir(dirPath) {
30732
31273
  await fs62.mkdir(dirPath, { recursive: true });
30733
31274
  }
31275
+ async acquireLock(lockPath) {
31276
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
31277
+ const lockFile = `${canonicalPath}.lock`;
31278
+ const ownerId = randomUUID2();
31279
+ const start = Date.now();
31280
+ while (true) {
31281
+ try {
31282
+ await fs62.writeFile(lockFile, ownerId, { flag: "wx" });
31283
+ return this.createLockRelease(lockFile, ownerId);
31284
+ } catch (error) {
31285
+ if (!this.hasErrnoCode(error, "EEXIST")) {
31286
+ throw error;
31287
+ }
31288
+ const stats = await fs62.stat(lockFile).catch(() => null);
31289
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS2) {
31290
+ const reclaimed = await fs62.rm(lockFile, { force: true }).then(() => true).catch(() => false);
31291
+ if (reclaimed)
31292
+ continue;
31293
+ }
31294
+ if (Date.now() - start > LOCK_MAX_WAIT_MS2) {
31295
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
31296
+ }
31297
+ await new Promise((resolve22) => setTimeout(resolve22, LOCK_RETRY_MIN_MS2 + Math.random() * LOCK_RETRY_JITTER_MS2));
31298
+ }
31299
+ }
31300
+ }
31301
+ async canonicalizeLockTarget(lockPath) {
31302
+ const absolute = path22.resolve(lockPath);
31303
+ const fullReal = await fs62.realpath(absolute).catch(() => null);
31304
+ if (fullReal)
31305
+ return fullReal;
31306
+ const parent = path22.dirname(absolute);
31307
+ const base = path22.basename(absolute);
31308
+ const canonicalParent = await fs62.realpath(parent).catch(() => parent);
31309
+ return path22.join(canonicalParent, base);
31310
+ }
31311
+ createLockRelease(lockFile, ownerId) {
31312
+ const heartbeatStart = Date.now();
31313
+ let heartbeatTimer;
31314
+ let stopped = false;
31315
+ const stopHeartbeat = () => {
31316
+ stopped = true;
31317
+ if (heartbeatTimer)
31318
+ clearTimeout(heartbeatTimer);
31319
+ };
31320
+ const scheduleNextHeartbeat = () => {
31321
+ if (stopped)
31322
+ return;
31323
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS2) {
31324
+ stopped = true;
31325
+ return;
31326
+ }
31327
+ heartbeatTimer = setTimeout(() => {
31328
+ runHeartbeat();
31329
+ }, LOCK_HEARTBEAT_MS2);
31330
+ heartbeatTimer.unref?.();
31331
+ };
31332
+ const runHeartbeat = async () => {
31333
+ if (stopped)
31334
+ return;
31335
+ const current = await fs62.readFile(lockFile, "utf-8").catch(() => null);
31336
+ if (stopped)
31337
+ return;
31338
+ if (current !== ownerId) {
31339
+ stopped = true;
31340
+ return;
31341
+ }
31342
+ const now = Date.now() / 1000;
31343
+ await fs62.utimes(lockFile, now, now).catch(() => {});
31344
+ scheduleNextHeartbeat();
31345
+ };
31346
+ scheduleNextHeartbeat();
31347
+ let released = false;
31348
+ return async () => {
31349
+ if (released)
31350
+ return;
31351
+ released = true;
31352
+ stopHeartbeat();
31353
+ const current = await fs62.readFile(lockFile, "utf-8").catch(() => null);
31354
+ if (current === ownerId) {
31355
+ await fs62.rm(lockFile, { force: true });
31356
+ }
31357
+ };
31358
+ }
30734
31359
  async rm(filePath) {
30735
31360
  await fs62.rm(filePath, { recursive: true, force: true });
30736
31361
  }
@@ -30776,16 +31401,23 @@ class NodeFileSystem2 {
30776
31401
  }
30777
31402
  }
30778
31403
  isEnoent(error) {
30779
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
31404
+ return this.hasErrnoCode(error, "ENOENT");
31405
+ }
31406
+ hasErrnoCode(error, code) {
31407
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
30780
31408
  }
30781
31409
  }
31410
+ var LOCK_HEARTBEAT_MS2 = 5000;
31411
+ var LOCK_STALE_MS2 = 15000;
31412
+ var LOCK_MAX_WAIT_MS2 = 20000;
31413
+ var LOCK_MAX_HOLD_MS2 = 60000;
31414
+ var LOCK_RETRY_MIN_MS2 = 100;
31415
+ var LOCK_RETRY_JITTER_MS2 = 200;
30782
31416
  var init_node2 = __esm2(() => {
30783
31417
  init_open2();
30784
31418
  });
30785
31419
  var fsInstance2;
30786
- var getFileSystem2 = () => {
30787
- return fsInstance2;
30788
- };
31420
+ var getFileSystem2 = () => fsInstance2;
30789
31421
  var init_src2 = __esm2(() => {
30790
31422
  init_node2();
30791
31423
  init_node2();
@@ -48592,9 +49224,13 @@ var require_dist2 = __commonJS3((exports) => {
48592
49224
  exports.RobotProxyConstructor = RobotProxyConstructor;
48593
49225
  __exportStar(require_agent2(), exports);
48594
49226
  });
48595
- var package_default2 = {
49227
+ var init_server2 = __esm2(() => {
49228
+ init_constants2();
49229
+ });
49230
+ var package_default3 = {
48596
49231
  name: "@uipath/aops-policy-tool",
48597
- version: "0.3.0",
49232
+ license: "MIT",
49233
+ version: "1.2.0",
48598
49234
  description: "CLI plugin for managing UiPath AOps governance policies.",
48599
49235
  private: false,
48600
49236
  repository: {
@@ -48636,6 +49272,132 @@ var package_default2 = {
48636
49272
  typescript: "^6.0.2"
48637
49273
  }
48638
49274
  };
49275
+ var PREFIX2 = "@uipath/common/";
49276
+ var _g2 = globalThis;
49277
+ function singleton2(ctorOrName) {
49278
+ const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
49279
+ const key = Symbol.for(PREFIX2 + name);
49280
+ return {
49281
+ get(fallback) {
49282
+ return _g2[key] ?? fallback;
49283
+ },
49284
+ set(value) {
49285
+ _g2[key] = value;
49286
+ },
49287
+ clear() {
49288
+ delete _g2[key];
49289
+ },
49290
+ getOrInit(factory, guard) {
49291
+ const existing = _g2[key];
49292
+ if (existing != null && typeof existing === "object") {
49293
+ if (!guard || guard(existing)) {
49294
+ return existing;
49295
+ }
49296
+ }
49297
+ const instance = factory();
49298
+ _g2[key] = instance;
49299
+ return instance;
49300
+ }
49301
+ };
49302
+ }
49303
+ var USER_AGENT_HEADER2 = "User-Agent";
49304
+ var sdkUserAgentHostToken2 = singleton2("SdkUserAgentHostToken");
49305
+ function userAgentPatchKey2(userAgent) {
49306
+ return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
49307
+ }
49308
+ function splitUserAgentTokens2(value) {
49309
+ return value?.trim().split(/\s+/).filter(Boolean) ?? [];
49310
+ }
49311
+ function appendUserAgentToken2(value, userAgent) {
49312
+ const tokens = splitUserAgentTokens2(value);
49313
+ const seen = new Set(tokens);
49314
+ for (const token of splitUserAgentTokens2(userAgent)) {
49315
+ if (!seen.has(token)) {
49316
+ tokens.push(token);
49317
+ seen.add(token);
49318
+ }
49319
+ }
49320
+ return tokens.join(" ");
49321
+ }
49322
+ function getEffectiveUserAgent2(userAgent) {
49323
+ return appendUserAgentToken2(sdkUserAgentHostToken2.get(), userAgent);
49324
+ }
49325
+ function isHeadersLike2(headers) {
49326
+ return typeof headers === "object" && headers !== null && "get" in headers && typeof headers.get === "function" && "set" in headers && typeof headers.set === "function";
49327
+ }
49328
+ function getSdkUserAgentToken2(pkg) {
49329
+ const packageName = pkg.name.replace(/^@uipath\//, "");
49330
+ return getEffectiveUserAgent2(`${packageName}/${pkg.version}`);
49331
+ }
49332
+ function addSdkUserAgentHeader2(headers, userAgent) {
49333
+ const result = { ...headers ?? {} };
49334
+ const effectiveUserAgent = getEffectiveUserAgent2(userAgent);
49335
+ const headerName = Object.keys(result).find((key) => key.toLowerCase() === USER_AGENT_HEADER2.toLowerCase());
49336
+ if (headerName) {
49337
+ result[headerName] = appendUserAgentToken2(result[headerName], effectiveUserAgent);
49338
+ } else {
49339
+ result[USER_AGENT_HEADER2] = effectiveUserAgent;
49340
+ }
49341
+ return result;
49342
+ }
49343
+ function withSdkUserAgentHeader2(headers, userAgent) {
49344
+ const effectiveUserAgent = getEffectiveUserAgent2(userAgent);
49345
+ if (isHeadersLike2(headers)) {
49346
+ headers.set(USER_AGENT_HEADER2, appendUserAgentToken2(headers.get(USER_AGENT_HEADER2), effectiveUserAgent));
49347
+ return headers;
49348
+ }
49349
+ if (Array.isArray(headers)) {
49350
+ const result = headers.map((entry) => {
49351
+ const [key, value] = entry;
49352
+ return [key, value];
49353
+ });
49354
+ const headerIndex = result.findIndex(([key]) => key.toLowerCase() === USER_AGENT_HEADER2.toLowerCase());
49355
+ if (headerIndex >= 0) {
49356
+ const [key, value] = result[headerIndex];
49357
+ result[headerIndex] = [
49358
+ key,
49359
+ appendUserAgentToken2(value, effectiveUserAgent)
49360
+ ];
49361
+ } else {
49362
+ result.push([USER_AGENT_HEADER2, effectiveUserAgent]);
49363
+ }
49364
+ return result;
49365
+ }
49366
+ return addSdkUserAgentHeader2(typeof headers === "object" && headers !== null ? { ...headers } : {}, effectiveUserAgent);
49367
+ }
49368
+ function withUserAgentInitOverride2(initOverrides, userAgent) {
49369
+ return async (requestContext) => {
49370
+ const initWithUserAgent = {
49371
+ ...requestContext.init,
49372
+ headers: withSdkUserAgentHeader2(requestContext.init.headers, userAgent)
49373
+ };
49374
+ const override = typeof initOverrides === "function" ? await initOverrides({
49375
+ ...requestContext,
49376
+ init: initWithUserAgent
49377
+ }) : initOverrides;
49378
+ return {
49379
+ ...override ?? {},
49380
+ headers: withSdkUserAgentHeader2(override?.headers ?? initWithUserAgent.headers, userAgent)
49381
+ };
49382
+ };
49383
+ }
49384
+ function installSdkUserAgentHeader2(BaseApiClass, userAgent) {
49385
+ const prototype = BaseApiClass.prototype;
49386
+ const patchKey = userAgentPatchKey2(userAgent);
49387
+ if (prototype[patchKey]) {
49388
+ return;
49389
+ }
49390
+ if (typeof prototype.request !== "function") {
49391
+ throw new Error("Generated BaseAPI request function not found.");
49392
+ }
49393
+ const originalRequest = prototype.request;
49394
+ prototype.request = function requestWithUserAgent(context, initOverrides) {
49395
+ return originalRequest.call(this, context, withUserAgentInitOverride2(initOverrides, userAgent));
49396
+ };
49397
+ Object.defineProperty(prototype, patchKey, {
49398
+ value: true
49399
+ });
49400
+ }
48639
49401
  var BASE_PATH2 = "http://localhost".replace(/\/+$/, "");
48640
49402
 
48641
49403
  class Configuration2 {
@@ -48903,6 +49665,53 @@ class TextApiResponse {
48903
49665
  return await this.raw.text();
48904
49666
  }
48905
49667
  }
49668
+ var package_default22 = {
49669
+ name: "@uipath/aops-policy-sdk",
49670
+ license: "MIT",
49671
+ version: "1.2.0",
49672
+ description: "SDK for the UiPath AOps Governance API — policy management and deployment.",
49673
+ repository: {
49674
+ type: "git",
49675
+ url: "https://github.com/UiPath/cli.git",
49676
+ directory: "packages/gov/aops-policy-sdk"
49677
+ },
49678
+ publishConfig: {
49679
+ registry: "https://npm.pkg.github.com/@uipath"
49680
+ },
49681
+ keywords: [
49682
+ "uipath",
49683
+ "governance",
49684
+ "policy",
49685
+ "sdk"
49686
+ ],
49687
+ type: "module",
49688
+ main: "./dist/index.js",
49689
+ types: "./dist/src/index.d.ts",
49690
+ exports: {
49691
+ ".": {
49692
+ types: "./dist/src/index.d.ts",
49693
+ default: "./dist/index.js"
49694
+ }
49695
+ },
49696
+ files: [
49697
+ "dist"
49698
+ ],
49699
+ private: true,
49700
+ scripts: {
49701
+ build: "bun build ./src/index.ts --outdir dist --format esm --target node && tsc -p tsconfig.build.json --noCheck",
49702
+ generate: "bun run src/scripts/generate-sdk.ts",
49703
+ lint: "biome check ."
49704
+ },
49705
+ devDependencies: {
49706
+ "@openapitools/openapi-generator-cli": "^2.31.1",
49707
+ "@types/node": "^25.5.2",
49708
+ "@uipath/auth": "workspace:*",
49709
+ "@uipath/common": "workspace:*",
49710
+ typescript: "^6.0.2"
49711
+ }
49712
+ };
49713
+ var SDK_USER_AGENT2 = getSdkUserAgentToken2(package_default22);
49714
+ installSdkUserAgentHeader2(BaseAPI2, SDK_USER_AGENT2);
48906
49715
  function AddLicenseTypeRequestToJSON(json2) {
48907
49716
  return AddLicenseTypeRequestToJSONTyped(json2, false);
48908
49717
  }
@@ -51559,30 +52368,7 @@ class InvalidBaseUrlError2 extends Error {
51559
52368
  this.name = "InvalidBaseUrlError";
51560
52369
  }
51561
52370
  }
51562
- var DEFAULT_SCOPES2 = [
51563
- "offline_access",
51564
- "ProcessMining",
51565
- "OrchestratorApiUserAccess",
51566
- "StudioWebBackend",
51567
- "IdentityServerApi",
51568
- "ConnectionService",
51569
- "DataService",
51570
- "DataServiceApiUserAccess",
51571
- "DocumentUnderstanding",
51572
- "EnterpriseContextService",
51573
- "Directory",
51574
- "JamJamApi",
51575
- "LLMGateway",
51576
- "LLMOps",
51577
- "OMS",
51578
- "RCS.FolderAuthorization",
51579
- "RCS.TagsManagement",
51580
- "TestmanagerApiUserAccess",
51581
- "AutomationSolutions",
51582
- "StudioWebTypeCacheService",
51583
- "Docs.GPT.Search",
51584
- "Insights"
51585
- ];
52371
+ var DEFAULT_SCOPES2 = ["openid", "profile", "offline_access"];
51586
52372
  var normalizeAndValidateBaseUrl2 = (rawUrl) => {
51587
52373
  let baseUrl = rawUrl;
51588
52374
  if (baseUrl.endsWith("/identity_/")) {
@@ -51632,7 +52418,8 @@ var resolveConfigAsync2 = async ({
51632
52418
  if (!clientSecret && fileAuth.clientSecret) {
51633
52419
  clientSecret = fileAuth.clientSecret;
51634
52420
  }
51635
- const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : DEFAULT_SCOPES2;
52421
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID2 && Boolean(clientSecret);
52422
+ const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES2;
51636
52423
  return {
51637
52424
  clientId,
51638
52425
  clientSecret,
@@ -51715,6 +52502,7 @@ var getTokenExpiration2 = (accessToken) => {
51715
52502
  }
51716
52503
  };
51717
52504
  var ENV_AUTH_ENABLE_VAR2 = "UIPATH_CLI_ENABLE_ENV_AUTH";
52505
+ var ENFORCE_ROBOT_AUTH_VAR2 = "UIPATH_CLI_ENFORCE_ROBOT_AUTH";
51718
52506
  var ENV_AUTH_VARS2 = {
51719
52507
  token: "UIPATH_CLI_AUTH_TOKEN",
51720
52508
  organizationName: "UIPATH_CLI_ORGANIZATION_NAME",
@@ -51730,6 +52518,7 @@ class EnvAuthConfigError2 extends Error {
51730
52518
  }
51731
52519
  }
51732
52520
  var isEnvAuthEnabled2 = () => process.env[ENV_AUTH_ENABLE_VAR2] === "true";
52521
+ var isRobotAuthEnforced2 = () => process.env[ENFORCE_ROBOT_AUTH_VAR2] === "true";
51733
52522
  var requireEnv2 = (name) => {
51734
52523
  const value = process.env[name];
51735
52524
  if (!value) {
@@ -51771,6 +52560,7 @@ var readAuthFromEnv2 = () => {
51771
52560
  expiration
51772
52561
  };
51773
52562
  };
52563
+ init_src2();
51774
52564
  var DEFAULT_TIMEOUT_MS2 = 1000;
51775
52565
  var CLOSE_TIMEOUT_MS2 = 500;
51776
52566
  var NOTICE_SENTINEL2 = Symbol.for("@uipath/auth/robotFallbackNoticePrinted");
@@ -51782,6 +52572,35 @@ var printNoticeOnce2 = () => {
51782
52572
  catchError3(() => process.stderr.write(`Using UiPath Robot credentials. Run 'uip login' for a dedicated session.
51783
52573
  `));
51784
52574
  };
52575
+ var ROBOT_USER_SERVICES_PIPE2 = "UiPathUserServices";
52576
+ var ROBOT_USER_SERVICES_ALTERNATE_PIPE2 = `${ROBOT_USER_SERVICES_PIPE2}Alternate`;
52577
+ var PIPE_NAME_MAX_LENGTH2 = 103;
52578
+ var getRobotIpcPipeNames2 = async () => {
52579
+ const fs72 = getFileSystem2();
52580
+ const username = fs72.env.getenv("USER") ?? fs72.env.getenv("USERNAME");
52581
+ if (!username) {
52582
+ throw new Error("Unable to determine current username");
52583
+ }
52584
+ const tempPath = fs72.env.getenv("TMPDIR") ?? "/tmp/";
52585
+ return [ROBOT_USER_SERVICES_PIPE2, ROBOT_USER_SERVICES_ALTERNATE_PIPE2].map((baseName) => fs72.path.join(tempPath, `${baseName}_${username}`).substring(0, PIPE_NAME_MAX_LENGTH2));
52586
+ };
52587
+ var defaultIsRobotIpcAvailable2 = async () => {
52588
+ if (process.platform === "win32") {
52589
+ return true;
52590
+ }
52591
+ const [pipeNamesError, pipeNames] = await catchError3(getRobotIpcPipeNames2());
52592
+ if (pipeNamesError || !pipeNames) {
52593
+ return false;
52594
+ }
52595
+ const fs72 = getFileSystem2();
52596
+ for (const pipeName of pipeNames) {
52597
+ const [existsError, exists] = await catchError3(fs72.exists(pipeName));
52598
+ if (!existsError && exists === true) {
52599
+ return true;
52600
+ }
52601
+ }
52602
+ return false;
52603
+ };
51785
52604
  var withTimeout2 = (promise, timeoutMs) => new Promise((resolve22, reject) => {
51786
52605
  const timer = setTimeout(() => reject(new Error(`Robot IPC call timed out after ${timeoutMs}ms`)), timeoutMs);
51787
52606
  promise.then((value) => {
@@ -51813,14 +52632,20 @@ var defaultLoadModule2 = async () => {
51813
52632
  var tryRobotClientFallback2 = async (options = {}) => {
51814
52633
  if (isBrowser2())
51815
52634
  return;
51816
- if (process.env.CI || process.env.GITHUB_ACTIONS) {
51817
- return;
51818
- }
51819
- if (process.env.UIPATH_URL) {
51820
- return;
52635
+ if (!options.force) {
52636
+ if (process.env.CI || process.env.GITHUB_ACTIONS) {
52637
+ return;
52638
+ }
52639
+ if (process.env.UIPATH_URL) {
52640
+ return;
52641
+ }
51821
52642
  }
51822
52643
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
52644
+ const isRobotIpcAvailable = options.isRobotIpcAvailable ?? defaultIsRobotIpcAvailable2;
51823
52645
  const loadModule = options.loadModule ?? defaultLoadModule2;
52646
+ if (!await isRobotIpcAvailable()) {
52647
+ return;
52648
+ }
51824
52649
  const mod2 = await loadModule();
51825
52650
  if (!mod2)
51826
52651
  return;
@@ -52081,11 +52906,130 @@ function normalizeTokenRefreshFailure2() {
52081
52906
  function normalizeTokenRefreshUnavailableFailure2() {
52082
52907
  return "token refresh failed before authentication completed";
52083
52908
  }
52084
- var getLoginStatusWithDeps2 = async (options = {}, deps = {}) => {
52085
- if (isEnvAuthEnabled2()) {
52086
- return readAuthFromEnv2();
52909
+ function errorMessage2(error) {
52910
+ return error instanceof Error ? error.message : String(error);
52911
+ }
52912
+ function computeExpirationThreshold2(ensureTokenValidityMinutes) {
52913
+ return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
52914
+ }
52915
+ async function runRefreshLocked2(inputs) {
52916
+ const {
52917
+ absolutePath,
52918
+ refreshToken: callerRefreshToken,
52919
+ customAuthority,
52920
+ ensureTokenValidityMinutes,
52921
+ loadEnvFile,
52922
+ saveEnvFile,
52923
+ refreshFn,
52924
+ resolveConfig: resolveConfig2
52925
+ } = inputs;
52926
+ const expirationThreshold = computeExpirationThreshold2(ensureTokenValidityMinutes);
52927
+ let fresh;
52928
+ try {
52929
+ fresh = await loadEnvFile({ envPath: absolutePath });
52930
+ } catch (error) {
52931
+ return {
52932
+ kind: "fail",
52933
+ status: {
52934
+ loginStatus: "Refresh Failed",
52935
+ hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
52936
+ tokenRefresh: {
52937
+ attempted: false,
52938
+ success: false,
52939
+ errorMessage: `auth file read failed: ${errorMessage2(error)}`
52940
+ }
52941
+ }
52942
+ };
52087
52943
  }
52088
- const { envFilePath = DEFAULT_ENV_FILENAME2, ensureTokenValidityMinutes } = options;
52944
+ const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
52945
+ const freshExp = freshAccess ? getTokenExpiration2(freshAccess) : undefined;
52946
+ if (freshAccess && freshExp && freshExp > expirationThreshold) {
52947
+ return {
52948
+ kind: "ok",
52949
+ accessToken: freshAccess,
52950
+ refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
52951
+ expiration: freshExp,
52952
+ tokenRefresh: { attempted: false, success: true }
52953
+ };
52954
+ }
52955
+ const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
52956
+ let refreshedAccess;
52957
+ let refreshedRefresh;
52958
+ try {
52959
+ const config = await resolveConfig2({ customAuthority });
52960
+ const refreshed = await refreshFn({
52961
+ refreshToken: tokenForIdP,
52962
+ tokenEndpoint: config.tokenEndpoint,
52963
+ clientId: config.clientId,
52964
+ expectedAuthority: customAuthority
52965
+ });
52966
+ refreshedAccess = refreshed.accessToken;
52967
+ refreshedRefresh = refreshed.refreshToken;
52968
+ } catch (error) {
52969
+ const isOAuthFailure = isTokenRefreshOAuthFailure2(error);
52970
+ 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.";
52971
+ const message = isOAuthFailure ? normalizeTokenRefreshFailure2() : normalizeTokenRefreshUnavailableFailure2();
52972
+ return {
52973
+ kind: "fail",
52974
+ status: {
52975
+ loginStatus: "Refresh Failed",
52976
+ hint,
52977
+ tokenRefresh: {
52978
+ attempted: true,
52979
+ success: false,
52980
+ errorMessage: message
52981
+ }
52982
+ }
52983
+ };
52984
+ }
52985
+ const refreshedExp = getTokenExpiration2(refreshedAccess);
52986
+ if (!refreshedExp || refreshedExp <= new Date) {
52987
+ return {
52988
+ kind: "fail",
52989
+ status: {
52990
+ loginStatus: "Refresh Failed",
52991
+ hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
52992
+ tokenRefresh: {
52993
+ attempted: true,
52994
+ success: false,
52995
+ errorMessage: "refreshed token has no valid expiration claim"
52996
+ }
52997
+ }
52998
+ };
52999
+ }
53000
+ try {
53001
+ await saveEnvFile({
53002
+ envPath: absolutePath,
53003
+ data: {
53004
+ UIPATH_ACCESS_TOKEN: refreshedAccess,
53005
+ UIPATH_REFRESH_TOKEN: refreshedRefresh
53006
+ },
53007
+ merge: true
53008
+ });
53009
+ return {
53010
+ kind: "ok",
53011
+ accessToken: refreshedAccess,
53012
+ refreshToken: refreshedRefresh,
53013
+ expiration: refreshedExp,
53014
+ tokenRefresh: { attempted: true, success: true }
53015
+ };
53016
+ } catch (error) {
53017
+ const msg = errorMessage2(error);
53018
+ return {
53019
+ kind: "ok",
53020
+ accessToken: refreshedAccess,
53021
+ refreshToken: refreshedRefresh,
53022
+ expiration: refreshedExp,
53023
+ 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.`,
53024
+ tokenRefresh: {
53025
+ attempted: true,
53026
+ success: true,
53027
+ errorMessage: `persistence failed: ${msg}`
53028
+ }
53029
+ };
53030
+ }
53031
+ }
53032
+ var getLoginStatusWithDeps2 = async (options = {}, deps = {}) => {
52089
53033
  const {
52090
53034
  resolveEnvFilePath = resolveEnvFilePathAsync2,
52091
53035
  loadEnvFile = loadEnvFileAsync2,
@@ -52095,6 +53039,34 @@ var getLoginStatusWithDeps2 = async (options = {}, deps = {}) => {
52095
53039
  resolveConfig: resolveConfig2 = resolveConfigAsync2,
52096
53040
  robotFallback = tryRobotClientFallback2
52097
53041
  } = deps;
53042
+ if (isRobotAuthEnforced2()) {
53043
+ if (isEnvAuthEnabled2()) {
53044
+ throw new EnvAuthConfigError2(`${ENV_AUTH_ENABLE_VAR2}=true and ${ENFORCE_ROBOT_AUTH_VAR2}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
53045
+ }
53046
+ const robotCreds = await robotFallback({ force: true });
53047
+ if (!robotCreds) {
53048
+ return {
53049
+ loginStatus: "Not logged in",
53050
+ hint: `${ENFORCE_ROBOT_AUTH_VAR2}=true but the UiPath Robot ` + `session is unavailable. Start and sign in to the Assistant, ` + `or unset ${ENFORCE_ROBOT_AUTH_VAR2} to fall back to file or ` + `env-var authentication.`
53051
+ };
53052
+ }
53053
+ const expiration2 = getTokenExpiration2(robotCreds.accessToken);
53054
+ return {
53055
+ loginStatus: "Logged in",
53056
+ accessToken: robotCreds.accessToken,
53057
+ baseUrl: robotCreds.baseUrl,
53058
+ organizationName: robotCreds.organizationName,
53059
+ organizationId: robotCreds.organizationId,
53060
+ tenantName: robotCreds.tenantName,
53061
+ tenantId: robotCreds.tenantId,
53062
+ expiration: expiration2,
53063
+ source: "robot"
53064
+ };
53065
+ }
53066
+ if (isEnvAuthEnabled2()) {
53067
+ return readAuthFromEnv2();
53068
+ }
53069
+ const { envFilePath = DEFAULT_ENV_FILENAME2, ensureTokenValidityMinutes } = options;
52098
53070
  const { absolutePath } = await resolveEnvFilePath(envFilePath);
52099
53071
  if (absolutePath === undefined) {
52100
53072
  const robotCreds = await robotFallback();
@@ -52131,73 +53103,103 @@ var getLoginStatusWithDeps2 = async (options = {}, deps = {}) => {
52131
53103
  let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
52132
53104
  let expiration = getTokenExpiration2(accessToken);
52133
53105
  let persistenceWarning;
53106
+ let lockReleaseFailed = false;
52134
53107
  let tokenRefresh;
52135
- const expirationThreshold = new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
52136
- if (expiration && expiration <= expirationThreshold && refreshToken) {
52137
- let refreshedAccess;
52138
- let refreshedRefresh;
53108
+ const outerThreshold = computeExpirationThreshold2(ensureTokenValidityMinutes);
53109
+ const tryGlobalCredsHint = async () => {
53110
+ const fs72 = getFs();
53111
+ const globalPath = fs72.path.join(fs72.env.homedir(), envFilePath);
53112
+ if (absolutePath === globalPath)
53113
+ return;
53114
+ if (!await fs72.exists(globalPath))
53115
+ return;
52139
53116
  try {
52140
- const config = await resolveConfig2({
52141
- customAuthority: credentials.UIPATH_URL
52142
- });
52143
- const refreshed = await refreshTokenFn({
52144
- refreshToken,
52145
- tokenEndpoint: config.tokenEndpoint,
52146
- clientId: config.clientId,
52147
- expectedAuthority: credentials.UIPATH_URL
52148
- });
52149
- refreshedAccess = refreshed.accessToken;
52150
- refreshedRefresh = refreshed.refreshToken;
53117
+ const globalCreds = await loadEnvFile({ envPath: globalPath });
53118
+ if (!globalCreds.UIPATH_ACCESS_TOKEN)
53119
+ return;
53120
+ const globalExp = getTokenExpiration2(globalCreds.UIPATH_ACCESS_TOKEN);
53121
+ if (globalExp && globalExp <= new Date)
53122
+ return;
53123
+ 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.`;
53124
+ } catch {
53125
+ return;
53126
+ }
53127
+ };
53128
+ if (expiration && expiration <= outerThreshold && refreshToken) {
53129
+ let release;
53130
+ try {
53131
+ release = await getFs().acquireLock(absolutePath);
52151
53132
  } catch (error) {
52152
- const isOAuthFailure = isTokenRefreshOAuthFailure2(error);
52153
- 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.";
52154
- const errorMessage = isOAuthFailure ? normalizeTokenRefreshFailure2() : normalizeTokenRefreshUnavailableFailure2();
53133
+ const msg = errorMessage2(error);
53134
+ const globalHint = await tryGlobalCredsHint();
53135
+ if (globalHint) {
53136
+ return {
53137
+ loginStatus: "Expired",
53138
+ accessToken,
53139
+ refreshToken,
53140
+ baseUrl: credentials.UIPATH_URL,
53141
+ organizationName: credentials.UIPATH_ORGANIZATION_NAME,
53142
+ organizationId: credentials.UIPATH_ORGANIZATION_ID,
53143
+ tenantName: credentials.UIPATH_TENANT_NAME,
53144
+ tenantId: credentials.UIPATH_TENANT_ID,
53145
+ expiration,
53146
+ source: "file",
53147
+ hint: globalHint,
53148
+ tokenRefresh: {
53149
+ attempted: false,
53150
+ success: false,
53151
+ errorMessage: `lock acquisition failed: ${msg}`
53152
+ }
53153
+ };
53154
+ }
52155
53155
  return {
52156
53156
  loginStatus: "Refresh Failed",
52157
- hint,
53157
+ 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.",
52158
53158
  tokenRefresh: {
52159
- attempted: true,
53159
+ attempted: false,
52160
53160
  success: false,
52161
- errorMessage
53161
+ errorMessage: `lock acquisition failed: ${msg}`
52162
53162
  }
52163
53163
  };
52164
53164
  }
52165
- const refreshedExp = getTokenExpiration2(refreshedAccess);
52166
- if (!refreshedExp || refreshedExp <= new Date) {
52167
- return {
52168
- loginStatus: "Refresh Failed",
52169
- hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
52170
- tokenRefresh: {
52171
- attempted: true,
52172
- success: false,
52173
- errorMessage: "refreshed token has no valid expiration claim"
53165
+ let lockedFailure;
53166
+ try {
53167
+ const outcome = await runRefreshLocked2({
53168
+ absolutePath,
53169
+ refreshToken,
53170
+ customAuthority: credentials.UIPATH_URL,
53171
+ ensureTokenValidityMinutes,
53172
+ loadEnvFile,
53173
+ saveEnvFile,
53174
+ refreshFn: refreshTokenFn,
53175
+ resolveConfig: resolveConfig2
53176
+ });
53177
+ if (outcome.kind === "fail") {
53178
+ lockedFailure = outcome.status;
53179
+ } else {
53180
+ accessToken = outcome.accessToken;
53181
+ refreshToken = outcome.refreshToken;
53182
+ expiration = outcome.expiration;
53183
+ tokenRefresh = outcome.tokenRefresh;
53184
+ if (outcome.persistenceWarning) {
53185
+ persistenceWarning = outcome.persistenceWarning;
52174
53186
  }
52175
- };
53187
+ }
53188
+ } finally {
53189
+ try {
53190
+ await release();
53191
+ } catch {
53192
+ lockReleaseFailed = true;
53193
+ }
52176
53194
  }
52177
- accessToken = refreshedAccess;
52178
- refreshToken = refreshedRefresh;
52179
- expiration = refreshedExp;
52180
- try {
52181
- await saveEnvFile({
52182
- envPath: absolutePath,
52183
- data: {
52184
- UIPATH_ACCESS_TOKEN: accessToken,
52185
- UIPATH_REFRESH_TOKEN: refreshToken
52186
- },
52187
- merge: true
52188
- });
52189
- tokenRefresh = {
52190
- attempted: true,
52191
- success: true
52192
- };
52193
- } catch (error) {
52194
- const msg = error instanceof Error ? error.message : String(error);
52195
- 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.`;
52196
- tokenRefresh = {
52197
- attempted: true,
52198
- success: true,
52199
- errorMessage: `persistence failed: ${msg}`
52200
- };
53195
+ if (lockedFailure) {
53196
+ const globalHint = await tryGlobalCredsHint();
53197
+ const base = globalHint ? {
53198
+ ...lockedFailure,
53199
+ loginStatus: "Expired",
53200
+ hint: globalHint
53201
+ } : lockedFailure;
53202
+ return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
52201
53203
  }
52202
53204
  }
52203
53205
  const result = {
@@ -52212,23 +53214,13 @@ var getLoginStatusWithDeps2 = async (options = {}, deps = {}) => {
52212
53214
  expiration,
52213
53215
  source: "file",
52214
53216
  ...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
53217
+ ...lockReleaseFailed ? { lockReleaseFailed: true } : {},
52215
53218
  ...tokenRefresh ? { tokenRefresh } : {}
52216
53219
  };
52217
53220
  if (result.loginStatus === "Expired") {
52218
- const fs72 = getFs();
52219
- const globalPath = fs72.path.join(fs72.env.homedir(), envFilePath);
52220
- if (absolutePath !== globalPath && await fs72.exists(globalPath)) {
52221
- try {
52222
- const globalCreds = await loadEnvFile({
52223
- envPath: globalPath
52224
- });
52225
- if (globalCreds.UIPATH_ACCESS_TOKEN) {
52226
- const globalExp = getTokenExpiration2(globalCreds.UIPATH_ACCESS_TOKEN);
52227
- if (!globalExp || globalExp > new Date) {
52228
- 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.`;
52229
- }
52230
- }
52231
- } catch {}
53221
+ const globalHint = await tryGlobalCredsHint();
53222
+ if (globalHint) {
53223
+ result.hint = globalHint;
52232
53224
  }
52233
53225
  }
52234
53226
  return result;
@@ -52243,6 +53235,7 @@ var getLoginStatusAsync2 = async (options = {}) => {
52243
53235
  };
52244
53236
  init_src2();
52245
53237
  init_src2();
53238
+ init_server2();
52246
53239
  async function createGovernanceConfig(options) {
52247
53240
  const status = await getLoginStatusAsync2({
52248
53241
  ensureTokenValidityMinutes: options?.loginValidity
@@ -52258,13 +53251,15 @@ async function createGovernanceConfig(options) {
52258
53251
  const bearerToken = options?.s2sToken ?? status.accessToken;
52259
53252
  return new Configuration2({
52260
53253
  basePath,
52261
- apiKey: () => `Bearer ${bearerToken}`
53254
+ apiKey: () => `Bearer ${bearerToken}`,
53255
+ headers: addSdkUserAgentHeader2(undefined, SDK_USER_AGENT2)
52262
53256
  });
52263
53257
  }
52264
- async function createApiClient(ApiClass, options) {
53258
+ async function createApiClient2(ApiClass, options) {
52265
53259
  const config = await createGovernanceConfig(options);
52266
53260
  return new ApiClass(config);
52267
53261
  }
53262
+ init_src2();
52268
53263
  function isPromiseLike22(value) {
52269
53264
  return value !== null && typeof value === "object" && typeof value.then === "function";
52270
53265
  }
@@ -52291,71 +53286,6 @@ function settlePromiseLike22(thenable) {
52291
53286
  undefined
52292
53287
  ]);
52293
53288
  }
52294
- var examplesByCommand2 = new WeakMap;
52295
- Command.prototype.examples = function(examples) {
52296
- examplesByCommand2.set(this, examples);
52297
- return this;
52298
- };
52299
- var PREFIX2 = "@uipath/common/";
52300
- var _g2 = globalThis;
52301
- function singleton2(ctorOrName) {
52302
- const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
52303
- const key = Symbol.for(PREFIX2 + name);
52304
- return {
52305
- get(fallback) {
52306
- return _g2[key] ?? fallback;
52307
- },
52308
- set(value) {
52309
- _g2[key] = value;
52310
- },
52311
- clear() {
52312
- delete _g2[key];
52313
- },
52314
- getOrInit(factory, guard) {
52315
- const existing = _g2[key];
52316
- if (existing != null && typeof existing === "object") {
52317
- if (!guard || guard(existing)) {
52318
- return existing;
52319
- }
52320
- }
52321
- const instance = factory();
52322
- _g2[key] = instance;
52323
- return instance;
52324
- }
52325
- };
52326
- }
52327
- function createStorage2() {
52328
- const [error, mod2] = catchError22(() => __require3("node:async_hooks"));
52329
- if (error || typeof mod2?.AsyncLocalStorage !== "function") {
52330
- return {
52331
- getStore: () => {
52332
- return;
52333
- },
52334
- run: (_store, fn) => fn()
52335
- };
52336
- }
52337
- return new mod2.AsyncLocalStorage;
52338
- }
52339
- var storageSingleton2 = singleton2("OutputStorage");
52340
- var sinkSlot2 = singleton2("OutputSink");
52341
- var outputStorage2 = storageSingleton2.getOrInit(createStorage2, (v) => ("getStore" in v));
52342
- var CONSOLE_FALLBACK2 = {
52343
- writeOut: (str2) => process.stdout.write(str2),
52344
- writeErr: (str2) => process.stderr.write(str2),
52345
- writeLog: (str2) => process.stdout.write(str2),
52346
- capabilities: {
52347
- isInteractive: false,
52348
- supportsColor: false,
52349
- outputWidth: 80
52350
- }
52351
- };
52352
- function getOutputSink2() {
52353
- return outputStorage2.getStore() ?? sinkSlot2.get() ?? CONSOLE_FALLBACK2;
52354
- }
52355
- var COMPLETER_SYMBOL2 = Symbol.for("@uipath/common/completer");
52356
- var guardInstalledSlot2 = singleton2("ConsoleGuardInstalled");
52357
- var savedOriginalsSlot2 = singleton2("ConsoleGuardOriginals");
52358
- var DEFAULT_AUTH_TIMEOUT_MS22 = 5 * 60 * 1000;
52359
53289
  var DEFAULT_4012 = "Unauthorized (401). Run `uip login` to authenticate.";
52360
53290
  var DEFAULT_4032 = "Forbidden (403). Ensure the account has the required permissions.";
52361
53291
  var DEFAULT_4052 = "Method Not Allowed (405). The endpoint may not exist or the base URL may be incorrect.";
@@ -52461,10 +53391,15 @@ async function extractErrorDetails2(error, options) {
52461
53391
  }
52462
53392
  if (parsedBody?.errorCode && typeof parsedBody.errorCode === "string") {
52463
53393
  context.errorCode = parsedBody.errorCode;
53394
+ } else if (parsedBody?.code && typeof parsedBody.code === "string") {
53395
+ context.errorCode = parsedBody.code;
52464
53396
  }
52465
53397
  if (parsedBody?.requestId && typeof parsedBody.requestId === "string") {
52466
53398
  context.requestId = parsedBody.requestId;
52467
53399
  }
53400
+ if (parsedBody?.traceId && typeof parsedBody.traceId === "string") {
53401
+ context.traceId = parsedBody.traceId;
53402
+ }
52468
53403
  if (status === 429) {
52469
53404
  const resp = response;
52470
53405
  const headersObj = resp?.headers;
@@ -52484,12 +53419,77 @@ async function extractErrorDetails2(error, options) {
52484
53419
  }
52485
53420
  }
52486
53421
  const hasContext = Object.keys(context).length > 0;
52487
- return { result, message, details, ...hasContext ? { context } : {} };
53422
+ let parsedErrors;
53423
+ if (parsedBody?.errors && typeof parsedBody.errors === "object") {
53424
+ const errors = {};
53425
+ for (const [field, raw] of Object.entries(parsedBody.errors)) {
53426
+ if (Array.isArray(raw)) {
53427
+ const messages = raw.map((entry) => {
53428
+ if (typeof entry === "string")
53429
+ return entry;
53430
+ if (entry && typeof entry === "object" && typeof entry.message === "string") {
53431
+ return entry.message;
53432
+ }
53433
+ return String(entry);
53434
+ }).filter(Boolean);
53435
+ if (messages.length > 0)
53436
+ errors[field] = messages;
53437
+ } else if (typeof raw === "string") {
53438
+ errors[field] = [raw];
53439
+ }
53440
+ }
53441
+ if (Object.keys(errors).length > 0)
53442
+ parsedErrors = errors;
53443
+ }
53444
+ return {
53445
+ result,
53446
+ message,
53447
+ details,
53448
+ ...hasContext ? { context } : {},
53449
+ ...parsedErrors ? { parsedErrors } : {}
53450
+ };
52488
53451
  }
52489
53452
  async function extractErrorMessage2(error, options) {
52490
53453
  const { message } = await extractErrorDetails2(error, options);
52491
53454
  return message;
52492
53455
  }
53456
+ var examplesByCommand2 = new WeakMap;
53457
+ Command.prototype.examples = function(examples) {
53458
+ examplesByCommand2.set(this, examples);
53459
+ return this;
53460
+ };
53461
+ function createStorage2() {
53462
+ const [error, mod2] = catchError22(() => __require3("node:async_hooks"));
53463
+ if (error || typeof mod2?.AsyncLocalStorage !== "function") {
53464
+ return {
53465
+ getStore: () => {
53466
+ return;
53467
+ },
53468
+ run: (_store, fn) => fn()
53469
+ };
53470
+ }
53471
+ return new mod2.AsyncLocalStorage;
53472
+ }
53473
+ var storageSingleton2 = singleton2("OutputStorage");
53474
+ var sinkSlot2 = singleton2("OutputSink");
53475
+ var outputStorage2 = storageSingleton2.getOrInit(createStorage2, (v) => ("getStore" in v));
53476
+ var CONSOLE_FALLBACK2 = {
53477
+ writeOut: (str2) => process.stdout.write(str2),
53478
+ writeErr: (str2) => process.stderr.write(str2),
53479
+ writeLog: (str2) => process.stdout.write(str2),
53480
+ capabilities: {
53481
+ isInteractive: false,
53482
+ supportsColor: false,
53483
+ outputWidth: 80
53484
+ }
53485
+ };
53486
+ function getOutputSink2() {
53487
+ return outputStorage2.getStore() ?? sinkSlot2.get() ?? CONSOLE_FALLBACK2;
53488
+ }
53489
+ var COMPLETER_SYMBOL2 = Symbol.for("@uipath/common/completer");
53490
+ var guardInstalledSlot2 = singleton2("ConsoleGuardInstalled");
53491
+ var savedOriginalsSlot2 = singleton2("ConsoleGuardOriginals");
53492
+ var DEFAULT_AUTH_TIMEOUT_MS22 = 5 * 60 * 1000;
52493
53493
  var isObject3 = (obj) => {
52494
53494
  return obj !== null && Object.prototype.toString.call(obj) === "[object Object]";
52495
53495
  };
@@ -57515,15 +58515,80 @@ class SuccessOutput2 {
57515
58515
  }
57516
58516
  }
57517
58517
  }
57518
- function printOutput2(data, format = "json", logFn) {
58518
+ function escapeNonAscii2(jsonText) {
58519
+ return jsonText.replace(/[\u0080-\uffff]/g, (c) => {
58520
+ const hex = c.charCodeAt(0).toString(16).padStart(4, "0");
58521
+ return `\\u${hex}`;
58522
+ });
58523
+ }
58524
+ function needsAsciiSafeJson2(sink) {
58525
+ return process.platform === "win32" && !sink.capabilities.isInteractive;
58526
+ }
58527
+ function isPlainRecord2(value) {
58528
+ if (value === null || typeof value !== "object")
58529
+ return false;
58530
+ const prototype = Object.getPrototypeOf(value);
58531
+ return prototype === Object.prototype || prototype === null;
58532
+ }
58533
+ function toLowerCamelCaseKey2(key) {
58534
+ if (!key)
58535
+ return key;
58536
+ if (/[_\-\s]/.test(key)) {
58537
+ const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
58538
+ if (!firstPart)
58539
+ return key;
58540
+ return [
58541
+ toLowerCamelCaseSimpleKey2(firstPart),
58542
+ ...restParts.map((part) => {
58543
+ const normalized = toLowerCamelCaseSimpleKey2(part);
58544
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
58545
+ })
58546
+ ].join("");
58547
+ }
58548
+ return toLowerCamelCaseSimpleKey2(key);
58549
+ }
58550
+ function toLowerCamelCaseSimpleKey2(key) {
58551
+ if (/^[A-Z0-9]+$/.test(key))
58552
+ return key.toLowerCase();
58553
+ return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
58554
+ }
58555
+ function toPascalCaseKey2(key) {
58556
+ const lowerCamelKey = toLowerCamelCaseKey2(key);
58557
+ return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
58558
+ }
58559
+ function toPascalCaseData2(value) {
58560
+ if (Array.isArray(value))
58561
+ return value.map(toPascalCaseData2);
58562
+ if (!isPlainRecord2(value))
58563
+ return value;
58564
+ const result = {};
58565
+ for (const [key, nestedValue] of Object.entries(value)) {
58566
+ result[toPascalCaseKey2(key)] = toPascalCaseData2(nestedValue);
58567
+ }
58568
+ return result;
58569
+ }
58570
+ function normalizeDataKeys2(data) {
58571
+ return toPascalCaseData2(data);
58572
+ }
58573
+ function normalizeOutputKeys2(data) {
58574
+ const result = {};
58575
+ for (const [key, value] of Object.entries(data)) {
58576
+ const pascalKey = toPascalCaseKey2(key);
58577
+ result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData2(value);
58578
+ }
58579
+ return result;
58580
+ }
58581
+ function printOutput2(data, format = "json", logFn, asciiSafe = false) {
57519
58582
  if (!data) {
57520
58583
  logFn("Empty response object. No data to display.");
57521
58584
  return;
57522
58585
  }
57523
58586
  switch (format) {
57524
- case "json":
57525
- logFn(JSON.stringify(data, null, 2));
58587
+ case "json": {
58588
+ const json22 = JSON.stringify(data, null, 2);
58589
+ logFn(asciiSafe ? escapeNonAscii2(json22) : json22);
57526
58590
  break;
58591
+ }
57527
58592
  case "yaml":
57528
58593
  logFn(toYaml2(data));
57529
58594
  break;
@@ -57558,7 +58623,7 @@ function printOutput2(data, format = "json", logFn) {
57558
58623
  function logOutput2(data, format = "json") {
57559
58624
  const sink = getOutputSink2();
57560
58625
  printOutput2(data, format, (msg) => sink.writeOut(`${msg}
57561
- `));
58626
+ `), needsAsciiSafeJson2(sink));
57562
58627
  }
57563
58628
  function cellToString2(val) {
57564
58629
  return val != null && typeof val === "object" ? JSON.stringify(val) : String(val ?? "");
@@ -57575,7 +58640,7 @@ function wrapText2(text, width) {
57575
58640
  function printTable2(data, logFn, externalLogValue) {
57576
58641
  if (data.length === 0)
57577
58642
  return;
57578
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
58643
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
57579
58644
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString2(item[key]).length)));
57580
58645
  const header = keys.map((key, i22) => key.padEnd(maxWidths[i22])).join(" | ");
57581
58646
  logFn(header);
@@ -57590,7 +58655,7 @@ function printTable2(data, logFn, externalLogValue) {
57590
58655
  }
57591
58656
  }
57592
58657
  function printVerticalTable2(data, logFn = console.log, externalLogValue) {
57593
- const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
58658
+ const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
57594
58659
  if (keys.length === 0)
57595
58660
  return;
57596
58661
  const maxKeyWidth = Math.max(...keys.map((key) => key.length));
@@ -57606,7 +58671,7 @@ function printVerticalTable2(data, logFn = console.log, externalLogValue) {
57606
58671
  function printResizableTable2(data, logFn = console.log, externalLogValue) {
57607
58672
  if (data.length === 0)
57608
58673
  return;
57609
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
58674
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
57610
58675
  if (keys.length === 0)
57611
58676
  return;
57612
58677
  if (!process.stdout.isTTY) {
@@ -57682,8 +58747,27 @@ function printResizableTable2(data, logFn = console.log, externalLogValue) {
57682
58747
  function toYaml2(data) {
57683
58748
  return dump2(data);
57684
58749
  }
58750
+
58751
+ class FilterEvaluationError2 extends Error {
58752
+ __brand = "FilterEvaluationError";
58753
+ filter;
58754
+ instructions;
58755
+ result = RESULTS2.ValidationError;
58756
+ constructor(filter, cause) {
58757
+ const underlying = cause instanceof Error ? cause.message : String(cause);
58758
+ super(`Filter '${filter}' failed to evaluate: ${underlying}`);
58759
+ this.name = "FilterEvaluationError";
58760
+ this.filter = filter;
58761
+ 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(@)'.";
58762
+ }
58763
+ }
57685
58764
  function applyFilter2(data, filter) {
57686
- const result = search2(data, filter);
58765
+ let result;
58766
+ try {
58767
+ result = search2(data, filter);
58768
+ } catch (err) {
58769
+ throw new FilterEvaluationError2(filter, err);
58770
+ }
57687
58771
  if (result == null)
57688
58772
  return [];
57689
58773
  if (Array.isArray(result)) {
@@ -57700,13 +58784,18 @@ function applyFilter2(data, filter) {
57700
58784
  }
57701
58785
  var OutputFormatter2;
57702
58786
  ((OutputFormatter3) => {
57703
- function success(data) {
58787
+ function success(data, options) {
57704
58788
  data.Log ??= getLogFilePath2() || undefined;
58789
+ const normalize = !options?.preserveDataKeys;
58790
+ if (normalize) {
58791
+ data.Data = normalizeDataKeys2(data.Data);
58792
+ }
57705
58793
  const filter = getOutputFilter2();
57706
58794
  if (filter) {
57707
- data.Data = applyFilter2(data.Data, filter);
58795
+ const filtered = applyFilter2(data.Data, filter);
58796
+ data.Data = normalize ? normalizeDataKeys2(filtered) : filtered;
57708
58797
  }
57709
- logOutput2(data, getOutputFormat2());
58798
+ logOutput2(normalizeOutputKeys2(data), getOutputFormat2());
57710
58799
  }
57711
58800
  OutputFormatter3.success = success;
57712
58801
  function error(data) {
@@ -57716,7 +58805,7 @@ var OutputFormatter2;
57716
58805
  result: data.Result,
57717
58806
  message: data.Message
57718
58807
  });
57719
- logOutput2(data, getOutputFormat2());
58808
+ logOutput2(normalizeOutputKeys2(data), getOutputFormat2());
57720
58809
  }
57721
58810
  OutputFormatter3.error = error;
57722
58811
  function emitList(code, items, opts) {
@@ -57737,11 +58826,14 @@ var OutputFormatter2;
57737
58826
  function log(data) {
57738
58827
  const format = getOutputFormat2();
57739
58828
  const sink = getOutputSink2();
58829
+ const normalized = toPascalCaseData2(data);
57740
58830
  if (format === "json") {
57741
- sink.writeErr(`${JSON.stringify(data)}
58831
+ const json22 = JSON.stringify(normalized);
58832
+ const safe = needsAsciiSafeJson2(sink) ? escapeNonAscii2(json22) : json22;
58833
+ sink.writeErr(`${safe}
57742
58834
  `);
57743
58835
  } else {
57744
- for (const [key, value] of Object.entries(data)) {
58836
+ for (const [key, value] of Object.entries(normalized)) {
57745
58837
  sink.writeErr(`${key}: ${value}
57746
58838
  `);
57747
58839
  }
@@ -57750,13 +58842,18 @@ var OutputFormatter2;
57750
58842
  OutputFormatter3.log = log;
57751
58843
  function formatToString(data) {
57752
58844
  const filter = getOutputFilter2();
57753
- if (filter && "Data" in data && data.Data != null) {
57754
- data.Data = applyFilter2(data.Data, filter);
58845
+ if ("Data" in data && data.Data != null) {
58846
+ data.Data = normalizeDataKeys2(data.Data);
58847
+ if (filter) {
58848
+ data.Data = normalizeDataKeys2(applyFilter2(data.Data, filter));
58849
+ }
57755
58850
  }
58851
+ const output = normalizeOutputKeys2(data);
57756
58852
  const lines = [];
57757
- printOutput2(data, getOutputFormat2(), (msg) => {
58853
+ const sink = getOutputSink2();
58854
+ printOutput2(output, getOutputFormat2(), (msg) => {
57758
58855
  lines.push(msg);
57759
- });
58856
+ }, needsAsciiSafeJson2(sink));
57760
58857
  return lines.join(`
57761
58858
  `);
57762
58859
  }
@@ -59163,6 +60260,19 @@ JSONPath2.prototype.safeVm = {
59163
60260
  Script: SafeScript2
59164
60261
  };
59165
60262
  JSONPath2.prototype.vm = vm2;
60263
+ var PollOutcome2 = {
60264
+ Completed: "completed",
60265
+ Timeout: "timeout",
60266
+ Interrupted: "interrupted",
60267
+ Aborted: "aborted",
60268
+ Failed: "failed"
60269
+ };
60270
+ var REASON_BY_OUTCOME2 = {
60271
+ [PollOutcome2.Timeout]: "poll_timeout",
60272
+ [PollOutcome2.Failed]: "poll_failed",
60273
+ [PollOutcome2.Interrupted]: "poll_failed",
60274
+ [PollOutcome2.Aborted]: "poll_aborted"
60275
+ };
59166
60276
  var TERMINAL_STATUSES2 = new Set([
59167
60277
  "completed",
59168
60278
  "successful",
@@ -59362,17 +60472,21 @@ Command.prototype.trackedAction = function(context, fn, properties) {
59362
60472
  const telemetryName = deriveCommandPath2(command);
59363
60473
  const props = typeof properties === "function" ? properties(...args) : properties;
59364
60474
  const startTime = performance.now();
59365
- let errorMessage;
60475
+ let errorMessage22;
59366
60476
  const [error] = await catchError22(fn(...args));
59367
60477
  if (error) {
59368
- errorMessage = error instanceof Error ? error.message : String(error);
59369
- logger2.error(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
60478
+ errorMessage22 = error instanceof Error ? error.message : String(error);
60479
+ logger2.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage22}`);
60480
+ const typed = error;
60481
+ const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
60482
+ const customResult = typeof typed.result === "string" && typed.result !== RESULTS2.Success && Object.values(RESULTS2).includes(typed.result) ? typed.result : undefined;
60483
+ const finalResult = customResult ?? RESULTS2.Failure;
59370
60484
  OutputFormatter2.error({
59371
- Result: RESULTS2.Failure,
59372
- Message: errorMessage,
59373
- Instructions: "An unexpected error occurred. Run with --log-level debug for details."
60485
+ Result: finalResult,
60486
+ Message: errorMessage22,
60487
+ Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
59374
60488
  });
59375
- context.exit(1);
60489
+ context.exit(EXIT_CODES2[finalResult]);
59376
60490
  }
59377
60491
  const durationMs = performance.now() - startTime;
59378
60492
  const success = !error && (process.exitCode === undefined || process.exitCode === 0);
@@ -59381,7 +60495,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
59381
60495
  ...props,
59382
60496
  duration: String(durationMs),
59383
60497
  success: String(success),
59384
- ...errorMessage ? { errorMessage } : {}
60498
+ ...errorMessage22 ? { errorMessage: errorMessage22 } : {}
59385
60499
  }));
59386
60500
  });
59387
60501
  };
@@ -59402,13 +60516,15 @@ async function readJsonFile(path32) {
59402
60516
  async function readRawJson(raw) {
59403
60517
  if (raw.status === 204)
59404
60518
  return null;
60519
+ const text = await raw.text();
60520
+ if (!text)
60521
+ return null;
59405
60522
  const contentType = raw.headers.get("content-type") ?? "";
59406
60523
  if (!contentType.toLowerCase().includes("json")) {
59407
- const body = await raw.text();
59408
- const preview = body.length > 500 ? `${body.slice(0, 500)}…` : body;
60524
+ const preview = text.length > 500 ? `${text.slice(0, 500)}…` : text;
59409
60525
  throw new Error(`Expected JSON response but got content-type '${contentType || "(none)"}' (HTTP ${raw.status}). Body: ${preview}`);
59410
60526
  }
59411
- return await raw.json();
60527
+ return JSON.parse(text);
59412
60528
  }
59413
60529
  var GET_EXAMPLES2 = [
59414
60530
  {
@@ -59426,7 +60542,7 @@ var GET_EXAMPLES2 = [
59426
60542
  ];
59427
60543
  var LIST_EXAMPLES2 = [
59428
60544
  {
59429
- Description: "List every rule that applies to a (licenseType, product, tenant) for the caller",
60545
+ Description: "List every rule that applies to a (license type, product, tenant) for the caller",
59430
60546
  Command: "uip gov aops-policy deployed-policy list Attended StudioX a1b2c3d4-0000-0000-0000-000000000100",
59431
60547
  Output: {
59432
60548
  Code: "AopsPolicyDeployedPolicyList",
@@ -59475,7 +60591,7 @@ var registerDeployedPolicyCommands = (aopsPolicy) => {
59475
60591
  ].join(`
59476
60592
  `));
59477
60593
  deployedPolicy.command("get").description([
59478
- "Return the single effective deployed policy for a (licenseType, product, tenant) subject.",
60594
+ "Return the single effective deployed policy for a (license type, product, tenant) subject.",
59479
60595
  "",
59480
60596
  "Three resolution modes:",
59481
60597
  " (default) — use the caller's own user token; resolves for the caller's own identity.",
@@ -59488,7 +60604,7 @@ var registerDeployedPolicyCommands = (aopsPolicy) => {
59488
60604
  "Output: the resolved policy's data payload, or `{ Message: 'No policy applies.' }` when the service returns 204",
59489
60605
  "(no rule matches and no default exists). Use `deployed-policy list` to see every rule, not just the effective one."
59490
60606
  ].join(`
59491
- `)).argument("<licenseType>", "License type (e.g. Attended, Unattended). Must match a name from `license-type list`.").argument("<productName>", "Product name (e.g. StudioX). Must match a name from `product list`.").argument("<tenantIdentifier>", "Tenant GUID. From `deployment tenant list`.").option("--s2s-token <token>", "Service-to-service bearer token. Overrides the user token from 'uip login' for this call only. Still requires `uip login` for base URL / org context. For security, prefer setting the UIP_S2S_TOKEN environment variable — tokens passed as CLI arguments are visible in process listings (ps aux, /proc/*/cmdline).").option("--user-id <userId>", "Resolve the effective policy for this specific user (runs the full user→group→tenant walk). Requires --s2s-token.").option("--tenant-only", "Resolve the tenant-level policy only, ignoring user/group overrides. Requires --s2s-token.").option("--login-validity <minutes>", "Override the interactive-login token lifetime. Ignored when --s2s-token is set (the S2S token lifetime is controlled by the caller).", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES2).trackedAction(processContext2, async (licenseType, productName, tenantIdentifier, options) => {
60607
+ `)).argument("<license-type>", "License type (e.g. Attended, Unattended). Must match a name from `license-type list`.").argument("<product-name>", "Product name (e.g. StudioX). Must match a name from `product list`.").argument("<tenantIdentifier>", "Tenant GUID. From `deployment tenant list`.").option("--s2s-token <token>", "Service-to-service bearer token. Overrides the user token from 'uip login' for this call only. Still requires `uip login` for base URL / org context. For security, prefer setting the UIP_S2S_TOKEN environment variable — tokens passed as CLI arguments are visible in process listings (ps aux, /proc/*/cmdline).").option("--user-id <userId>", "Resolve the effective policy for this specific user (runs the full user→group→tenant walk). Requires --s2s-token.").option("--tenant-only", "Resolve the tenant-level policy only, ignoring user/group overrides. Requires --s2s-token.").option("--login-validity <minutes>", "Override the interactive-login token lifetime. Ignored when --s2s-token is set (the S2S token lifetime is controlled by the caller).", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES2).trackedAction(processContext2, async (licenseType, productName, tenantIdentifier, options) => {
59492
60608
  const s2sToken = resolveS2sToken(options);
59493
60609
  const validationError = validateGetOptions(options, s2sToken);
59494
60610
  if (validationError) {
@@ -59501,7 +60617,7 @@ var registerDeployedPolicyCommands = (aopsPolicy) => {
59501
60617
  return;
59502
60618
  }
59503
60619
  const [error, result] = await catchError22((async () => {
59504
- const api = await createApiClient(PolicyApi, {
60620
+ const api = await createApiClient2(PolicyApi, {
59505
60621
  loginValidity: options.loginValidity,
59506
60622
  s2sToken
59507
60623
  });
@@ -59551,7 +60667,7 @@ var registerDeployedPolicyCommands = (aopsPolicy) => {
59551
60667
  });
59552
60668
  });
59553
60669
  deployedPolicy.command("list").description([
59554
- "List every rule that applies to a (licenseType, product, tenant) for the calling user.",
60670
+ "List every rule that applies to a (license type, product, tenant) for the calling user.",
59555
60671
  "",
59556
60672
  "Unlike `deployed-policy get` (which returns only the effective top-priority policy), this returns the",
59557
60673
  "full set of applicable rules in priority order — useful for understanding why a particular value wins.",
@@ -59560,9 +60676,9 @@ var registerDeployedPolicyCommands = (aopsPolicy) => {
59560
60676
  "user or use `deployed-policy get --s2s-token --user-id <id>` for the effective single policy.",
59561
60677
  "Returns an empty array when no rules apply."
59562
60678
  ].join(`
59563
- `)).argument("<licenseType>", "License type (e.g. Attended, Unattended). Must match a name from `license-type list`.").argument("<productName>", "Product name (e.g. StudioX). Must match a name from `product list`.").argument("<tenantIdentifier>", "Tenant GUID. From `deployment tenant list`.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES2).trackedAction(processContext2, async (licenseType, productName, tenantIdentifier, options) => {
60679
+ `)).argument("<license-type>", "License type (e.g. Attended, Unattended). Must match a name from `license-type list`.").argument("<product-name>", "Product name (e.g. StudioX). Must match a name from `product list`.").argument("<tenantIdentifier>", "Tenant GUID. From `deployment tenant list`.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES2).trackedAction(processContext2, async (licenseType, productName, tenantIdentifier, options) => {
59564
60680
  const [error, result] = await catchError22((async () => {
59565
- const api = await createApiClient(PolicyApi, {
60681
+ const api = await createApiClient2(PolicyApi, {
59566
60682
  loginValidity: options.loginValidity
59567
60683
  });
59568
60684
  return await api.policyGetAllRulesForProduct({
@@ -59683,7 +60799,7 @@ var registerDeploymentGroupCommands = (deployment) => {
59683
60799
  ].join(`
59684
60800
  `)).option("--limit <n>", "Page size — how many groups to return in one call. Defaults to 20.", (v) => Number.parseInt(v, 10), 20).option("--offset <n>", "Zero-based page index (NOT a row offset). Page 0 returns rows 1..limit.", (v) => Number.parseInt(v, 10), 0).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES22).trackedAction(processContext2, async (options) => {
59685
60801
  const [error, result] = await catchError22((async () => {
59686
- const api = await createApiClient(GroupApi, {
60802
+ const api = await createApiClient2(GroupApi, {
59687
60803
  loginValidity: options.loginValidity
59688
60804
  });
59689
60805
  return await api.groupGetAllGroups({
@@ -59713,7 +60829,7 @@ var registerDeploymentGroupCommands = (deployment) => {
59713
60829
  ].join(`
59714
60830
  `)).argument("<groupIdentifier>", "Group GUID. From `deployment group list` (the `identifier` field).").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES22).trackedAction(processContext2, async (groupIdentifier, options) => {
59715
60831
  const [error, result] = await catchError22((async () => {
59716
- const api = await createApiClient(PolicyApi, {
60832
+ const api = await createApiClient2(PolicyApi, {
59717
60833
  loginValidity: options.loginValidity
59718
60834
  });
59719
60835
  const response = await api.policyGetGroupPoliciesForAllProductsRaw({
@@ -59739,6 +60855,10 @@ var registerDeploymentGroupCommands = (deployment) => {
59739
60855
  group.command("configure").description([
59740
60856
  "Replace a group's per-product policy overrides with the list from a JSON file.",
59741
60857
  "",
60858
+ "If the group is not yet registered with the governance service, this command",
60859
+ "auto-registers it (via the AddGroup endpoint) in the same call. For already-",
60860
+ "registered groups it runs as a full-replace upsert (SaveGroupPolicies).",
60861
+ "",
59742
60862
  "This is a FULL replace, not a merge: products not in the input file are removed from the group's",
59743
60863
  "override list (members fall back to tenant inheritance unless a per-user override exists).",
59744
60864
  "Scope is per productIdentifier (not license-type-scoped).",
@@ -59757,7 +60877,7 @@ var registerDeploymentGroupCommands = (deployment) => {
59757
60877
  " policyIdentifier = null — pins 'No Policy' at group level (blocks tenant inheritance for members).",
59758
60878
  " policyIdentifier = GUID — pins that policy for this group + product."
59759
60879
  ].join(`
59760
- `)).argument("<groupIdentifier>", "Group GUID to configure. From `deployment group list`, or the upstream identity provider.").requiredOption("--group <group>", "Display name stored alongside the override (surfaced in audit logs / UI).").requiredOption("--input <path>", "Path to the JSON file holding the assignment array (see command description for the shape).").option("--source <source>", "Identity-provider source for the group (e.g. 'local', 'aad', 'cloud'). Defaults to 'local'. Use the value the upstream identity provider reports.", "local").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CONFIGURE_EXAMPLES).trackedAction(processContext2, async (groupIdentifier, options) => {
60880
+ `)).argument("<groupIdentifier>", "Group GUID to configure. From `deployment group list`, or the upstream identity provider.").requiredOption("--group <group>", "Display name stored alongside the override (surfaced in audit logs / UI).").requiredOption("--input <path>", "Path to the JSON file holding the assignment array (see command description for the shape).").option("--source <source>", "Identity-provider source for the group (e.g. 'local', 'aad', 'cloud'). Defaults to 'local'. Used only on the upsert path (when the group already exists in governance); on first-time registration the server resolves source from CIS.", "local").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CONFIGURE_EXAMPLES).trackedAction(processContext2, async (groupIdentifier, options) => {
59761
60881
  const [error, result] = await catchError22((async () => {
59762
60882
  const raw = await readJsonFile(options.input);
59763
60883
  const entries = parseGroupPolicyInput(raw);
@@ -59767,22 +60887,40 @@ var registerDeploymentGroupCommands = (deployment) => {
59767
60887
  groupId: groupIdentifier,
59768
60888
  groupName: options.group
59769
60889
  }));
59770
- const groupDto = {
59771
- source: options.source,
60890
+ const groupApi = await createApiClient2(GroupApi, {
60891
+ loginValidity: options.loginValidity
60892
+ });
60893
+ const existingRaw = await groupApi.groupGetGroupByIdentifierRaw({
60894
+ identifier: groupIdentifier
60895
+ });
60896
+ const existing = await readRawJson(existingRaw.raw);
60897
+ if (existing?.identifier) {
60898
+ const groupDto = {
60899
+ source: options.source,
60900
+ identifier: groupIdentifier,
60901
+ name: options.group,
60902
+ groupPolicies
60903
+ };
60904
+ const saved = await groupApi.groupSaveGroupPoliciesRaw({
60905
+ groupDto
60906
+ });
60907
+ return await readRawJson(saved.raw);
60908
+ }
60909
+ const groupToAddDto = {
59772
60910
  identifier: groupIdentifier,
59773
60911
  name: options.group,
59774
60912
  groupPolicies
59775
60913
  };
59776
- const groupApi = await createApiClient(GroupApi, {
59777
- loginValidity: options.loginValidity
60914
+ const added = await groupApi.groupAddGroupRaw({
60915
+ groupToAddDto
59778
60916
  });
59779
- return await groupApi.groupSaveGroupPolicies({ groupDto });
60917
+ return await readRawJson(added.raw);
59780
60918
  })());
59781
60919
  if (error) {
59782
60920
  OutputFormatter2.error({
59783
60921
  Result: RESULTS2.Failure,
59784
60922
  Message: await extractErrorMessage2(error),
59785
- Instructions: "Ensure the group exists, the input file is valid JSON, and you have governance admin permissions."
60923
+ Instructions: "Check that the group identifier is correct, the input file is valid JSON, and you have governance admin permissions."
59786
60924
  });
59787
60925
  processContext2.exit(1);
59788
60926
  return;
@@ -59800,10 +60938,13 @@ var registerDeploymentGroupCommands = (deployment) => {
59800
60938
  ].join(`
59801
60939
  `)).argument("<groupIdentifier>", "Group GUID to delete. From `deployment group list`.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(DELETE_EXAMPLES2).trackedAction(processContext2, async (groupIdentifier, options) => {
59802
60940
  const [error, result] = await catchError22((async () => {
59803
- const api = await createApiClient(GroupApi, {
60941
+ const api = await createApiClient2(GroupApi, {
59804
60942
  loginValidity: options.loginValidity
59805
60943
  });
59806
- return await api.groupDeleteGroup({ groupIdentifier });
60944
+ const deleted = await api.groupDeleteGroupRaw({
60945
+ groupIdentifier
60946
+ });
60947
+ return await readRawJson(deleted.raw);
59807
60948
  })());
59808
60949
  if (error) {
59809
60950
  OutputFormatter2.error({
@@ -59846,7 +60987,7 @@ var LIST_EXAMPLES3 = [
59846
60987
  ];
59847
60988
  var GET_EXAMPLES3 = [
59848
60989
  {
59849
- Description: "Fetch a tenant's full set of (product, licenseType, policy) assignments",
60990
+ Description: "Fetch a tenant's full set of (product, license type, policy) assignments",
59850
60991
  Command: "uip gov aops-policy deployment tenant get a1b2c3d4-0000-0000-0000-000000000100",
59851
60992
  Output: {
59852
60993
  Code: "AopsPolicyDeploymentTenantGet",
@@ -59937,18 +61078,23 @@ var registerDeploymentTenantCommands = (deployment) => {
59937
61078
  `));
59938
61079
  tenant.command("list").description([
59939
61080
  "List tenants registered in the governance system along with their current policy assignments.",
61081
+ "",
61082
+ "Triggers an upstream sync from OMS before returning, so the page reflects the latest",
61083
+ "tenant catalog (new tenants, disabled/re-enabled state) — not just governance's local cache.",
59940
61084
  "Each entry includes the `tenantIdentifier` needed by `deployment tenant get/configure/remove`",
59941
61085
  "and by `deployed-policy get/list`. Results are paginated."
59942
61086
  ].join(`
59943
- `)).option("--product-name <productName>", "Return only tenants that have an assignment for this product (e.g. StudioX). Matches `product list` names.").option("--limit <n>", "Page size — how many tenants to return in one call. Defaults to 20.", (v) => Number.parseInt(v, 10), 20).option("--offset <n>", "Zero-based page index (NOT a row offset). Page 0 returns rows 1..limit.", (v) => Number.parseInt(v, 10), 0).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES3).trackedAction(processContext2, async (options) => {
61087
+ `)).option("--product-name <product-name>", "Return only tenants that have an assignment for this product (e.g. StudioX). Matches `product list` names.").option("--limit <n>", "Page size — how many tenants to return in one call. Defaults to 20.", (v) => Number.parseInt(v, 10), 20).option("--offset <n>", "Zero-based page index (NOT a row offset). Page 0 returns rows 1..limit.", (v) => Number.parseInt(v, 10), 0).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES3).trackedAction(processContext2, async (options) => {
59944
61088
  const [error, result] = await catchError22((async () => {
59945
- const api = await createApiClient(TenantApi, {
61089
+ const api = await createApiClient2(TenantApi, {
59946
61090
  loginValidity: options.loginValidity
59947
61091
  });
59948
- return await api.tenantGetAllTenants({
59949
- pageIndex: options.offset,
59950
- pageSize: options.limit,
59951
- productName: options.productName
61092
+ return await api.tenantSyncAndGetAllTenants({
61093
+ governanceQueryOptions: {
61094
+ pageIndex: options.offset,
61095
+ pageSize: options.limit,
61096
+ productName: options.productName
61097
+ }
59952
61098
  });
59953
61099
  })());
59954
61100
  if (error) {
@@ -59972,10 +61118,13 @@ var registerDeploymentTenantCommands = (deployment) => {
59972
61118
  ].join(`
59973
61119
  `)).argument("<tenantIdentifier>", "Tenant GUID. Obtain from `deployment tenant list` (the `identifier` field).").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES3).trackedAction(processContext2, async (tenantIdentifier, options) => {
59974
61120
  const [error, result] = await catchError22((async () => {
59975
- const api = await createApiClient(TenantApi, {
61121
+ const api = await createApiClient2(TenantApi, {
59976
61122
  loginValidity: options.loginValidity
59977
61123
  });
59978
- return await api.tenantGetTenantById({ tenantIdentifier });
61124
+ const fetched = await api.tenantGetTenantByIdRaw({
61125
+ tenantIdentifier
61126
+ });
61127
+ return await readRawJson(fetched.raw);
59979
61128
  })());
59980
61129
  if (error) {
59981
61130
  OutputFormatter2.error({
@@ -59993,7 +61142,10 @@ var registerDeploymentTenantCommands = (deployment) => {
59993
61142
  });
59994
61143
  });
59995
61144
  tenant.command("configure").description([
59996
- "Replace a tenant's per-(product, licenseType) policy assignments with the list from a JSON file.",
61145
+ "Replace a tenant's per-(product, license type) policy assignments with the list from a JSON file.",
61146
+ "",
61147
+ "Triggers an upstream sync from OMS before saving, so a freshly-created tenant (or a tenant",
61148
+ "whose status changed) is reconciled into governance before assignments are persisted.",
59997
61149
  "",
59998
61150
  "This is a FULL replace, not a merge: entries not in the input file are removed from the tenant.",
59999
61151
  "To preserve existing assignments while adding new ones, start from `deployment tenant get` output.",
@@ -60009,9 +61161,9 @@ var registerDeploymentTenantCommands = (deployment) => {
60009
61161
  " ]",
60010
61162
  "",
60011
61163
  "Semantics:",
60012
- " Omit an (product, licenseType) entry entirely — inherits (nothing pinned at tenant level).",
61164
+ " Omit a (product, license type) entry entirely — inherits (nothing pinned at tenant level).",
60013
61165
  " Set policyIdentifier to null — pins 'No Policy' at tenant level (blocks inheritance).",
60014
- " Set policyIdentifier to a GUID — pins that policy for this (product, licenseType)."
61166
+ " Set policyIdentifier to a GUID — pins that policy for this (product, license type)."
60015
61167
  ].join(`
60016
61168
  `)).argument("<tenantIdentifier>", "Tenant GUID to configure. From `deployment tenant list`.").requiredOption("--tenant-name <tenantName>", "Tenant display name. Must match the tenant's name in the governance service (from `tenant get`/`tenant list`).").requiredOption("--input <path>", "Path to the JSON file holding the assignment array (see command description for the shape).").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CONFIGURE_EXAMPLES2).trackedAction(processContext2, async (tenantIdentifier, options) => {
60017
61169
  const [error, result] = await catchError22((async () => {
@@ -60024,12 +61176,14 @@ var registerDeploymentTenantCommands = (deployment) => {
60024
61176
  productIdentifier: entry.productIdentifier,
60025
61177
  licenseTypeIdentifier: entry.licenseTypeIdentifier
60026
61178
  }));
60027
- const tenantApi = await createApiClient(TenantApi, {
61179
+ const tenantApi = await createApiClient2(TenantApi, {
60028
61180
  loginValidity: options.loginValidity
60029
61181
  });
60030
- return await tenantApi.tenantSaveTenantPolicies({
61182
+ await tenantApi.tenantSyncAndGetAllTenants({});
61183
+ const saved = await tenantApi.tenantSaveTenantPoliciesRaw({
60031
61184
  tenantPolicyDto
60032
61185
  });
61186
+ return await readRawJson(saved.raw);
60033
61187
  })());
60034
61188
  if (error) {
60035
61189
  OutputFormatter2.error({
@@ -60049,6 +61203,9 @@ var registerDeploymentTenantCommands = (deployment) => {
60049
61203
  tenant.command("remove").description([
60050
61204
  "Remove a tenant's policy assignment(s) for a product without rewriting the full list yourself.",
60051
61205
  "",
61206
+ "Triggers an upstream sync from OMS before reading, so the read-modify-write sees the latest",
61207
+ "tenant state.",
61208
+ "",
60052
61209
  "The command reads the tenant's current assignments, drops entries matching --product-name",
60053
61210
  "(and --license-type if supplied), then re-saves the filtered list via `tenant configure`.",
60054
61211
  "Fails fast with 'No matching policy assignment to remove' if nothing matches.",
@@ -60059,14 +61216,19 @@ var registerDeploymentTenantCommands = (deployment) => {
60059
61216
  "",
60060
61217
  "Output includes both the removed entries and the new tenantPolicies snapshot so you can audit the change."
60061
61218
  ].join(`
60062
- `)).argument("<tenantIdentifier>", "Tenant GUID. From `deployment tenant list`.").requiredOption("--product-name <productName>", "Product to unpin (e.g. StudioX). Matches the `productIdentifier` field on the tenant's saved entries.").option("--license-type <licenseType>", "Narrow the removal to one license type. Omit to remove every license-type entry for the product.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(REMOVE_EXAMPLES).trackedAction(processContext2, async (tenantIdentifier, options) => {
61219
+ `)).argument("<tenantIdentifier>", "Tenant GUID. From `deployment tenant list`.").requiredOption("--product-name <product-name>", "Product to unpin (e.g. StudioX). Matches the `productIdentifier` field on the tenant's saved entries.").option("--license-type <license-type>", "Narrow the removal to one license type. Omit to remove every license-type entry for the product.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(REMOVE_EXAMPLES).trackedAction(processContext2, async (tenantIdentifier, options) => {
60063
61220
  const [error, result] = await catchError22((async () => {
60064
- const tenantApi = await createApiClient(TenantApi, {
61221
+ const tenantApi = await createApiClient2(TenantApi, {
60065
61222
  loginValidity: options.loginValidity
60066
61223
  });
60067
- const current = await tenantApi.tenantGetTenantById({
61224
+ await tenantApi.tenantSyncAndGetAllTenants({});
61225
+ const currentRaw = await tenantApi.tenantGetTenantByIdRaw({
60068
61226
  tenantIdentifier
60069
61227
  });
61228
+ const current = await readRawJson(currentRaw.raw);
61229
+ if (!current) {
61230
+ throw new Error(`Tenant '${tenantIdentifier}' not found in governance.`);
61231
+ }
60070
61232
  const existing = current.tenantPolicies ?? [];
60071
61233
  const removed = [];
60072
61234
  const kept = [];
@@ -60082,9 +61244,10 @@ var registerDeploymentTenantCommands = (deployment) => {
60082
61244
  if (removed.length === 0) {
60083
61245
  throw new Error("No matching policy assignment to remove.");
60084
61246
  }
60085
- const saved = await tenantApi.tenantSaveTenantPolicies({
61247
+ const savedRaw = await tenantApi.tenantSaveTenantPoliciesRaw({
60086
61248
  tenantPolicyDto: kept
60087
61249
  });
61250
+ const saved = await readRawJson(savedRaw.raw);
60088
61251
  return { removed, tenantPolicies: saved };
60089
61252
  })());
60090
61253
  if (error) {
@@ -60195,7 +61358,7 @@ var registerDeploymentUserCommands = (deployment) => {
60195
61358
  const user = deployment.command("user").description([
60196
61359
  "Override tenant-level policy assignments for an individual user.",
60197
61360
  "User assignments win over group and tenant at resolution time. Scope is per productIdentifier",
60198
- "(unlike tenant, which is per (product, licenseType))."
61361
+ "(unlike tenant, which is per (product, license type))."
60199
61362
  ].join(`
60200
61363
  `));
60201
61364
  user.command("list").description([
@@ -60205,7 +61368,7 @@ var registerDeploymentUserCommands = (deployment) => {
60205
61368
  ].join(`
60206
61369
  `)).option("--limit <n>", "Page size — how many users to return in one call. Defaults to 20.", (v) => Number.parseInt(v, 10), 20).option("--offset <n>", "Zero-based page index (NOT a row offset). Page 0 returns rows 1..limit.", (v) => Number.parseInt(v, 10), 0).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES4).trackedAction(processContext2, async (options) => {
60207
61370
  const [error, result] = await catchError22((async () => {
60208
- const api = await createApiClient(UserApi, {
61371
+ const api = await createApiClient2(UserApi, {
60209
61372
  loginValidity: options.loginValidity
60210
61373
  });
60211
61374
  return await api.userGetAllUsers({
@@ -60236,7 +61399,7 @@ var registerDeploymentUserCommands = (deployment) => {
60236
61399
  ].join(`
60237
61400
  `)).argument("<userIdentifier>", "User GUID. From `deployment user list` (the `identifier` field).").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES4).trackedAction(processContext2, async (userIdentifier, options) => {
60238
61401
  const [error, result] = await catchError22((async () => {
60239
- const api = await createApiClient(PolicyApi, {
61402
+ const api = await createApiClient2(PolicyApi, {
60240
61403
  loginValidity: options.loginValidity
60241
61404
  });
60242
61405
  const response = await api.policyGetUserPoliciesForAllProductsRaw({
@@ -60262,9 +61425,13 @@ var registerDeploymentUserCommands = (deployment) => {
60262
61425
  user.command("configure").description([
60263
61426
  "Replace a user's per-product policy overrides with the list from a JSON file.",
60264
61427
  "",
61428
+ "If the user is not yet registered with the governance service, this command",
61429
+ "auto-registers them (via the AddUser endpoint) in the same call. For already-",
61430
+ "registered users it runs as a full-replace upsert (SaveUserPolicies).",
61431
+ "",
60265
61432
  "This is a FULL replace, not a merge: products not in the input file are removed from the user's",
60266
61433
  "override list (they will fall back to group/tenant inheritance). Scope is per productIdentifier —",
60267
- "user overrides are not license-type-scoped (unlike tenant assignments).",
61434
+ "user overrides are not license-type scoped (unlike tenant assignments).",
60268
61435
  "",
60269
61436
  "Input file shape (JSON array):",
60270
61437
  " [",
@@ -60280,7 +61447,7 @@ var registerDeploymentUserCommands = (deployment) => {
60280
61447
  " policyIdentifier = null — pins 'No Policy' at user level (blocks group/tenant inheritance).",
60281
61448
  " policyIdentifier = GUID — pins that policy for this user + product."
60282
61449
  ].join(`
60283
- `)).argument("<userIdentifier>", "User GUID to configure. From `deployment user list`, or the upstream identity provider.").requiredOption("--user <user>", "Display name stored alongside the override (surfaced in audit logs / UI).").requiredOption("--input <path>", "Path to the JSON file holding the assignment array (see command description for the shape).").option("--source <source>", "Identity-provider source for the user (e.g. 'local', 'aad', 'cloud'). Defaults to 'local'. Use the value the upstream identity provider reports.", "local").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CONFIGURE_EXAMPLES3).trackedAction(processContext2, async (userIdentifier, options) => {
61450
+ `)).argument("<userIdentifier>", "User GUID to configure. From `deployment user list`, or the upstream identity provider.").requiredOption("--user <user>", "Display name stored alongside the override (surfaced in audit logs / UI).").requiredOption("--input <path>", "Path to the JSON file holding the assignment array (see command description for the shape).").option("--source <source>", "Identity-provider source for the user (e.g. 'local', 'aad', 'cloud'). Defaults to 'local'. Used only on the upsert path (when the user already exists in governance); on first-time registration the server resolves source from CIS.", "local").option("--email <email>", "Email used only when registering a brand-new user with the governance service. Ignored once the user is already known to governance. Defaults to --user when omitted.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CONFIGURE_EXAMPLES3).trackedAction(processContext2, async (userIdentifier, options) => {
60284
61451
  const [error, result] = await catchError22((async () => {
60285
61452
  const raw = await readJsonFile(options.input);
60286
61453
  const entries = parseUserPolicyInput(raw);
@@ -60290,22 +61457,40 @@ var registerDeploymentUserCommands = (deployment) => {
60290
61457
  userId: userIdentifier,
60291
61458
  userName: options.user
60292
61459
  }));
60293
- const userDto = {
60294
- source: options.source,
61460
+ const userApi = await createApiClient2(UserApi, {
61461
+ loginValidity: options.loginValidity
61462
+ });
61463
+ const existingRaw = await userApi.userGetUserByIdentifierRaw({
61464
+ identifier: userIdentifier
61465
+ });
61466
+ const existing = await readRawJson(existingRaw.raw);
61467
+ if (existing?.identifier) {
61468
+ const userDto = {
61469
+ source: options.source,
61470
+ identifier: userIdentifier,
61471
+ name: options.user,
61472
+ userPolicies
61473
+ };
61474
+ const saved = await userApi.userSaveUserPoliciesRaw({
61475
+ userDto
61476
+ });
61477
+ return await readRawJson(saved.raw);
61478
+ }
61479
+ const userToAddDto = {
60295
61480
  identifier: userIdentifier,
60296
- name: options.user,
61481
+ email: options.email ?? options.user,
60297
61482
  userPolicies
60298
61483
  };
60299
- const userApi = await createApiClient(UserApi, {
60300
- loginValidity: options.loginValidity
61484
+ const added = await userApi.userAddUserRaw({
61485
+ userToAddDto
60301
61486
  });
60302
- return await userApi.userSaveUserPolicies({ userDto });
61487
+ return await readRawJson(added.raw);
60303
61488
  })());
60304
61489
  if (error) {
60305
61490
  OutputFormatter2.error({
60306
61491
  Result: RESULTS2.Failure,
60307
61492
  Message: await extractErrorMessage2(error),
60308
- Instructions: "Ensure the user exists, the input file is valid JSON, and you have governance admin permissions."
61493
+ Instructions: "Check that the user identifier is correct, the input file is valid JSON, and you have governance admin permissions."
60309
61494
  });
60310
61495
  processContext2.exit(1);
60311
61496
  return;
@@ -60323,12 +61508,13 @@ var registerDeploymentUserCommands = (deployment) => {
60323
61508
  ].join(`
60324
61509
  `)).argument("<userIdentifier>", "User GUID whose overrides should be cleared. From `deployment user list`.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(DELETE_EXAMPLES22).trackedAction(processContext2, async (userIdentifier, options) => {
60325
61510
  const [error, result] = await catchError22((async () => {
60326
- const api = await createApiClient(UserApi, {
61511
+ const api = await createApiClient2(UserApi, {
60327
61512
  loginValidity: options.loginValidity
60328
61513
  });
60329
- return await api.userDeleteUserPolicies({
61514
+ const deleted = await api.userDeleteUserPoliciesRaw({
60330
61515
  userIdentifier
60331
61516
  });
61517
+ return await readRawJson(deleted.raw);
60332
61518
  })());
60333
61519
  if (error) {
60334
61520
  OutputFormatter2.error({
@@ -60351,7 +61537,7 @@ var registerDeploymentCommands = (aopsPolicy) => {
60351
61537
  "Assign, remove, and inspect policy deployments on governance subjects (tenants, users, groups).",
60352
61538
  "",
60353
61539
  "Resolution order at runtime is user → group → tenant (user beats group beats tenant). A subject with no",
60354
- "explicit assignment for a (product, licenseType) inherits from the next level up; use `null` as the",
61540
+ "explicit assignment for a (product, license type) inherits from the next level up; use `null` as the",
60355
61541
  "policyIdentifier in a configure input to explicitly pin 'No Policy' and short-circuit inheritance.",
60356
61542
  "",
60357
61543
  "Subcommand groups:",
@@ -60389,17 +61575,17 @@ var registerLicenseTypeCommands = (aopsPolicy) => {
60389
61575
  const licenseType = aopsPolicy.command("license-type").description([
60390
61576
  "Inspect the catalog of license types recognized by the governance service.",
60391
61577
  "License types (e.g. Attended, Unattended) are read-only — used to scope `deployment tenant configure` entries",
60392
- "and as the `<licenseType>` argument to `deployed-policy get/list`."
61578
+ "and as the `<license-type>` argument to `deployed-policy get/list`."
60393
61579
  ].join(`
60394
61580
  `));
60395
61581
  licenseType.command("list").description([
60396
61582
  "List every license type known to the governance service.",
60397
- "The `identifier` field feeds `deployment tenant configure` entries (one policy per (product, licenseType) pair);",
60398
- "the display name is what `deployed-policy get/list` accept as the `<licenseType>` argument."
61583
+ "The `identifier` field feeds `deployment tenant configure` entries (one policy per (product, license type) pair);",
61584
+ "the display name is what `deployed-policy get/list` accept as the `<license-type>` argument."
60399
61585
  ].join(`
60400
61586
  `)).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES5).trackedAction(processContext2, async (options) => {
60401
61587
  const [error, result] = await catchError22((async () => {
60402
- const api = await createApiClient(LicenseTypeApi, {
61588
+ const api = await createApiClient2(LicenseTypeApi, {
60403
61589
  loginValidity: options.loginValidity
60404
61590
  });
60405
61591
  return await api.licenseTypeGetAllLicenseTypes();
@@ -60470,7 +61656,7 @@ var registerProductCommands = (aopsPolicy) => {
60470
61656
  ].join(`
60471
61657
  `)).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES6).trackedAction(processContext2, async (options) => {
60472
61658
  const [error, result] = await catchError22((async () => {
60473
- const api = await createApiClient(ProductApi, {
61659
+ const api = await createApiClient2(ProductApi, {
60474
61660
  loginValidity: options.loginValidity
60475
61661
  });
60476
61662
  return await api.productGetAllProducts();
@@ -60492,7 +61678,7 @@ var registerProductCommands = (aopsPolicy) => {
60492
61678
  });
60493
61679
  product.command("get").description("Fetch a single product record (name, label, identifier, flags). Use to verify a name is valid before calling `policy create` or `template get`.").argument("<productIdentifier>", "Product name (e.g. StudioX) or GUID. Either the `name` or the `identifier` from `product list` is accepted.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES5).trackedAction(processContext2, async (productIdentifier, options) => {
60494
61680
  const [error, result] = await catchError22((async () => {
60495
- const api = await createApiClient(ProductApi, {
61681
+ const api = await createApiClient2(ProductApi, {
60496
61682
  loginValidity: options.loginValidity
60497
61683
  });
60498
61684
  return await api.productGetProductByName({
@@ -62747,7 +63933,7 @@ var registerTemplateCommands = (aopsPolicy) => {
62747
63933
  `));
62748
63934
  template.command("get").description("Fetch the active Form.io policy template for one product and emit policy artifacts. " + "Pass --output-form-data to write the fillable blueprint (the object you fill in and submit back on create/update); display-only components (hidden, button, submit, HTML, content) are skipped and missing leaves get type-appropriate defaults (false for checkbox, [] for editgrid, {} for selectboxes, null for text/select). " + "Pass --output-template-locale-resource to write a human-readable reference derived from the DTO: every product-scoped locale key is replaced with its English string (with a sibling `<prop>-key` preserving the original for traceability) and `defaultData.data` is replaced with a flat annotated map ({ value, type, label, description?, tooltip? }); cross-product prefixes (e.g. `AutomationOps.submit`) are left unresolved. " + "If neither --output flag is passed, the template and form-data are returned in the stdout Success payload (`Data.template` and `Data.formData`) for piping/scripting.").argument("<productIdentifier>", "Product name or identifier (e.g. StudioX, AITrustLayer). Use 'uip gov aops-policy product list' to list options.").option("--output-form-data <path>", "Write the fillable form-data blueprint JSON (the object you edit and submit back).").option("--output-template-locale-resource <path>", "Write the locale-resolved template reference JSON (open this to understand every field, option label, description, tooltip, and validation message).").option("--login-validity <minutes>", "Login token validity in minutes", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES6).trackedAction(processContext2, async (productIdentifier, options) => {
62749
63935
  const [templateError, dto] = await catchError22((async () => {
62750
- const api = await createApiClient(ContentApi, {
63936
+ const api = await createApiClient2(ContentApi, {
62751
63937
  loginValidity: options.loginValidity
62752
63938
  });
62753
63939
  return await api.contentGetFormioTemplatesByProductIdentifier({ productIdentifier });
@@ -62806,7 +63992,7 @@ var registerTemplateCommands = (aopsPolicy) => {
62806
63992
  });
62807
63993
  template.command("list").description("Fetch every product's active Form.io template and dump a full artifact set per product. " + "For each product, writes three files under <output-dir>/<ProductName>/: " + "`form-template.json` (the raw DTO returned by the governance API, for debugging/reference); " + "`form-data.json` (the fillable blueprint — edit this and submit to create/update a policy); " + "`form-template-locale-resource.json` (the locale-resolved reference — open this first to understand each field, its options, and its validation rules before filling `form-data.json`; see `template get --help` for the file's shape). " + "Per-product fetch failures are collected and do not abort the run; the command exits 1 only if every product fails. Use this instead of looping `template get` to dump all products in one pass.").requiredOption("--output-dir <path>", "Directory under which <ProductName>/ folders (containing the three artifacts) will be created.").option("--login-validity <minutes>", "Login token validity in minutes", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES7).trackedAction(processContext2, async (options) => {
62808
63994
  const [productsError, products] = await catchError22((async () => {
62809
- const api = await createApiClient(ProductApi, {
63995
+ const api = await createApiClient2(ProductApi, {
62810
63996
  loginValidity: options.loginValidity
62811
63997
  });
62812
63998
  return await api.productGetAllProducts();
@@ -62823,7 +64009,7 @@ var registerTemplateCommands = (aopsPolicy) => {
62823
64009
  const locale = en_US_default;
62824
64010
  const fs72 = getFileSystem2();
62825
64011
  const outputDir = fs72.path.resolve(options.outputDir);
62826
- const contentApi = await createApiClient(ContentApi, {
64012
+ const contentApi = await createApiClient2(ContentApi, {
62827
64013
  loginValidity: options.loginValidity
62828
64014
  });
62829
64015
  const productList = Array.isArray(products) ? products : [];
@@ -62979,7 +64165,7 @@ var registerAopsPolicyCommand = (program2) => {
62979
64165
  " license-type — list license types (feeds deployment entries).",
62980
64166
  " template — fetch Form.io templates and emit the form-data blueprint you pass to create/update.",
62981
64167
  " deployment — assign policies to tenants/users/groups.",
62982
- " deployed-policy — resolve the effective policy for a (licenseType, product, tenant) subject.",
64168
+ " deployed-policy — resolve the effective policy for a (license type, product, tenant) subject.",
62983
64169
  "",
62984
64170
  "Typical flow: `template get <product>` → edit the emitted form-data.json →",
62985
64171
  "`policy create --product-name <product> --name <name> --input form-data.json` →",
@@ -62997,24 +64183,24 @@ var registerAopsPolicyCommand = (program2) => {
62997
64183
  "Use the returned `identifier` with `policy get`, `policy update`, `policy delete`, or with",
62998
64184
  "`deployment tenant|user|group configure` to assign the policy."
62999
64185
  ].join(`
63000
- `)).option("--product-name <productName>", "Restrict results to one product (e.g. StudioX). Matches `product.name` — use `product list` to see available names.").option("--product-label <productLabel>", "Restrict results to one product by its display label (e.g. 'Studio X'). Prefer --product-name for scripting.").option("--search <searchTerm>", "Case-insensitive substring match against policy name/description.").option("--order-by <field>", "Field to sort by (e.g. name, createdOn, priority). Passed through to the governance API.").option("--order-direction <direction>", "Sort direction for --order-by: 'asc' (ascending) or 'desc' (descending). Case-insensitive.").option("--limit <n>", "Page size — how many policies to return in one call. Defaults to 20.", (v) => Number.parseInt(v, 10), 20).option("--offset <n>", "Zero-based page index (NOT a row offset). Page 0 returns rows 1..limit, page 1 returns limit+1..2*limit, etc.", (v) => Number.parseInt(v, 10), 0).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES8).trackedAction(processContext2, async (options) => {
64186
+ `)).option("--product-name <product-name>", "Restrict results to one product (e.g. StudioX). Matches `product.name` — use `product list` to see available names.").option("--product-label <productLabel>", "Restrict results to one product by its display label (e.g. 'Studio X'). Prefer --product-name for scripting.").option("--search <searchTerm>", "Case-insensitive substring match against policy name/description.").option("--sort-by <field>", "Field to sort by (e.g. name, createdOn, priority). Passed through to the governance API.").option("--sort-order <direction>", "Sort direction for --sort-by: 'asc' (ascending) or 'desc' (descending). Case-insensitive.").option("--limit <n>", "Page size — how many policies to return in one call. Defaults to 20.", (v) => Number.parseInt(v, 10), 20).option("--offset <n>", "Zero-based page index (NOT a row offset). Page 0 returns rows 1..limit, page 1 returns limit+1..2*limit, etc.", (v) => Number.parseInt(v, 10), 0).option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(LIST_EXAMPLES8).trackedAction(processContext2, async (options) => {
63001
64187
  const [error, result] = await catchError22((async () => {
63002
64188
  let sortOrder;
63003
- if (options.orderDirection) {
63004
- const direction = options.orderDirection.toLowerCase();
64189
+ if (options.sortOrder) {
64190
+ const direction = options.sortOrder.toLowerCase();
63005
64191
  if (direction !== "asc" && direction !== "desc") {
63006
- throw new Error(`Invalid --order-direction '${options.orderDirection}'. Use 'asc' or 'desc'.`);
64192
+ throw new Error(`Invalid --sort-order '${options.sortOrder}'. Use 'asc' or 'desc'.`);
63007
64193
  }
63008
64194
  sortOrder = direction === "asc" ? SortOrder.NUMBER_0 : SortOrder.NUMBER_1;
63009
64195
  }
63010
- const api = await createApiClient(PolicyApi, {
64196
+ const api = await createApiClient2(PolicyApi, {
63011
64197
  loginValidity: options.loginValidity
63012
64198
  });
63013
64199
  return await api.policyGetAllPoliciesByQueryOptions({
63014
64200
  productName: options.productName,
63015
64201
  productLabel: options.productLabel,
63016
64202
  searchTerm: options.search,
63017
- sortBy: options.orderBy,
64203
+ sortBy: options.sortBy,
63018
64204
  sortOrder,
63019
64205
  pageIndex: options.offset,
63020
64206
  pageSize: options.limit
@@ -63042,7 +64228,7 @@ var registerAopsPolicyCommand = (program2) => {
63042
64228
  ].join(`
63043
64229
  `)).argument("<policyIdentifier>", "Policy GUID. Obtain from `policy list` (the `identifier` field of each returned policy).").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(GET_EXAMPLES7).trackedAction(processContext2, async (policyIdentifier, options) => {
63044
64230
  const [error, result] = await catchError22((async () => {
63045
- const api = await createApiClient(PolicyApi, {
64231
+ const api = await createApiClient2(PolicyApi, {
63046
64232
  loginValidity: options.loginValidity
63047
64233
  });
63048
64234
  return await api.policyGetPolicyById({ policyIdentifier });
@@ -63072,7 +64258,7 @@ var registerAopsPolicyCommand = (program2) => {
63072
64258
  "After creation, the new policy's identifier can be passed to `deployment tenant|user|group configure`",
63073
64259
  "to assign it to a subject."
63074
64260
  ].join(`
63075
- `)).requiredOption("--name <name>", "Human-readable policy name (must be unique within the product).").requiredOption("--product-name <productName>", "Target product (e.g. StudioX, AITrustLayer). Must match a name from `product list`.").option("--description <description>", "Optional free-text description surfaced in the governance UI.").option("--priority <n>", "Integer priority. When multiple policies apply to the same subject, higher numbers win.", (v) => Number.parseInt(v, 10)).option("--availability <n>", "Availability flag (product-specific enum). Check the governance UI or service docs for valid values.", (v) => Number.parseInt(v, 10)).option("--input <path>", "Path to a JSON file with the filled form-data object (produced by `template get --output-form-data`). Omit for a policy with no data payload.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CREATE_EXAMPLES2).trackedAction(processContext2, async (options) => {
64261
+ `)).requiredOption("--name <name>", "Human-readable policy name (must be unique within the product).").requiredOption("--product-name <product-name>", "Target product (e.g. StudioX, AITrustLayer). Must match a name from `product list`.").option("--description <description>", "Optional free-text description surfaced in the governance UI.").option("--priority <n>", "Integer priority. When multiple policies apply to the same subject, higher numbers win.", (v) => Number.parseInt(v, 10)).option("--availability <n>", "Availability flag (product-specific enum). Check the governance UI or service docs for valid values.", (v) => Number.parseInt(v, 10)).option("--input <path>", "Path to a JSON file with the filled form-data object (produced by `template get --output-form-data`). Omit for a policy with no data payload.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(CREATE_EXAMPLES2).trackedAction(processContext2, async (options) => {
63076
64262
  const [error, result] = await catchError22((async () => {
63077
64263
  const data = await readPolicyDataFile(options.input);
63078
64264
  const createPolicyRequest = {
@@ -63083,7 +64269,7 @@ var registerAopsPolicyCommand = (program2) => {
63083
64269
  availability: options.availability,
63084
64270
  data
63085
64271
  };
63086
- const api = await createApiClient(PolicyApi, {
64272
+ const api = await createApiClient2(PolicyApi, {
63087
64273
  loginValidity: options.loginValidity
63088
64274
  });
63089
64275
  return await api.policyCreatePolicyV2({
@@ -63115,7 +64301,7 @@ var registerAopsPolicyCommand = (program2) => {
63115
64301
  "Fails with a 'template upgrade in progress' error if the underlying Form.io template is being migrated;",
63116
64302
  "retry once the upgrade completes."
63117
64303
  ].join(`
63118
- `)).requiredOption("--identifier <identifier>", "Policy GUID to update. From `policy list` or `policy get`.").requiredOption("--name <name>", "Policy name. Required on every update — passing the existing name preserves it.").requiredOption("--product-name <productName>", "Target product. Must match the policy's existing product (changing product on update is not supported).").option("--description <description>", "Free-text description. Full-replace: omitting this flag clears the description — re-pass the existing value from `policy get` to preserve it.").option("--priority <n>", "Integer priority. Full-replace: omitting this flag clears priority on the server — re-pass the existing value from `policy get` to preserve it.", (v) => Number.parseInt(v, 10)).option("--availability <n>", "Availability flag. Full-replace: omitting this flag clears availability — re-pass the existing value from `policy get` to preserve it.", (v) => Number.parseInt(v, 10)).option("--input <path>", "Path to a JSON file with the updated form-data object. Full-replace: omitting this flag clears the data payload — re-pass the existing data (save `policy get` output to a file) to preserve it.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(UPDATE_EXAMPLES2).trackedAction(processContext2, async (options) => {
64304
+ `)).requiredOption("--identifier <identifier>", "Policy GUID to update. From `policy list` or `policy get`.").requiredOption("--name <name>", "Policy name. Required on every update — passing the existing name preserves it.").requiredOption("--product-name <product-name>", "Target product. Must match the policy's existing product (changing product on update is not supported).").option("--description <description>", "Free-text description. Full-replace: omitting this flag clears the description — re-pass the existing value from `policy get` to preserve it.").option("--priority <n>", "Integer priority. Full-replace: omitting this flag clears priority on the server — re-pass the existing value from `policy get` to preserve it.", (v) => Number.parseInt(v, 10)).option("--availability <n>", "Availability flag. Full-replace: omitting this flag clears availability — re-pass the existing value from `policy get` to preserve it.", (v) => Number.parseInt(v, 10)).option("--input <path>", "Path to a JSON file with the updated form-data object. Full-replace: omitting this flag clears the data payload — re-pass the existing data (save `policy get` output to a file) to preserve it.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(UPDATE_EXAMPLES2).trackedAction(processContext2, async (options) => {
63119
64305
  const [error, result] = await catchError22((async () => {
63120
64306
  const data = await readPolicyDataFile(options.input);
63121
64307
  const updatePolicyRequest = {
@@ -63127,7 +64313,7 @@ var registerAopsPolicyCommand = (program2) => {
63127
64313
  availability: options.availability,
63128
64314
  data
63129
64315
  };
63130
- const api = await createApiClient(PolicyApi, {
64316
+ const api = await createApiClient2(PolicyApi, {
63131
64317
  loginValidity: options.loginValidity
63132
64318
  });
63133
64319
  return await api.policyUpdatePolicyV2({
@@ -63158,7 +64344,7 @@ var registerAopsPolicyCommand = (program2) => {
63158
64344
  ].join(`
63159
64345
  `)).argument("<policyIdentifier>", "Policy GUID to delete. From `policy list`.").option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10)).examples(DELETE_EXAMPLES3).trackedAction(processContext2, async (policyIdentifier, options) => {
63160
64346
  const [error, result] = await catchError22((async () => {
63161
- const api = await createApiClient(PolicyApi, {
64347
+ const api = await createApiClient2(PolicyApi, {
63162
64348
  loginValidity: options.loginValidity
63163
64349
  });
63164
64350
  return await api.policyDeletePolicy({ policyIdentifier });
@@ -63181,7 +64367,7 @@ var registerAopsPolicyCommand = (program2) => {
63181
64367
  };
63182
64368
  var metadata2 = {
63183
64369
  name: "aops-policy-tool",
63184
- version: package_default2.version,
64370
+ version: package_default3.version,
63185
64371
  description: "Manage UiPath AOps governance policies.",
63186
64372
  commandPrefix: "gov"
63187
64373
  };
@@ -63189,9 +64375,10 @@ var registerCommands2 = async (program2) => {
63189
64375
  registerAopsPolicyCommand(program2);
63190
64376
  };
63191
64377
  // package.json
63192
- var package_default3 = {
64378
+ var package_default5 = {
63193
64379
  name: "@uipath/gov-tool",
63194
- version: "0.3.0",
64380
+ license: "MIT",
64381
+ version: "1.2.0",
63195
64382
  description: "Manage UiPath governance (AOps and Access policies) end-to-end.",
63196
64383
  private: false,
63197
64384
  repository: {
@@ -63233,7 +64420,7 @@ var package_default3 = {
63233
64420
  // src/tool.ts
63234
64421
  var metadata3 = {
63235
64422
  name: "gov-tool",
63236
- version: package_default3.version,
64423
+ version: package_default5.version,
63237
64424
  description: "Manage UiPath governance — AOps policies and Access policies.",
63238
64425
  commandPrefix: "gov"
63239
64426
  };