@code-pushup/utils 0.8.20 → 0.8.22

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/index.js CHANGED
@@ -18,59 +18,48 @@ var MAX_DESCRIPTION_LENGTH = 65536;
18
18
  var MAX_ISSUE_MESSAGE_LENGTH = 1024;
19
19
 
20
20
  // packages/models/src/lib/implementation/utils.ts
21
- var slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
21
+ var slugRegex = /^[a-z\d]+(?:-[a-z\d]+)*$/;
22
22
  var filenameRegex = /^(?!.*[ \\/:*?"<>|]).+$/;
23
23
  function hasDuplicateStrings(strings) {
24
- const uniqueStrings = Array.from(new Set(strings));
25
- const duplicatedStrings = strings.filter(
26
- /* @__PURE__ */ ((i) => (v) => uniqueStrings[i] !== v || !++i)(0)
24
+ const sortedStrings = [...strings].sort();
25
+ const duplStrings = sortedStrings.filter(
26
+ (item, index) => index !== 0 && item === sortedStrings[index - 1]
27
27
  );
28
- return duplicatedStrings.length === 0 ? false : duplicatedStrings;
28
+ return duplStrings.length === 0 ? false : [...new Set(duplStrings)];
29
29
  }
30
30
  function hasMissingStrings(toCheck, existing) {
31
31
  const nonExisting = toCheck.filter((s) => !existing.includes(s));
32
32
  return nonExisting.length === 0 ? false : nonExisting;
33
33
  }
34
- function errorItems(items, transform = (items2) => items2.join(", ")) {
35
- const paredItems = items ? items : [];
36
- return transform(paredItems);
34
+ function errorItems(items, transform = (itemArr) => itemArr.join(", ")) {
35
+ return transform(items || []);
37
36
  }
38
37
  function exists(value) {
39
38
  return value != null;
40
39
  }
41
40
  function getMissingRefsForCategories(categories, plugins) {
42
- const missingRefs = [];
43
41
  const auditRefsFromCategory = categories.flatMap(
44
42
  ({ refs }) => refs.filter(({ type }) => type === "audit").map(({ plugin, slug }) => `${plugin}/${slug}`)
45
43
  );
46
44
  const auditRefsFromPlugins = plugins.flatMap(
47
- ({ audits, slug: pluginSlug }) => {
48
- return audits.map(({ slug }) => `${pluginSlug}/${slug}`);
49
- }
45
+ ({ audits, slug: pluginSlug }) => audits.map(({ slug }) => `${pluginSlug}/${slug}`)
50
46
  );
51
47
  const missingAuditRefs = hasMissingStrings(
52
48
  auditRefsFromCategory,
53
49
  auditRefsFromPlugins
54
50
  );
55
- if (Array.isArray(missingAuditRefs) && missingAuditRefs.length > 0) {
56
- missingRefs.push(...missingAuditRefs);
57
- }
58
51
  const groupRefsFromCategory = categories.flatMap(
59
52
  ({ refs }) => refs.filter(({ type }) => type === "group").map(({ plugin, slug }) => `${plugin}#${slug} (group)`)
60
53
  );
61
54
  const groupRefsFromPlugins = plugins.flatMap(
62
- ({ groups, slug: pluginSlug }) => {
63
- return Array.isArray(groups) ? groups.map(({ slug }) => `${pluginSlug}#${slug} (group)`) : [];
64
- }
55
+ ({ groups, slug: pluginSlug }) => Array.isArray(groups) ? groups.map(({ slug }) => `${pluginSlug}#${slug} (group)`) : []
65
56
  );
66
57
  const missingGroupRefs = hasMissingStrings(
67
58
  groupRefsFromCategory,
68
59
  groupRefsFromPlugins
69
60
  );
70
- if (Array.isArray(missingGroupRefs) && missingGroupRefs.length > 0) {
71
- missingRefs.push(...missingGroupRefs);
72
- }
73
- return missingRefs.length ? missingRefs : false;
61
+ const missingRefs = [missingAuditRefs, missingGroupRefs].filter((refs) => Array.isArray(refs) && refs.length > 0).flat();
62
+ return missingRefs.length > 0 ? missingRefs : false;
74
63
  }
75
64
  function missingRefsForCategoriesErrorMsg(categories, plugins) {
76
65
  const missingRefs = getMissingRefsForCategories(categories, plugins);
@@ -114,7 +103,7 @@ function metaSchema(options) {
114
103
  titleDescription,
115
104
  docsUrlDescription,
116
105
  description
117
- } = options || {};
106
+ } = options ?? {};
118
107
  return z.object(
119
108
  {
120
109
  title: titleSchema(titleDescription),
@@ -569,7 +558,7 @@ function slugify(text) {
569
558
  }
570
559
  function pluralize(text) {
571
560
  if (text.endsWith("y")) {
572
- return text.slice(0, -1) + "ies";
561
+ return `${text.slice(0, -1)}ies`;
573
562
  }
574
563
  if (text.endsWith("s")) {
575
564
  return `${text}es`;
@@ -578,13 +567,14 @@ function pluralize(text) {
578
567
  }
579
568
  function formatBytes(bytes, decimals = 2) {
580
569
  bytes = Math.max(bytes, 0);
581
- if (!bytes)
570
+ if (!bytes) {
582
571
  return "0 B";
572
+ }
583
573
  const k = 1024;
584
574
  const dm = decimals < 0 ? 0 : decimals;
585
575
  const sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
586
576
  const i = Math.floor(Math.log(bytes) / Math.log(k));
587
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
577
+ return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
588
578
  }
589
579
  function pluralizeToken(token, times = 0) {
590
580
  return `${times} ${Math.abs(times) === 1 ? token : pluralize(token)}`;
@@ -640,7 +630,7 @@ function logMultipleResults(results, messagePrefix, succeededCallback, failedCal
640
630
  }
641
631
  }
642
632
  function logPromiseResults(results, logMessage, callback) {
643
- if (results.length) {
633
+ if (results.length > 0) {
644
634
  if (results[0]?.status === "fulfilled") {
645
635
  console.info(logMessage);
646
636
  } else {
@@ -689,9 +679,8 @@ async function ensureDirectoryExists(baseDir) {
689
679
  function logMultipleFileResults(fileResults, messagePrefix) {
690
680
  const succeededCallback = (result) => {
691
681
  const [fileName, size] = result.value;
692
- console.info(
693
- `- ${chalk.bold(fileName)}` + (size ? ` (${chalk.gray(formatBytes(size))})` : "")
694
- );
682
+ const formattedSize = size ? ` (${chalk.gray(formatBytes(size))})` : "";
683
+ console.info(`- ${chalk.bold(fileName)}${formattedSize}`);
695
684
  };
696
685
  const failedCallback = (result) => {
697
686
  console.warn(`- ${chalk.bold(result.reason)}`);
@@ -749,6 +738,7 @@ function findLineNumberInText(content, pattern) {
749
738
  }
750
739
 
751
740
  // packages/utils/src/lib/reports/constants.ts
741
+ var TERMINAL_WIDTH = 80;
752
742
  var NEW_LINE = "\n";
753
743
  var SCORE_COLOR_RANGE = {
754
744
  GREEN_MIN: 0.9,
@@ -817,28 +807,20 @@ function getSeverityIcon(severity) {
817
807
  return "\u2139\uFE0F";
818
808
  }
819
809
  function calcDuration(start, stop) {
820
- stop = stop !== void 0 ? stop : performance.now();
810
+ stop ??= performance.now();
821
811
  return Math.floor(stop - start);
822
812
  }
823
813
  function countCategoryAudits(refs, plugins) {
824
814
  const groupLookup = plugins.reduce(
825
815
  (lookup, plugin) => {
826
- if (!plugin.groups.length) {
816
+ if (plugin.groups.length === 0) {
827
817
  return lookup;
828
818
  }
829
819
  return {
830
820
  ...lookup,
831
- [plugin.slug]: {
832
- ...plugin.groups.reduce(
833
- (groupLookup2, group) => {
834
- return {
835
- ...groupLookup2,
836
- [group.slug]: group
837
- };
838
- },
839
- {}
840
- )
841
- }
821
+ [plugin.slug]: Object.fromEntries(
822
+ plugin.groups.map((group) => [group.slug, group])
823
+ )
842
824
  };
843
825
  },
844
826
  {}
@@ -846,7 +828,7 @@ function countCategoryAudits(refs, plugins) {
846
828
  return refs.reduce((acc, ref) => {
847
829
  if (ref.type === "group") {
848
830
  const groupRefs = groupLookup[ref.plugin]?.[ref.slug]?.refs;
849
- return acc + (groupRefs?.length || 0);
831
+ return acc + (groupRefs?.length ?? 0);
850
832
  }
851
833
  return acc + 1;
852
834
  }, 0);
@@ -952,7 +934,7 @@ function compareIssues(a, b) {
952
934
  return 1;
953
935
  }
954
936
  if (a.source?.file !== b.source?.file) {
955
- return a.source?.file.localeCompare(b.source?.file || "") || 0;
937
+ return a.source?.file.localeCompare(b.source?.file || "") ?? 0;
956
938
  }
957
939
  if (!a.source?.position && b.source?.position) {
958
940
  return -1;
@@ -961,7 +943,7 @@ function compareIssues(a, b) {
961
943
  return 1;
962
944
  }
963
945
  if (a.source?.position?.startLine !== b.source?.position?.startLine) {
964
- return (a.source?.position?.startLine || 0) - (b.source?.position?.startLine || 0);
946
+ return (a.source?.position?.startLine ?? 0) - (b.source?.position?.startLine ?? 0);
965
947
  }
966
948
  return 0;
967
949
  }
@@ -979,12 +961,12 @@ var ProcessError = class extends Error {
979
961
  }
980
962
  };
981
963
  function executeProcess(cfg) {
982
- const { observer, cwd } = cfg;
983
- const { onStdout, onError, onComplete } = observer || {};
964
+ const { observer, cwd, command, args } = cfg;
965
+ const { onStdout, onError, onComplete } = observer ?? {};
984
966
  const date = (/* @__PURE__ */ new Date()).toISOString();
985
967
  const start = performance.now();
986
968
  return new Promise((resolve, reject) => {
987
- const process2 = spawn(cfg.command, cfg.args, { cwd, shell: true });
969
+ const process2 = spawn(command, args, { cwd, shell: true });
988
970
  let stdout = "";
989
971
  let stderr = "";
990
972
  process2.stdout.on("data", (data) => {
@@ -1118,7 +1100,7 @@ function style(text, styles = ["b"]) {
1118
1100
 
1119
1101
  // packages/utils/src/lib/reports/md/headline.ts
1120
1102
  function headline(text, hierarchy = 1) {
1121
- return `${new Array(hierarchy).fill("#").join("")} ${text}`;
1103
+ return `${"#".repeat(hierarchy)} ${text}`;
1122
1104
  }
1123
1105
  function h2(text) {
1124
1106
  return headline(text, 2);
@@ -1148,45 +1130,50 @@ function tableMd(data, align) {
1148
1130
  if (data.length === 0) {
1149
1131
  throw new Error("Data can't be empty");
1150
1132
  }
1151
- align = align || data[0]?.map(() => "c");
1152
- const _data = data.map((arr) => "|" + arr.join("|") + "|");
1153
- const secondRow = "|" + align?.map((s) => alignString.get(s)).join("|") + "|";
1154
- return _data.shift() + NEW_LINE + secondRow + NEW_LINE + _data.join(NEW_LINE);
1133
+ align ??= data[0]?.map(() => "c");
1134
+ const tableContent = data.map((arr) => `|${arr.join("|")}|`);
1135
+ const secondRow = `|${align?.map((s) => alignString.get(s)).join("|")}|`;
1136
+ return tableContent.shift() + NEW_LINE + secondRow + NEW_LINE + tableContent.join(NEW_LINE);
1155
1137
  }
1156
1138
  function tableHtml(data) {
1157
1139
  if (data.length === 0) {
1158
1140
  throw new Error("Data can't be empty");
1159
1141
  }
1160
- const _data = data.map((arr, index) => {
1142
+ const tableContent = data.map((arr, index) => {
1161
1143
  if (index === 0) {
1162
- return "<tr>" + arr.map((s) => `<th>${s}</th>`).join("") + "</tr>";
1144
+ const headerRow = arr.map((s) => `<th>${s}</th>`).join("");
1145
+ return `<tr>${headerRow}</tr>`;
1163
1146
  }
1164
- return "<tr>" + arr.map((s) => `<td>${s}</td>`).join("") + "</tr>";
1147
+ const row = arr.map((s) => `<td>${s}</td>`).join("");
1148
+ return `<tr>${row}</tr>`;
1165
1149
  });
1166
- return "<table>" + _data.join("") + "</table>";
1150
+ return `<table>${tableContent.join("")}</table>`;
1167
1151
  }
1168
1152
 
1169
1153
  // packages/utils/src/lib/reports/generate-md-report.ts
1170
1154
  function generateMdReport(report, commitData) {
1171
- let md = reportToHeaderSection() + NEW_LINE;
1172
- md += reportToOverviewSection(report) + NEW_LINE + NEW_LINE;
1173
- md += reportToCategoriesSection(report) + NEW_LINE + NEW_LINE;
1174
- md += reportToAuditsSection(report) + NEW_LINE + NEW_LINE;
1175
- md += reportToAboutSection(report, commitData) + NEW_LINE + NEW_LINE;
1176
- md += `${FOOTER_PREFIX} ${link(README_LINK, "Code PushUp")}`;
1177
- return md;
1155
+ return (
1156
+ // header section
1157
+ // eslint-disable-next-line prefer-template
1158
+ reportToHeaderSection() + NEW_LINE + // overview section
1159
+ reportToOverviewSection(report) + NEW_LINE + NEW_LINE + // categories section
1160
+ reportToCategoriesSection(report) + NEW_LINE + NEW_LINE + // audits section
1161
+ reportToAuditsSection(report) + NEW_LINE + NEW_LINE + // about section
1162
+ reportToAboutSection(report, commitData) + NEW_LINE + NEW_LINE + // footer section
1163
+ `${FOOTER_PREFIX} ${link(README_LINK, "Code PushUp")}`
1164
+ );
1178
1165
  }
1179
1166
  function reportToHeaderSection() {
1180
1167
  return headline(reportHeadlineText) + NEW_LINE;
1181
1168
  }
1182
1169
  function reportToOverviewSection(report) {
1183
- const { categories } = report;
1170
+ const { categories, plugins } = report;
1184
1171
  const tableContent = [
1185
1172
  reportOverviewTableHeaders,
1186
1173
  ...categories.map(({ title, refs, score }) => [
1187
1174
  link(`#${slugify(title)}`, title),
1188
1175
  `${getRoundScoreMarker(score)} ${style(formatReportScore(score))}`,
1189
- countCategoryAudits(refs, report.plugins).toString()
1176
+ countCategoryAudits(refs, plugins).toString()
1190
1177
  ])
1191
1178
  ];
1192
1179
  return tableMd(tableContent, ["l", "c", "c"]);
@@ -1322,7 +1309,10 @@ function reportToAboutSection(report, commitData) {
1322
1309
  formatDuration(duration2)
1323
1310
  ])
1324
1311
  ];
1325
- return h2("About") + NEW_LINE + NEW_LINE + `Report was created by [Code PushUp](${README_LINK}) on ${date}.` + NEW_LINE + NEW_LINE + tableMd(reportMetaTable, ["l", "c", "c", "c", "c", "c"]) + NEW_LINE + NEW_LINE + "The following plugins were run:" + NEW_LINE + NEW_LINE + tableMd(pluginMetaTable, ["l", "c", "c", "c"]);
1312
+ return (
1313
+ // eslint-disable-next-line prefer-template
1314
+ h2("About") + NEW_LINE + NEW_LINE + `Report was created by [Code PushUp](${README_LINK}) on ${date}.` + NEW_LINE + NEW_LINE + tableMd(reportMetaTable, ["l", "c", "c", "c", "c", "c"]) + NEW_LINE + NEW_LINE + "The following plugins were run:" + NEW_LINE + NEW_LINE + tableMd(pluginMetaTable, ["l", "c", "c", "c"])
1315
+ );
1326
1316
  }
1327
1317
  function getDocsAndDescription({
1328
1318
  docsUrl,
@@ -1356,13 +1346,7 @@ function addLine(line = "") {
1356
1346
  return line + NEW_LINE;
1357
1347
  }
1358
1348
  function generateStdoutSummary(report) {
1359
- let output = "";
1360
- output += addLine(reportToHeaderSection2(report));
1361
- output += addLine();
1362
- output += addLine(reportToDetailSection(report));
1363
- output += addLine(reportToOverviewSection2(report));
1364
- output += addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
1365
- return output;
1349
+ return addLine(reportToHeaderSection2(report)) + addLine() + addLine(reportToDetailSection(report)) + addLine(reportToOverviewSection2(report)) + addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
1366
1350
  }
1367
1351
  function reportToHeaderSection2(report) {
1368
1352
  const { packageName, version } = report;
@@ -1370,12 +1354,9 @@ function reportToHeaderSection2(report) {
1370
1354
  }
1371
1355
  function reportToDetailSection(report) {
1372
1356
  const { plugins } = report;
1373
- let output = "";
1374
- plugins.forEach(({ title, audits }) => {
1375
- output += addLine();
1376
- output += addLine(chalk3.magentaBright.bold(`${title} audits`));
1377
- output += addLine();
1378
- const ui = cliui({ width: 80 });
1357
+ return plugins.reduce((acc, plugin) => {
1358
+ const { title, audits } = plugin;
1359
+ const ui = cliui({ width: TERMINAL_WIDTH });
1379
1360
  audits.forEach(({ score, title: title2, displayValue, value }) => {
1380
1361
  ui.div(
1381
1362
  {
@@ -1385,6 +1366,7 @@ function reportToDetailSection(report) {
1385
1366
  },
1386
1367
  {
1387
1368
  text: title2,
1369
+ // eslint-disable-next-line no-magic-numbers
1388
1370
  padding: [0, 3, 0, 0]
1389
1371
  },
1390
1372
  {
@@ -1394,17 +1376,13 @@ function reportToDetailSection(report) {
1394
1376
  }
1395
1377
  );
1396
1378
  });
1397
- output += addLine(ui.toString());
1398
- output += addLine();
1399
- });
1400
- return output;
1379
+ return acc + addLine() + addLine(chalk3.magentaBright.bold(`${title} audits`)) + addLine() + addLine(ui.toString()) + addLine();
1380
+ }, "");
1401
1381
  }
1402
1382
  function reportToOverviewSection2({
1403
1383
  categories,
1404
1384
  plugins
1405
1385
  }) {
1406
- let output = addLine(chalk3.magentaBright.bold("Categories"));
1407
- output += addLine();
1408
1386
  const table = new Table({
1409
1387
  head: reportRawOverviewTableHeaders,
1410
1388
  colAligns: ["left", "right", "right"],
@@ -1419,8 +1397,7 @@ function reportToOverviewSection2({
1419
1397
  countCategoryAudits(refs, plugins)
1420
1398
  ])
1421
1399
  );
1422
- output += addLine(table.toString());
1423
- return output;
1400
+ return addLine(chalk3.magentaBright.bold("Categories")) + addLine() + addLine(table.toString());
1424
1401
  }
1425
1402
  function withColor({ score, text }) {
1426
1403
  const formattedScore = text ?? formatReportScore(score);
@@ -1451,7 +1428,7 @@ function countOccurrences(values) {
1451
1428
  );
1452
1429
  }
1453
1430
  function distinct(array) {
1454
- return Array.from(new Set(array));
1431
+ return [...new Set(array)];
1455
1432
  }
1456
1433
  function deepClone(obj) {
1457
1434
  if (obj == null || typeof obj !== "object") {
@@ -1479,11 +1456,7 @@ function objectToCliArgs(params) {
1479
1456
  }
1480
1457
  return Object.entries(params).flatMap(([key, value]) => {
1481
1458
  if (key === "_") {
1482
- if (Array.isArray(value)) {
1483
- return value;
1484
- } else {
1485
- return [value + ""];
1486
- }
1459
+ return Array.isArray(value) ? value : [`${value}`];
1487
1460
  }
1488
1461
  const prefix = key.length === 1 ? "-" : "--";
1489
1462
  if (Array.isArray(value)) {
@@ -1507,7 +1480,7 @@ function objectToCliArgs(params) {
1507
1480
  function toUnixPath(path, options) {
1508
1481
  const unixPath = path.replace(/\\/g, "/");
1509
1482
  if (options?.toRelative) {
1510
- return unixPath.replace(process.cwd().replace(/\\/g, "/") + "/", "");
1483
+ return unixPath.replace(`${process.cwd().replace(/\\/g, "/")}/`, "");
1511
1484
  }
1512
1485
  return unixPath;
1513
1486
  }
@@ -1535,28 +1508,28 @@ function scoreReport(report) {
1535
1508
  const scoredReport = deepClone(report);
1536
1509
  const allScoredAuditsAndGroups = /* @__PURE__ */ new Map();
1537
1510
  scoredReport.plugins?.forEach((plugin) => {
1538
- const { audits } = plugin;
1511
+ const { slug, audits } = plugin;
1539
1512
  const groups = plugin.groups || [];
1540
1513
  audits.forEach((audit) => {
1541
- const key = `${plugin.slug}-${audit.slug}-audit`;
1542
- audit.plugin = plugin.slug;
1514
+ const key = `${slug}-${audit.slug}-audit`;
1515
+ audit.plugin = slug;
1543
1516
  allScoredAuditsAndGroups.set(key, audit);
1544
1517
  });
1545
1518
  function groupScoreFn(ref) {
1546
1519
  const score = allScoredAuditsAndGroups.get(
1547
- `${plugin.slug}-${ref.slug}-audit`
1520
+ `${slug}-${ref.slug}-audit`
1548
1521
  )?.score;
1549
1522
  if (score == null) {
1550
1523
  throw new Error(
1551
- `Group has invalid ref - audit with slug ${plugin.slug}-${ref.slug}-audit not found`
1524
+ `Group has invalid ref - audit with slug ${slug}-${ref.slug}-audit not found`
1552
1525
  );
1553
1526
  }
1554
1527
  return score;
1555
1528
  }
1556
1529
  groups.forEach((group) => {
1557
- const key = `${plugin.slug}-${group.slug}-group`;
1530
+ const key = `${slug}-${group.slug}-group`;
1558
1531
  group.score = calculateScore(group.refs, groupScoreFn);
1559
- group.plugin = plugin.slug;
1532
+ group.plugin = slug;
1560
1533
  allScoredAuditsAndGroups.set(key, group);
1561
1534
  });
1562
1535
  plugin.groups = groups;
@@ -1576,7 +1549,7 @@ function scoreReport(report) {
1576
1549
  category.score = calculateScore(category.refs, catScoreFn);
1577
1550
  scoredCategoriesMap.set(category.slug, category);
1578
1551
  }
1579
- scoredReport.categories = Array.from(scoredCategoriesMap.values());
1552
+ scoredReport.categories = [...scoredCategoriesMap.values()];
1580
1553
  return scoredReport;
1581
1554
  }
1582
1555
 
@@ -1602,7 +1575,7 @@ function sortReport(report) {
1602
1575
  ...groups,
1603
1576
  ...audits.sort(compareCategoryAudits)
1604
1577
  ];
1605
- const sortedRefs = category.refs.slice().sort((a, b) => {
1578
+ const sortedRefs = [...category.refs].sort((a, b) => {
1606
1579
  const aIndex = sortedAuditsAndGroups.findIndex(
1607
1580
  (ref) => ref.slug === a.slug
1608
1581
  );
@@ -1615,13 +1588,15 @@ function sortReport(report) {
1615
1588
  });
1616
1589
  const sortedPlugins = plugins.map((plugin) => ({
1617
1590
  ...plugin,
1618
- audits: plugin.audits.sort(compareAudits).map((audit) => ({
1619
- ...audit,
1620
- details: {
1621
- ...audit.details,
1622
- issues: audit?.details?.issues.slice().sort(compareIssues) || []
1623
- }
1624
- }))
1591
+ audits: [...plugin.audits].sort(compareAudits).map(
1592
+ (audit) => audit.details?.issues ? {
1593
+ ...audit,
1594
+ details: {
1595
+ ...audit.details,
1596
+ issues: [...audit.details.issues].sort(compareIssues)
1597
+ }
1598
+ } : audit
1599
+ )
1625
1600
  }));
1626
1601
  return {
1627
1602
  ...report,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/utils",
3
- "version": "0.8.20",
3
+ "version": "0.8.22",
4
4
  "dependencies": {
5
5
  "@code-pushup/models": "*",
6
6
  "bundle-require": "^4.0.1",
@@ -1,3 +1,4 @@
1
+ export declare const TERMINAL_WIDTH = 80;
1
2
  export declare const NEW_LINE = "\n";
2
3
  export declare const SCORE_COLOR_RANGE: {
3
4
  GREEN_MIN: number;
@@ -6,7 +6,8 @@ export declare function distinct<T extends string | number | boolean>(array: T[]
6
6
  export declare function deepClone<T>(obj: T): T;
7
7
  export declare function factorOf<T>(items: T[], filterFn: (i: T) => boolean): number;
8
8
  type ArgumentValue = number | string | boolean | string[];
9
- export type CliArgsObject<T extends object = Record<string, ArgumentValue>> = T extends never ? Record<string, ArgumentValue | undefined> | {
9
+ export type CliArgsObject<T extends object = Record<string, ArgumentValue>> = T extends never ? // eslint-disable-next-line @typescript-eslint/naming-convention
10
+ Record<string, ArgumentValue | undefined> | {
10
11
  _: string;
11
12
  } : T;
12
13
  /**