@uipath/authz-commands 1.202.1-preview.217 → 1.202.1-preview.238
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
|
@@ -7018,7 +7018,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
7018
7018
|
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).";
|
|
7019
7019
|
}
|
|
7020
7020
|
}
|
|
7021
|
-
function
|
|
7021
|
+
function countRecords(data) {
|
|
7022
|
+
if (Array.isArray(data))
|
|
7023
|
+
return data.length;
|
|
7024
|
+
return data == null ? 0 : 1;
|
|
7025
|
+
}
|
|
7026
|
+
function availableFields(data) {
|
|
7027
|
+
const records = Array.isArray(data) ? data : [data];
|
|
7028
|
+
const keys = new Set;
|
|
7029
|
+
for (const record of records) {
|
|
7030
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
7031
|
+
for (const key of Object.keys(record))
|
|
7032
|
+
keys.add(key);
|
|
7033
|
+
}
|
|
7034
|
+
}
|
|
7035
|
+
return [...keys];
|
|
7036
|
+
}
|
|
7037
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
7038
|
+
const [error, decoded] = catchError2(() => JSON.parse(whole));
|
|
7039
|
+
if (!error && typeof decoded === "string")
|
|
7040
|
+
return decoded;
|
|
7041
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
7042
|
+
}
|
|
7043
|
+
function referencedFields(filter) {
|
|
7044
|
+
const top = new Set;
|
|
7045
|
+
const nested = new Set;
|
|
7046
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
7047
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
7048
|
+
const quoted = [];
|
|
7049
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
7050
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
7051
|
+
if (!isAlias) {
|
|
7052
|
+
quoted.push({
|
|
7053
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
7054
|
+
index,
|
|
7055
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
7056
|
+
});
|
|
7057
|
+
}
|
|
7058
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
7059
|
+
});
|
|
7060
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
7061
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
7062
|
+
const place = (name, index, tail) => {
|
|
7063
|
+
if (tail || index >= rootEnd)
|
|
7064
|
+
nested.add(name);
|
|
7065
|
+
else
|
|
7066
|
+
top.add(name);
|
|
7067
|
+
};
|
|
7068
|
+
for (const entry of quoted)
|
|
7069
|
+
place(entry.name, entry.index, entry.tail);
|
|
7070
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
7071
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
7072
|
+
for (const match of identifiers) {
|
|
7073
|
+
const [, name, trailing] = match;
|
|
7074
|
+
if (trailing || reserved.has(name))
|
|
7075
|
+
continue;
|
|
7076
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
7077
|
+
}
|
|
7078
|
+
return {
|
|
7079
|
+
top: [...top],
|
|
7080
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
7081
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
7082
|
+
};
|
|
7083
|
+
}
|
|
7084
|
+
function appearsBelowTopLevel(data, name) {
|
|
7085
|
+
let budget = 2000;
|
|
7086
|
+
const visit = (value, depth) => {
|
|
7087
|
+
if (budget-- <= 0 || depth > 4)
|
|
7088
|
+
return false;
|
|
7089
|
+
if (value === null || typeof value !== "object")
|
|
7090
|
+
return false;
|
|
7091
|
+
if (Array.isArray(value))
|
|
7092
|
+
return value.some((entry) => visit(entry, depth));
|
|
7093
|
+
const record = value;
|
|
7094
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
7095
|
+
return true;
|
|
7096
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
7097
|
+
};
|
|
7098
|
+
return visit(data, 0);
|
|
7099
|
+
}
|
|
7100
|
+
function alwaysNullKeys(records) {
|
|
7101
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
7102
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
7103
|
+
return [];
|
|
7104
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
7105
|
+
if (keys.length === 0)
|
|
7106
|
+
return [];
|
|
7107
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
7108
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
7109
|
+
}
|
|
7110
|
+
function carriesOnlyNulls(value) {
|
|
7111
|
+
if (value === null)
|
|
7112
|
+
return true;
|
|
7113
|
+
if (Array.isArray(value)) {
|
|
7114
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
7115
|
+
}
|
|
7116
|
+
if (typeof value === "object" && value !== undefined) {
|
|
7117
|
+
const values = Object.values(value);
|
|
7118
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
7119
|
+
}
|
|
7120
|
+
return false;
|
|
7121
|
+
}
|
|
7122
|
+
function nameList(names, cap2 = 12) {
|
|
7123
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
7124
|
+
const rest = names.length - shown.length;
|
|
7125
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
7126
|
+
}
|
|
7127
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
7128
|
+
const present = availableFields(data);
|
|
7129
|
+
const refs = referencedFields(filter);
|
|
7130
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
7131
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
7132
|
+
const count = countRecords(data);
|
|
7133
|
+
const scope = `${count} record(s)`;
|
|
7134
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
7135
|
+
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" : "";
|
|
7136
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
7137
|
+
let detail;
|
|
7138
|
+
let lede;
|
|
7139
|
+
if (outcome.kind === "null-elements") {
|
|
7140
|
+
lede = "returned only null values";
|
|
7141
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
7142
|
+
if (unknown.length > 0) {
|
|
7143
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
7144
|
+
} else if (unchecked.length > 0) {
|
|
7145
|
+
detail = withSoundness(projected);
|
|
7146
|
+
} else {
|
|
7147
|
+
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`;
|
|
7148
|
+
}
|
|
7149
|
+
} else if (outcome.kind === "null-rows") {
|
|
7150
|
+
lede = "returned only null values";
|
|
7151
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
7152
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
7153
|
+
} else if (outcome.kind === "null-values") {
|
|
7154
|
+
lede = "returned only null values";
|
|
7155
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
7156
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
7157
|
+
if (sameSet) {
|
|
7158
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
7159
|
+
} else if (unknown.length > 0) {
|
|
7160
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
7161
|
+
} else {
|
|
7162
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
7163
|
+
}
|
|
7164
|
+
} else {
|
|
7165
|
+
lede = "returned nothing";
|
|
7166
|
+
if (unknown.length > 0) {
|
|
7167
|
+
detail = isNotAField(unknown);
|
|
7168
|
+
} else {
|
|
7169
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
7170
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
7171
|
+
}
|
|
7172
|
+
}
|
|
7173
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
7174
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
7175
|
+
}
|
|
7176
|
+
function appendWarning(existing, note) {
|
|
7177
|
+
return existing ? `${existing} ${note}` : note;
|
|
7178
|
+
}
|
|
7179
|
+
function applyFilter(data, filter, onWarning) {
|
|
7022
7180
|
const codec = requireJmespath();
|
|
7023
7181
|
let result;
|
|
7024
7182
|
try {
|
|
@@ -7026,9 +7184,34 @@ function applyFilter(data, filter) {
|
|
|
7026
7184
|
} catch (err) {
|
|
7027
7185
|
throw new FilterEvaluationError(filter, err);
|
|
7028
7186
|
}
|
|
7029
|
-
|
|
7187
|
+
const inputCount = countRecords(data);
|
|
7188
|
+
const warn = (outcome) => {
|
|
7189
|
+
if (inputCount === 0)
|
|
7190
|
+
return;
|
|
7191
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
7192
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
7193
|
+
`);
|
|
7194
|
+
onWarning?.(note);
|
|
7195
|
+
};
|
|
7196
|
+
const warnIfAllNull = (records) => {
|
|
7197
|
+
const keys = alwaysNullKeys(records);
|
|
7198
|
+
if (keys.length > 0)
|
|
7199
|
+
warn({ kind: "null-values", keys });
|
|
7200
|
+
};
|
|
7201
|
+
if (result == null) {
|
|
7202
|
+
warn({ kind: "empty" });
|
|
7030
7203
|
return [];
|
|
7204
|
+
}
|
|
7031
7205
|
if (Array.isArray(result)) {
|
|
7206
|
+
if (result.length === 0) {
|
|
7207
|
+
warn({ kind: "empty" });
|
|
7208
|
+
} else if (result.every((entry) => entry === null)) {
|
|
7209
|
+
warn({ kind: "null-elements", count: result.length });
|
|
7210
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
7211
|
+
warn({ kind: "null-rows", count: result.length });
|
|
7212
|
+
} else {
|
|
7213
|
+
warnIfAllNull(result);
|
|
7214
|
+
}
|
|
7032
7215
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
7033
7216
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
7034
7217
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -7036,10 +7219,30 @@ function applyFilter(data, filter) {
|
|
|
7036
7219
|
}
|
|
7037
7220
|
return result;
|
|
7038
7221
|
}
|
|
7039
|
-
if (typeof result === "object")
|
|
7222
|
+
if (typeof result === "object") {
|
|
7223
|
+
warnIfAllNull([result]);
|
|
7040
7224
|
return result;
|
|
7225
|
+
}
|
|
7041
7226
|
return { Value: result };
|
|
7042
7227
|
}
|
|
7228
|
+
function filterFailureData(envelope) {
|
|
7229
|
+
const filter = getOutputFilter();
|
|
7230
|
+
const data = envelope.Data;
|
|
7231
|
+
if (!filter || data == null)
|
|
7232
|
+
return;
|
|
7233
|
+
let note;
|
|
7234
|
+
const [filterError, filtered] = catchError2(() => applyFilter(data, filter, (n) => {
|
|
7235
|
+
note = n;
|
|
7236
|
+
}));
|
|
7237
|
+
if (filterError) {
|
|
7238
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
7239
|
+
return;
|
|
7240
|
+
}
|
|
7241
|
+
envelope.Data = filtered;
|
|
7242
|
+
if (note) {
|
|
7243
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
7244
|
+
}
|
|
7245
|
+
}
|
|
7043
7246
|
function defaultErrorCodeForResult(result) {
|
|
7044
7247
|
switch (result) {
|
|
7045
7248
|
case RESULTS.AuthenticationError:
|
|
@@ -7122,8 +7325,14 @@ var OutputFormatter;
|
|
|
7122
7325
|
}
|
|
7123
7326
|
const filter = getOutputFilter();
|
|
7124
7327
|
if (filter) {
|
|
7125
|
-
|
|
7328
|
+
let note;
|
|
7329
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
7330
|
+
note = n;
|
|
7331
|
+
});
|
|
7126
7332
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
7333
|
+
if (note) {
|
|
7334
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
7335
|
+
}
|
|
7127
7336
|
}
|
|
7128
7337
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
7129
7338
|
}
|
|
@@ -7151,6 +7360,7 @@ var OutputFormatter;
|
|
|
7151
7360
|
delete envelope.TelemetryErrorClass;
|
|
7152
7361
|
delete envelope.TelemetryTerminalOutcome;
|
|
7153
7362
|
delete envelope.TelemetryTerminalSignal;
|
|
7363
|
+
filterFailureData(envelope);
|
|
7154
7364
|
if (!suppressTelemetry) {
|
|
7155
7365
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
7156
7366
|
result: data.Result,
|
|
@@ -7199,13 +7409,20 @@ var OutputFormatter;
|
|
|
7199
7409
|
OutputFormatter.log = log;
|
|
7200
7410
|
function formatToString(data) {
|
|
7201
7411
|
const filter = getOutputFilter();
|
|
7412
|
+
const envelope = data;
|
|
7202
7413
|
if ("Data" in data && data.Data != null) {
|
|
7203
7414
|
data.Data = normalizeDataKeys(data.Data);
|
|
7204
7415
|
if (filter) {
|
|
7205
|
-
|
|
7416
|
+
let note;
|
|
7417
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
7418
|
+
note = n;
|
|
7419
|
+
}));
|
|
7420
|
+
if (note) {
|
|
7421
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
7422
|
+
}
|
|
7206
7423
|
}
|
|
7207
7424
|
}
|
|
7208
|
-
const output = normalizeOutputKeys(
|
|
7425
|
+
const output = normalizeOutputKeys(envelope);
|
|
7209
7426
|
const lines = [];
|
|
7210
7427
|
const sink = getOutputSink();
|
|
7211
7428
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -10626,4 +10843,4 @@ export {
|
|
|
10626
10843
|
registerCommands
|
|
10627
10844
|
};
|
|
10628
10845
|
|
|
10629
|
-
//# debugId=
|
|
10846
|
+
//# debugId=DD1B3228E67B284864756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/authz-commands",
|
|
3
3
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "1.202.1-preview.
|
|
4
|
+
"version": "1.202.1-preview.238",
|
|
5
5
|
"description": "Admin CLI commands for the UiPath Authorization service. 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": "537e43df1d3583633cfd3a0b88634f9ce3ba9d6b"
|
|
29
29
|
}
|