@uipath/uipath-python-bridge 1.203.0-preview.235 → 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
|
@@ -9958,7 +9958,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
9958
9958
|
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).";
|
|
9959
9959
|
}
|
|
9960
9960
|
}
|
|
9961
|
-
function
|
|
9961
|
+
function countRecords(data) {
|
|
9962
|
+
if (Array.isArray(data))
|
|
9963
|
+
return data.length;
|
|
9964
|
+
return data == null ? 0 : 1;
|
|
9965
|
+
}
|
|
9966
|
+
function availableFields(data) {
|
|
9967
|
+
const records = Array.isArray(data) ? data : [data];
|
|
9968
|
+
const keys = new Set;
|
|
9969
|
+
for (const record of records) {
|
|
9970
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
9971
|
+
for (const key of Object.keys(record))
|
|
9972
|
+
keys.add(key);
|
|
9973
|
+
}
|
|
9974
|
+
}
|
|
9975
|
+
return [...keys];
|
|
9976
|
+
}
|
|
9977
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
9978
|
+
const [error, decoded] = catchError(() => JSON.parse(whole));
|
|
9979
|
+
if (!error && typeof decoded === "string")
|
|
9980
|
+
return decoded;
|
|
9981
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
9982
|
+
}
|
|
9983
|
+
function referencedFields(filter) {
|
|
9984
|
+
const top = new Set;
|
|
9985
|
+
const nested = new Set;
|
|
9986
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
9987
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
9988
|
+
const quoted = [];
|
|
9989
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
9990
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
9991
|
+
if (!isAlias) {
|
|
9992
|
+
quoted.push({
|
|
9993
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
9994
|
+
index,
|
|
9995
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
9996
|
+
});
|
|
9997
|
+
}
|
|
9998
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
9999
|
+
});
|
|
10000
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
10001
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
10002
|
+
const place = (name, index, tail) => {
|
|
10003
|
+
if (tail || index >= rootEnd)
|
|
10004
|
+
nested.add(name);
|
|
10005
|
+
else
|
|
10006
|
+
top.add(name);
|
|
10007
|
+
};
|
|
10008
|
+
for (const entry of quoted)
|
|
10009
|
+
place(entry.name, entry.index, entry.tail);
|
|
10010
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
10011
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
10012
|
+
for (const match of identifiers) {
|
|
10013
|
+
const [, name, trailing] = match;
|
|
10014
|
+
if (trailing || reserved.has(name))
|
|
10015
|
+
continue;
|
|
10016
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
10017
|
+
}
|
|
10018
|
+
return {
|
|
10019
|
+
top: [...top],
|
|
10020
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
10021
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
10022
|
+
};
|
|
10023
|
+
}
|
|
10024
|
+
function appearsBelowTopLevel(data, name) {
|
|
10025
|
+
let budget = 2000;
|
|
10026
|
+
const visit = (value, depth) => {
|
|
10027
|
+
if (budget-- <= 0 || depth > 4)
|
|
10028
|
+
return false;
|
|
10029
|
+
if (value === null || typeof value !== "object")
|
|
10030
|
+
return false;
|
|
10031
|
+
if (Array.isArray(value))
|
|
10032
|
+
return value.some((entry) => visit(entry, depth));
|
|
10033
|
+
const record = value;
|
|
10034
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
10035
|
+
return true;
|
|
10036
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
10037
|
+
};
|
|
10038
|
+
return visit(data, 0);
|
|
10039
|
+
}
|
|
10040
|
+
function alwaysNullKeys(records) {
|
|
10041
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
10042
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
10043
|
+
return [];
|
|
10044
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
10045
|
+
if (keys.length === 0)
|
|
10046
|
+
return [];
|
|
10047
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
10048
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
10049
|
+
}
|
|
10050
|
+
function carriesOnlyNulls(value) {
|
|
10051
|
+
if (value === null)
|
|
10052
|
+
return true;
|
|
10053
|
+
if (Array.isArray(value)) {
|
|
10054
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
10055
|
+
}
|
|
10056
|
+
if (typeof value === "object" && value !== undefined) {
|
|
10057
|
+
const values = Object.values(value);
|
|
10058
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
10059
|
+
}
|
|
10060
|
+
return false;
|
|
10061
|
+
}
|
|
10062
|
+
function nameList(names, cap2 = 12) {
|
|
10063
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
10064
|
+
const rest = names.length - shown.length;
|
|
10065
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
10066
|
+
}
|
|
10067
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
10068
|
+
const present = availableFields(data);
|
|
10069
|
+
const refs = referencedFields(filter);
|
|
10070
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
10071
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
10072
|
+
const count = countRecords(data);
|
|
10073
|
+
const scope = `${count} record(s)`;
|
|
10074
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
10075
|
+
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" : "";
|
|
10076
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
10077
|
+
let detail;
|
|
10078
|
+
let lede;
|
|
10079
|
+
if (outcome.kind === "null-elements") {
|
|
10080
|
+
lede = "returned only null values";
|
|
10081
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
10082
|
+
if (unknown.length > 0) {
|
|
10083
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
10084
|
+
} else if (unchecked.length > 0) {
|
|
10085
|
+
detail = withSoundness(projected);
|
|
10086
|
+
} else {
|
|
10087
|
+
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`;
|
|
10088
|
+
}
|
|
10089
|
+
} else if (outcome.kind === "null-rows") {
|
|
10090
|
+
lede = "returned only null values";
|
|
10091
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
10092
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
10093
|
+
} else if (outcome.kind === "null-values") {
|
|
10094
|
+
lede = "returned only null values";
|
|
10095
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
10096
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
10097
|
+
if (sameSet) {
|
|
10098
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
10099
|
+
} else if (unknown.length > 0) {
|
|
10100
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
10101
|
+
} else {
|
|
10102
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
10103
|
+
}
|
|
10104
|
+
} else {
|
|
10105
|
+
lede = "returned nothing";
|
|
10106
|
+
if (unknown.length > 0) {
|
|
10107
|
+
detail = isNotAField(unknown);
|
|
10108
|
+
} else {
|
|
10109
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
10110
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
10111
|
+
}
|
|
10112
|
+
}
|
|
10113
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
10114
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
10115
|
+
}
|
|
10116
|
+
function appendWarning(existing, note) {
|
|
10117
|
+
return existing ? `${existing} ${note}` : note;
|
|
10118
|
+
}
|
|
10119
|
+
function applyFilter(data, filter, onWarning) {
|
|
9962
10120
|
const codec = requireJmespath();
|
|
9963
10121
|
let result;
|
|
9964
10122
|
try {
|
|
@@ -9966,9 +10124,34 @@ function applyFilter(data, filter) {
|
|
|
9966
10124
|
} catch (err) {
|
|
9967
10125
|
throw new FilterEvaluationError(filter, err);
|
|
9968
10126
|
}
|
|
9969
|
-
|
|
10127
|
+
const inputCount = countRecords(data);
|
|
10128
|
+
const warn = (outcome) => {
|
|
10129
|
+
if (inputCount === 0)
|
|
10130
|
+
return;
|
|
10131
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
10132
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
10133
|
+
`);
|
|
10134
|
+
onWarning?.(note);
|
|
10135
|
+
};
|
|
10136
|
+
const warnIfAllNull = (records) => {
|
|
10137
|
+
const keys = alwaysNullKeys(records);
|
|
10138
|
+
if (keys.length > 0)
|
|
10139
|
+
warn({ kind: "null-values", keys });
|
|
10140
|
+
};
|
|
10141
|
+
if (result == null) {
|
|
10142
|
+
warn({ kind: "empty" });
|
|
9970
10143
|
return [];
|
|
10144
|
+
}
|
|
9971
10145
|
if (Array.isArray(result)) {
|
|
10146
|
+
if (result.length === 0) {
|
|
10147
|
+
warn({ kind: "empty" });
|
|
10148
|
+
} else if (result.every((entry) => entry === null)) {
|
|
10149
|
+
warn({ kind: "null-elements", count: result.length });
|
|
10150
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
10151
|
+
warn({ kind: "null-rows", count: result.length });
|
|
10152
|
+
} else {
|
|
10153
|
+
warnIfAllNull(result);
|
|
10154
|
+
}
|
|
9972
10155
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
9973
10156
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
9974
10157
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -9976,10 +10159,30 @@ function applyFilter(data, filter) {
|
|
|
9976
10159
|
}
|
|
9977
10160
|
return result;
|
|
9978
10161
|
}
|
|
9979
|
-
if (typeof result === "object")
|
|
10162
|
+
if (typeof result === "object") {
|
|
10163
|
+
warnIfAllNull([result]);
|
|
9980
10164
|
return result;
|
|
10165
|
+
}
|
|
9981
10166
|
return { Value: result };
|
|
9982
10167
|
}
|
|
10168
|
+
function filterFailureData(envelope) {
|
|
10169
|
+
const filter = getOutputFilter();
|
|
10170
|
+
const data = envelope.Data;
|
|
10171
|
+
if (!filter || data == null)
|
|
10172
|
+
return;
|
|
10173
|
+
let note;
|
|
10174
|
+
const [filterError, filtered] = catchError(() => applyFilter(data, filter, (n) => {
|
|
10175
|
+
note = n;
|
|
10176
|
+
}));
|
|
10177
|
+
if (filterError) {
|
|
10178
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
10179
|
+
return;
|
|
10180
|
+
}
|
|
10181
|
+
envelope.Data = filtered;
|
|
10182
|
+
if (note) {
|
|
10183
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
10184
|
+
}
|
|
10185
|
+
}
|
|
9983
10186
|
function defaultErrorCodeForResult(result) {
|
|
9984
10187
|
switch (result) {
|
|
9985
10188
|
case RESULTS.AuthenticationError:
|
|
@@ -10062,8 +10265,14 @@ var OutputFormatter;
|
|
|
10062
10265
|
}
|
|
10063
10266
|
const filter = getOutputFilter();
|
|
10064
10267
|
if (filter) {
|
|
10065
|
-
|
|
10268
|
+
let note;
|
|
10269
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
10270
|
+
note = n;
|
|
10271
|
+
});
|
|
10066
10272
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
10273
|
+
if (note) {
|
|
10274
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
10275
|
+
}
|
|
10067
10276
|
}
|
|
10068
10277
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
10069
10278
|
}
|
|
@@ -10091,6 +10300,7 @@ var OutputFormatter;
|
|
|
10091
10300
|
delete envelope.TelemetryErrorClass;
|
|
10092
10301
|
delete envelope.TelemetryTerminalOutcome;
|
|
10093
10302
|
delete envelope.TelemetryTerminalSignal;
|
|
10303
|
+
filterFailureData(envelope);
|
|
10094
10304
|
if (!suppressTelemetry) {
|
|
10095
10305
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
10096
10306
|
result: data.Result,
|
|
@@ -10139,13 +10349,20 @@ var OutputFormatter;
|
|
|
10139
10349
|
OutputFormatter.log = log;
|
|
10140
10350
|
function formatToString(data) {
|
|
10141
10351
|
const filter = getOutputFilter();
|
|
10352
|
+
const envelope = data;
|
|
10142
10353
|
if ("Data" in data && data.Data != null) {
|
|
10143
10354
|
data.Data = normalizeDataKeys(data.Data);
|
|
10144
10355
|
if (filter) {
|
|
10145
|
-
|
|
10356
|
+
let note;
|
|
10357
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
10358
|
+
note = n;
|
|
10359
|
+
}));
|
|
10360
|
+
if (note) {
|
|
10361
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
10362
|
+
}
|
|
10146
10363
|
}
|
|
10147
10364
|
}
|
|
10148
|
-
const output = normalizeOutputKeys(
|
|
10365
|
+
const output = normalizeOutputKeys(envelope);
|
|
10149
10366
|
const lines = [];
|
|
10150
10367
|
const sink = getOutputSink();
|
|
10151
10368
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -13071,4 +13288,4 @@ export {
|
|
|
13071
13288
|
runUipathPythonCommand
|
|
13072
13289
|
};
|
|
13073
13290
|
|
|
13074
|
-
//# debugId=
|
|
13291
|
+
//# debugId=BCBB8050D03A208464756E2164756E21
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/uipath-python-bridge",
|
|
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": "Shared Python detection, caching, and CLI bridge for UiPath Python SDK tools.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"uip",
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
"publishConfig": {
|
|
26
26
|
"registry": "https://registry.npmjs.org/"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "4ad3e17a66f2c7fb7fe1f0e3e04a5b6175a0a9a3"
|
|
29
29
|
}
|