@uipath/audit-commands 1.203.0-preview.203 → 1.204.0-preview.206
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.
- package/dist/index.js +1371 -100
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2133,8 +2133,156 @@ function getGlobalTelemetryProperties() {
|
|
|
2133
2133
|
return telemetryPropsSlot.get();
|
|
2134
2134
|
}
|
|
2135
2135
|
|
|
2136
|
+
// ../../common/src/telemetry/telemetry-dimensions.ts
|
|
2137
|
+
var BaseDimensions = {
|
|
2138
|
+
ApplicationName: "ApplicationName",
|
|
2139
|
+
ProductVersion: "ProductVersion",
|
|
2140
|
+
InstallationId: "InstallationId",
|
|
2141
|
+
CloudUserId: "CloudUserId",
|
|
2142
|
+
CloudTenantId: "CloudTenantId",
|
|
2143
|
+
CloudOrganizationId: "CloudOrganizationId",
|
|
2144
|
+
IsInternalUser: "IsInternalUser",
|
|
2145
|
+
Environment: "Environment",
|
|
2146
|
+
BaseUrl: "BaseUrl",
|
|
2147
|
+
Region: "Region",
|
|
2148
|
+
Agent: "Agent",
|
|
2149
|
+
AgentVersion: "AgentVersion",
|
|
2150
|
+
AgentModel: "AgentModel",
|
|
2151
|
+
ToolName: "ToolName",
|
|
2152
|
+
ToolVersion: "ToolVersion",
|
|
2153
|
+
ExecutionContext: "ExecutionContext",
|
|
2154
|
+
CiProvider: "CiProvider",
|
|
2155
|
+
SessionIdSource: "SessionIdSource",
|
|
2156
|
+
SessionId: "SessionId"
|
|
2157
|
+
};
|
|
2158
|
+
var CommandDimensions = {
|
|
2159
|
+
IsCommand: "IsCommand",
|
|
2160
|
+
IsReexec: "IsReexec",
|
|
2161
|
+
CommandName: "CommandName",
|
|
2162
|
+
ExitCode: "ExitCode",
|
|
2163
|
+
TerminalOutcome: "TerminalOutcome",
|
|
2164
|
+
ErrorClass: "ErrorClass",
|
|
2165
|
+
TerminalSignal: "TerminalSignal",
|
|
2166
|
+
ErrorMessage: "ErrorMessage",
|
|
2167
|
+
SkillName: "SkillName",
|
|
2168
|
+
ProductArea: "ProductArea",
|
|
2169
|
+
Mode: "Mode"
|
|
2170
|
+
};
|
|
2171
|
+
var ShipDimensions = {
|
|
2172
|
+
ShipKind: "ShipKind",
|
|
2173
|
+
Target: "Target",
|
|
2174
|
+
ProjectType: "ProjectType",
|
|
2175
|
+
ProjectTypes: "ProjectTypes",
|
|
2176
|
+
ArtifactCorrelationKey: "ArtifactCorrelationKey",
|
|
2177
|
+
PackageName: "PackageName",
|
|
2178
|
+
PackageVersion: "PackageVersion",
|
|
2179
|
+
PackageVersionKey: "PackageVersionKey",
|
|
2180
|
+
DeploymentKey: "DeploymentKey",
|
|
2181
|
+
SolutionId: "SolutionId",
|
|
2182
|
+
FolderKey: "FolderKey",
|
|
2183
|
+
FeedId: "FeedId"
|
|
2184
|
+
};
|
|
2185
|
+
var ErrorDimensions = {
|
|
2186
|
+
Result: "Result",
|
|
2187
|
+
ErrorCode: "ErrorCode",
|
|
2188
|
+
Retry: "Retry",
|
|
2189
|
+
ErrorMessage: "ErrorMessage"
|
|
2190
|
+
};
|
|
2191
|
+
var AuthDimensions = {
|
|
2192
|
+
AuthenticationMethod: "AuthenticationMethod",
|
|
2193
|
+
Success: "Success",
|
|
2194
|
+
Reason: "Reason"
|
|
2195
|
+
};
|
|
2196
|
+
var SkillsDimensions = {
|
|
2197
|
+
SchemaVersion: "SchemaVersion",
|
|
2198
|
+
AgentType: "AgentType",
|
|
2199
|
+
SkillsVersion: "SkillsVersion",
|
|
2200
|
+
UipSubcommand: "UipSubcommand",
|
|
2201
|
+
FileExtension: "FileExtension",
|
|
2202
|
+
SubagentModel: "SubagentModel",
|
|
2203
|
+
SubagentType: "SubagentType",
|
|
2204
|
+
PermissionMode: "PermissionMode",
|
|
2205
|
+
EffortLevel: "EffortLevel",
|
|
2206
|
+
SessionSource: "SessionSource",
|
|
2207
|
+
Outcome: "Outcome",
|
|
2208
|
+
DurationMs: "DurationMs",
|
|
2209
|
+
Source: "Source"
|
|
2210
|
+
};
|
|
2211
|
+
var PackagerDimensions = {
|
|
2212
|
+
ProjectId: "ProjectId",
|
|
2213
|
+
ProjectType: "ProjectType",
|
|
2214
|
+
SolutionId: "SolutionId"
|
|
2215
|
+
};
|
|
2216
|
+
var ScopeDimensions = {
|
|
2217
|
+
FolderId: "FolderId"
|
|
2218
|
+
};
|
|
2219
|
+
var ID_DIMENSIONS = new Set([
|
|
2220
|
+
BaseDimensions.CloudUserId,
|
|
2221
|
+
BaseDimensions.CloudTenantId,
|
|
2222
|
+
BaseDimensions.CloudOrganizationId,
|
|
2223
|
+
BaseDimensions.InstallationId,
|
|
2224
|
+
ShipDimensions.ArtifactCorrelationKey,
|
|
2225
|
+
ShipDimensions.PackageVersionKey,
|
|
2226
|
+
ShipDimensions.DeploymentKey,
|
|
2227
|
+
ShipDimensions.SolutionId,
|
|
2228
|
+
ShipDimensions.FolderKey,
|
|
2229
|
+
ShipDimensions.FeedId,
|
|
2230
|
+
PackagerDimensions.ProjectId
|
|
2231
|
+
]);
|
|
2232
|
+
var NON_IDENTIFIER_PLACEHOLDER_PATTERN = /^(?:\[[A-Z_]+\]|<[^>]+>)$/;
|
|
2233
|
+
var RESERVED_DIMENSION_NAMES = new Set([
|
|
2234
|
+
...Object.values(BaseDimensions),
|
|
2235
|
+
...Object.values(CommandDimensions),
|
|
2236
|
+
...Object.values(ShipDimensions),
|
|
2237
|
+
...Object.values(ErrorDimensions),
|
|
2238
|
+
...Object.values(AuthDimensions),
|
|
2239
|
+
...Object.values(SkillsDimensions),
|
|
2240
|
+
...Object.values(PackagerDimensions),
|
|
2241
|
+
...Object.values(ScopeDimensions)
|
|
2242
|
+
]);
|
|
2243
|
+
var CURATED_DIMENSIONS = new Set([
|
|
2244
|
+
BaseDimensions.ApplicationName,
|
|
2245
|
+
BaseDimensions.ProductVersion,
|
|
2246
|
+
BaseDimensions.InstallationId,
|
|
2247
|
+
BaseDimensions.CloudUserId,
|
|
2248
|
+
BaseDimensions.CloudTenantId,
|
|
2249
|
+
BaseDimensions.CloudOrganizationId,
|
|
2250
|
+
BaseDimensions.IsInternalUser,
|
|
2251
|
+
BaseDimensions.Environment,
|
|
2252
|
+
BaseDimensions.BaseUrl,
|
|
2253
|
+
BaseDimensions.Region,
|
|
2254
|
+
BaseDimensions.Agent,
|
|
2255
|
+
BaseDimensions.AgentVersion,
|
|
2256
|
+
BaseDimensions.ToolVersion,
|
|
2257
|
+
BaseDimensions.ExecutionContext,
|
|
2258
|
+
BaseDimensions.CiProvider,
|
|
2259
|
+
BaseDimensions.SessionIdSource,
|
|
2260
|
+
BaseDimensions.SessionId,
|
|
2261
|
+
...Object.values(CommandDimensions),
|
|
2262
|
+
...Object.values(ShipDimensions)
|
|
2263
|
+
]);
|
|
2264
|
+
function lowercaseIdDimensionValues(properties) {
|
|
2265
|
+
let changed = false;
|
|
2266
|
+
const result = {
|
|
2267
|
+
...properties
|
|
2268
|
+
};
|
|
2269
|
+
for (const key of Object.keys(result)) {
|
|
2270
|
+
const value = result[key];
|
|
2271
|
+
if (!ID_DIMENSIONS.has(key) || typeof value !== "string" || NON_IDENTIFIER_PLACEHOLDER_PATTERN.test(value)) {
|
|
2272
|
+
continue;
|
|
2273
|
+
}
|
|
2274
|
+
const lowered = value.toLowerCase();
|
|
2275
|
+
if (lowered !== value) {
|
|
2276
|
+
result[key] = lowered;
|
|
2277
|
+
changed = true;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
return changed ? result : properties;
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2136
2283
|
// ../../common/src/sdk-user-agent.ts
|
|
2137
2284
|
var USER_AGENT_HEADER = "User-Agent";
|
|
2285
|
+
var AGENT_PROPERTY = BaseDimensions.Agent;
|
|
2138
2286
|
var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
|
|
2139
2287
|
function userAgentPatchKey(userAgent) {
|
|
2140
2288
|
return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
|
|
@@ -2414,6 +2562,19 @@ class FetchError extends Error {
|
|
|
2414
2562
|
}
|
|
2415
2563
|
}
|
|
2416
2564
|
}
|
|
2565
|
+
|
|
2566
|
+
class RequiredError extends Error {
|
|
2567
|
+
field;
|
|
2568
|
+
name = "RequiredError";
|
|
2569
|
+
constructor(field, msg) {
|
|
2570
|
+
super(msg);
|
|
2571
|
+
this.field = field;
|
|
2572
|
+
const actualProto = new.target.prototype;
|
|
2573
|
+
if (Object.setPrototypeOf) {
|
|
2574
|
+
Object.setPrototypeOf(this, actualProto);
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2417
2578
|
function querystring(params, prefix = "") {
|
|
2418
2579
|
return Object.keys(params).map((key) => querystringSingleKey(key, params[key], prefix)).filter((part) => part.length > 0).join("&");
|
|
2419
2580
|
}
|
|
@@ -2461,8 +2622,8 @@ var package_default = {
|
|
|
2461
2622
|
name: "@uipath/audit-sdk",
|
|
2462
2623
|
author: "UiPath",
|
|
2463
2624
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
2464
|
-
version: "1.
|
|
2465
|
-
description: "SDK for the UiPath Audit Service — query audit event sources, list events,
|
|
2625
|
+
version: "1.204.0",
|
|
2626
|
+
description: "SDK for the UiPath Audit Service — query audit event sources, list events, download long-term-store exports, and manage audit exclusion rules.",
|
|
2466
2627
|
repository: {
|
|
2467
2628
|
type: "git",
|
|
2468
2629
|
url: "https://github.com/UiPath/cli.git",
|
|
@@ -2620,6 +2781,208 @@ function AuditEventSourceDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
2620
2781
|
};
|
|
2621
2782
|
}
|
|
2622
2783
|
|
|
2784
|
+
// ../audit-sdk/generated/src/models/ExclusionSelectorDto.ts
|
|
2785
|
+
function ExclusionSelectorDtoFromJSON(json) {
|
|
2786
|
+
return ExclusionSelectorDtoFromJSONTyped(json, false);
|
|
2787
|
+
}
|
|
2788
|
+
function ExclusionSelectorDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
2789
|
+
if (json == null) {
|
|
2790
|
+
return json;
|
|
2791
|
+
}
|
|
2792
|
+
return {
|
|
2793
|
+
type: json["type"] == null ? undefined : json["type"],
|
|
2794
|
+
values: json["values"] == null ? undefined : json["values"]
|
|
2795
|
+
};
|
|
2796
|
+
}
|
|
2797
|
+
function ExclusionSelectorDtoToJSON(json) {
|
|
2798
|
+
return ExclusionSelectorDtoToJSONTyped(json, false);
|
|
2799
|
+
}
|
|
2800
|
+
function ExclusionSelectorDtoToJSONTyped(value, ignoreDiscriminator = false) {
|
|
2801
|
+
if (value == null) {
|
|
2802
|
+
return value;
|
|
2803
|
+
}
|
|
2804
|
+
return {
|
|
2805
|
+
type: value["type"],
|
|
2806
|
+
values: value["values"]
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
// ../audit-sdk/generated/src/models/ExclusionRuleDto.ts
|
|
2811
|
+
function ExclusionRuleDtoFromJSON(json) {
|
|
2812
|
+
return ExclusionRuleDtoFromJSONTyped(json, false);
|
|
2813
|
+
}
|
|
2814
|
+
function ExclusionRuleDtoFromJSONTyped(json, ignoreDiscriminator) {
|
|
2815
|
+
if (json == null) {
|
|
2816
|
+
return json;
|
|
2817
|
+
}
|
|
2818
|
+
return {
|
|
2819
|
+
policyId: json["policyId"] == null ? undefined : json["policyId"],
|
|
2820
|
+
name: json["name"] == null ? undefined : json["name"],
|
|
2821
|
+
enforcement: json["enforcement"] == null ? undefined : json["enforcement"],
|
|
2822
|
+
isActive: json["isActive"] == null ? undefined : json["isActive"],
|
|
2823
|
+
activatedOn: json["activatedOn"] == null ? undefined : new Date(json["activatedOn"]),
|
|
2824
|
+
selectors: json["selectors"] == null ? undefined : json["selectors"].map(ExclusionSelectorDtoFromJSON),
|
|
2825
|
+
createdOn: json["createdOn"] == null ? undefined : new Date(json["createdOn"]),
|
|
2826
|
+
lastModifiedOn: json["lastModifiedOn"] == null ? undefined : new Date(json["lastModifiedOn"])
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
// ../audit-sdk/generated/src/models/ExclusionRuleWriteDto.ts
|
|
2831
|
+
function ExclusionRuleWriteDtoToJSON(json) {
|
|
2832
|
+
return ExclusionRuleWriteDtoToJSONTyped(json, false);
|
|
2833
|
+
}
|
|
2834
|
+
function ExclusionRuleWriteDtoToJSONTyped(value, ignoreDiscriminator = false) {
|
|
2835
|
+
if (value == null) {
|
|
2836
|
+
return value;
|
|
2837
|
+
}
|
|
2838
|
+
return {
|
|
2839
|
+
name: value["name"],
|
|
2840
|
+
enforcement: value["enforcement"],
|
|
2841
|
+
isActive: value["isActive"],
|
|
2842
|
+
selectors: value["selectors"] == null ? undefined : value["selectors"].map(ExclusionSelectorDtoToJSON)
|
|
2843
|
+
};
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2846
|
+
// ../audit-sdk/generated/src/apis/EventConfigApi.ts
|
|
2847
|
+
class EventConfigApi extends BaseAPI {
|
|
2848
|
+
async eventConfigCreateRuleRequestOpts(requestParameters) {
|
|
2849
|
+
if (requestParameters["exclusionRuleWriteDto"] == null) {
|
|
2850
|
+
throw new RequiredError("exclusionRuleWriteDto", 'Required parameter "exclusionRuleWriteDto" was null or undefined when calling eventConfigCreateRule().');
|
|
2851
|
+
}
|
|
2852
|
+
const queryParameters = {};
|
|
2853
|
+
const headerParameters = {};
|
|
2854
|
+
headerParameters["Content-Type"] = "application/json";
|
|
2855
|
+
if (this.configuration && this.configuration.apiKey) {
|
|
2856
|
+
headerParameters["Authorization"] = await this.configuration.apiKey("Authorization");
|
|
2857
|
+
}
|
|
2858
|
+
let urlPath = `/api/EventConfig/rules`;
|
|
2859
|
+
return {
|
|
2860
|
+
path: urlPath,
|
|
2861
|
+
method: "POST",
|
|
2862
|
+
headers: headerParameters,
|
|
2863
|
+
query: queryParameters,
|
|
2864
|
+
body: ExclusionRuleWriteDtoToJSON(requestParameters["exclusionRuleWriteDto"])
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2867
|
+
async eventConfigCreateRuleRaw(requestParameters, initOverrides) {
|
|
2868
|
+
const requestOptions = await this.eventConfigCreateRuleRequestOpts(requestParameters);
|
|
2869
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
2870
|
+
return new JSONApiResponse(response, (jsonValue) => ExclusionRuleDtoFromJSON(jsonValue));
|
|
2871
|
+
}
|
|
2872
|
+
async eventConfigCreateRule(requestParameters, initOverrides) {
|
|
2873
|
+
const response = await this.eventConfigCreateRuleRaw(requestParameters, initOverrides);
|
|
2874
|
+
return await response.value();
|
|
2875
|
+
}
|
|
2876
|
+
async eventConfigDeleteRuleRequestOpts(requestParameters) {
|
|
2877
|
+
if (requestParameters["policyId"] == null) {
|
|
2878
|
+
throw new RequiredError("policyId", 'Required parameter "policyId" was null or undefined when calling eventConfigDeleteRule().');
|
|
2879
|
+
}
|
|
2880
|
+
const queryParameters = {};
|
|
2881
|
+
const headerParameters = {};
|
|
2882
|
+
if (this.configuration && this.configuration.apiKey) {
|
|
2883
|
+
headerParameters["Authorization"] = await this.configuration.apiKey("Authorization");
|
|
2884
|
+
}
|
|
2885
|
+
let urlPath = `/api/EventConfig/rules/{policyId}`;
|
|
2886
|
+
urlPath = urlPath.replace(`{${"policyId"}}`, encodeURIComponent(String(requestParameters["policyId"])));
|
|
2887
|
+
return {
|
|
2888
|
+
path: urlPath,
|
|
2889
|
+
method: "DELETE",
|
|
2890
|
+
headers: headerParameters,
|
|
2891
|
+
query: queryParameters
|
|
2892
|
+
};
|
|
2893
|
+
}
|
|
2894
|
+
async eventConfigDeleteRuleRaw(requestParameters, initOverrides) {
|
|
2895
|
+
const requestOptions = await this.eventConfigDeleteRuleRequestOpts(requestParameters);
|
|
2896
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
2897
|
+
return new VoidApiResponse(response);
|
|
2898
|
+
}
|
|
2899
|
+
async eventConfigDeleteRule(requestParameters, initOverrides) {
|
|
2900
|
+
await this.eventConfigDeleteRuleRaw(requestParameters, initOverrides);
|
|
2901
|
+
}
|
|
2902
|
+
async eventConfigGetRuleRequestOpts(requestParameters) {
|
|
2903
|
+
if (requestParameters["policyId"] == null) {
|
|
2904
|
+
throw new RequiredError("policyId", 'Required parameter "policyId" was null or undefined when calling eventConfigGetRule().');
|
|
2905
|
+
}
|
|
2906
|
+
const queryParameters = {};
|
|
2907
|
+
const headerParameters = {};
|
|
2908
|
+
if (this.configuration && this.configuration.apiKey) {
|
|
2909
|
+
headerParameters["Authorization"] = await this.configuration.apiKey("Authorization");
|
|
2910
|
+
}
|
|
2911
|
+
let urlPath = `/api/EventConfig/rules/{policyId}`;
|
|
2912
|
+
urlPath = urlPath.replace(`{${"policyId"}}`, encodeURIComponent(String(requestParameters["policyId"])));
|
|
2913
|
+
return {
|
|
2914
|
+
path: urlPath,
|
|
2915
|
+
method: "GET",
|
|
2916
|
+
headers: headerParameters,
|
|
2917
|
+
query: queryParameters
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
async eventConfigGetRuleRaw(requestParameters, initOverrides) {
|
|
2921
|
+
const requestOptions = await this.eventConfigGetRuleRequestOpts(requestParameters);
|
|
2922
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
2923
|
+
return new JSONApiResponse(response, (jsonValue) => ExclusionRuleDtoFromJSON(jsonValue));
|
|
2924
|
+
}
|
|
2925
|
+
async eventConfigGetRule(requestParameters, initOverrides) {
|
|
2926
|
+
const response = await this.eventConfigGetRuleRaw(requestParameters, initOverrides);
|
|
2927
|
+
return await response.value();
|
|
2928
|
+
}
|
|
2929
|
+
async eventConfigGetRulesRequestOpts() {
|
|
2930
|
+
const queryParameters = {};
|
|
2931
|
+
const headerParameters = {};
|
|
2932
|
+
if (this.configuration && this.configuration.apiKey) {
|
|
2933
|
+
headerParameters["Authorization"] = await this.configuration.apiKey("Authorization");
|
|
2934
|
+
}
|
|
2935
|
+
let urlPath = `/api/EventConfig/rules`;
|
|
2936
|
+
return {
|
|
2937
|
+
path: urlPath,
|
|
2938
|
+
method: "GET",
|
|
2939
|
+
headers: headerParameters,
|
|
2940
|
+
query: queryParameters
|
|
2941
|
+
};
|
|
2942
|
+
}
|
|
2943
|
+
async eventConfigGetRulesRaw(initOverrides) {
|
|
2944
|
+
const requestOptions = await this.eventConfigGetRulesRequestOpts();
|
|
2945
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
2946
|
+
return new JSONApiResponse(response, (jsonValue) => jsonValue.map(ExclusionRuleDtoFromJSON));
|
|
2947
|
+
}
|
|
2948
|
+
async eventConfigGetRules(initOverrides) {
|
|
2949
|
+
const response = await this.eventConfigGetRulesRaw(initOverrides);
|
|
2950
|
+
return await response.value();
|
|
2951
|
+
}
|
|
2952
|
+
async eventConfigReplaceRuleRequestOpts(requestParameters) {
|
|
2953
|
+
if (requestParameters["policyId"] == null) {
|
|
2954
|
+
throw new RequiredError("policyId", 'Required parameter "policyId" was null or undefined when calling eventConfigReplaceRule().');
|
|
2955
|
+
}
|
|
2956
|
+
if (requestParameters["exclusionRuleWriteDto"] == null) {
|
|
2957
|
+
throw new RequiredError("exclusionRuleWriteDto", 'Required parameter "exclusionRuleWriteDto" was null or undefined when calling eventConfigReplaceRule().');
|
|
2958
|
+
}
|
|
2959
|
+
const queryParameters = {};
|
|
2960
|
+
const headerParameters = {};
|
|
2961
|
+
headerParameters["Content-Type"] = "application/json";
|
|
2962
|
+
if (this.configuration && this.configuration.apiKey) {
|
|
2963
|
+
headerParameters["Authorization"] = await this.configuration.apiKey("Authorization");
|
|
2964
|
+
}
|
|
2965
|
+
let urlPath = `/api/EventConfig/rules/{policyId}`;
|
|
2966
|
+
urlPath = urlPath.replace(`{${"policyId"}}`, encodeURIComponent(String(requestParameters["policyId"])));
|
|
2967
|
+
return {
|
|
2968
|
+
path: urlPath,
|
|
2969
|
+
method: "PUT",
|
|
2970
|
+
headers: headerParameters,
|
|
2971
|
+
query: queryParameters,
|
|
2972
|
+
body: ExclusionRuleWriteDtoToJSON(requestParameters["exclusionRuleWriteDto"])
|
|
2973
|
+
};
|
|
2974
|
+
}
|
|
2975
|
+
async eventConfigReplaceRuleRaw(requestParameters, initOverrides) {
|
|
2976
|
+
const requestOptions = await this.eventConfigReplaceRuleRequestOpts(requestParameters);
|
|
2977
|
+
const response = await this.request(requestOptions, initOverrides);
|
|
2978
|
+
return new JSONApiResponse(response, (jsonValue) => ExclusionRuleDtoFromJSON(jsonValue));
|
|
2979
|
+
}
|
|
2980
|
+
async eventConfigReplaceRule(requestParameters, initOverrides) {
|
|
2981
|
+
const response = await this.eventConfigReplaceRuleRaw(requestParameters, initOverrides);
|
|
2982
|
+
return await response.value();
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
|
|
2623
2986
|
// ../audit-sdk/generated/src/apis/QueryApi.ts
|
|
2624
2987
|
class QueryApi extends BaseAPI {
|
|
2625
2988
|
async queryDownloadAuditEventsFromLongTermStoreRequestOpts(requestParameters) {
|
|
@@ -3283,6 +3646,11 @@ var pickName = (claims) => {
|
|
|
3283
3646
|
const username = asString(claims?.preferred_username);
|
|
3284
3647
|
return asString(claims?.name) ?? (looksLikeEmail(username) ? undefined : username);
|
|
3285
3648
|
};
|
|
3649
|
+
var pickScopes = (claims) => {
|
|
3650
|
+
const raw = claims?.scope;
|
|
3651
|
+
const scopes = Array.isArray(raw) ? raw.filter((entry) => asString(entry) !== undefined) : typeof raw === "string" ? raw.split(/\s+/).filter(Boolean) : [];
|
|
3652
|
+
return scopes.length > 0 ? scopes : undefined;
|
|
3653
|
+
};
|
|
3286
3654
|
var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
3287
3655
|
const claims = accessToken ? decodeClaims(accessToken) : undefined;
|
|
3288
3656
|
const email = pickEmail(claims);
|
|
@@ -3308,6 +3676,7 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
|
3308
3676
|
identity.clientId = clientId;
|
|
3309
3677
|
return identity;
|
|
3310
3678
|
};
|
|
3679
|
+
var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
|
|
3311
3680
|
|
|
3312
3681
|
// ../../auth/src/envAuth.ts
|
|
3313
3682
|
var ENV_AUTH_ENABLE_VAR = "UIPATH_CLI_ENABLE_ENV_AUTH";
|
|
@@ -3380,6 +3749,7 @@ var readAuthFromEnv = () => {
|
|
|
3380
3749
|
const expiration = getTokenExpiration(accessToken);
|
|
3381
3750
|
const loginStatus = expiration && expiration <= new Date ? "Expired" : "Logged in";
|
|
3382
3751
|
const identity = resolveSessionIdentity(accessToken);
|
|
3752
|
+
const scopes = readTokenScopes(accessToken);
|
|
3383
3753
|
return {
|
|
3384
3754
|
loginStatus,
|
|
3385
3755
|
accessToken,
|
|
@@ -3390,7 +3760,8 @@ var readAuthFromEnv = () => {
|
|
|
3390
3760
|
tenantId,
|
|
3391
3761
|
expiration,
|
|
3392
3762
|
source: "env-vars" /* EnvironmentVariables */,
|
|
3393
|
-
...identity ? { identity } : {}
|
|
3763
|
+
...identity ? { identity } : {},
|
|
3764
|
+
...scopes ? { scopes } : {}
|
|
3394
3765
|
};
|
|
3395
3766
|
};
|
|
3396
3767
|
|
|
@@ -4028,10 +4399,15 @@ async function buildFileStatus(tokens, credentials, globalHint) {
|
|
|
4028
4399
|
}
|
|
4029
4400
|
function identityFields(accessToken, credentials) {
|
|
4030
4401
|
const identity = resolveSessionIdentity(accessToken, parseAuthFlow(credentials[AUTH_FLOW_ENV_VAR]));
|
|
4031
|
-
|
|
4402
|
+
const scopes = readTokenScopes(accessToken);
|
|
4403
|
+
return {
|
|
4404
|
+
...identity ? { identity } : {},
|
|
4405
|
+
...scopes ? { scopes } : {}
|
|
4406
|
+
};
|
|
4032
4407
|
}
|
|
4033
4408
|
function buildRobotStatus(robotCreds) {
|
|
4034
4409
|
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
4410
|
+
const scopes = readTokenScopes(robotCreds.accessToken);
|
|
4035
4411
|
return {
|
|
4036
4412
|
loginStatus: "Logged in",
|
|
4037
4413
|
accessToken: robotCreds.accessToken,
|
|
@@ -4043,7 +4419,8 @@ function buildRobotStatus(robotCreds) {
|
|
|
4043
4419
|
issuer: robotCreds.issuer,
|
|
4044
4420
|
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
4045
4421
|
source: "robot" /* Robot */,
|
|
4046
|
-
...identity ? { identity } : {}
|
|
4422
|
+
...identity ? { identity } : {},
|
|
4423
|
+
...scopes ? { scopes } : {}
|
|
4047
4424
|
};
|
|
4048
4425
|
}
|
|
4049
4426
|
var isFileNotFoundError = (error) => {
|
|
@@ -4325,6 +4702,47 @@ async function createApiClient(ApiClass, options) {
|
|
|
4325
4702
|
const config = await createAuditConfig(options);
|
|
4326
4703
|
return new ApiClass(config);
|
|
4327
4704
|
}
|
|
4705
|
+
// ../../common/src/guid.ts
|
|
4706
|
+
var GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4707
|
+
function isGuid(value) {
|
|
4708
|
+
return GUID_REGEX.test(value);
|
|
4709
|
+
}
|
|
4710
|
+
|
|
4711
|
+
// ../audit-sdk/src/exclusion-rules.ts
|
|
4712
|
+
class ExclusionRuleLookupError extends Error {
|
|
4713
|
+
reason;
|
|
4714
|
+
candidates;
|
|
4715
|
+
constructor(message, reason, candidates = []) {
|
|
4716
|
+
super(message);
|
|
4717
|
+
this.name = "ExclusionRuleLookupError";
|
|
4718
|
+
this.reason = reason;
|
|
4719
|
+
this.candidates = candidates;
|
|
4720
|
+
}
|
|
4721
|
+
}
|
|
4722
|
+
function describe(rule) {
|
|
4723
|
+
return `${rule.policyId} (${rule.isActive ? "active" : "inactive"})`;
|
|
4724
|
+
}
|
|
4725
|
+
async function resolveExclusionRule(api, nameOrId) {
|
|
4726
|
+
const value = nameOrId.trim();
|
|
4727
|
+
if (isGuid(value)) {
|
|
4728
|
+
return { policyId: value };
|
|
4729
|
+
}
|
|
4730
|
+
const rules = await api.eventConfigGetRules() ?? [];
|
|
4731
|
+
const matches = rules.filter((rule) => rule.name === value);
|
|
4732
|
+
const resolved = matches.length > 0 ? matches : rules.filter((rule) => rule.name?.toLowerCase() === value.toLowerCase());
|
|
4733
|
+
if (resolved.length === 1) {
|
|
4734
|
+
const rule = resolved[0];
|
|
4735
|
+
if (rule.policyId) {
|
|
4736
|
+
return { policyId: rule.policyId, rule };
|
|
4737
|
+
}
|
|
4738
|
+
throw new ExclusionRuleLookupError(`The rule named '${value}' was listed without a policy id, so it cannot be addressed.`, "unidentifiable");
|
|
4739
|
+
}
|
|
4740
|
+
if (resolved.length > 1) {
|
|
4741
|
+
const candidates = resolved.map((rule) => rule.policyId).filter((id) => typeof id === "string");
|
|
4742
|
+
throw new ExclusionRuleLookupError(`'${value}' matches ${resolved.length} rules: ${resolved.map(describe).join(", ")}.`, "ambiguous", candidates);
|
|
4743
|
+
}
|
|
4744
|
+
throw new ExclusionRuleLookupError(`No exclusion rule named '${value}' exists in this organization.`, "not-found");
|
|
4745
|
+
}
|
|
4328
4746
|
// ../../common/src/telemetry/pseudonymize.ts
|
|
4329
4747
|
var PSEUDONYM_DOMAIN = "uipath-cli/telemetry/pseudonym/v1:";
|
|
4330
4748
|
var PSEUDONYM_HEX_LENGTH = 32;
|
|
@@ -4832,9 +5250,60 @@ function settlePromiseLike2(thenable) {
|
|
|
4832
5250
|
return Promise.resolve(thenable).then((data) => [undefined, data]).catch((error) => [toError(error), undefined]);
|
|
4833
5251
|
}
|
|
4834
5252
|
|
|
5253
|
+
// ../../common/src/error-graph.ts
|
|
5254
|
+
function* walkErrorGraph(error) {
|
|
5255
|
+
const queue = [error];
|
|
5256
|
+
const seen = new Set;
|
|
5257
|
+
for (let steps = 0;queue.length > 0 && steps < 32; steps++) {
|
|
5258
|
+
const current = queue.shift();
|
|
5259
|
+
if (current === null || typeof current !== "object")
|
|
5260
|
+
continue;
|
|
5261
|
+
if (seen.has(current))
|
|
5262
|
+
continue;
|
|
5263
|
+
seen.add(current);
|
|
5264
|
+
const cur = current;
|
|
5265
|
+
yield cur;
|
|
5266
|
+
if (cur.cause !== undefined)
|
|
5267
|
+
queue.push(cur.cause);
|
|
5268
|
+
if (Array.isArray(cur.errors))
|
|
5269
|
+
queue.push(...cur.errors);
|
|
5270
|
+
}
|
|
5271
|
+
return;
|
|
5272
|
+
}
|
|
5273
|
+
function parseHttpStatusFromMessage(message) {
|
|
5274
|
+
const match = /^HTTP\s+(\d{3})(?::|\s|-|$)/i.exec(message.trim());
|
|
5275
|
+
if (!match)
|
|
5276
|
+
return;
|
|
5277
|
+
const status = Number(match[1]);
|
|
5278
|
+
return Number.isInteger(status) && status >= 100 && status <= 599 ? status : undefined;
|
|
5279
|
+
}
|
|
5280
|
+
function findHttpStatusInGraph(error) {
|
|
5281
|
+
for (const node of walkErrorGraph(error)) {
|
|
5282
|
+
const response = node.response;
|
|
5283
|
+
const explicit = typeof node.status === "number" ? node.status : response?.status;
|
|
5284
|
+
if (typeof explicit === "number" && explicit >= 400 && explicit <= 599) {
|
|
5285
|
+
return explicit;
|
|
5286
|
+
}
|
|
5287
|
+
if (typeof node.message === "string") {
|
|
5288
|
+
const parsed = parseHttpStatusFromMessage(node.message);
|
|
5289
|
+
if (parsed !== undefined && parsed >= 400) {
|
|
5290
|
+
return parsed;
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
}
|
|
5294
|
+
return;
|
|
5295
|
+
}
|
|
5296
|
+
|
|
5297
|
+
// ../../common/src/local-permission-codes.ts
|
|
5298
|
+
var LOCAL_PERMISSION_ERROR_CODES = new Set([
|
|
5299
|
+
"EACCES",
|
|
5300
|
+
"EPERM",
|
|
5301
|
+
"EROFS"
|
|
5302
|
+
]);
|
|
5303
|
+
|
|
4835
5304
|
// ../../common/src/error-handler.ts
|
|
4836
|
-
var DEFAULT_401 = "Unauthorized (401). Run `uip login` to
|
|
4837
|
-
var DEFAULT_403 = "Forbidden (403).
|
|
5305
|
+
var DEFAULT_401 = "Unauthorized (401). The session is missing or expired, or its token carries no scope for this API. Run `uip login status --detailed` to see the session and its scopes.";
|
|
5306
|
+
var DEFAULT_403 = "Forbidden (403). The account lacks permission for this operation, or the token carries no scope for this API. Run `uip login status --detailed` to see the token's scopes.";
|
|
4838
5307
|
var DEFAULT_405 = "Method Not Allowed (405). The endpoint may not exist or the base URL may be incorrect.";
|
|
4839
5308
|
var DEFAULT_413 = "Payload too large (413). The upload exceeded the server or CDN size limit. Reduce the package size — for example, exclude unused dependencies or remove large files from the project — and try again.";
|
|
4840
5309
|
var HTML_RESPONSE_MESSAGE = "Received HTML instead of the expected JSON response.";
|
|
@@ -4861,14 +5330,14 @@ var TLS_ERROR_CODES = new Set([
|
|
|
4861
5330
|
]);
|
|
4862
5331
|
var TLS_INSTRUCTIONS = "The server's TLS certificate could not be verified. Most often a " + "corporate proxy/firewall re-signs HTTPS with a root CA that Node does " + "not trust — set NODE_EXTRA_CA_CERTS to that CA's PEM file (and HTTPS_PROXY " + "if you connect through a proxy). If the certificate is instead expired or " + "its hostname does not match, fix the endpoint URL or the system clock. " + "Then retry.";
|
|
4863
5332
|
var NETWORK_INSTRUCTIONS = "Could not reach the UiPath service. Check your network connection and " + "VPN, confirm any HTTP_PROXY/HTTPS_PROXY/NO_PROXY settings are correct, " + "then retry.";
|
|
4864
|
-
var
|
|
4865
|
-
var LOCAL_PERMISSION_MESSAGE_PATTERN = /\b(EACCES|EPERM|EROFS)\b/;
|
|
5333
|
+
var LOCAL_PERMISSION_MESSAGE_PATTERN = new RegExp(`\\b(${[...LOCAL_PERMISSION_ERROR_CODES].join("|")})\\b`);
|
|
4866
5334
|
function localPermissionInstructions(code, path2) {
|
|
4867
5335
|
const target = path2 !== undefined ? `'${path2}'` : "a local file or resource";
|
|
4868
5336
|
if (code === "EROFS") {
|
|
4869
5337
|
return `The filesystem containing ${target} is read-only (EROFS), so the ` + "CLI could not write to it. This is a local environment problem, " + "not a UiPath service error — retrying will not help. Use a " + "writable location, or give this environment write access to the " + "path.";
|
|
4870
5338
|
}
|
|
4871
|
-
const
|
|
5339
|
+
const onWindows = typeof process !== "undefined" && process.platform === "win32";
|
|
5340
|
+
const remedy = onWindows ? "Re-run from an elevated terminal, close any program holding " + "the file open, or grant your user access to the path." : "Grant this user (or the sandbox the command runs in) access " + "to the path, or run the command outside the sandbox.";
|
|
4872
5341
|
return `The operating system denied access to ${target} (${code}). This is ` + "a local permission problem, not a UiPath service error — retrying " + `without a permission change will not help. ${remedy}`;
|
|
4873
5342
|
}
|
|
4874
5343
|
function describeConnectivityError(error) {
|
|
@@ -4922,48 +5391,6 @@ function localPermissionPath(path2, message) {
|
|
|
4922
5391
|
return path2;
|
|
4923
5392
|
return message ? /'([^']+)'/.exec(message)?.[1] : undefined;
|
|
4924
5393
|
}
|
|
4925
|
-
function* walkErrorGraph(error) {
|
|
4926
|
-
const queue = [error];
|
|
4927
|
-
const seen = new Set;
|
|
4928
|
-
for (let steps = 0;queue.length > 0 && steps < 32; steps++) {
|
|
4929
|
-
const current = queue.shift();
|
|
4930
|
-
if (current === null || typeof current !== "object")
|
|
4931
|
-
continue;
|
|
4932
|
-
if (seen.has(current))
|
|
4933
|
-
continue;
|
|
4934
|
-
seen.add(current);
|
|
4935
|
-
const cur = current;
|
|
4936
|
-
yield cur;
|
|
4937
|
-
if (cur.cause !== undefined)
|
|
4938
|
-
queue.push(cur.cause);
|
|
4939
|
-
if (Array.isArray(cur.errors))
|
|
4940
|
-
queue.push(...cur.errors);
|
|
4941
|
-
}
|
|
4942
|
-
return;
|
|
4943
|
-
}
|
|
4944
|
-
function parseHttpStatusFromMessage(message) {
|
|
4945
|
-
const match = /^HTTP\s+(\d{3})(?::|\s|-|$)/i.exec(message.trim());
|
|
4946
|
-
if (!match)
|
|
4947
|
-
return;
|
|
4948
|
-
const status = Number(match[1]);
|
|
4949
|
-
return Number.isInteger(status) && status >= 100 && status <= 599 ? status : undefined;
|
|
4950
|
-
}
|
|
4951
|
-
function findHttpStatusInGraph(error) {
|
|
4952
|
-
for (const node of walkErrorGraph(error)) {
|
|
4953
|
-
const response = node.response;
|
|
4954
|
-
const explicit = typeof node.status === "number" ? node.status : response?.status;
|
|
4955
|
-
if (typeof explicit === "number" && explicit >= 400 && explicit <= 599) {
|
|
4956
|
-
return explicit;
|
|
4957
|
-
}
|
|
4958
|
-
if (typeof node.message === "string") {
|
|
4959
|
-
const parsed = parseHttpStatusFromMessage(node.message);
|
|
4960
|
-
if (parsed !== undefined && parsed >= 400) {
|
|
4961
|
-
return parsed;
|
|
4962
|
-
}
|
|
4963
|
-
}
|
|
4964
|
-
}
|
|
4965
|
-
return;
|
|
4966
|
-
}
|
|
4967
5394
|
function isHtmlDocument(body) {
|
|
4968
5395
|
return /^\s*(<!doctype html|<html\b)/i.test(body);
|
|
4969
5396
|
}
|
|
@@ -5491,6 +5918,9 @@ var AUTH_ERROR_CODES = new Set([
|
|
|
5491
5918
|
"authentication_required",
|
|
5492
5919
|
"permission_denied"
|
|
5493
5920
|
]);
|
|
5921
|
+
var LOCAL_PERMISSION_CLI_ERROR_CODES = new Set([
|
|
5922
|
+
"local_permission_denied"
|
|
5923
|
+
]);
|
|
5494
5924
|
var VALIDATION_ERROR_CODES = new Set(["invalid_argument"]);
|
|
5495
5925
|
var NETWORK_HTTP_ERROR_CODES = new Set([
|
|
5496
5926
|
"network_error",
|
|
@@ -5631,6 +6061,9 @@ function classifyFromErrorCode(errorCode2) {
|
|
|
5631
6061
|
if (AUTH_ERROR_CODES.has(errorCode2)) {
|
|
5632
6062
|
return "auth";
|
|
5633
6063
|
}
|
|
6064
|
+
if (LOCAL_PERMISSION_CLI_ERROR_CODES.has(errorCode2)) {
|
|
6065
|
+
return "local_permission";
|
|
6066
|
+
}
|
|
5634
6067
|
if (VALIDATION_ERROR_CODES.has(errorCode2)) {
|
|
5635
6068
|
return "validation";
|
|
5636
6069
|
}
|
|
@@ -5642,6 +6075,15 @@ function classifyFromErrorCode(errorCode2) {
|
|
|
5642
6075
|
}
|
|
5643
6076
|
return;
|
|
5644
6077
|
}
|
|
6078
|
+
function hasLocalPermissionCode(error) {
|
|
6079
|
+
for (const node of walkErrorGraph(error)) {
|
|
6080
|
+
const code = node.code;
|
|
6081
|
+
if (typeof code === "string" && LOCAL_PERMISSION_ERROR_CODES.has(code)) {
|
|
6082
|
+
return true;
|
|
6083
|
+
}
|
|
6084
|
+
}
|
|
6085
|
+
return false;
|
|
6086
|
+
}
|
|
5645
6087
|
function classifyFromError(error) {
|
|
5646
6088
|
const code = findCodeInCauseChain(error);
|
|
5647
6089
|
if (code) {
|
|
@@ -5658,6 +6100,9 @@ function classifyFromError(error) {
|
|
|
5658
6100
|
return "missing_dependency";
|
|
5659
6101
|
}
|
|
5660
6102
|
}
|
|
6103
|
+
if (hasLocalPermissionCode(error)) {
|
|
6104
|
+
return "local_permission";
|
|
6105
|
+
}
|
|
5661
6106
|
const message = stringField(error, "message");
|
|
5662
6107
|
if (message?.includes("fetch failed") === true) {
|
|
5663
6108
|
return "network_http";
|
|
@@ -5673,7 +6118,7 @@ function classifyError2(input) {
|
|
|
5673
6118
|
if (recorded?.errorClass) {
|
|
5674
6119
|
return recorded.errorClass;
|
|
5675
6120
|
}
|
|
5676
|
-
const status = recorded?.context?.httpStatus;
|
|
6121
|
+
const status = recorded?.context?.httpStatus ?? findHttpStatusInGraph(input.error);
|
|
5677
6122
|
if (status !== undefined) {
|
|
5678
6123
|
return classifyHttpStatus(status);
|
|
5679
6124
|
}
|
|
@@ -5696,17 +6141,18 @@ function buildCommandTerminalTelemetryProperties(input) {
|
|
|
5696
6141
|
const errorClass = outcome === "success" || outcome === "no_op" ? undefined : outcome === "cancelled" ? "user_cancelled" : classifyError2(input);
|
|
5697
6142
|
const terminalSignal = terminalSignalFor(input, outcome);
|
|
5698
6143
|
return {
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
...errorClass ? {
|
|
5702
|
-
...terminalSignal ? {
|
|
6144
|
+
[CommandDimensions.ExitCode]: input.exitCode,
|
|
6145
|
+
[CommandDimensions.TerminalOutcome]: outcome,
|
|
6146
|
+
...errorClass ? { [CommandDimensions.ErrorClass]: errorClass } : {},
|
|
6147
|
+
...terminalSignal ? { [CommandDimensions.TerminalSignal]: terminalSignal } : {}
|
|
5703
6148
|
};
|
|
5704
6149
|
}
|
|
5705
6150
|
|
|
5706
6151
|
// ../../common/src/telemetry/telemetry-events.ts
|
|
5707
6152
|
var CommonTelemetryEvents = {
|
|
5708
|
-
|
|
5709
|
-
|
|
6153
|
+
Start: "Application.Start",
|
|
6154
|
+
Error: "Application.Error",
|
|
6155
|
+
ShipSucceeded: "Cli.ShipSucceeded"
|
|
5710
6156
|
};
|
|
5711
6157
|
|
|
5712
6158
|
// ../../common/src/registry.ts
|
|
@@ -5914,8 +6360,8 @@ function detectExecutionContext(options = {}) {
|
|
|
5914
6360
|
function getExecutionContextTelemetryProperties() {
|
|
5915
6361
|
const detected = detectExecutionContext();
|
|
5916
6362
|
return {
|
|
5917
|
-
|
|
5918
|
-
...detected.ciProvider ? {
|
|
6363
|
+
[BaseDimensions.ExecutionContext]: detected.executionContext,
|
|
6364
|
+
...detected.ciProvider ? { [BaseDimensions.CiProvider]: detected.ciProvider } : {}
|
|
5919
6365
|
};
|
|
5920
6366
|
}
|
|
5921
6367
|
// ../../common/src/telemetry/node-context-storage.ts
|
|
@@ -5958,7 +6404,7 @@ function getInboundTraceContext() {
|
|
|
5958
6404
|
var TELEMETRY_SESSION_ID_ENV = "UIPATH_SESSION_ID";
|
|
5959
6405
|
var SESSION_ID_MAX_LENGTH = 64;
|
|
5960
6406
|
var RANDOM_SESSION_ID_LENGTH = 32;
|
|
5961
|
-
var TELEMETRY_SESSION_SOURCE_PROPERTY = "
|
|
6407
|
+
var TELEMETRY_SESSION_SOURCE_PROPERTY = "SessionIdSource";
|
|
5962
6408
|
var CONTROL_CHARACTERS = /\p{Cc}/gu;
|
|
5963
6409
|
var INHERITED_SESSION_SOURCES = [
|
|
5964
6410
|
{ envVar: "CLAUDE_CODE_SESSION_ID", source: "claude-code" },
|
|
@@ -6010,6 +6456,9 @@ function resolveTelemetrySession() {
|
|
|
6010
6456
|
telemetrySessionSlot.set(resolved);
|
|
6011
6457
|
return resolved;
|
|
6012
6458
|
}
|
|
6459
|
+
function getTelemetrySessionId() {
|
|
6460
|
+
return resolveTelemetrySession().id;
|
|
6461
|
+
}
|
|
6013
6462
|
function getTelemetrySessionSource() {
|
|
6014
6463
|
return resolveTelemetrySession().source;
|
|
6015
6464
|
}
|
|
@@ -6084,7 +6533,10 @@ class TelemetryService {
|
|
|
6084
6533
|
} catch (error) {
|
|
6085
6534
|
const durationMs = clock.elapsedMs();
|
|
6086
6535
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
6087
|
-
await this.telemetryProvider.trackRequest(this.spanFor(name, durationMs, false, {
|
|
6536
|
+
await this.telemetryProvider.trackRequest(this.spanFor(name, durationMs, false, {
|
|
6537
|
+
...properties,
|
|
6538
|
+
[CommandDimensions.ErrorMessage]: err.message
|
|
6539
|
+
}, context));
|
|
6088
6540
|
throw error;
|
|
6089
6541
|
}
|
|
6090
6542
|
}
|
|
@@ -6155,7 +6607,10 @@ class TelemetryService {
|
|
|
6155
6607
|
const durationMs = clock.elapsedMs();
|
|
6156
6608
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
6157
6609
|
await this.telemetryProvider.trackDependency({
|
|
6158
|
-
...this.spanFor(name, durationMs, false, {
|
|
6610
|
+
...this.spanFor(name, durationMs, false, {
|
|
6611
|
+
...properties,
|
|
6612
|
+
[CommandDimensions.ErrorMessage]: err.message
|
|
6613
|
+
}, childContext),
|
|
6159
6614
|
type
|
|
6160
6615
|
});
|
|
6161
6616
|
throw error;
|
|
@@ -6190,9 +6645,10 @@ class TelemetryService {
|
|
|
6190
6645
|
...globalProperties,
|
|
6191
6646
|
...this.defaultProperties,
|
|
6192
6647
|
...redactProperties(properties ?? {}),
|
|
6193
|
-
[TELEMETRY_SESSION_SOURCE_PROPERTY]: getTelemetrySessionSource()
|
|
6648
|
+
[TELEMETRY_SESSION_SOURCE_PROPERTY]: getTelemetrySessionSource(),
|
|
6649
|
+
[BaseDimensions.SessionId]: this.telemetryProvider.getSessionId?.() ?? getTelemetrySessionId()
|
|
6194
6650
|
};
|
|
6195
|
-
return enriched;
|
|
6651
|
+
return lowercaseIdDimensionValues(enriched);
|
|
6196
6652
|
}
|
|
6197
6653
|
generateId() {
|
|
6198
6654
|
const bytes = new Uint8Array(8);
|
|
@@ -6953,7 +7409,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
6953
7409
|
this.instructions = "Pass --limit <n> to choose how many records the filter applies to. " + "To filter over all records, pass the command's maximum accepted --limit (see the option's description in --help).";
|
|
6954
7410
|
}
|
|
6955
7411
|
}
|
|
6956
|
-
function
|
|
7412
|
+
function countRecords(data) {
|
|
7413
|
+
if (Array.isArray(data))
|
|
7414
|
+
return data.length;
|
|
7415
|
+
return data == null ? 0 : 1;
|
|
7416
|
+
}
|
|
7417
|
+
function availableFields(data) {
|
|
7418
|
+
const records = Array.isArray(data) ? data : [data];
|
|
7419
|
+
const keys = new Set;
|
|
7420
|
+
for (const record of records) {
|
|
7421
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
7422
|
+
for (const key of Object.keys(record))
|
|
7423
|
+
keys.add(key);
|
|
7424
|
+
}
|
|
7425
|
+
}
|
|
7426
|
+
return [...keys];
|
|
7427
|
+
}
|
|
7428
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
7429
|
+
const [error, decoded] = catchError2(() => JSON.parse(whole));
|
|
7430
|
+
if (!error && typeof decoded === "string")
|
|
7431
|
+
return decoded;
|
|
7432
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
7433
|
+
}
|
|
7434
|
+
function referencedFields(filter) {
|
|
7435
|
+
const top = new Set;
|
|
7436
|
+
const nested = new Set;
|
|
7437
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
7438
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
7439
|
+
const quoted = [];
|
|
7440
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
7441
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
7442
|
+
if (!isAlias) {
|
|
7443
|
+
quoted.push({
|
|
7444
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
7445
|
+
index,
|
|
7446
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
7447
|
+
});
|
|
7448
|
+
}
|
|
7449
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
7450
|
+
});
|
|
7451
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
7452
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
7453
|
+
const place = (name, index, tail) => {
|
|
7454
|
+
if (tail || index >= rootEnd)
|
|
7455
|
+
nested.add(name);
|
|
7456
|
+
else
|
|
7457
|
+
top.add(name);
|
|
7458
|
+
};
|
|
7459
|
+
for (const entry of quoted)
|
|
7460
|
+
place(entry.name, entry.index, entry.tail);
|
|
7461
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
7462
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
7463
|
+
for (const match of identifiers) {
|
|
7464
|
+
const [, name, trailing] = match;
|
|
7465
|
+
if (trailing || reserved.has(name))
|
|
7466
|
+
continue;
|
|
7467
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
7468
|
+
}
|
|
7469
|
+
return {
|
|
7470
|
+
top: [...top],
|
|
7471
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
7472
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
7473
|
+
};
|
|
7474
|
+
}
|
|
7475
|
+
function appearsBelowTopLevel(data, name) {
|
|
7476
|
+
let budget = 2000;
|
|
7477
|
+
const visit = (value, depth) => {
|
|
7478
|
+
if (budget-- <= 0 || depth > 4)
|
|
7479
|
+
return false;
|
|
7480
|
+
if (value === null || typeof value !== "object")
|
|
7481
|
+
return false;
|
|
7482
|
+
if (Array.isArray(value))
|
|
7483
|
+
return value.some((entry) => visit(entry, depth));
|
|
7484
|
+
const record = value;
|
|
7485
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
7486
|
+
return true;
|
|
7487
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
7488
|
+
};
|
|
7489
|
+
return visit(data, 0);
|
|
7490
|
+
}
|
|
7491
|
+
function alwaysNullKeys(records) {
|
|
7492
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
7493
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
7494
|
+
return [];
|
|
7495
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
7496
|
+
if (keys.length === 0)
|
|
7497
|
+
return [];
|
|
7498
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
7499
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
7500
|
+
}
|
|
7501
|
+
function carriesOnlyNulls(value) {
|
|
7502
|
+
if (value === null)
|
|
7503
|
+
return true;
|
|
7504
|
+
if (Array.isArray(value)) {
|
|
7505
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
7506
|
+
}
|
|
7507
|
+
if (typeof value === "object" && value !== undefined) {
|
|
7508
|
+
const values = Object.values(value);
|
|
7509
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
7510
|
+
}
|
|
7511
|
+
return false;
|
|
7512
|
+
}
|
|
7513
|
+
function nameList(names, cap2 = 12) {
|
|
7514
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
7515
|
+
const rest = names.length - shown.length;
|
|
7516
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
7517
|
+
}
|
|
7518
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
7519
|
+
const present = availableFields(data);
|
|
7520
|
+
const refs = referencedFields(filter);
|
|
7521
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
7522
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
7523
|
+
const count = countRecords(data);
|
|
7524
|
+
const scope = `${count} record(s)`;
|
|
7525
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
7526
|
+
const soundness = unchecked.length > 0 ? `${nameList(unchecked)} ${unchecked.length === 1 ? "reads" : "read"} below the top level, so ${unchecked.length === 1 ? "it was" : "they were"} not checked against the record keys` : refs.top.length > 0 ? "every field it names exists" : "";
|
|
7527
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
7528
|
+
let detail;
|
|
7529
|
+
let lede;
|
|
7530
|
+
if (outcome.kind === "null-elements") {
|
|
7531
|
+
lede = "returned only null values";
|
|
7532
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
7533
|
+
if (unknown.length > 0) {
|
|
7534
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
7535
|
+
} else if (unchecked.length > 0) {
|
|
7536
|
+
detail = withSoundness(projected);
|
|
7537
|
+
} else {
|
|
7538
|
+
detail = `${projected}, and every field it names exists — a multi-select list ` + `(\`[A, B]\`) reads each entry against \`Data\` itself, so on a list ` + `result use \`[].[A, B]\` or \`[].{a: A, b: B}\` to read the records`;
|
|
7539
|
+
}
|
|
7540
|
+
} else if (outcome.kind === "null-rows") {
|
|
7541
|
+
lede = "returned only null values";
|
|
7542
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
7543
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
7544
|
+
} else if (outcome.kind === "null-values") {
|
|
7545
|
+
lede = "returned only null values";
|
|
7546
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
7547
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
7548
|
+
if (sameSet) {
|
|
7549
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
7550
|
+
} else if (unknown.length > 0) {
|
|
7551
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
7552
|
+
} else {
|
|
7553
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
7554
|
+
}
|
|
7555
|
+
} else {
|
|
7556
|
+
lede = "returned nothing";
|
|
7557
|
+
if (unknown.length > 0) {
|
|
7558
|
+
detail = isNotAField(unknown);
|
|
7559
|
+
} else {
|
|
7560
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
7561
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
7562
|
+
}
|
|
7563
|
+
}
|
|
7564
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
7565
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
7566
|
+
}
|
|
7567
|
+
function appendWarning(existing, note) {
|
|
7568
|
+
return existing ? `${existing} ${note}` : note;
|
|
7569
|
+
}
|
|
7570
|
+
function applyFilter(data, filter, onWarning) {
|
|
6957
7571
|
const codec = requireJmespath();
|
|
6958
7572
|
let result;
|
|
6959
7573
|
try {
|
|
@@ -6961,9 +7575,34 @@ function applyFilter(data, filter) {
|
|
|
6961
7575
|
} catch (err) {
|
|
6962
7576
|
throw new FilterEvaluationError(filter, err);
|
|
6963
7577
|
}
|
|
6964
|
-
|
|
7578
|
+
const inputCount = countRecords(data);
|
|
7579
|
+
const warn = (outcome) => {
|
|
7580
|
+
if (inputCount === 0)
|
|
7581
|
+
return;
|
|
7582
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
7583
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
7584
|
+
`);
|
|
7585
|
+
onWarning?.(note);
|
|
7586
|
+
};
|
|
7587
|
+
const warnIfAllNull = (records) => {
|
|
7588
|
+
const keys = alwaysNullKeys(records);
|
|
7589
|
+
if (keys.length > 0)
|
|
7590
|
+
warn({ kind: "null-values", keys });
|
|
7591
|
+
};
|
|
7592
|
+
if (result == null) {
|
|
7593
|
+
warn({ kind: "empty" });
|
|
6965
7594
|
return [];
|
|
7595
|
+
}
|
|
6966
7596
|
if (Array.isArray(result)) {
|
|
7597
|
+
if (result.length === 0) {
|
|
7598
|
+
warn({ kind: "empty" });
|
|
7599
|
+
} else if (result.every((entry) => entry === null)) {
|
|
7600
|
+
warn({ kind: "null-elements", count: result.length });
|
|
7601
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
7602
|
+
warn({ kind: "null-rows", count: result.length });
|
|
7603
|
+
} else {
|
|
7604
|
+
warnIfAllNull(result);
|
|
7605
|
+
}
|
|
6967
7606
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
6968
7607
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
6969
7608
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -6971,10 +7610,30 @@ function applyFilter(data, filter) {
|
|
|
6971
7610
|
}
|
|
6972
7611
|
return result;
|
|
6973
7612
|
}
|
|
6974
|
-
if (typeof result === "object")
|
|
7613
|
+
if (typeof result === "object") {
|
|
7614
|
+
warnIfAllNull([result]);
|
|
6975
7615
|
return result;
|
|
7616
|
+
}
|
|
6976
7617
|
return { Value: result };
|
|
6977
7618
|
}
|
|
7619
|
+
function filterFailureData(envelope) {
|
|
7620
|
+
const filter = getOutputFilter();
|
|
7621
|
+
const data = envelope.Data;
|
|
7622
|
+
if (!filter || data == null)
|
|
7623
|
+
return;
|
|
7624
|
+
let note;
|
|
7625
|
+
const [filterError, filtered] = catchError2(() => applyFilter(data, filter, (n) => {
|
|
7626
|
+
note = n;
|
|
7627
|
+
}));
|
|
7628
|
+
if (filterError) {
|
|
7629
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
7630
|
+
return;
|
|
7631
|
+
}
|
|
7632
|
+
envelope.Data = filtered;
|
|
7633
|
+
if (note) {
|
|
7634
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
6978
7637
|
function defaultErrorCodeForResult(result) {
|
|
6979
7638
|
switch (result) {
|
|
6980
7639
|
case RESULTS.AuthenticationError:
|
|
@@ -7018,7 +7677,7 @@ function defaultErrorCodeForHttpStatus(status) {
|
|
|
7018
7677
|
return "server_error";
|
|
7019
7678
|
return;
|
|
7020
7679
|
}
|
|
7021
|
-
var LOCAL_PERMISSION_TEXT_PATTERN =
|
|
7680
|
+
var LOCAL_PERMISSION_TEXT_PATTERN = new RegExp(`(?:\\b|\\()(?:${[...LOCAL_PERMISSION_ERROR_CODES].join("|")})(?::\\s|\\))`);
|
|
7022
7681
|
function defaultErrorCodeForFailure(data) {
|
|
7023
7682
|
if (data.Result === RESULTS.Failure) {
|
|
7024
7683
|
const status = data.Context?.httpStatus ?? parseHttpStatusFromMessage2(data.Message);
|
|
@@ -7057,8 +7716,14 @@ var OutputFormatter;
|
|
|
7057
7716
|
}
|
|
7058
7717
|
const filter = getOutputFilter();
|
|
7059
7718
|
if (filter) {
|
|
7060
|
-
|
|
7719
|
+
let note;
|
|
7720
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
7721
|
+
note = n;
|
|
7722
|
+
});
|
|
7061
7723
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
7724
|
+
if (note) {
|
|
7725
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
7726
|
+
}
|
|
7062
7727
|
}
|
|
7063
7728
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
7064
7729
|
}
|
|
@@ -7086,12 +7751,13 @@ var OutputFormatter;
|
|
|
7086
7751
|
delete envelope.TelemetryErrorClass;
|
|
7087
7752
|
delete envelope.TelemetryTerminalOutcome;
|
|
7088
7753
|
delete envelope.TelemetryTerminalSignal;
|
|
7754
|
+
filterFailureData(envelope);
|
|
7089
7755
|
if (!suppressTelemetry) {
|
|
7090
7756
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7757
|
+
[ErrorDimensions.Result]: data.Result,
|
|
7758
|
+
[ErrorDimensions.ErrorCode]: data.ErrorCode,
|
|
7759
|
+
[ErrorDimensions.Retry]: data.Retry,
|
|
7760
|
+
[ErrorDimensions.ErrorMessage]: data.Message
|
|
7095
7761
|
});
|
|
7096
7762
|
}
|
|
7097
7763
|
logOutput(normalizeOutputKeys(envelope), getOutputFormat());
|
|
@@ -7134,13 +7800,20 @@ var OutputFormatter;
|
|
|
7134
7800
|
OutputFormatter.log = log;
|
|
7135
7801
|
function formatToString(data) {
|
|
7136
7802
|
const filter = getOutputFilter();
|
|
7803
|
+
const envelope = data;
|
|
7137
7804
|
if ("Data" in data && data.Data != null) {
|
|
7138
7805
|
data.Data = normalizeDataKeys(data.Data);
|
|
7139
7806
|
if (filter) {
|
|
7140
|
-
|
|
7807
|
+
let note;
|
|
7808
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
7809
|
+
note = n;
|
|
7810
|
+
}));
|
|
7811
|
+
if (note) {
|
|
7812
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
7813
|
+
}
|
|
7141
7814
|
}
|
|
7142
7815
|
}
|
|
7143
|
-
const output = normalizeOutputKeys(
|
|
7816
|
+
const output = normalizeOutputKeys(envelope);
|
|
7144
7817
|
const lines = [];
|
|
7145
7818
|
const sink = getOutputSink();
|
|
7146
7819
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -7190,7 +7863,7 @@ var LEGACY_SKILL_NAMESPACE = "uipath:";
|
|
|
7190
7863
|
var MAX_SKILL_NAME_LENGTH = 80;
|
|
7191
7864
|
var SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
7192
7865
|
function productMode(productArea, mode) {
|
|
7193
|
-
return {
|
|
7866
|
+
return { ProductArea: productArea, Mode: mode };
|
|
7194
7867
|
}
|
|
7195
7868
|
function attributionRecord(groups) {
|
|
7196
7869
|
const record = {};
|
|
@@ -7248,6 +7921,7 @@ var COMMAND_ATTRIBUTION = commandAttribution([
|
|
|
7248
7921
|
["rpa", "build", ["uip.rpa-legacy"]],
|
|
7249
7922
|
["conversational", "operate", ["uip.conversational"]],
|
|
7250
7923
|
["agents", "build", ["uip.codedagent", "uip.agent"]],
|
|
7924
|
+
["coding-agents", "build", ["uip.coder"]],
|
|
7251
7925
|
["agenthub", "build", ["uip.agenthub"]],
|
|
7252
7926
|
["coded-apps", "build", ["uip.codedapp"]],
|
|
7253
7927
|
["functions", "build", ["uip.function", "uip.functions"]],
|
|
@@ -7333,32 +8007,64 @@ function normalizeSkillName(value) {
|
|
|
7333
8007
|
function buildCommandTelemetryAttribution(commandPath, skillSource) {
|
|
7334
8008
|
const skillName = normalizeSkillName(skillSource);
|
|
7335
8009
|
return {
|
|
7336
|
-
...skillName ? {
|
|
8010
|
+
...skillName ? { SkillName: skillName } : {},
|
|
7337
8011
|
...getCommandProductModeAttribution(commandPath)
|
|
7338
8012
|
};
|
|
7339
8013
|
}
|
|
8014
|
+
var AGENT_SESSION_ENV = {
|
|
8015
|
+
[BaseDimensions.AgentModel]: "UIPATH_AGENT_MODEL",
|
|
8016
|
+
[SkillsDimensions.PermissionMode]: "UIPATH_PERMISSION_MODE",
|
|
8017
|
+
[SkillsDimensions.EffortLevel]: "UIPATH_EFFORT_LEVEL",
|
|
8018
|
+
[SkillsDimensions.SkillsVersion]: "UIPATH_SKILLS_VERSION"
|
|
8019
|
+
};
|
|
8020
|
+
var MAX_TELEMETRY_TOKEN_LENGTH = 120;
|
|
8021
|
+
function sanitizeTelemetryToken(value) {
|
|
8022
|
+
return value.replace(/[^A-Za-z0-9:._/ -]/g, "_").slice(0, MAX_TELEMETRY_TOKEN_LENGTH);
|
|
8023
|
+
}
|
|
8024
|
+
function buildAgentSessionTelemetry(env) {
|
|
8025
|
+
const dimensions = {};
|
|
8026
|
+
for (const [key, variable] of Object.entries(AGENT_SESSION_ENV)) {
|
|
8027
|
+
const value = env[variable]?.trim();
|
|
8028
|
+
if (value) {
|
|
8029
|
+
dimensions[key] = sanitizeTelemetryToken(value);
|
|
8030
|
+
}
|
|
8031
|
+
}
|
|
8032
|
+
return dimensions;
|
|
8033
|
+
}
|
|
7340
8034
|
|
|
7341
8035
|
// ../../common/src/telemetry/command-name.ts
|
|
7342
|
-
var
|
|
8036
|
+
var TELEMETRY_NAME_ROOT = "Cli";
|
|
8037
|
+
var CLI_COMMAND_ROOT = "uip";
|
|
8038
|
+
var TELEMETRY_NAME_BARE_ACTION = "Invoke";
|
|
7343
8039
|
function commandTelemetryName(parts) {
|
|
8040
|
+
const action = vetCommandTokens(parts).map(pascalizeToken).join("");
|
|
8041
|
+
return `${TELEMETRY_NAME_ROOT}.${action || TELEMETRY_NAME_BARE_ACTION}`;
|
|
8042
|
+
}
|
|
8043
|
+
function commandInvocationPath(parts) {
|
|
8044
|
+
return [CLI_COMMAND_ROOT, ...vetCommandTokens(parts)].join(" ");
|
|
8045
|
+
}
|
|
8046
|
+
function vetCommandTokens(parts) {
|
|
7344
8047
|
const tokens = [];
|
|
7345
8048
|
for (const part of parts) {
|
|
7346
|
-
const pieces = String(part ?? "").split(/\s+/).filter((token) => token && !token.startsWith("-") && token !==
|
|
8049
|
+
const pieces = String(part ?? "").split(/\s+/).filter((token) => token && !token.startsWith("-") && token !== CLI_COMMAND_ROOT);
|
|
7347
8050
|
if (pieces.every(isCommandToken)) {
|
|
7348
8051
|
tokens.push(...pieces);
|
|
7349
8052
|
continue;
|
|
7350
8053
|
}
|
|
7351
8054
|
tokens.push(UNKNOWN_TOKEN);
|
|
7352
8055
|
}
|
|
7353
|
-
return
|
|
8056
|
+
return tokens;
|
|
8057
|
+
}
|
|
8058
|
+
function pascalizeToken(token) {
|
|
8059
|
+
return token.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
7354
8060
|
}
|
|
7355
|
-
var COMMAND_TOKEN_PATTERN = /^[a-
|
|
8061
|
+
var COMMAND_TOKEN_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
7356
8062
|
var MAX_COMMAND_TOKEN_LENGTH = 32;
|
|
7357
8063
|
var GUID_TOKEN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
7358
8064
|
function isCommandToken(token) {
|
|
7359
|
-
return token.length <= MAX_COMMAND_TOKEN_LENGTH && COMMAND_TOKEN_PATTERN.test(token) && !GUID_TOKEN.test(token)
|
|
8065
|
+
return token.length <= MAX_COMMAND_TOKEN_LENGTH && COMMAND_TOKEN_PATTERN.test(token) && !GUID_TOKEN.test(token);
|
|
7360
8066
|
}
|
|
7361
|
-
var UNKNOWN_TOKEN = "
|
|
8067
|
+
var UNKNOWN_TOKEN = "unknown";
|
|
7362
8068
|
|
|
7363
8069
|
// ../../common/src/telemetry/invocation-request.ts
|
|
7364
8070
|
var requestContextSlot = singleton("TelemetryInvocationRequestContext");
|
|
@@ -7463,7 +8169,7 @@ function withheldArgumentValues(cmd) {
|
|
|
7463
8169
|
});
|
|
7464
8170
|
return values;
|
|
7465
8171
|
}
|
|
7466
|
-
function
|
|
8172
|
+
function deriveCommandParts(cmd) {
|
|
7467
8173
|
const parts = [];
|
|
7468
8174
|
let current = cmd;
|
|
7469
8175
|
while (current) {
|
|
@@ -7476,14 +8182,13 @@ function deriveCommandPath(cmd) {
|
|
|
7476
8182
|
if (parts.length > 1) {
|
|
7477
8183
|
parts.shift();
|
|
7478
8184
|
}
|
|
7479
|
-
return
|
|
8185
|
+
return parts;
|
|
7480
8186
|
}
|
|
7481
8187
|
function isErrorContext(value) {
|
|
7482
8188
|
return value !== null && typeof value === "object";
|
|
7483
8189
|
}
|
|
7484
8190
|
function commandHelpHint(commandPath) {
|
|
7485
|
-
|
|
7486
|
-
return `An unexpected error occurred. Run '${command} --help' to verify command syntax, or run with --log-level debug for details.`;
|
|
8191
|
+
return `An unexpected error occurred. Run '${commandPath} --help' to verify command syntax, or run with --log-level debug for details.`;
|
|
7487
8192
|
}
|
|
7488
8193
|
function isPromptCancellation(error) {
|
|
7489
8194
|
return error instanceof Error && error.name === "ExitPromptError";
|
|
@@ -7508,7 +8213,9 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
7508
8213
|
yaml: getOutputFormat() === "yaml",
|
|
7509
8214
|
filter: getOutputFilter() !== undefined
|
|
7510
8215
|
});
|
|
7511
|
-
const
|
|
8216
|
+
const commandParts = deriveCommandParts(command);
|
|
8217
|
+
const telemetryName = commandTelemetryName(commandParts);
|
|
8218
|
+
const commandPath = commandInvocationPath(commandParts);
|
|
7512
8219
|
const props = typeof properties === "function" ? properties(...args) : properties;
|
|
7513
8220
|
markCommandStart();
|
|
7514
8221
|
const supplied = recordSuppliedArgumentValues(withheldArgumentValues(command));
|
|
@@ -7543,7 +8250,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
7543
8250
|
Result: finalResult,
|
|
7544
8251
|
...customErrorCode ? { ErrorCode: customErrorCode } : {},
|
|
7545
8252
|
Message: errorMessage2,
|
|
7546
|
-
Instructions: customInstructions ?? commandHelpHint(
|
|
8253
|
+
Instructions: customInstructions ?? commandHelpHint(commandPath),
|
|
7547
8254
|
...customRetry ? { Retry: customRetry } : {},
|
|
7548
8255
|
...customContext ? { Context: customContext } : {}
|
|
7549
8256
|
});
|
|
@@ -7560,8 +8267,8 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
7560
8267
|
recordedFailure,
|
|
7561
8268
|
pollSignal: context.pollSignal
|
|
7562
8269
|
});
|
|
7563
|
-
if (terminalTelemetry.
|
|
7564
|
-
telemetry.trackException(error instanceof Error ? error : new Error(String(error)), {
|
|
8270
|
+
if (terminalTelemetry[CommandDimensions.ErrorClass] === "internal" && error) {
|
|
8271
|
+
telemetry.trackException(error instanceof Error ? error : new Error(String(error)), { [CommandDimensions.CommandName]: commandPath }, getInvocationRequestContext());
|
|
7565
8272
|
}
|
|
7566
8273
|
const commandParams = extractCommandParams(command);
|
|
7567
8274
|
if (props) {
|
|
@@ -7572,10 +8279,12 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
7572
8279
|
const baseProperties = redactProperties({
|
|
7573
8280
|
...commandParams,
|
|
7574
8281
|
...props,
|
|
7575
|
-
...buildCommandTelemetryAttribution(
|
|
7576
|
-
|
|
8282
|
+
...buildCommandTelemetryAttribution(commandPath, process.env.UIPATH_SKILL),
|
|
8283
|
+
...buildAgentSessionTelemetry(process.env),
|
|
8284
|
+
[CommandDimensions.CommandName]: commandPath,
|
|
8285
|
+
[CommandDimensions.IsCommand]: "true",
|
|
7577
8286
|
...terminalTelemetry,
|
|
7578
|
-
...errorMessage2 ? {
|
|
8287
|
+
...errorMessage2 ? { [CommandDimensions.ErrorMessage]: errorMessage2 } : {}
|
|
7579
8288
|
});
|
|
7580
8289
|
emitInvocationRequest(telemetryName, success, baseProperties);
|
|
7581
8290
|
} finally {
|
|
@@ -7806,6 +8515,40 @@ var BOOLEAN_FLAGS = new Set(HOST_GLOBAL_FLAGS);
|
|
|
7806
8515
|
// ../../common/src/interactivity-context.ts
|
|
7807
8516
|
var modeSlot = singleton("InteractivityMode");
|
|
7808
8517
|
var interactiveFlagSlot = singleton("InteractiveFlag");
|
|
8518
|
+
// ../../common/src/mime-types.ts
|
|
8519
|
+
var MIME_TYPES_BY_EXTENSION = Object.freeze({
|
|
8520
|
+
pdf: "application/pdf",
|
|
8521
|
+
png: "image/png",
|
|
8522
|
+
jpg: "image/jpeg",
|
|
8523
|
+
jpeg: "image/jpeg",
|
|
8524
|
+
gif: "image/gif",
|
|
8525
|
+
webp: "image/webp",
|
|
8526
|
+
bmp: "image/bmp",
|
|
8527
|
+
tif: "image/tiff",
|
|
8528
|
+
tiff: "image/tiff",
|
|
8529
|
+
svg: "image/svg+xml",
|
|
8530
|
+
txt: "text/plain",
|
|
8531
|
+
log: "text/plain",
|
|
8532
|
+
md: "text/markdown",
|
|
8533
|
+
csv: "text/csv",
|
|
8534
|
+
tsv: "text/tab-separated-values",
|
|
8535
|
+
json: "application/json",
|
|
8536
|
+
xml: "application/xml",
|
|
8537
|
+
html: "text/html",
|
|
8538
|
+
htm: "text/html",
|
|
8539
|
+
yaml: "application/yaml",
|
|
8540
|
+
yml: "application/yaml",
|
|
8541
|
+
doc: "application/msword",
|
|
8542
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
8543
|
+
xls: "application/vnd.ms-excel",
|
|
8544
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
8545
|
+
ppt: "application/vnd.ms-powerpoint",
|
|
8546
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
8547
|
+
zip: "application/zip",
|
|
8548
|
+
mp3: "audio/mpeg",
|
|
8549
|
+
wav: "audio/wav",
|
|
8550
|
+
mp4: "video/mp4"
|
|
8551
|
+
});
|
|
7809
8552
|
// ../../common/src/option-validators.ts
|
|
7810
8553
|
function parseLimit(raw, _previous) {
|
|
7811
8554
|
return parseBoundedInt(raw, "--limit", { min: 1, max: 1e4 });
|
|
@@ -7871,6 +8614,530 @@ var ScreenLogger;
|
|
|
7871
8614
|
var shippedKeysSlot = singleton("ShipSucceededDedupeKeys");
|
|
7872
8615
|
// ../../common/src/tool-provider.ts
|
|
7873
8616
|
var factorySlot = singleton("PackagerFactoryProvider");
|
|
8617
|
+
// src/commands/exclusions.ts
|
|
8618
|
+
var ENFORCEMENT = "Exclude";
|
|
8619
|
+
var ID_DIMENSIONS2 = [
|
|
8620
|
+
{ option: "excludeTenant", flag: "--exclude-tenant", dimension: "Tenant" },
|
|
8621
|
+
{ option: "source", flag: "--source", dimension: "EventSource" },
|
|
8622
|
+
{ option: "target", flag: "--target", dimension: "EventTarget" },
|
|
8623
|
+
{ option: "type", flag: "--type", dimension: "EventType" }
|
|
8624
|
+
];
|
|
8625
|
+
var STATUS_VALUES = ["Success", "Failure"];
|
|
8626
|
+
var SELECTOR_FLAGS = [
|
|
8627
|
+
...ID_DIMENSIONS2.map((d) => d.flag),
|
|
8628
|
+
"--status"
|
|
8629
|
+
];
|
|
8630
|
+
var GUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
8631
|
+
var EMPTY_GUID = "00000000-0000-0000-0000-000000000000";
|
|
8632
|
+
var WRITE_BODY_KEYS = ["name", "enforcement", "isActive", "selectors"];
|
|
8633
|
+
var SELECTOR_KEYS = ["type", "values"];
|
|
8634
|
+
var MAX_FILE_LENGTH = 64 * 1024;
|
|
8635
|
+
var SAMPLE_ID = "3f6b1d84-9a1e-4c2b-8e71-2f9c5d0a7b13";
|
|
8636
|
+
var SAMPLE_NAME = "Mute successful robot logins";
|
|
8637
|
+
var SAMPLE_TYPE_ID = "0f54d68a-15fd-427d-a86a-2812bb7fbb28";
|
|
8638
|
+
var CODE_INSTRUCTIONS = {
|
|
8639
|
+
RuleNotFound: "Check the name or id with 'uip admin audit org exclusions list'. A rule owned by another organization also reads as not found.",
|
|
8640
|
+
DuplicateRuleName: "Another ACTIVE rule already uses that name. Pick a different --name, or update the existing rule. An inactive rule may keep a name in use.",
|
|
8641
|
+
OverlappingRuleExists: "An active rule already excludes everything this one would — its id is in the message. Delete or narrow that rule, or save this one with --inactive to stage it alongside.",
|
|
8642
|
+
RuleLimitExceeded: "The organization is at its exclusion-rule cap. Delete a rule with 'uip admin audit org exclusions delete <rule>' before adding another.",
|
|
8643
|
+
EmptySelectorsNotAllowed: `Pass at least one of ${SELECTOR_FLAGS.join(" / ")}. A rule that constrains nothing would exclude every event in the organization.`,
|
|
8644
|
+
InvalidSelectorValue: "Selector values are GUIDs, except --status which takes 'Success' or 'Failure'.",
|
|
8645
|
+
UnknownSelectorValue: "No audit metadata defines that id. Discover valid source / target / type ids with 'uip admin audit org sources --output json'.",
|
|
8646
|
+
SelectorValueNotPermitted: "That value cannot be excluded: UiPath's own monitoring events and audit-configuration changes always stay in the trail. Narrow the rule to the events you own.",
|
|
8647
|
+
SelectorLimitExceeded: "Too many selectors, or too many values in one selector. Split the rule into several narrower ones.",
|
|
8648
|
+
RuleModifiedConcurrently: "Another admin changed the rule while this call was in flight. Re-read it with 'exclusions get <rule>' and retry.",
|
|
8649
|
+
InvalidRequest: "The body was rejected before it reached the rule logic — the message names the field. Server-owned fields (policyId, timestamps) may not be sent."
|
|
8650
|
+
};
|
|
8651
|
+
function fallbackInstructions(verb, message, status) {
|
|
8652
|
+
if (/Not logged in/i.test(message))
|
|
8653
|
+
return "Run 'uip login' and retry.";
|
|
8654
|
+
if (status === 401)
|
|
8655
|
+
return "Token may be missing the 'Audit.Read' scope. Run 'uip logout && uip login' to mint a fresh token.";
|
|
8656
|
+
if (status === 403)
|
|
8657
|
+
return "Reading rules needs audit-read permission; creating, replacing or deleting one needs an Administrators-group membership and a user token — a service-to-service token is refused on writes.";
|
|
8658
|
+
if (verb === "list" || verb === "get")
|
|
8659
|
+
return "Confirm you are logged in against the right organization with 'uip login status'.";
|
|
8660
|
+
if (verb === "delete")
|
|
8661
|
+
return "Check the name or id with 'uip admin audit org exclusions list'.";
|
|
8662
|
+
return `Pass --name plus at least one of ${SELECTOR_FLAGS.join(" / ")}, or --file with an ExclusionRuleWriteDto body.`;
|
|
8663
|
+
}
|
|
8664
|
+
async function emitFailure(verb, error) {
|
|
8665
|
+
const details = await extractErrorDetails(error);
|
|
8666
|
+
OutputFormatter.error({
|
|
8667
|
+
Result: details.result,
|
|
8668
|
+
ErrorCode: details.errorCode,
|
|
8669
|
+
Retry: details.retry,
|
|
8670
|
+
Message: details.message,
|
|
8671
|
+
Instructions: codeInstructions(details.context?.errorCode) ?? fallbackInstructions(verb, details.message, details.context?.httpStatus),
|
|
8672
|
+
...details.context ? { Context: details.context } : {}
|
|
8673
|
+
});
|
|
8674
|
+
processContext.exit(EXIT_CODES[details.result] ?? EXIT_CODES.Failure);
|
|
8675
|
+
}
|
|
8676
|
+
function codeInstructions(code) {
|
|
8677
|
+
if (code === undefined)
|
|
8678
|
+
return;
|
|
8679
|
+
return Object.hasOwn(CODE_INSTRUCTIONS, code) ? CODE_INSTRUCTIONS[code] : undefined;
|
|
8680
|
+
}
|
|
8681
|
+
var LOOKUP_INSTRUCTIONS = {
|
|
8682
|
+
ambiguous: "A name is unique only among ACTIVE rules, so an inactive rule may share it. Pass the policy id of the one you mean.",
|
|
8683
|
+
unidentifiable: "Nothing can address that rule - not even the id, which the service did not return. Re-read the list with 'uip admin audit org exclusions list'; a rule still listed without a policyId needs fixing server-side.",
|
|
8684
|
+
"not-found": "Check the name with 'uip admin audit org exclusions list', or pass the rule's policy id instead."
|
|
8685
|
+
};
|
|
8686
|
+
function emitLookupError(verb, error) {
|
|
8687
|
+
const isCallerError = error.reason === "ambiguous";
|
|
8688
|
+
OutputFormatter.error({
|
|
8689
|
+
Result: isCallerError ? RESULTS.ValidationError : RESULTS.Failure,
|
|
8690
|
+
ErrorCode: isCallerError ? "invalid_argument" : "not_found",
|
|
8691
|
+
Retry: "RetryWillNotFix",
|
|
8692
|
+
Message: error.message,
|
|
8693
|
+
Instructions: error.reason === "not-found" ? `${LOOKUP_INSTRUCTIONS["not-found"]} ('${verb}' takes either.)` : LOOKUP_INSTRUCTIONS[error.reason]
|
|
8694
|
+
});
|
|
8695
|
+
processContext.exit(isCallerError ? EXIT_CODES.ValidationError : EXIT_CODES.Failure);
|
|
8696
|
+
}
|
|
8697
|
+
|
|
8698
|
+
class BodyError extends Error {
|
|
8699
|
+
instructions;
|
|
8700
|
+
constructor(message, instructions) {
|
|
8701
|
+
super(message);
|
|
8702
|
+
this.name = "BodyError";
|
|
8703
|
+
this.instructions = instructions;
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8706
|
+
async function emitBodyFailure(verb, error) {
|
|
8707
|
+
if (!(error instanceof BodyError)) {
|
|
8708
|
+
await emitFailure(verb, error);
|
|
8709
|
+
return;
|
|
8710
|
+
}
|
|
8711
|
+
OutputFormatter.error({
|
|
8712
|
+
Result: RESULTS.ValidationError,
|
|
8713
|
+
Message: error.message,
|
|
8714
|
+
Instructions: error.instructions
|
|
8715
|
+
});
|
|
8716
|
+
processContext.exit(EXIT_CODES.ValidationError);
|
|
8717
|
+
}
|
|
8718
|
+
var FILE_BODY_INSTRUCTIONS = "A rule body carries only name, enforcement, isActive and selectors. policyId and the timestamps are server-owned and are rejected rather than ignored.";
|
|
8719
|
+
var FILE_READ_INSTRUCTIONS = "Check the --file path and that the file holds one JSON object shaped like an ExclusionRuleWriteDto.";
|
|
8720
|
+
var ID_INSTRUCTIONS = "Selector ids are GUIDs. Discover source / target / type ids with 'uip admin audit org sources --output json'.";
|
|
8721
|
+
function assertIds(label, values) {
|
|
8722
|
+
for (const value of values) {
|
|
8723
|
+
const trimmed = value.trim();
|
|
8724
|
+
if (!GUID_RE.test(trimmed) || trimmed.toLowerCase() === EMPTY_GUID) {
|
|
8725
|
+
throw new BodyError(`${label} expects a GUID, got '${value}'.`, ID_INSTRUCTIONS);
|
|
8726
|
+
}
|
|
8727
|
+
}
|
|
8728
|
+
}
|
|
8729
|
+
function assertNotGuidShaped(name) {
|
|
8730
|
+
if (isGuid(name)) {
|
|
8731
|
+
throw new BodyError(`'${name}' cannot be used as a rule name: it is shaped like a policy id.`, "Pick a name that is not a bare GUID. 'get', 'update' and 'delete' read a GUID as a policy id, so a rule named like one could not be reached by name — and would shadow whichever rule owns that id.");
|
|
8732
|
+
}
|
|
8733
|
+
}
|
|
8734
|
+
var STATUS_ALIASES = new Map([
|
|
8735
|
+
["success", "Success"],
|
|
8736
|
+
["0", "Success"],
|
|
8737
|
+
["failure", "Failure"],
|
|
8738
|
+
["1", "Failure"]
|
|
8739
|
+
]);
|
|
8740
|
+
var DIMENSION_NAMES = [
|
|
8741
|
+
...ID_DIMENSIONS2.map((dimension) => dimension.dimension),
|
|
8742
|
+
"Status"
|
|
8743
|
+
];
|
|
8744
|
+
function validateSelector(raw, seen) {
|
|
8745
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
8746
|
+
throw new BodyError("Each selector must be a JSON object.", FILE_BODY_INSTRUCTIONS);
|
|
8747
|
+
}
|
|
8748
|
+
const selector = raw;
|
|
8749
|
+
const unknownKeys = Object.keys(selector).filter((key) => !SELECTOR_KEYS.includes(key));
|
|
8750
|
+
if (unknownKeys.length > 0) {
|
|
8751
|
+
throw new BodyError(`Unsupported field(s) in a selector: ${unknownKeys.join(", ")}.`, `A selector carries only ${SELECTOR_KEYS.join(" and ")}: a 'type' naming the dimension and its 'values'.`);
|
|
8752
|
+
}
|
|
8753
|
+
const type = selector.type;
|
|
8754
|
+
if (typeof type !== "string" || !DIMENSION_NAMES.includes(type)) {
|
|
8755
|
+
throw new BodyError(`'${String(type)}' is not an exclusion dimension.`, `A selector's 'type' is one of ${DIMENSION_NAMES.join(", ")}.`);
|
|
8756
|
+
}
|
|
8757
|
+
if (seen.has(type)) {
|
|
8758
|
+
throw new BodyError(`Two selectors constrain '${type}'.`, "A rule constrains each dimension at most once. Put every value for a dimension in that one selector's 'values'.");
|
|
8759
|
+
}
|
|
8760
|
+
seen.add(type);
|
|
8761
|
+
const values = selector.values;
|
|
8762
|
+
if (!Array.isArray(values) || values.length === 0 || values.some((value) => typeof value !== "string")) {
|
|
8763
|
+
throw new BodyError(`The '${type}' selector needs a non-empty 'values' array of strings.`, "A selector names the values it matches; an empty one would constrain nothing on that dimension.");
|
|
8764
|
+
}
|
|
8765
|
+
const label = `selector '${type}'`;
|
|
8766
|
+
if (type === "Status") {
|
|
8767
|
+
return {
|
|
8768
|
+
type,
|
|
8769
|
+
values: values.map((value) => canonicalStatus(value, label))
|
|
8770
|
+
};
|
|
8771
|
+
}
|
|
8772
|
+
assertIds(label, values);
|
|
8773
|
+
return { type, values: values.map((value) => value.trim()) };
|
|
8774
|
+
}
|
|
8775
|
+
function canonicalStatus(value, label = "--status") {
|
|
8776
|
+
const match = STATUS_ALIASES.get(value.trim().toLowerCase());
|
|
8777
|
+
if (!match) {
|
|
8778
|
+
throw new BodyError(`${label} expects ${STATUS_VALUES.join(" or ")}, got '${value}'.`, "Use --status Success or --status Failure (case-insensitive; 0 and 1 work too, as on `audit <scope> events`). One or the other: a rule that excludes both outcomes constrains nothing on this dimension.");
|
|
8779
|
+
}
|
|
8780
|
+
return match;
|
|
8781
|
+
}
|
|
8782
|
+
function bodyFromFlags(options) {
|
|
8783
|
+
const name = options.name?.trim();
|
|
8784
|
+
if (!name) {
|
|
8785
|
+
throw new BodyError("--name is required.", `Pass --name "<rule name>". It must be unique among the organization's active rules.`);
|
|
8786
|
+
}
|
|
8787
|
+
assertNotGuidShaped(name);
|
|
8788
|
+
const selectors = [];
|
|
8789
|
+
for (const { option, flag, dimension } of ID_DIMENSIONS2) {
|
|
8790
|
+
const values = options[option];
|
|
8791
|
+
if (!values?.length)
|
|
8792
|
+
continue;
|
|
8793
|
+
assertIds(flag, values);
|
|
8794
|
+
selectors.push({
|
|
8795
|
+
type: dimension,
|
|
8796
|
+
values: values.map((v) => v.trim())
|
|
8797
|
+
});
|
|
8798
|
+
}
|
|
8799
|
+
if (options.status !== undefined) {
|
|
8800
|
+
selectors.push({
|
|
8801
|
+
type: "Status",
|
|
8802
|
+
values: [canonicalStatus(options.status)]
|
|
8803
|
+
});
|
|
8804
|
+
}
|
|
8805
|
+
if (selectors.length === 0) {
|
|
8806
|
+
throw new BodyError("A rule must constrain at least one dimension.", CODE_INSTRUCTIONS.EmptySelectorsNotAllowed);
|
|
8807
|
+
}
|
|
8808
|
+
return {
|
|
8809
|
+
name,
|
|
8810
|
+
enforcement: ENFORCEMENT,
|
|
8811
|
+
isActive: options.inactive !== true,
|
|
8812
|
+
selectors
|
|
8813
|
+
};
|
|
8814
|
+
}
|
|
8815
|
+
function validateWriteBody(parsed) {
|
|
8816
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
8817
|
+
throw new BodyError("The file must contain a JSON object.", FILE_READ_INSTRUCTIONS);
|
|
8818
|
+
}
|
|
8819
|
+
const body = parsed;
|
|
8820
|
+
const unknown = Object.keys(body).filter((key) => !WRITE_BODY_KEYS.includes(key));
|
|
8821
|
+
if (unknown.length > 0) {
|
|
8822
|
+
throw new BodyError(`Unsupported field(s) in --file: ${unknown.join(", ")}.`, FILE_BODY_INSTRUCTIONS);
|
|
8823
|
+
}
|
|
8824
|
+
if (typeof body.name !== "string" || body.name.trim() === "") {
|
|
8825
|
+
throw new BodyError("The file must set a non-empty 'name'.", "Give the rule a name in the file's 'name' field. It must be unique among the organization's active rules.");
|
|
8826
|
+
}
|
|
8827
|
+
const name = body.name.trim();
|
|
8828
|
+
assertNotGuidShaped(name);
|
|
8829
|
+
if (body.selectors !== undefined && body.selectors !== null && !Array.isArray(body.selectors)) {
|
|
8830
|
+
throw new BodyError("'selectors' must be an array.", FILE_BODY_INSTRUCTIONS);
|
|
8831
|
+
}
|
|
8832
|
+
const seenDimensions = new Set;
|
|
8833
|
+
const selectors = Array.isArray(body.selectors) ? body.selectors.map((selector) => validateSelector(selector, seenDimensions)) : [];
|
|
8834
|
+
if (selectors.length === 0) {
|
|
8835
|
+
throw new BodyError("A rule must constrain at least one dimension.", "Give the file's 'selectors' at least one entry. A rule that constrains nothing would exclude every event in the organization.");
|
|
8836
|
+
}
|
|
8837
|
+
return {
|
|
8838
|
+
...body,
|
|
8839
|
+
name,
|
|
8840
|
+
selectors,
|
|
8841
|
+
enforcement: body.enforcement ?? ENFORCEMENT,
|
|
8842
|
+
isActive: body.isActive ?? true
|
|
8843
|
+
};
|
|
8844
|
+
}
|
|
8845
|
+
function tooLarge(amount, unit) {
|
|
8846
|
+
return new BodyError(`--file is ${amount} ${unit}; a rule body may not exceed ${MAX_FILE_LENGTH}.`, "Point --file at a single rule body. The file is one rule, not an export of many.");
|
|
8847
|
+
}
|
|
8848
|
+
async function bodyFromFile(file) {
|
|
8849
|
+
const fs2 = getFileSystem();
|
|
8850
|
+
const stats = await fs2.stat(file);
|
|
8851
|
+
if (stats && stats.size > MAX_FILE_LENGTH) {
|
|
8852
|
+
throw tooLarge(stats.size, "bytes");
|
|
8853
|
+
}
|
|
8854
|
+
const content = await fs2.readFile(file, "utf-8");
|
|
8855
|
+
if (content === null || content === undefined) {
|
|
8856
|
+
throw new BodyError(`File not found: ${file}`, FILE_READ_INSTRUCTIONS);
|
|
8857
|
+
}
|
|
8858
|
+
const raw = String(content);
|
|
8859
|
+
const byteLength = new TextEncoder().encode(raw).length;
|
|
8860
|
+
if (byteLength > MAX_FILE_LENGTH) {
|
|
8861
|
+
throw tooLarge(byteLength, "bytes");
|
|
8862
|
+
}
|
|
8863
|
+
let parsed;
|
|
8864
|
+
try {
|
|
8865
|
+
parsed = JSON.parse(raw);
|
|
8866
|
+
} catch (err) {
|
|
8867
|
+
throw new BodyError(`--file is not valid JSON: ${err instanceof Error ? err.message : String(err)}`, FILE_READ_INSTRUCTIONS);
|
|
8868
|
+
}
|
|
8869
|
+
return validateWriteBody(parsed);
|
|
8870
|
+
}
|
|
8871
|
+
async function resolveBody(options) {
|
|
8872
|
+
const inlineFlags = [
|
|
8873
|
+
options.name !== undefined && "--name",
|
|
8874
|
+
options.inactive === true && "--inactive",
|
|
8875
|
+
...ID_DIMENSIONS2.map(({ option, flag }) => options[option]?.length && flag),
|
|
8876
|
+
options.status !== undefined && "--status"
|
|
8877
|
+
].filter((flag) => typeof flag === "string");
|
|
8878
|
+
if (options.file !== undefined) {
|
|
8879
|
+
if (inlineFlags.length > 0) {
|
|
8880
|
+
throw new BodyError(`--file cannot be combined with ${inlineFlags.join(", ")}.`, "Pass either --file with the whole body, or the inline flags — not both. Merging them would leave it ambiguous which input owns a field both set.");
|
|
8881
|
+
}
|
|
8882
|
+
return await bodyFromFile(options.file);
|
|
8883
|
+
}
|
|
8884
|
+
return bodyFromFlags(options);
|
|
8885
|
+
}
|
|
8886
|
+
async function getApi(options) {
|
|
8887
|
+
return await createApiClient(EventConfigApi, {
|
|
8888
|
+
scope: "org",
|
|
8889
|
+
loginValidity: options.loginValidity
|
|
8890
|
+
});
|
|
8891
|
+
}
|
|
8892
|
+
var RULE_ARGUMENT = [
|
|
8893
|
+
"<rule>",
|
|
8894
|
+
"Rule name, or its policy id. A name is matched against the organization's rules; an id is used as it stands."
|
|
8895
|
+
];
|
|
8896
|
+
async function resolveTarget(verb, rule, options) {
|
|
8897
|
+
const [apiError, api] = await catchError2(getApi(options));
|
|
8898
|
+
if (apiError || !api) {
|
|
8899
|
+
await emitFailure(verb, apiError);
|
|
8900
|
+
return;
|
|
8901
|
+
}
|
|
8902
|
+
const [lookupError, target] = await catchError2(resolveExclusionRule(api, rule));
|
|
8903
|
+
if (lookupError || !target) {
|
|
8904
|
+
if (lookupError instanceof ExclusionRuleLookupError) {
|
|
8905
|
+
emitLookupError(verb, lookupError);
|
|
8906
|
+
} else {
|
|
8907
|
+
await emitFailure(verb, lookupError);
|
|
8908
|
+
}
|
|
8909
|
+
return;
|
|
8910
|
+
}
|
|
8911
|
+
return { api, policyId: target.policyId, resolved: target.rule };
|
|
8912
|
+
}
|
|
8913
|
+
function withLoginValidity(cmd) {
|
|
8914
|
+
return cmd.option("--login-validity <minutes>", "Override the interactive-login token lifetime for this call. Rarely needed.", (v) => Number.parseInt(v, 10));
|
|
8915
|
+
}
|
|
8916
|
+
function withWriteOptions(cmd) {
|
|
8917
|
+
return withLoginValidity(cmd.option("--name <name>", "Rule name, unique among the organization's ACTIVE rules. Max 256 characters.").option("--exclude-tenant <guid...>", "Tenant selector: exclude events from these tenants only. Repeatable. Not spelled --tenant-id, which on the read verbs picks the tenant a call runs against rather than the tenants a rule matches. A tenant outside this organization is accepted but matches nothing, so a typo reads as a rule that silently never fires.").option("--source <guid...>", "EventSource selector. Repeatable. Discover ids with `audit org sources`.").option("--target <guid...>", "EventTarget selector. Repeatable. Discover ids with `audit org sources`.").option("--type <guid...>", "EventType selector. Repeatable. Discover ids with `audit org sources`.").option("--status <status>", "Status selector: 'Success' or 'Failure' (case-insensitive). Single-valued, like --status on `audit <scope> events` — a selector holding both statuses matches every event, which is what omitting the flag already does.").option("--inactive", "Save the rule without activating it. Nothing is excluded until it is active, and an inactive rule may reuse an active rule's name or match set.").option("--file <path>", "Path to a JSON file holding the whole rule body (name, enforcement, isActive, selectors). Mutually exclusive with the flags above."));
|
|
8918
|
+
}
|
|
8919
|
+
var SAMPLE_RULE = {
|
|
8920
|
+
policyId: SAMPLE_ID,
|
|
8921
|
+
name: SAMPLE_NAME,
|
|
8922
|
+
enforcement: ENFORCEMENT,
|
|
8923
|
+
isActive: true,
|
|
8924
|
+
activatedOn: "2026-09-17T09:14:22.000Z",
|
|
8925
|
+
selectors: [
|
|
8926
|
+
{ type: "EventType", values: [SAMPLE_TYPE_ID] },
|
|
8927
|
+
{ type: "Status", values: ["Success"] }
|
|
8928
|
+
],
|
|
8929
|
+
createdOn: "2026-09-17T09:14:22.000Z",
|
|
8930
|
+
lastModifiedOn: "2026-09-17T09:14:22.000Z"
|
|
8931
|
+
};
|
|
8932
|
+
var LIST_EXAMPLES = [
|
|
8933
|
+
{
|
|
8934
|
+
Description: "List the organization's exclusion rules, ordered by name",
|
|
8935
|
+
Command: "uip admin audit org exclusions list",
|
|
8936
|
+
Output: { Code: "AuditOrgExclusionsList", Data: [SAMPLE_RULE] }
|
|
8937
|
+
}
|
|
8938
|
+
];
|
|
8939
|
+
var GET_EXAMPLES = [
|
|
8940
|
+
{
|
|
8941
|
+
Description: "Read one rule by the name it was given",
|
|
8942
|
+
Command: `uip admin audit org exclusions get "${SAMPLE_NAME}"`,
|
|
8943
|
+
Output: { Code: "AuditOrgExclusionsGet", Data: SAMPLE_RULE }
|
|
8944
|
+
},
|
|
8945
|
+
{
|
|
8946
|
+
Description: "Read it by policy id instead, which skips the name lookup",
|
|
8947
|
+
Command: `uip admin audit org exclusions get ${SAMPLE_ID}`,
|
|
8948
|
+
Output: { Code: "AuditOrgExclusionsGet", Data: SAMPLE_RULE }
|
|
8949
|
+
}
|
|
8950
|
+
];
|
|
8951
|
+
var CREATE_EXAMPLES = [
|
|
8952
|
+
{
|
|
8953
|
+
Description: "Stop recording successful events of one event type (the two selectors are AND-ed)",
|
|
8954
|
+
Command: `uip admin audit org exclusions create --name "Mute successful robot logins" --type ${SAMPLE_TYPE_ID} --status Success`,
|
|
8955
|
+
Output: { Code: "AuditOrgExclusionsCreated", Data: SAMPLE_RULE }
|
|
8956
|
+
},
|
|
8957
|
+
{
|
|
8958
|
+
Description: "Stage a rule without activating it, so it excludes nothing until it is turned on",
|
|
8959
|
+
Command: `uip admin audit org exclusions create --name "Staged" --source ${SAMPLE_ID} --inactive`,
|
|
8960
|
+
Output: {
|
|
8961
|
+
Code: "AuditOrgExclusionsCreated",
|
|
8962
|
+
Data: { ...SAMPLE_RULE, isActive: false, activatedOn: null }
|
|
8963
|
+
}
|
|
8964
|
+
},
|
|
8965
|
+
{
|
|
8966
|
+
Description: "Create from a JSON body instead of flags",
|
|
8967
|
+
Command: "uip admin audit org exclusions create --file ./rule.json",
|
|
8968
|
+
Output: { Code: "AuditOrgExclusionsCreated", Data: SAMPLE_RULE }
|
|
8969
|
+
}
|
|
8970
|
+
];
|
|
8971
|
+
var UPDATE_EXAMPLES = [
|
|
8972
|
+
{
|
|
8973
|
+
Description: "Replace a rule in full — every field is resent, and omitted selectors are dropped",
|
|
8974
|
+
Command: `uip admin audit org exclusions update "${SAMPLE_NAME}" --name "${SAMPLE_NAME}" --type ${SAMPLE_TYPE_ID} --status Success`,
|
|
8975
|
+
Output: { Code: "AuditOrgExclusionsUpdated", Data: SAMPLE_RULE }
|
|
8976
|
+
}
|
|
8977
|
+
];
|
|
8978
|
+
var DELETE_EXAMPLES = [
|
|
8979
|
+
{
|
|
8980
|
+
Description: "Delete a rule, so its events are recorded again from now on",
|
|
8981
|
+
Command: `uip admin audit org exclusions delete "${SAMPLE_NAME}"`,
|
|
8982
|
+
Output: { Code: "AuditOrgExclusionsDeleted", Data: {} }
|
|
8983
|
+
}
|
|
8984
|
+
];
|
|
8985
|
+
function registerExclusionCommands(org) {
|
|
8986
|
+
const exclusions = org.command("exclusions").description([
|
|
8987
|
+
"Manage the organization's audit exclusion rules — which events the audit trail stops recording.",
|
|
8988
|
+
"",
|
|
8989
|
+
"A rule carries one selector per dimension (Tenant, EventSource, EventTarget, EventType, Status).",
|
|
8990
|
+
"Values inside a selector are OR-ed, and selectors are AND-ed: `--type A --type B --status Success`",
|
|
8991
|
+
"excludes successful events of type A or B. A rule with no selector is refused — it would",
|
|
8992
|
+
"exclude everything.",
|
|
8993
|
+
"",
|
|
8994
|
+
"Exclusion starts when the rule becomes active and is never retroactive: events already in the",
|
|
8995
|
+
"trail stay there, and widening a rule's match set re-stamps that start time. An inactive rule",
|
|
8996
|
+
"excludes nothing, which is how you stage a replacement next to the rule it takes over from.",
|
|
8997
|
+
"",
|
|
8998
|
+
"`get`, `update` and `delete` take the rule's name or its policy id. A name is unique only",
|
|
8999
|
+
"among ACTIVE rules, so if an inactive rule shares one the CLI asks for the id rather than",
|
|
9000
|
+
"guessing which you meant.",
|
|
9001
|
+
"",
|
|
9002
|
+
"Org-scoped only (there is no `audit tenant exclusions`): name the tenants a rule applies to with",
|
|
9003
|
+
"--exclude-tenant. Reading rules needs audit-read permission; every write needs a user token whose",
|
|
9004
|
+
"identity is in the Administrators group.",
|
|
9005
|
+
"",
|
|
9006
|
+
"Two things can never be excluded: UiPath's own monitoring events, and audit-configuration",
|
|
9007
|
+
"changes — including the rules themselves."
|
|
9008
|
+
].join(`
|
|
9009
|
+
`));
|
|
9010
|
+
withLoginValidity(exclusions.command("list").description([
|
|
9011
|
+
"List every exclusion rule in the organization, ordered by name.",
|
|
9012
|
+
"",
|
|
9013
|
+
"The set is capped server-side, so there is no pagination. A rule whose stored",
|
|
9014
|
+
"document cannot be parsed is still listed, with an empty `selectors` array, so",
|
|
9015
|
+
"it can be deleted."
|
|
9016
|
+
].join(`
|
|
9017
|
+
`)).examples(LIST_EXAMPLES)).trackedAction(processContext, async (options) => {
|
|
9018
|
+
const [error, result] = await catchError2((async () => await (await getApi(options)).eventConfigGetRules())());
|
|
9019
|
+
if (error) {
|
|
9020
|
+
await emitFailure("list", error);
|
|
9021
|
+
return;
|
|
9022
|
+
}
|
|
9023
|
+
OutputFormatter.success({
|
|
9024
|
+
Result: RESULTS.Success,
|
|
9025
|
+
Code: "AuditOrgExclusionsList",
|
|
9026
|
+
Data: result ?? []
|
|
9027
|
+
});
|
|
9028
|
+
});
|
|
9029
|
+
withLoginValidity(exclusions.command("get").description("Read one exclusion rule, by name or by policy id.").argument(...RULE_ARGUMENT).examples(GET_EXAMPLES)).trackedAction(processContext, async (rule, options) => {
|
|
9030
|
+
const target = await resolveTarget("get", rule, options);
|
|
9031
|
+
if (!target)
|
|
9032
|
+
return;
|
|
9033
|
+
if (target.resolved) {
|
|
9034
|
+
OutputFormatter.success({
|
|
9035
|
+
Result: RESULTS.Success,
|
|
9036
|
+
Code: "AuditOrgExclusionsGet",
|
|
9037
|
+
Data: target.resolved
|
|
9038
|
+
});
|
|
9039
|
+
return;
|
|
9040
|
+
}
|
|
9041
|
+
const [error, result] = await catchError2(target.api.eventConfigGetRule({ policyId: target.policyId }));
|
|
9042
|
+
if (error) {
|
|
9043
|
+
await emitFailure("get", error);
|
|
9044
|
+
return;
|
|
9045
|
+
}
|
|
9046
|
+
OutputFormatter.success({
|
|
9047
|
+
Result: RESULTS.Success,
|
|
9048
|
+
Code: "AuditOrgExclusionsGet",
|
|
9049
|
+
Data: result
|
|
9050
|
+
});
|
|
9051
|
+
});
|
|
9052
|
+
withWriteOptions(exclusions.command("create").description([
|
|
9053
|
+
"Create an exclusion rule.",
|
|
9054
|
+
"",
|
|
9055
|
+
"The rule is active unless --inactive is passed, and an active rule is refused when",
|
|
9056
|
+
"another active rule already carries the same name or already excludes everything",
|
|
9057
|
+
"this one would."
|
|
9058
|
+
].join(`
|
|
9059
|
+
`)).examples(CREATE_EXAMPLES)).trackedAction(processContext, async (options) => {
|
|
9060
|
+
const [bodyError, body] = await catchError2(resolveBody(options));
|
|
9061
|
+
if (bodyError) {
|
|
9062
|
+
await emitBodyFailure("create", bodyError);
|
|
9063
|
+
return;
|
|
9064
|
+
}
|
|
9065
|
+
const [error, result] = await catchError2((async () => await (await getApi(options)).eventConfigCreateRule({
|
|
9066
|
+
exclusionRuleWriteDto: body
|
|
9067
|
+
}))());
|
|
9068
|
+
if (error) {
|
|
9069
|
+
await emitFailure("create", error);
|
|
9070
|
+
return;
|
|
9071
|
+
}
|
|
9072
|
+
OutputFormatter.success({
|
|
9073
|
+
Result: RESULTS.Success,
|
|
9074
|
+
Code: "AuditOrgExclusionsCreated",
|
|
9075
|
+
Data: result
|
|
9076
|
+
});
|
|
9077
|
+
});
|
|
9078
|
+
withWriteOptions(exclusions.command("update").description([
|
|
9079
|
+
"Replace an exclusion rule in full.",
|
|
9080
|
+
"",
|
|
9081
|
+
"This is a replacement, not a patch: whatever you leave out is dropped, so resend",
|
|
9082
|
+
"every flag the rule should keep (read it first with `exclusions get`). Renaming a",
|
|
9083
|
+
"rule leaves its exclusion start time alone; changing which events it matches",
|
|
9084
|
+
"re-stamps that time, so the widened rule does not cover events it never matched.",
|
|
9085
|
+
"",
|
|
9086
|
+
"Activation is part of the replacement: without --inactive the rule comes back",
|
|
9087
|
+
"ACTIVE, so editing a rule you deliberately staged inactive starts it excluding",
|
|
9088
|
+
"events. Pass --inactive again to keep it staged.",
|
|
9089
|
+
"",
|
|
9090
|
+
"Pass <rule> before the selector flags. Those flags take a list, so a value",
|
|
9091
|
+
"written after one is read as another of its values."
|
|
9092
|
+
].join(`
|
|
9093
|
+
`)).argument(...RULE_ARGUMENT).examples(UPDATE_EXAMPLES)).trackedAction(processContext, async (rule, options) => {
|
|
9094
|
+
const [bodyError, body] = await catchError2(resolveBody(options));
|
|
9095
|
+
if (bodyError) {
|
|
9096
|
+
await emitBodyFailure("update", bodyError);
|
|
9097
|
+
return;
|
|
9098
|
+
}
|
|
9099
|
+
const target = await resolveTarget("update", rule, options);
|
|
9100
|
+
if (!target)
|
|
9101
|
+
return;
|
|
9102
|
+
const [error, result] = await catchError2(target.api.eventConfigReplaceRule({
|
|
9103
|
+
policyId: target.policyId,
|
|
9104
|
+
exclusionRuleWriteDto: body
|
|
9105
|
+
}));
|
|
9106
|
+
if (error) {
|
|
9107
|
+
await emitFailure("update", error);
|
|
9108
|
+
return;
|
|
9109
|
+
}
|
|
9110
|
+
OutputFormatter.success({
|
|
9111
|
+
Result: RESULTS.Success,
|
|
9112
|
+
Code: "AuditOrgExclusionsUpdated",
|
|
9113
|
+
Data: result
|
|
9114
|
+
});
|
|
9115
|
+
});
|
|
9116
|
+
withLoginValidity(exclusions.command("delete").description([
|
|
9117
|
+
"Delete an exclusion rule.",
|
|
9118
|
+
"",
|
|
9119
|
+
"Events it was excluding are recorded again from now on. Events suppressed while",
|
|
9120
|
+
"it was active are gone for good — deleting the rule does not bring them back."
|
|
9121
|
+
].join(`
|
|
9122
|
+
`)).argument(...RULE_ARGUMENT).examples(DELETE_EXAMPLES)).trackedAction(processContext, async (rule, options) => {
|
|
9123
|
+
const target = await resolveTarget("delete", rule, options);
|
|
9124
|
+
if (!target)
|
|
9125
|
+
return;
|
|
9126
|
+
const [error] = await catchError2(target.api.eventConfigDeleteRule({
|
|
9127
|
+
policyId: target.policyId
|
|
9128
|
+
}));
|
|
9129
|
+
if (error) {
|
|
9130
|
+
await emitFailure("delete", error);
|
|
9131
|
+
return;
|
|
9132
|
+
}
|
|
9133
|
+
OutputFormatter.success({
|
|
9134
|
+
Result: RESULTS.Success,
|
|
9135
|
+
Code: "AuditOrgExclusionsDeleted",
|
|
9136
|
+
Data: {}
|
|
9137
|
+
});
|
|
9138
|
+
});
|
|
9139
|
+
}
|
|
9140
|
+
|
|
7874
9141
|
// src/utils/chunked-export.ts
|
|
7875
9142
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
7876
9143
|
|
|
@@ -8885,23 +10152,27 @@ function registerExport(parent, opts) {
|
|
|
8885
10152
|
// src/commands/audit.ts
|
|
8886
10153
|
var registerAuditCommand = (program2) => {
|
|
8887
10154
|
const audit = program2.command("audit").description([
|
|
8888
|
-
"Query and export UiPath audit events.",
|
|
10155
|
+
"Query and export UiPath audit events, and configure which events are recorded.",
|
|
8889
10156
|
"",
|
|
8890
|
-
"Subject subgroups
|
|
10157
|
+
"Subject subgroups:",
|
|
8891
10158
|
" org — organization-scoped audit (admin events that are tenant-agnostic).",
|
|
8892
10159
|
" tenant — tenant-scoped audit (events scoped to the active or --tenant-id-overridden tenant).",
|
|
8893
10160
|
"",
|
|
8894
|
-
"
|
|
10161
|
+
"Read verbs (the same three under each subject):",
|
|
8895
10162
|
" sources — list event sources/targets/types visible at this scope.",
|
|
8896
10163
|
" events — paginated query of audit events with cursor and filters.",
|
|
8897
10164
|
" export — chunked download from the long-term store as a ZIP of day-wise files or a single merged CSV (requires --from-date / --to-date).",
|
|
8898
10165
|
"",
|
|
10166
|
+
"Configuration (org only):",
|
|
10167
|
+
" exclusions — CRUD over the exclusion rules that stop matching events being recorded at all.",
|
|
10168
|
+
"",
|
|
8899
10169
|
"Typical workflow: `audit <scope> sources` (discover IDs) → `audit <scope> events --source <guid>",
|
|
8900
10170
|
"--from-date … --to-date …` (find the rows) → `audit <scope> export --from-date … --to-date … --output-path …`."
|
|
8901
10171
|
].join(`
|
|
8902
10172
|
`));
|
|
8903
10173
|
const org = audit.command("org").description("Organization-scoped audit operations.");
|
|
8904
10174
|
registerScopeCommands(org, { scope: "org", codeSuffix: "Org" });
|
|
10175
|
+
registerExclusionCommands(org);
|
|
8905
10176
|
const tenant = audit.command("tenant").description("Tenant-scoped audit operations.");
|
|
8906
10177
|
registerScopeCommands(tenant, { scope: "tenant", codeSuffix: "Tenant" });
|
|
8907
10178
|
};
|
|
@@ -8914,4 +10185,4 @@ export {
|
|
|
8914
10185
|
registerCommands
|
|
8915
10186
|
};
|
|
8916
10187
|
|
|
8917
|
-
//# debugId=
|
|
10188
|
+
//# debugId=A3B08992C797FBE564756E2164756E21
|