@uipath/authz-commands 1.203.0-preview.233 → 1.203.0-preview.237
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
|
@@ -7268,7 +7268,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
7268
7268
|
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).";
|
|
7269
7269
|
}
|
|
7270
7270
|
}
|
|
7271
|
-
function
|
|
7271
|
+
function countRecords(data) {
|
|
7272
|
+
if (Array.isArray(data))
|
|
7273
|
+
return data.length;
|
|
7274
|
+
return data == null ? 0 : 1;
|
|
7275
|
+
}
|
|
7276
|
+
function availableFields(data) {
|
|
7277
|
+
const records = Array.isArray(data) ? data : [data];
|
|
7278
|
+
const keys = new Set;
|
|
7279
|
+
for (const record of records) {
|
|
7280
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
7281
|
+
for (const key of Object.keys(record))
|
|
7282
|
+
keys.add(key);
|
|
7283
|
+
}
|
|
7284
|
+
}
|
|
7285
|
+
return [...keys];
|
|
7286
|
+
}
|
|
7287
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
7288
|
+
const [error, decoded] = catchError2(() => JSON.parse(whole));
|
|
7289
|
+
if (!error && typeof decoded === "string")
|
|
7290
|
+
return decoded;
|
|
7291
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
7292
|
+
}
|
|
7293
|
+
function referencedFields(filter) {
|
|
7294
|
+
const top = new Set;
|
|
7295
|
+
const nested = new Set;
|
|
7296
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
7297
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
7298
|
+
const quoted = [];
|
|
7299
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
7300
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
7301
|
+
if (!isAlias) {
|
|
7302
|
+
quoted.push({
|
|
7303
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
7304
|
+
index,
|
|
7305
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
7306
|
+
});
|
|
7307
|
+
}
|
|
7308
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
7309
|
+
});
|
|
7310
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
7311
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
7312
|
+
const place = (name, index, tail) => {
|
|
7313
|
+
if (tail || index >= rootEnd)
|
|
7314
|
+
nested.add(name);
|
|
7315
|
+
else
|
|
7316
|
+
top.add(name);
|
|
7317
|
+
};
|
|
7318
|
+
for (const entry of quoted)
|
|
7319
|
+
place(entry.name, entry.index, entry.tail);
|
|
7320
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
7321
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
7322
|
+
for (const match of identifiers) {
|
|
7323
|
+
const [, name, trailing] = match;
|
|
7324
|
+
if (trailing || reserved.has(name))
|
|
7325
|
+
continue;
|
|
7326
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
7327
|
+
}
|
|
7328
|
+
return {
|
|
7329
|
+
top: [...top],
|
|
7330
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
7331
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
7332
|
+
};
|
|
7333
|
+
}
|
|
7334
|
+
function appearsBelowTopLevel(data, name) {
|
|
7335
|
+
let budget = 2000;
|
|
7336
|
+
const visit = (value, depth) => {
|
|
7337
|
+
if (budget-- <= 0 || depth > 4)
|
|
7338
|
+
return false;
|
|
7339
|
+
if (value === null || typeof value !== "object")
|
|
7340
|
+
return false;
|
|
7341
|
+
if (Array.isArray(value))
|
|
7342
|
+
return value.some((entry) => visit(entry, depth));
|
|
7343
|
+
const record = value;
|
|
7344
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
7345
|
+
return true;
|
|
7346
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
7347
|
+
};
|
|
7348
|
+
return visit(data, 0);
|
|
7349
|
+
}
|
|
7350
|
+
function alwaysNullKeys(records) {
|
|
7351
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
7352
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
7353
|
+
return [];
|
|
7354
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
7355
|
+
if (keys.length === 0)
|
|
7356
|
+
return [];
|
|
7357
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
7358
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
7359
|
+
}
|
|
7360
|
+
function carriesOnlyNulls(value) {
|
|
7361
|
+
if (value === null)
|
|
7362
|
+
return true;
|
|
7363
|
+
if (Array.isArray(value)) {
|
|
7364
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
7365
|
+
}
|
|
7366
|
+
if (typeof value === "object" && value !== undefined) {
|
|
7367
|
+
const values = Object.values(value);
|
|
7368
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
7369
|
+
}
|
|
7370
|
+
return false;
|
|
7371
|
+
}
|
|
7372
|
+
function nameList(names, cap2 = 12) {
|
|
7373
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
7374
|
+
const rest = names.length - shown.length;
|
|
7375
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
7376
|
+
}
|
|
7377
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
7378
|
+
const present = availableFields(data);
|
|
7379
|
+
const refs = referencedFields(filter);
|
|
7380
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
7381
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
7382
|
+
const count = countRecords(data);
|
|
7383
|
+
const scope = `${count} record(s)`;
|
|
7384
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
7385
|
+
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" : "";
|
|
7386
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
7387
|
+
let detail;
|
|
7388
|
+
let lede;
|
|
7389
|
+
if (outcome.kind === "null-elements") {
|
|
7390
|
+
lede = "returned only null values";
|
|
7391
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
7392
|
+
if (unknown.length > 0) {
|
|
7393
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
7394
|
+
} else if (unchecked.length > 0) {
|
|
7395
|
+
detail = withSoundness(projected);
|
|
7396
|
+
} else {
|
|
7397
|
+
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`;
|
|
7398
|
+
}
|
|
7399
|
+
} else if (outcome.kind === "null-rows") {
|
|
7400
|
+
lede = "returned only null values";
|
|
7401
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
7402
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
7403
|
+
} else if (outcome.kind === "null-values") {
|
|
7404
|
+
lede = "returned only null values";
|
|
7405
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
7406
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
7407
|
+
if (sameSet) {
|
|
7408
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
7409
|
+
} else if (unknown.length > 0) {
|
|
7410
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
7411
|
+
} else {
|
|
7412
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
7413
|
+
}
|
|
7414
|
+
} else {
|
|
7415
|
+
lede = "returned nothing";
|
|
7416
|
+
if (unknown.length > 0) {
|
|
7417
|
+
detail = isNotAField(unknown);
|
|
7418
|
+
} else {
|
|
7419
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
7420
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
7421
|
+
}
|
|
7422
|
+
}
|
|
7423
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
7424
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
7425
|
+
}
|
|
7426
|
+
function appendWarning(existing, note) {
|
|
7427
|
+
return existing ? `${existing} ${note}` : note;
|
|
7428
|
+
}
|
|
7429
|
+
function applyFilter(data, filter, onWarning) {
|
|
7272
7430
|
const codec = requireJmespath();
|
|
7273
7431
|
let result;
|
|
7274
7432
|
try {
|
|
@@ -7276,9 +7434,34 @@ function applyFilter(data, filter) {
|
|
|
7276
7434
|
} catch (err) {
|
|
7277
7435
|
throw new FilterEvaluationError(filter, err);
|
|
7278
7436
|
}
|
|
7279
|
-
|
|
7437
|
+
const inputCount = countRecords(data);
|
|
7438
|
+
const warn = (outcome) => {
|
|
7439
|
+
if (inputCount === 0)
|
|
7440
|
+
return;
|
|
7441
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
7442
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
7443
|
+
`);
|
|
7444
|
+
onWarning?.(note);
|
|
7445
|
+
};
|
|
7446
|
+
const warnIfAllNull = (records) => {
|
|
7447
|
+
const keys = alwaysNullKeys(records);
|
|
7448
|
+
if (keys.length > 0)
|
|
7449
|
+
warn({ kind: "null-values", keys });
|
|
7450
|
+
};
|
|
7451
|
+
if (result == null) {
|
|
7452
|
+
warn({ kind: "empty" });
|
|
7280
7453
|
return [];
|
|
7454
|
+
}
|
|
7281
7455
|
if (Array.isArray(result)) {
|
|
7456
|
+
if (result.length === 0) {
|
|
7457
|
+
warn({ kind: "empty" });
|
|
7458
|
+
} else if (result.every((entry) => entry === null)) {
|
|
7459
|
+
warn({ kind: "null-elements", count: result.length });
|
|
7460
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
7461
|
+
warn({ kind: "null-rows", count: result.length });
|
|
7462
|
+
} else {
|
|
7463
|
+
warnIfAllNull(result);
|
|
7464
|
+
}
|
|
7282
7465
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
7283
7466
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
7284
7467
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -7286,10 +7469,30 @@ function applyFilter(data, filter) {
|
|
|
7286
7469
|
}
|
|
7287
7470
|
return result;
|
|
7288
7471
|
}
|
|
7289
|
-
if (typeof result === "object")
|
|
7472
|
+
if (typeof result === "object") {
|
|
7473
|
+
warnIfAllNull([result]);
|
|
7290
7474
|
return result;
|
|
7475
|
+
}
|
|
7291
7476
|
return { Value: result };
|
|
7292
7477
|
}
|
|
7478
|
+
function filterFailureData(envelope) {
|
|
7479
|
+
const filter = getOutputFilter();
|
|
7480
|
+
const data = envelope.Data;
|
|
7481
|
+
if (!filter || data == null)
|
|
7482
|
+
return;
|
|
7483
|
+
let note;
|
|
7484
|
+
const [filterError, filtered] = catchError2(() => applyFilter(data, filter, (n) => {
|
|
7485
|
+
note = n;
|
|
7486
|
+
}));
|
|
7487
|
+
if (filterError) {
|
|
7488
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
7489
|
+
return;
|
|
7490
|
+
}
|
|
7491
|
+
envelope.Data = filtered;
|
|
7492
|
+
if (note) {
|
|
7493
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
7494
|
+
}
|
|
7495
|
+
}
|
|
7293
7496
|
function defaultErrorCodeForResult(result) {
|
|
7294
7497
|
switch (result) {
|
|
7295
7498
|
case RESULTS.AuthenticationError:
|
|
@@ -7372,8 +7575,14 @@ var OutputFormatter;
|
|
|
7372
7575
|
}
|
|
7373
7576
|
const filter = getOutputFilter();
|
|
7374
7577
|
if (filter) {
|
|
7375
|
-
|
|
7578
|
+
let note;
|
|
7579
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
7580
|
+
note = n;
|
|
7581
|
+
});
|
|
7376
7582
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
7583
|
+
if (note) {
|
|
7584
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
7585
|
+
}
|
|
7377
7586
|
}
|
|
7378
7587
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
7379
7588
|
}
|
|
@@ -7401,6 +7610,7 @@ var OutputFormatter;
|
|
|
7401
7610
|
delete envelope.TelemetryErrorClass;
|
|
7402
7611
|
delete envelope.TelemetryTerminalOutcome;
|
|
7403
7612
|
delete envelope.TelemetryTerminalSignal;
|
|
7613
|
+
filterFailureData(envelope);
|
|
7404
7614
|
if (!suppressTelemetry) {
|
|
7405
7615
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
7406
7616
|
result: data.Result,
|
|
@@ -7449,13 +7659,20 @@ var OutputFormatter;
|
|
|
7449
7659
|
OutputFormatter.log = log;
|
|
7450
7660
|
function formatToString(data) {
|
|
7451
7661
|
const filter = getOutputFilter();
|
|
7662
|
+
const envelope = data;
|
|
7452
7663
|
if ("Data" in data && data.Data != null) {
|
|
7453
7664
|
data.Data = normalizeDataKeys(data.Data);
|
|
7454
7665
|
if (filter) {
|
|
7455
|
-
|
|
7666
|
+
let note;
|
|
7667
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
7668
|
+
note = n;
|
|
7669
|
+
}));
|
|
7670
|
+
if (note) {
|
|
7671
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
7672
|
+
}
|
|
7456
7673
|
}
|
|
7457
7674
|
}
|
|
7458
|
-
const output = normalizeOutputKeys(
|
|
7675
|
+
const output = normalizeOutputKeys(envelope);
|
|
7459
7676
|
const lines = [];
|
|
7460
7677
|
const sink = getOutputSink();
|
|
7461
7678
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -10877,4 +11094,4 @@ export {
|
|
|
10877
11094
|
registerCommands
|
|
10878
11095
|
};
|
|
10879
11096
|
|
|
10880
|
-
//# debugId=
|
|
11097
|
+
//# debugId=6EEE5B5474DB930C64756E2164756E21
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/authz-commands",
|
|
3
3
|
"author": "UiPath",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
|
-
"version": "1.203.0-preview.
|
|
5
|
+
"version": "1.203.0-preview.237",
|
|
6
6
|
"description": "Admin CLI commands for the UiPath Authorization service. Library composed by admin-tool, not a standalone CLI tool.",
|
|
7
7
|
"private": false,
|
|
8
8
|
"repository": {
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"dist"
|
|
28
28
|
],
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "4ad3e17a66f2c7fb7fe1f0e3e04a5b6175a0a9a3"
|
|
30
30
|
}
|