@uipath/gov-tool 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.
Files changed (2) hide show
  1. package/dist/tool.js +226 -9
  2. package/package.json +2 -2
package/dist/tool.js CHANGED
@@ -7654,7 +7654,7 @@ var package_default = {
7654
7654
  name: "@uipath/gov-tool",
7655
7655
  author: "UiPath",
7656
7656
  license: "SEE LICENSE IN LICENSE.txt",
7657
- version: "1.203.0-preview.235",
7657
+ version: "1.203.0-preview.237",
7658
7658
  description: "Manage UiPath governance — AOps policies, Access policies, and compliance packs.",
7659
7659
  private: false,
7660
7660
  repository: {
@@ -12674,7 +12674,165 @@ class FilterImplicitLimitError extends Error {
12674
12674
  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).";
12675
12675
  }
12676
12676
  }
12677
- function applyFilter(data, filter) {
12677
+ function countRecords(data) {
12678
+ if (Array.isArray(data))
12679
+ return data.length;
12680
+ return data == null ? 0 : 1;
12681
+ }
12682
+ function availableFields(data) {
12683
+ const records = Array.isArray(data) ? data : [data];
12684
+ const keys = new Set;
12685
+ for (const record of records) {
12686
+ if (record && typeof record === "object" && !Array.isArray(record)) {
12687
+ for (const key of Object.keys(record))
12688
+ keys.add(key);
12689
+ }
12690
+ }
12691
+ return [...keys];
12692
+ }
12693
+ function decodeQuotedIdentifier(whole, inner) {
12694
+ const [error, decoded] = catchError2(() => JSON.parse(whole));
12695
+ if (!error && typeof decoded === "string")
12696
+ return decoded;
12697
+ return inner.replace(/\\(.)/g, "$1");
12698
+ }
12699
+ function referencedFields(filter) {
12700
+ const top = new Set;
12701
+ const nested = new Set;
12702
+ const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
12703
+ const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
12704
+ const quoted = [];
12705
+ const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
12706
+ const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
12707
+ if (!isAlias) {
12708
+ quoted.push({
12709
+ name: decodeQuotedIdentifier(whole, name),
12710
+ index,
12711
+ tail: isPathTail(withoutValueLiterals, index)
12712
+ });
12713
+ }
12714
+ return `"${" ".repeat(whole.length - 2)}"`;
12715
+ });
12716
+ const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
12717
+ const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
12718
+ const place = (name, index, tail) => {
12719
+ if (tail || index >= rootEnd)
12720
+ nested.add(name);
12721
+ else
12722
+ top.add(name);
12723
+ };
12724
+ for (const entry of quoted)
12725
+ place(entry.name, entry.index, entry.tail);
12726
+ const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
12727
+ const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
12728
+ for (const match of identifiers) {
12729
+ const [, name, trailing] = match;
12730
+ if (trailing || reserved.has(name))
12731
+ continue;
12732
+ place(name, match.index, isPathTail(withoutLiterals, match.index));
12733
+ }
12734
+ return {
12735
+ top: [...top],
12736
+ nested: [...nested].filter((name) => !top.has(name)),
12737
+ hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
12738
+ };
12739
+ }
12740
+ function appearsBelowTopLevel(data, name) {
12741
+ let budget = 2000;
12742
+ const visit = (value, depth) => {
12743
+ if (budget-- <= 0 || depth > 4)
12744
+ return false;
12745
+ if (value === null || typeof value !== "object")
12746
+ return false;
12747
+ if (Array.isArray(value))
12748
+ return value.some((entry) => visit(entry, depth));
12749
+ const record = value;
12750
+ if (depth > 0 && Object.hasOwn(record, name))
12751
+ return true;
12752
+ return Object.values(record).some((entry) => visit(entry, depth + 1));
12753
+ };
12754
+ return visit(data, 0);
12755
+ }
12756
+ function alwaysNullKeys(records) {
12757
+ const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
12758
+ if (objects.length === 0 || objects.length !== records.length)
12759
+ return [];
12760
+ const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
12761
+ if (keys.length === 0)
12762
+ return [];
12763
+ const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
12764
+ return nullKeys.length === keys.length ? nullKeys : [];
12765
+ }
12766
+ function carriesOnlyNulls(value) {
12767
+ if (value === null)
12768
+ return true;
12769
+ if (Array.isArray(value)) {
12770
+ return value.length > 0 && value.every(carriesOnlyNulls);
12771
+ }
12772
+ if (typeof value === "object" && value !== undefined) {
12773
+ const values = Object.values(value);
12774
+ return values.length > 0 && values.every(carriesOnlyNulls);
12775
+ }
12776
+ return false;
12777
+ }
12778
+ function nameList(names, cap2 = 12) {
12779
+ const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
12780
+ const rest = names.length - shown.length;
12781
+ return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
12782
+ }
12783
+ function buildFilterWarning(filter, data, outcome) {
12784
+ const present = availableFields(data);
12785
+ const refs = referencedFields(filter);
12786
+ const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
12787
+ const unchecked = refs.nested.filter((name) => !present.includes(name));
12788
+ const count = countRecords(data);
12789
+ const scope = `${count} record(s)`;
12790
+ const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
12791
+ 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" : "";
12792
+ const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
12793
+ let detail;
12794
+ let lede;
12795
+ if (outcome.kind === "null-elements") {
12796
+ lede = "returned only null values";
12797
+ const projected = `all ${outcome.count} of the elements it projected are null`;
12798
+ if (unknown.length > 0) {
12799
+ detail = `${projected}, because ${isNotAField(unknown)}`;
12800
+ } else if (unchecked.length > 0) {
12801
+ detail = withSoundness(projected);
12802
+ } else {
12803
+ 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`;
12804
+ }
12805
+ } else if (outcome.kind === "null-rows") {
12806
+ lede = "returned only null values";
12807
+ const projected = `every value it projected is null on all ${outcome.count} row(s)`;
12808
+ detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
12809
+ } else if (outcome.kind === "null-values") {
12810
+ lede = "returned only null values";
12811
+ const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
12812
+ const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
12813
+ if (sameSet) {
12814
+ detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
12815
+ } else if (unknown.length > 0) {
12816
+ detail = `${projected}, because ${isNotAField(unknown)}`;
12817
+ } else {
12818
+ detail = withSoundness(`${projected} on all ${scope}`);
12819
+ }
12820
+ } else {
12821
+ lede = "returned nothing";
12822
+ if (unknown.length > 0) {
12823
+ detail = isNotAField(unknown);
12824
+ } else {
12825
+ const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
12826
+ detail = withSoundness(`${selection} — it read ${scope}`);
12827
+ }
12828
+ }
12829
+ const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
12830
+ return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
12831
+ }
12832
+ function appendWarning(existing, note) {
12833
+ return existing ? `${existing} ${note}` : note;
12834
+ }
12835
+ function applyFilter(data, filter, onWarning) {
12678
12836
  const codec = requireJmespath();
12679
12837
  let result;
12680
12838
  try {
@@ -12682,9 +12840,34 @@ function applyFilter(data, filter) {
12682
12840
  } catch (err) {
12683
12841
  throw new FilterEvaluationError(filter, err);
12684
12842
  }
12685
- if (result == null)
12843
+ const inputCount = countRecords(data);
12844
+ const warn = (outcome) => {
12845
+ if (inputCount === 0)
12846
+ return;
12847
+ const note = buildFilterWarning(filter, data, outcome);
12848
+ getOutputSink().writeErr(`[WARN] ${note}
12849
+ `);
12850
+ onWarning?.(note);
12851
+ };
12852
+ const warnIfAllNull = (records) => {
12853
+ const keys = alwaysNullKeys(records);
12854
+ if (keys.length > 0)
12855
+ warn({ kind: "null-values", keys });
12856
+ };
12857
+ if (result == null) {
12858
+ warn({ kind: "empty" });
12686
12859
  return [];
12860
+ }
12687
12861
  if (Array.isArray(result)) {
12862
+ if (result.length === 0) {
12863
+ warn({ kind: "empty" });
12864
+ } else if (result.every((entry) => entry === null)) {
12865
+ warn({ kind: "null-elements", count: result.length });
12866
+ } else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
12867
+ warn({ kind: "null-rows", count: result.length });
12868
+ } else {
12869
+ warnIfAllNull(result);
12870
+ }
12688
12871
  if (result.length > 0 && typeof result[0] !== "object") {
12689
12872
  const fieldMatch = filter.match(/\.(\w+)$/);
12690
12873
  const key = fieldMatch ? fieldMatch[1] : "Value";
@@ -12692,10 +12875,30 @@ function applyFilter(data, filter) {
12692
12875
  }
12693
12876
  return result;
12694
12877
  }
12695
- if (typeof result === "object")
12878
+ if (typeof result === "object") {
12879
+ warnIfAllNull([result]);
12696
12880
  return result;
12881
+ }
12697
12882
  return { Value: result };
12698
12883
  }
12884
+ function filterFailureData(envelope) {
12885
+ const filter = getOutputFilter();
12886
+ const data = envelope.Data;
12887
+ if (!filter || data == null)
12888
+ return;
12889
+ let note;
12890
+ const [filterError, filtered] = catchError2(() => applyFilter(data, filter, (n) => {
12891
+ note = n;
12892
+ }));
12893
+ if (filterError) {
12894
+ envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
12895
+ return;
12896
+ }
12897
+ envelope.Data = filtered;
12898
+ if (note) {
12899
+ envelope.Warning = appendWarning(envelope.Warning, note);
12900
+ }
12901
+ }
12699
12902
  function defaultErrorCodeForResult(result) {
12700
12903
  switch (result) {
12701
12904
  case RESULTS.AuthenticationError:
@@ -12778,8 +12981,14 @@ var OutputFormatter;
12778
12981
  }
12779
12982
  const filter = getOutputFilter();
12780
12983
  if (filter) {
12781
- const filtered = applyFilter(data.Data, filter);
12984
+ let note;
12985
+ const filtered = applyFilter(data.Data, filter, (n) => {
12986
+ note = n;
12987
+ });
12782
12988
  data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
12989
+ if (note) {
12990
+ data.Warning = appendWarning(data.Warning, note);
12991
+ }
12783
12992
  }
12784
12993
  logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
12785
12994
  }
@@ -12807,6 +13016,7 @@ var OutputFormatter;
12807
13016
  delete envelope.TelemetryErrorClass;
12808
13017
  delete envelope.TelemetryTerminalOutcome;
12809
13018
  delete envelope.TelemetryTerminalSignal;
13019
+ filterFailureData(envelope);
12810
13020
  if (!suppressTelemetry) {
12811
13021
  telemetry.trackEvent(CommonTelemetryEvents.Error, {
12812
13022
  result: data.Result,
@@ -12855,13 +13065,20 @@ var OutputFormatter;
12855
13065
  OutputFormatter.log = log;
12856
13066
  function formatToString(data) {
12857
13067
  const filter = getOutputFilter();
13068
+ const envelope = data;
12858
13069
  if ("Data" in data && data.Data != null) {
12859
13070
  data.Data = normalizeDataKeys(data.Data);
12860
13071
  if (filter) {
12861
- data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
13072
+ let note;
13073
+ data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
13074
+ note = n;
13075
+ }));
13076
+ if (note) {
13077
+ envelope.Warning = appendWarning(envelope.Warning, note);
13078
+ }
12862
13079
  }
12863
13080
  }
12864
- const output = normalizeOutputKeys(data);
13081
+ const output = normalizeOutputKeys(envelope);
12865
13082
  const lines = [];
12866
13083
  const sink = getOutputSink();
12867
13084
  printOutput(output, getOutputFormat(), (msg) => {
@@ -14257,7 +14474,7 @@ var package_default3 = {
14257
14474
  name: "@uipath/aops-policy-sdk",
14258
14475
  author: "UiPath",
14259
14476
  license: "SEE LICENSE IN LICENSE.txt",
14260
- version: "1.203.0-preview.235",
14477
+ version: "1.203.0-preview.237",
14261
14478
  description: "SDK for the UiPath AOps Governance API — policy management and deployment.",
14262
14479
  repository: {
14263
14480
  type: "git",
@@ -24768,4 +24985,4 @@ export {
24768
24985
  registerCommands
24769
24986
  };
24770
24987
 
24771
- //# debugId=3927F7FB514BCEAF64756E2164756E21
24988
+ //# debugId=C9FA7A663A857C8D64756E2164756E21
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@uipath/gov-tool",
3
3
  "author": "UiPath",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
- "version": "1.203.0-preview.235",
5
+ "version": "1.203.0-preview.237",
6
6
  "description": "Manage UiPath governance — AOps policies, Access policies, and compliance packs.",
7
7
  "private": false,
8
8
  "repository": {
@@ -24,5 +24,5 @@
24
24
  "files": [
25
25
  "dist"
26
26
  ],
27
- "gitHead": "4788b04c17a4429e5a994af2c3eba3898d1c4b13"
27
+ "gitHead": "4ad3e17a66f2c7fb7fe1f0e3e04a5b6175a0a9a3"
28
28
  }