@uipath/data-fabric-tool 1.203.0-preview.235 → 1.203.0-preview.240
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
CHANGED
|
@@ -6584,7 +6584,7 @@ var package_default = {
|
|
|
6584
6584
|
name: "@uipath/data-fabric-tool",
|
|
6585
6585
|
author: "UiPath",
|
|
6586
6586
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
6587
|
-
version: "1.203.0-preview.
|
|
6587
|
+
version: "1.203.0-preview.240",
|
|
6588
6588
|
description: "Manage Data Fabric entities and records.",
|
|
6589
6589
|
publishConfig: {
|
|
6590
6590
|
registry: "https://npm.pkg.github.com/"
|
|
@@ -9525,7 +9525,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
9525
9525
|
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).";
|
|
9526
9526
|
}
|
|
9527
9527
|
}
|
|
9528
|
-
function
|
|
9528
|
+
function countRecords(data) {
|
|
9529
|
+
if (Array.isArray(data))
|
|
9530
|
+
return data.length;
|
|
9531
|
+
return data == null ? 0 : 1;
|
|
9532
|
+
}
|
|
9533
|
+
function availableFields(data) {
|
|
9534
|
+
const records = Array.isArray(data) ? data : [data];
|
|
9535
|
+
const keys = new Set;
|
|
9536
|
+
for (const record of records) {
|
|
9537
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
9538
|
+
for (const key of Object.keys(record))
|
|
9539
|
+
keys.add(key);
|
|
9540
|
+
}
|
|
9541
|
+
}
|
|
9542
|
+
return [...keys];
|
|
9543
|
+
}
|
|
9544
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
9545
|
+
const [error, decoded] = catchError(() => JSON.parse(whole));
|
|
9546
|
+
if (!error && typeof decoded === "string")
|
|
9547
|
+
return decoded;
|
|
9548
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
9549
|
+
}
|
|
9550
|
+
function referencedFields(filter) {
|
|
9551
|
+
const top = new Set;
|
|
9552
|
+
const nested = new Set;
|
|
9553
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
9554
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
9555
|
+
const quoted = [];
|
|
9556
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
9557
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
9558
|
+
if (!isAlias) {
|
|
9559
|
+
quoted.push({
|
|
9560
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
9561
|
+
index,
|
|
9562
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
9563
|
+
});
|
|
9564
|
+
}
|
|
9565
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
9566
|
+
});
|
|
9567
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
9568
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
9569
|
+
const place = (name, index, tail) => {
|
|
9570
|
+
if (tail || index >= rootEnd)
|
|
9571
|
+
nested.add(name);
|
|
9572
|
+
else
|
|
9573
|
+
top.add(name);
|
|
9574
|
+
};
|
|
9575
|
+
for (const entry of quoted)
|
|
9576
|
+
place(entry.name, entry.index, entry.tail);
|
|
9577
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
9578
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
9579
|
+
for (const match of identifiers) {
|
|
9580
|
+
const [, name, trailing] = match;
|
|
9581
|
+
if (trailing || reserved.has(name))
|
|
9582
|
+
continue;
|
|
9583
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
9584
|
+
}
|
|
9585
|
+
return {
|
|
9586
|
+
top: [...top],
|
|
9587
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
9588
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
9589
|
+
};
|
|
9590
|
+
}
|
|
9591
|
+
function appearsBelowTopLevel(data, name) {
|
|
9592
|
+
let budget = 2000;
|
|
9593
|
+
const visit = (value, depth) => {
|
|
9594
|
+
if (budget-- <= 0 || depth > 4)
|
|
9595
|
+
return false;
|
|
9596
|
+
if (value === null || typeof value !== "object")
|
|
9597
|
+
return false;
|
|
9598
|
+
if (Array.isArray(value))
|
|
9599
|
+
return value.some((entry) => visit(entry, depth));
|
|
9600
|
+
const record = value;
|
|
9601
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
9602
|
+
return true;
|
|
9603
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
9604
|
+
};
|
|
9605
|
+
return visit(data, 0);
|
|
9606
|
+
}
|
|
9607
|
+
function alwaysNullKeys(records) {
|
|
9608
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
9609
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
9610
|
+
return [];
|
|
9611
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
9612
|
+
if (keys.length === 0)
|
|
9613
|
+
return [];
|
|
9614
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
9615
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
9616
|
+
}
|
|
9617
|
+
function carriesOnlyNulls(value) {
|
|
9618
|
+
if (value === null)
|
|
9619
|
+
return true;
|
|
9620
|
+
if (Array.isArray(value)) {
|
|
9621
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
9622
|
+
}
|
|
9623
|
+
if (typeof value === "object" && value !== undefined) {
|
|
9624
|
+
const values = Object.values(value);
|
|
9625
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
9626
|
+
}
|
|
9627
|
+
return false;
|
|
9628
|
+
}
|
|
9629
|
+
function nameList(names, cap2 = 12) {
|
|
9630
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
9631
|
+
const rest = names.length - shown.length;
|
|
9632
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
9633
|
+
}
|
|
9634
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
9635
|
+
const present = availableFields(data);
|
|
9636
|
+
const refs = referencedFields(filter);
|
|
9637
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
9638
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
9639
|
+
const count = countRecords(data);
|
|
9640
|
+
const scope = `${count} record(s)`;
|
|
9641
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
9642
|
+
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" : "";
|
|
9643
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
9644
|
+
let detail;
|
|
9645
|
+
let lede;
|
|
9646
|
+
if (outcome.kind === "null-elements") {
|
|
9647
|
+
lede = "returned only null values";
|
|
9648
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
9649
|
+
if (unknown.length > 0) {
|
|
9650
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
9651
|
+
} else if (unchecked.length > 0) {
|
|
9652
|
+
detail = withSoundness(projected);
|
|
9653
|
+
} else {
|
|
9654
|
+
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`;
|
|
9655
|
+
}
|
|
9656
|
+
} else if (outcome.kind === "null-rows") {
|
|
9657
|
+
lede = "returned only null values";
|
|
9658
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
9659
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
9660
|
+
} else if (outcome.kind === "null-values") {
|
|
9661
|
+
lede = "returned only null values";
|
|
9662
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
9663
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
9664
|
+
if (sameSet) {
|
|
9665
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
9666
|
+
} else if (unknown.length > 0) {
|
|
9667
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
9668
|
+
} else {
|
|
9669
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
9670
|
+
}
|
|
9671
|
+
} else {
|
|
9672
|
+
lede = "returned nothing";
|
|
9673
|
+
if (unknown.length > 0) {
|
|
9674
|
+
detail = isNotAField(unknown);
|
|
9675
|
+
} else {
|
|
9676
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
9677
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
9678
|
+
}
|
|
9679
|
+
}
|
|
9680
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
9681
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
9682
|
+
}
|
|
9683
|
+
function appendWarning(existing, note) {
|
|
9684
|
+
return existing ? `${existing} ${note}` : note;
|
|
9685
|
+
}
|
|
9686
|
+
function applyFilter(data, filter, onWarning) {
|
|
9529
9687
|
const codec = requireJmespath();
|
|
9530
9688
|
let result;
|
|
9531
9689
|
try {
|
|
@@ -9533,9 +9691,34 @@ function applyFilter(data, filter) {
|
|
|
9533
9691
|
} catch (err) {
|
|
9534
9692
|
throw new FilterEvaluationError(filter, err);
|
|
9535
9693
|
}
|
|
9536
|
-
|
|
9694
|
+
const inputCount = countRecords(data);
|
|
9695
|
+
const warn = (outcome) => {
|
|
9696
|
+
if (inputCount === 0)
|
|
9697
|
+
return;
|
|
9698
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
9699
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
9700
|
+
`);
|
|
9701
|
+
onWarning?.(note);
|
|
9702
|
+
};
|
|
9703
|
+
const warnIfAllNull = (records) => {
|
|
9704
|
+
const keys = alwaysNullKeys(records);
|
|
9705
|
+
if (keys.length > 0)
|
|
9706
|
+
warn({ kind: "null-values", keys });
|
|
9707
|
+
};
|
|
9708
|
+
if (result == null) {
|
|
9709
|
+
warn({ kind: "empty" });
|
|
9537
9710
|
return [];
|
|
9711
|
+
}
|
|
9538
9712
|
if (Array.isArray(result)) {
|
|
9713
|
+
if (result.length === 0) {
|
|
9714
|
+
warn({ kind: "empty" });
|
|
9715
|
+
} else if (result.every((entry) => entry === null)) {
|
|
9716
|
+
warn({ kind: "null-elements", count: result.length });
|
|
9717
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
9718
|
+
warn({ kind: "null-rows", count: result.length });
|
|
9719
|
+
} else {
|
|
9720
|
+
warnIfAllNull(result);
|
|
9721
|
+
}
|
|
9539
9722
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
9540
9723
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
9541
9724
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -9543,10 +9726,30 @@ function applyFilter(data, filter) {
|
|
|
9543
9726
|
}
|
|
9544
9727
|
return result;
|
|
9545
9728
|
}
|
|
9546
|
-
if (typeof result === "object")
|
|
9729
|
+
if (typeof result === "object") {
|
|
9730
|
+
warnIfAllNull([result]);
|
|
9547
9731
|
return result;
|
|
9732
|
+
}
|
|
9548
9733
|
return { Value: result };
|
|
9549
9734
|
}
|
|
9735
|
+
function filterFailureData(envelope) {
|
|
9736
|
+
const filter = getOutputFilter();
|
|
9737
|
+
const data = envelope.Data;
|
|
9738
|
+
if (!filter || data == null)
|
|
9739
|
+
return;
|
|
9740
|
+
let note;
|
|
9741
|
+
const [filterError, filtered] = catchError(() => applyFilter(data, filter, (n) => {
|
|
9742
|
+
note = n;
|
|
9743
|
+
}));
|
|
9744
|
+
if (filterError) {
|
|
9745
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
9746
|
+
return;
|
|
9747
|
+
}
|
|
9748
|
+
envelope.Data = filtered;
|
|
9749
|
+
if (note) {
|
|
9750
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
9751
|
+
}
|
|
9752
|
+
}
|
|
9550
9753
|
function defaultErrorCodeForResult(result) {
|
|
9551
9754
|
switch (result) {
|
|
9552
9755
|
case RESULTS.AuthenticationError:
|
|
@@ -9629,8 +9832,14 @@ var OutputFormatter;
|
|
|
9629
9832
|
}
|
|
9630
9833
|
const filter = getOutputFilter();
|
|
9631
9834
|
if (filter) {
|
|
9632
|
-
|
|
9835
|
+
let note;
|
|
9836
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
9837
|
+
note = n;
|
|
9838
|
+
});
|
|
9633
9839
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
9840
|
+
if (note) {
|
|
9841
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
9842
|
+
}
|
|
9634
9843
|
}
|
|
9635
9844
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
9636
9845
|
}
|
|
@@ -9658,6 +9867,7 @@ var OutputFormatter;
|
|
|
9658
9867
|
delete envelope.TelemetryErrorClass;
|
|
9659
9868
|
delete envelope.TelemetryTerminalOutcome;
|
|
9660
9869
|
delete envelope.TelemetryTerminalSignal;
|
|
9870
|
+
filterFailureData(envelope);
|
|
9661
9871
|
if (!suppressTelemetry) {
|
|
9662
9872
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
9663
9873
|
result: data.Result,
|
|
@@ -9706,13 +9916,20 @@ var OutputFormatter;
|
|
|
9706
9916
|
OutputFormatter.log = log;
|
|
9707
9917
|
function formatToString(data) {
|
|
9708
9918
|
const filter = getOutputFilter();
|
|
9919
|
+
const envelope = data;
|
|
9709
9920
|
if ("Data" in data && data.Data != null) {
|
|
9710
9921
|
data.Data = normalizeDataKeys(data.Data);
|
|
9711
9922
|
if (filter) {
|
|
9712
|
-
|
|
9923
|
+
let note;
|
|
9924
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
9925
|
+
note = n;
|
|
9926
|
+
}));
|
|
9927
|
+
if (note) {
|
|
9928
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
9929
|
+
}
|
|
9713
9930
|
}
|
|
9714
9931
|
}
|
|
9715
|
-
const output = normalizeOutputKeys(
|
|
9932
|
+
const output = normalizeOutputKeys(envelope);
|
|
9716
9933
|
const lines = [];
|
|
9717
9934
|
const sink = getOutputSink();
|
|
9718
9935
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -26093,4 +26310,4 @@ var registerCommands = async (program2) => {
|
|
|
26093
26310
|
|
|
26094
26311
|
export { Command, metadata, registerCommands };
|
|
26095
26312
|
|
|
26096
|
-
//# debugId=
|
|
26313
|
+
//# debugId=F6FC07632AD27A6D64756E2164756E21
|
package/dist/tool.js
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/data-fabric-tool",
|
|
3
3
|
"author": "UiPath",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
|
-
"version": "1.203.0-preview.
|
|
5
|
+
"version": "1.203.0-preview.240",
|
|
6
6
|
"description": "Manage Data Fabric entities and records.",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -19,5 +19,5 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"dist"
|
|
21
21
|
],
|
|
22
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "95409ea61d359dff5465afaf59cb3a5efae542af"
|
|
23
23
|
}
|