@uipath/audit-commands 1.202.1-preview.220 → 1.202.1-preview.239
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 +224 -7
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9189,7 +9189,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
9189
9189
|
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).";
|
|
9190
9190
|
}
|
|
9191
9191
|
}
|
|
9192
|
-
function
|
|
9192
|
+
function countRecords(data) {
|
|
9193
|
+
if (Array.isArray(data))
|
|
9194
|
+
return data.length;
|
|
9195
|
+
return data == null ? 0 : 1;
|
|
9196
|
+
}
|
|
9197
|
+
function availableFields(data) {
|
|
9198
|
+
const records = Array.isArray(data) ? data : [data];
|
|
9199
|
+
const keys = new Set;
|
|
9200
|
+
for (const record of records) {
|
|
9201
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
9202
|
+
for (const key of Object.keys(record))
|
|
9203
|
+
keys.add(key);
|
|
9204
|
+
}
|
|
9205
|
+
}
|
|
9206
|
+
return [...keys];
|
|
9207
|
+
}
|
|
9208
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
9209
|
+
const [error, decoded] = catchError2(() => JSON.parse(whole));
|
|
9210
|
+
if (!error && typeof decoded === "string")
|
|
9211
|
+
return decoded;
|
|
9212
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
9213
|
+
}
|
|
9214
|
+
function referencedFields(filter) {
|
|
9215
|
+
const top = new Set;
|
|
9216
|
+
const nested = new Set;
|
|
9217
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
9218
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
9219
|
+
const quoted = [];
|
|
9220
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
9221
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
9222
|
+
if (!isAlias) {
|
|
9223
|
+
quoted.push({
|
|
9224
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
9225
|
+
index,
|
|
9226
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
9227
|
+
});
|
|
9228
|
+
}
|
|
9229
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
9230
|
+
});
|
|
9231
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
9232
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
9233
|
+
const place = (name, index, tail) => {
|
|
9234
|
+
if (tail || index >= rootEnd)
|
|
9235
|
+
nested.add(name);
|
|
9236
|
+
else
|
|
9237
|
+
top.add(name);
|
|
9238
|
+
};
|
|
9239
|
+
for (const entry of quoted)
|
|
9240
|
+
place(entry.name, entry.index, entry.tail);
|
|
9241
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
9242
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
9243
|
+
for (const match of identifiers) {
|
|
9244
|
+
const [, name, trailing] = match;
|
|
9245
|
+
if (trailing || reserved.has(name))
|
|
9246
|
+
continue;
|
|
9247
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
9248
|
+
}
|
|
9249
|
+
return {
|
|
9250
|
+
top: [...top],
|
|
9251
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
9252
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
9253
|
+
};
|
|
9254
|
+
}
|
|
9255
|
+
function appearsBelowTopLevel(data, name) {
|
|
9256
|
+
let budget = 2000;
|
|
9257
|
+
const visit = (value, depth) => {
|
|
9258
|
+
if (budget-- <= 0 || depth > 4)
|
|
9259
|
+
return false;
|
|
9260
|
+
if (value === null || typeof value !== "object")
|
|
9261
|
+
return false;
|
|
9262
|
+
if (Array.isArray(value))
|
|
9263
|
+
return value.some((entry) => visit(entry, depth));
|
|
9264
|
+
const record = value;
|
|
9265
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
9266
|
+
return true;
|
|
9267
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
9268
|
+
};
|
|
9269
|
+
return visit(data, 0);
|
|
9270
|
+
}
|
|
9271
|
+
function alwaysNullKeys(records) {
|
|
9272
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
9273
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
9274
|
+
return [];
|
|
9275
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
9276
|
+
if (keys.length === 0)
|
|
9277
|
+
return [];
|
|
9278
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
9279
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
9280
|
+
}
|
|
9281
|
+
function carriesOnlyNulls(value) {
|
|
9282
|
+
if (value === null)
|
|
9283
|
+
return true;
|
|
9284
|
+
if (Array.isArray(value)) {
|
|
9285
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
9286
|
+
}
|
|
9287
|
+
if (typeof value === "object" && value !== undefined) {
|
|
9288
|
+
const values = Object.values(value);
|
|
9289
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
9290
|
+
}
|
|
9291
|
+
return false;
|
|
9292
|
+
}
|
|
9293
|
+
function nameList(names, cap2 = 12) {
|
|
9294
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
9295
|
+
const rest = names.length - shown.length;
|
|
9296
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
9297
|
+
}
|
|
9298
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
9299
|
+
const present = availableFields(data);
|
|
9300
|
+
const refs = referencedFields(filter);
|
|
9301
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
9302
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
9303
|
+
const count = countRecords(data);
|
|
9304
|
+
const scope = `${count} record(s)`;
|
|
9305
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
9306
|
+
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" : "";
|
|
9307
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
9308
|
+
let detail;
|
|
9309
|
+
let lede;
|
|
9310
|
+
if (outcome.kind === "null-elements") {
|
|
9311
|
+
lede = "returned only null values";
|
|
9312
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
9313
|
+
if (unknown.length > 0) {
|
|
9314
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
9315
|
+
} else if (unchecked.length > 0) {
|
|
9316
|
+
detail = withSoundness(projected);
|
|
9317
|
+
} else {
|
|
9318
|
+
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`;
|
|
9319
|
+
}
|
|
9320
|
+
} else if (outcome.kind === "null-rows") {
|
|
9321
|
+
lede = "returned only null values";
|
|
9322
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
9323
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
9324
|
+
} else if (outcome.kind === "null-values") {
|
|
9325
|
+
lede = "returned only null values";
|
|
9326
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
9327
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
9328
|
+
if (sameSet) {
|
|
9329
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
9330
|
+
} else if (unknown.length > 0) {
|
|
9331
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
9332
|
+
} else {
|
|
9333
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
9334
|
+
}
|
|
9335
|
+
} else {
|
|
9336
|
+
lede = "returned nothing";
|
|
9337
|
+
if (unknown.length > 0) {
|
|
9338
|
+
detail = isNotAField(unknown);
|
|
9339
|
+
} else {
|
|
9340
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
9341
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
9342
|
+
}
|
|
9343
|
+
}
|
|
9344
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
9345
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
9346
|
+
}
|
|
9347
|
+
function appendWarning(existing, note) {
|
|
9348
|
+
return existing ? `${existing} ${note}` : note;
|
|
9349
|
+
}
|
|
9350
|
+
function applyFilter(data, filter, onWarning) {
|
|
9193
9351
|
const codec = requireJmespath();
|
|
9194
9352
|
let result;
|
|
9195
9353
|
try {
|
|
@@ -9197,9 +9355,34 @@ function applyFilter(data, filter) {
|
|
|
9197
9355
|
} catch (err) {
|
|
9198
9356
|
throw new FilterEvaluationError(filter, err);
|
|
9199
9357
|
}
|
|
9200
|
-
|
|
9358
|
+
const inputCount = countRecords(data);
|
|
9359
|
+
const warn = (outcome) => {
|
|
9360
|
+
if (inputCount === 0)
|
|
9361
|
+
return;
|
|
9362
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
9363
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
9364
|
+
`);
|
|
9365
|
+
onWarning?.(note);
|
|
9366
|
+
};
|
|
9367
|
+
const warnIfAllNull = (records) => {
|
|
9368
|
+
const keys = alwaysNullKeys(records);
|
|
9369
|
+
if (keys.length > 0)
|
|
9370
|
+
warn({ kind: "null-values", keys });
|
|
9371
|
+
};
|
|
9372
|
+
if (result == null) {
|
|
9373
|
+
warn({ kind: "empty" });
|
|
9201
9374
|
return [];
|
|
9375
|
+
}
|
|
9202
9376
|
if (Array.isArray(result)) {
|
|
9377
|
+
if (result.length === 0) {
|
|
9378
|
+
warn({ kind: "empty" });
|
|
9379
|
+
} else if (result.every((entry) => entry === null)) {
|
|
9380
|
+
warn({ kind: "null-elements", count: result.length });
|
|
9381
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
9382
|
+
warn({ kind: "null-rows", count: result.length });
|
|
9383
|
+
} else {
|
|
9384
|
+
warnIfAllNull(result);
|
|
9385
|
+
}
|
|
9203
9386
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
9204
9387
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
9205
9388
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -9207,10 +9390,30 @@ function applyFilter(data, filter) {
|
|
|
9207
9390
|
}
|
|
9208
9391
|
return result;
|
|
9209
9392
|
}
|
|
9210
|
-
if (typeof result === "object")
|
|
9393
|
+
if (typeof result === "object") {
|
|
9394
|
+
warnIfAllNull([result]);
|
|
9211
9395
|
return result;
|
|
9396
|
+
}
|
|
9212
9397
|
return { Value: result };
|
|
9213
9398
|
}
|
|
9399
|
+
function filterFailureData(envelope) {
|
|
9400
|
+
const filter = getOutputFilter();
|
|
9401
|
+
const data = envelope.Data;
|
|
9402
|
+
if (!filter || data == null)
|
|
9403
|
+
return;
|
|
9404
|
+
let note;
|
|
9405
|
+
const [filterError, filtered] = catchError2(() => applyFilter(data, filter, (n) => {
|
|
9406
|
+
note = n;
|
|
9407
|
+
}));
|
|
9408
|
+
if (filterError) {
|
|
9409
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
9410
|
+
return;
|
|
9411
|
+
}
|
|
9412
|
+
envelope.Data = filtered;
|
|
9413
|
+
if (note) {
|
|
9414
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
9415
|
+
}
|
|
9416
|
+
}
|
|
9214
9417
|
function defaultErrorCodeForResult(result) {
|
|
9215
9418
|
switch (result) {
|
|
9216
9419
|
case RESULTS.AuthenticationError:
|
|
@@ -9293,8 +9496,14 @@ var OutputFormatter;
|
|
|
9293
9496
|
}
|
|
9294
9497
|
const filter = getOutputFilter();
|
|
9295
9498
|
if (filter) {
|
|
9296
|
-
|
|
9499
|
+
let note;
|
|
9500
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
9501
|
+
note = n;
|
|
9502
|
+
});
|
|
9297
9503
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
9504
|
+
if (note) {
|
|
9505
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
9506
|
+
}
|
|
9298
9507
|
}
|
|
9299
9508
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
9300
9509
|
}
|
|
@@ -9322,6 +9531,7 @@ var OutputFormatter;
|
|
|
9322
9531
|
delete envelope.TelemetryErrorClass;
|
|
9323
9532
|
delete envelope.TelemetryTerminalOutcome;
|
|
9324
9533
|
delete envelope.TelemetryTerminalSignal;
|
|
9534
|
+
filterFailureData(envelope);
|
|
9325
9535
|
if (!suppressTelemetry) {
|
|
9326
9536
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
9327
9537
|
result: data.Result,
|
|
@@ -9370,13 +9580,20 @@ var OutputFormatter;
|
|
|
9370
9580
|
OutputFormatter.log = log;
|
|
9371
9581
|
function formatToString(data) {
|
|
9372
9582
|
const filter = getOutputFilter();
|
|
9583
|
+
const envelope = data;
|
|
9373
9584
|
if ("Data" in data && data.Data != null) {
|
|
9374
9585
|
data.Data = normalizeDataKeys(data.Data);
|
|
9375
9586
|
if (filter) {
|
|
9376
|
-
|
|
9587
|
+
let note;
|
|
9588
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
9589
|
+
note = n;
|
|
9590
|
+
}));
|
|
9591
|
+
if (note) {
|
|
9592
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
9593
|
+
}
|
|
9377
9594
|
}
|
|
9378
9595
|
}
|
|
9379
|
-
const output = normalizeOutputKeys(
|
|
9596
|
+
const output = normalizeOutputKeys(envelope);
|
|
9380
9597
|
const lines = [];
|
|
9381
9598
|
const sink = getOutputSink();
|
|
9382
9599
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -10743,4 +10960,4 @@ export {
|
|
|
10743
10960
|
registerCommands
|
|
10744
10961
|
};
|
|
10745
10962
|
|
|
10746
|
-
//# debugId=
|
|
10963
|
+
//# debugId=F5707193B3462A7864756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/audit-commands",
|
|
3
3
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "1.202.1-preview.
|
|
4
|
+
"version": "1.202.1-preview.239",
|
|
5
5
|
"description": "Admin CLI commands for the UiPath Audit Service — query event sources, paginate events, and export ZIPs from the long-term store. Library composed by admin-tool, not a standalone CLI tool.",
|
|
6
6
|
"private": false,
|
|
7
7
|
"repository": {
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "97545a7857bdff7e6db62bbe13c6097607cf38f1"
|
|
29
29
|
}
|