@uipath/uipath-python-bridge 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
|
@@ -9728,7 +9728,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
9728
9728
|
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).";
|
|
9729
9729
|
}
|
|
9730
9730
|
}
|
|
9731
|
-
function
|
|
9731
|
+
function countRecords(data) {
|
|
9732
|
+
if (Array.isArray(data))
|
|
9733
|
+
return data.length;
|
|
9734
|
+
return data == null ? 0 : 1;
|
|
9735
|
+
}
|
|
9736
|
+
function availableFields(data) {
|
|
9737
|
+
const records = Array.isArray(data) ? data : [data];
|
|
9738
|
+
const keys = new Set;
|
|
9739
|
+
for (const record of records) {
|
|
9740
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
9741
|
+
for (const key of Object.keys(record))
|
|
9742
|
+
keys.add(key);
|
|
9743
|
+
}
|
|
9744
|
+
}
|
|
9745
|
+
return [...keys];
|
|
9746
|
+
}
|
|
9747
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
9748
|
+
const [error, decoded] = catchError(() => JSON.parse(whole));
|
|
9749
|
+
if (!error && typeof decoded === "string")
|
|
9750
|
+
return decoded;
|
|
9751
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
9752
|
+
}
|
|
9753
|
+
function referencedFields(filter) {
|
|
9754
|
+
const top = new Set;
|
|
9755
|
+
const nested = new Set;
|
|
9756
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
9757
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
9758
|
+
const quoted = [];
|
|
9759
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
9760
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
9761
|
+
if (!isAlias) {
|
|
9762
|
+
quoted.push({
|
|
9763
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
9764
|
+
index,
|
|
9765
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
9766
|
+
});
|
|
9767
|
+
}
|
|
9768
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
9769
|
+
});
|
|
9770
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
9771
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
9772
|
+
const place = (name, index, tail) => {
|
|
9773
|
+
if (tail || index >= rootEnd)
|
|
9774
|
+
nested.add(name);
|
|
9775
|
+
else
|
|
9776
|
+
top.add(name);
|
|
9777
|
+
};
|
|
9778
|
+
for (const entry of quoted)
|
|
9779
|
+
place(entry.name, entry.index, entry.tail);
|
|
9780
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
9781
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
9782
|
+
for (const match of identifiers) {
|
|
9783
|
+
const [, name, trailing] = match;
|
|
9784
|
+
if (trailing || reserved.has(name))
|
|
9785
|
+
continue;
|
|
9786
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
9787
|
+
}
|
|
9788
|
+
return {
|
|
9789
|
+
top: [...top],
|
|
9790
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
9791
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
9792
|
+
};
|
|
9793
|
+
}
|
|
9794
|
+
function appearsBelowTopLevel(data, name) {
|
|
9795
|
+
let budget = 2000;
|
|
9796
|
+
const visit = (value, depth) => {
|
|
9797
|
+
if (budget-- <= 0 || depth > 4)
|
|
9798
|
+
return false;
|
|
9799
|
+
if (value === null || typeof value !== "object")
|
|
9800
|
+
return false;
|
|
9801
|
+
if (Array.isArray(value))
|
|
9802
|
+
return value.some((entry) => visit(entry, depth));
|
|
9803
|
+
const record = value;
|
|
9804
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
9805
|
+
return true;
|
|
9806
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
9807
|
+
};
|
|
9808
|
+
return visit(data, 0);
|
|
9809
|
+
}
|
|
9810
|
+
function alwaysNullKeys(records) {
|
|
9811
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
9812
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
9813
|
+
return [];
|
|
9814
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
9815
|
+
if (keys.length === 0)
|
|
9816
|
+
return [];
|
|
9817
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
9818
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
9819
|
+
}
|
|
9820
|
+
function carriesOnlyNulls(value) {
|
|
9821
|
+
if (value === null)
|
|
9822
|
+
return true;
|
|
9823
|
+
if (Array.isArray(value)) {
|
|
9824
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
9825
|
+
}
|
|
9826
|
+
if (typeof value === "object" && value !== undefined) {
|
|
9827
|
+
const values = Object.values(value);
|
|
9828
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
9829
|
+
}
|
|
9830
|
+
return false;
|
|
9831
|
+
}
|
|
9832
|
+
function nameList(names, cap2 = 12) {
|
|
9833
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
9834
|
+
const rest = names.length - shown.length;
|
|
9835
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
9836
|
+
}
|
|
9837
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
9838
|
+
const present = availableFields(data);
|
|
9839
|
+
const refs = referencedFields(filter);
|
|
9840
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
9841
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
9842
|
+
const count = countRecords(data);
|
|
9843
|
+
const scope = `${count} record(s)`;
|
|
9844
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
9845
|
+
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" : "";
|
|
9846
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
9847
|
+
let detail;
|
|
9848
|
+
let lede;
|
|
9849
|
+
if (outcome.kind === "null-elements") {
|
|
9850
|
+
lede = "returned only null values";
|
|
9851
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
9852
|
+
if (unknown.length > 0) {
|
|
9853
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
9854
|
+
} else if (unchecked.length > 0) {
|
|
9855
|
+
detail = withSoundness(projected);
|
|
9856
|
+
} else {
|
|
9857
|
+
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`;
|
|
9858
|
+
}
|
|
9859
|
+
} else if (outcome.kind === "null-rows") {
|
|
9860
|
+
lede = "returned only null values";
|
|
9861
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
9862
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
9863
|
+
} else if (outcome.kind === "null-values") {
|
|
9864
|
+
lede = "returned only null values";
|
|
9865
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
9866
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
9867
|
+
if (sameSet) {
|
|
9868
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
9869
|
+
} else if (unknown.length > 0) {
|
|
9870
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
9871
|
+
} else {
|
|
9872
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
9873
|
+
}
|
|
9874
|
+
} else {
|
|
9875
|
+
lede = "returned nothing";
|
|
9876
|
+
if (unknown.length > 0) {
|
|
9877
|
+
detail = isNotAField(unknown);
|
|
9878
|
+
} else {
|
|
9879
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
9880
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
9881
|
+
}
|
|
9882
|
+
}
|
|
9883
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
9884
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
9885
|
+
}
|
|
9886
|
+
function appendWarning(existing, note) {
|
|
9887
|
+
return existing ? `${existing} ${note}` : note;
|
|
9888
|
+
}
|
|
9889
|
+
function applyFilter(data, filter, onWarning) {
|
|
9732
9890
|
const codec = requireJmespath();
|
|
9733
9891
|
let result;
|
|
9734
9892
|
try {
|
|
@@ -9736,9 +9894,34 @@ function applyFilter(data, filter) {
|
|
|
9736
9894
|
} catch (err) {
|
|
9737
9895
|
throw new FilterEvaluationError(filter, err);
|
|
9738
9896
|
}
|
|
9739
|
-
|
|
9897
|
+
const inputCount = countRecords(data);
|
|
9898
|
+
const warn = (outcome) => {
|
|
9899
|
+
if (inputCount === 0)
|
|
9900
|
+
return;
|
|
9901
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
9902
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
9903
|
+
`);
|
|
9904
|
+
onWarning?.(note);
|
|
9905
|
+
};
|
|
9906
|
+
const warnIfAllNull = (records) => {
|
|
9907
|
+
const keys = alwaysNullKeys(records);
|
|
9908
|
+
if (keys.length > 0)
|
|
9909
|
+
warn({ kind: "null-values", keys });
|
|
9910
|
+
};
|
|
9911
|
+
if (result == null) {
|
|
9912
|
+
warn({ kind: "empty" });
|
|
9740
9913
|
return [];
|
|
9914
|
+
}
|
|
9741
9915
|
if (Array.isArray(result)) {
|
|
9916
|
+
if (result.length === 0) {
|
|
9917
|
+
warn({ kind: "empty" });
|
|
9918
|
+
} else if (result.every((entry) => entry === null)) {
|
|
9919
|
+
warn({ kind: "null-elements", count: result.length });
|
|
9920
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
9921
|
+
warn({ kind: "null-rows", count: result.length });
|
|
9922
|
+
} else {
|
|
9923
|
+
warnIfAllNull(result);
|
|
9924
|
+
}
|
|
9742
9925
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
9743
9926
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
9744
9927
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -9746,10 +9929,30 @@ function applyFilter(data, filter) {
|
|
|
9746
9929
|
}
|
|
9747
9930
|
return result;
|
|
9748
9931
|
}
|
|
9749
|
-
if (typeof result === "object")
|
|
9932
|
+
if (typeof result === "object") {
|
|
9933
|
+
warnIfAllNull([result]);
|
|
9750
9934
|
return result;
|
|
9935
|
+
}
|
|
9751
9936
|
return { Value: result };
|
|
9752
9937
|
}
|
|
9938
|
+
function filterFailureData(envelope) {
|
|
9939
|
+
const filter = getOutputFilter();
|
|
9940
|
+
const data = envelope.Data;
|
|
9941
|
+
if (!filter || data == null)
|
|
9942
|
+
return;
|
|
9943
|
+
let note;
|
|
9944
|
+
const [filterError, filtered] = catchError(() => applyFilter(data, filter, (n) => {
|
|
9945
|
+
note = n;
|
|
9946
|
+
}));
|
|
9947
|
+
if (filterError) {
|
|
9948
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
9949
|
+
return;
|
|
9950
|
+
}
|
|
9951
|
+
envelope.Data = filtered;
|
|
9952
|
+
if (note) {
|
|
9953
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
9954
|
+
}
|
|
9955
|
+
}
|
|
9753
9956
|
function defaultErrorCodeForResult(result) {
|
|
9754
9957
|
switch (result) {
|
|
9755
9958
|
case RESULTS.AuthenticationError:
|
|
@@ -9832,8 +10035,14 @@ var OutputFormatter;
|
|
|
9832
10035
|
}
|
|
9833
10036
|
const filter = getOutputFilter();
|
|
9834
10037
|
if (filter) {
|
|
9835
|
-
|
|
10038
|
+
let note;
|
|
10039
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
10040
|
+
note = n;
|
|
10041
|
+
});
|
|
9836
10042
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
10043
|
+
if (note) {
|
|
10044
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
10045
|
+
}
|
|
9837
10046
|
}
|
|
9838
10047
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
9839
10048
|
}
|
|
@@ -9861,6 +10070,7 @@ var OutputFormatter;
|
|
|
9861
10070
|
delete envelope.TelemetryErrorClass;
|
|
9862
10071
|
delete envelope.TelemetryTerminalOutcome;
|
|
9863
10072
|
delete envelope.TelemetryTerminalSignal;
|
|
10073
|
+
filterFailureData(envelope);
|
|
9864
10074
|
if (!suppressTelemetry) {
|
|
9865
10075
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
9866
10076
|
result: data.Result,
|
|
@@ -9909,13 +10119,20 @@ var OutputFormatter;
|
|
|
9909
10119
|
OutputFormatter.log = log;
|
|
9910
10120
|
function formatToString(data) {
|
|
9911
10121
|
const filter = getOutputFilter();
|
|
10122
|
+
const envelope = data;
|
|
9912
10123
|
if ("Data" in data && data.Data != null) {
|
|
9913
10124
|
data.Data = normalizeDataKeys(data.Data);
|
|
9914
10125
|
if (filter) {
|
|
9915
|
-
|
|
10126
|
+
let note;
|
|
10127
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
10128
|
+
note = n;
|
|
10129
|
+
}));
|
|
10130
|
+
if (note) {
|
|
10131
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
10132
|
+
}
|
|
9916
10133
|
}
|
|
9917
10134
|
}
|
|
9918
|
-
const output = normalizeOutputKeys(
|
|
10135
|
+
const output = normalizeOutputKeys(envelope);
|
|
9919
10136
|
const lines = [];
|
|
9920
10137
|
const sink = getOutputSink();
|
|
9921
10138
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -12745,4 +12962,4 @@ export {
|
|
|
12745
12962
|
runUipathPythonCommand
|
|
12746
12963
|
};
|
|
12747
12964
|
|
|
12748
|
-
//# debugId=
|
|
12965
|
+
//# debugId=11AD95BBBAB0DB9F64756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/uipath-python-bridge",
|
|
3
3
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "1.202.1-preview.
|
|
4
|
+
"version": "1.202.1-preview.239",
|
|
5
5
|
"description": "Shared Python detection, caching, and CLI bridge for UiPath Python SDK tools.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"uip",
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"registry": "https://registry.npmjs.org/"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "97545a7857bdff7e6db62bbe13c6097607cf38f1"
|
|
28
28
|
}
|