@code-pushup/core 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.
Files changed (2) hide show
  1. package/index.js +84 -105
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -22,59 +22,48 @@ var MAX_DESCRIPTION_LENGTH = 65536;
22
22
  var MAX_ISSUE_MESSAGE_LENGTH = 1024;
23
23
 
24
24
  // packages/models/src/lib/implementation/utils.ts
25
- var slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
25
+ var slugRegex = /^[a-z\d]+(?:-[a-z\d]+)*$/;
26
26
  var filenameRegex = /^(?!.*[ \\/:*?"<>|]).+$/;
27
27
  function hasDuplicateStrings(strings) {
28
- const uniqueStrings = Array.from(new Set(strings));
29
- const duplicatedStrings = strings.filter(
30
- /* @__PURE__ */ ((i) => (v) => uniqueStrings[i] !== v || !++i)(0)
28
+ const sortedStrings = [...strings].sort();
29
+ const duplStrings = sortedStrings.filter(
30
+ (item, index) => index !== 0 && item === sortedStrings[index - 1]
31
31
  );
32
- return duplicatedStrings.length === 0 ? false : duplicatedStrings;
32
+ return duplStrings.length === 0 ? false : [...new Set(duplStrings)];
33
33
  }
34
34
  function hasMissingStrings(toCheck, existing) {
35
35
  const nonExisting = toCheck.filter((s) => !existing.includes(s));
36
36
  return nonExisting.length === 0 ? false : nonExisting;
37
37
  }
38
- function errorItems(items, transform = (items2) => items2.join(", ")) {
39
- const paredItems = items ? items : [];
40
- return transform(paredItems);
38
+ function errorItems(items, transform = (itemArr) => itemArr.join(", ")) {
39
+ return transform(items || []);
41
40
  }
42
41
  function exists(value) {
43
42
  return value != null;
44
43
  }
45
44
  function getMissingRefsForCategories(categories, plugins) {
46
- const missingRefs = [];
47
45
  const auditRefsFromCategory = categories.flatMap(
48
46
  ({ refs }) => refs.filter(({ type }) => type === "audit").map(({ plugin, slug }) => `${plugin}/${slug}`)
49
47
  );
50
48
  const auditRefsFromPlugins = plugins.flatMap(
51
- ({ audits, slug: pluginSlug }) => {
52
- return audits.map(({ slug }) => `${pluginSlug}/${slug}`);
53
- }
49
+ ({ audits, slug: pluginSlug }) => audits.map(({ slug }) => `${pluginSlug}/${slug}`)
54
50
  );
55
51
  const missingAuditRefs = hasMissingStrings(
56
52
  auditRefsFromCategory,
57
53
  auditRefsFromPlugins
58
54
  );
59
- if (Array.isArray(missingAuditRefs) && missingAuditRefs.length > 0) {
60
- missingRefs.push(...missingAuditRefs);
61
- }
62
55
  const groupRefsFromCategory = categories.flatMap(
63
56
  ({ refs }) => refs.filter(({ type }) => type === "group").map(({ plugin, slug }) => `${plugin}#${slug} (group)`)
64
57
  );
65
58
  const groupRefsFromPlugins = plugins.flatMap(
66
- ({ groups, slug: pluginSlug }) => {
67
- return Array.isArray(groups) ? groups.map(({ slug }) => `${pluginSlug}#${slug} (group)`) : [];
68
- }
59
+ ({ groups, slug: pluginSlug }) => Array.isArray(groups) ? groups.map(({ slug }) => `${pluginSlug}#${slug} (group)`) : []
69
60
  );
70
61
  const missingGroupRefs = hasMissingStrings(
71
62
  groupRefsFromCategory,
72
63
  groupRefsFromPlugins
73
64
  );
74
- if (Array.isArray(missingGroupRefs) && missingGroupRefs.length > 0) {
75
- missingRefs.push(...missingGroupRefs);
76
- }
77
- return missingRefs.length ? missingRefs : false;
65
+ const missingRefs = [missingAuditRefs, missingGroupRefs].filter((refs) => Array.isArray(refs) && refs.length > 0).flat();
66
+ return missingRefs.length > 0 ? missingRefs : false;
78
67
  }
79
68
  function missingRefsForCategoriesErrorMsg(categories, plugins) {
80
69
  const missingRefs = getMissingRefsForCategories(categories, plugins);
@@ -118,7 +107,7 @@ function metaSchema(options) {
118
107
  titleDescription,
119
108
  docsUrlDescription,
120
109
  description
121
- } = options || {};
110
+ } = options ?? {};
122
111
  return z.object(
123
112
  {
124
113
  title: titleSchema(titleDescription),
@@ -577,13 +566,14 @@ function slugify(text) {
577
566
  }
578
567
  function formatBytes(bytes, decimals = 2) {
579
568
  bytes = Math.max(bytes, 0);
580
- if (!bytes)
569
+ if (!bytes) {
581
570
  return "0 B";
571
+ }
582
572
  const k = 1024;
583
573
  const dm = decimals < 0 ? 0 : decimals;
584
574
  const sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
585
575
  const i = Math.floor(Math.log(bytes) / Math.log(k));
586
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
576
+ return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
587
577
  }
588
578
  function formatDuration(duration) {
589
579
  if (duration < 1e3) {
@@ -620,7 +610,7 @@ function logMultipleResults(results, messagePrefix, succeededCallback, failedCal
620
610
  }
621
611
  }
622
612
  function logPromiseResults(results, logMessage, callback) {
623
- if (results.length) {
613
+ if (results.length > 0) {
624
614
  if (results[0]?.status === "fulfilled") {
625
615
  console.info(logMessage);
626
616
  } else {
@@ -669,9 +659,8 @@ async function ensureDirectoryExists(baseDir) {
669
659
  function logMultipleFileResults(fileResults, messagePrefix) {
670
660
  const succeededCallback = (result) => {
671
661
  const [fileName, size] = result.value;
672
- console.info(
673
- `- ${chalk.bold(fileName)}` + (size ? ` (${chalk.gray(formatBytes(size))})` : "")
674
- );
662
+ const formattedSize = size ? ` (${chalk.gray(formatBytes(size))})` : "";
663
+ console.info(`- ${chalk.bold(fileName)}${formattedSize}`);
675
664
  };
676
665
  const failedCallback = (result) => {
677
666
  console.warn(`- ${chalk.bold(result.reason)}`);
@@ -700,6 +689,7 @@ async function importEsmModule(options) {
700
689
  }
701
690
 
702
691
  // packages/utils/src/lib/reports/constants.ts
692
+ var TERMINAL_WIDTH = 80;
703
693
  var NEW_LINE = "\n";
704
694
  var SCORE_COLOR_RANGE = {
705
695
  GREEN_MIN: 0.9,
@@ -768,28 +758,20 @@ function getSeverityIcon(severity) {
768
758
  return "\u2139\uFE0F";
769
759
  }
770
760
  function calcDuration(start, stop) {
771
- stop = stop !== void 0 ? stop : performance.now();
761
+ stop ??= performance.now();
772
762
  return Math.floor(stop - start);
773
763
  }
774
764
  function countCategoryAudits(refs, plugins) {
775
765
  const groupLookup = plugins.reduce(
776
766
  (lookup, plugin) => {
777
- if (!plugin.groups.length) {
767
+ if (plugin.groups.length === 0) {
778
768
  return lookup;
779
769
  }
780
770
  return {
781
771
  ...lookup,
782
- [plugin.slug]: {
783
- ...plugin.groups.reduce(
784
- (groupLookup2, group) => {
785
- return {
786
- ...groupLookup2,
787
- [group.slug]: group
788
- };
789
- },
790
- {}
791
- )
792
- }
772
+ [plugin.slug]: Object.fromEntries(
773
+ plugin.groups.map((group) => [group.slug, group])
774
+ )
793
775
  };
794
776
  },
795
777
  {}
@@ -797,7 +779,7 @@ function countCategoryAudits(refs, plugins) {
797
779
  return refs.reduce((acc, ref) => {
798
780
  if (ref.type === "group") {
799
781
  const groupRefs = groupLookup[ref.plugin]?.[ref.slug]?.refs;
800
- return acc + (groupRefs?.length || 0);
782
+ return acc + (groupRefs?.length ?? 0);
801
783
  }
802
784
  return acc + 1;
803
785
  }, 0);
@@ -903,7 +885,7 @@ function compareIssues(a, b) {
903
885
  return 1;
904
886
  }
905
887
  if (a.source?.file !== b.source?.file) {
906
- return a.source?.file.localeCompare(b.source?.file || "") || 0;
888
+ return a.source?.file.localeCompare(b.source?.file || "") ?? 0;
907
889
  }
908
890
  if (!a.source?.position && b.source?.position) {
909
891
  return -1;
@@ -912,7 +894,7 @@ function compareIssues(a, b) {
912
894
  return 1;
913
895
  }
914
896
  if (a.source?.position?.startLine !== b.source?.position?.startLine) {
915
- return (a.source?.position?.startLine || 0) - (b.source?.position?.startLine || 0);
897
+ return (a.source?.position?.startLine ?? 0) - (b.source?.position?.startLine ?? 0);
916
898
  }
917
899
  return 0;
918
900
  }
@@ -930,12 +912,12 @@ var ProcessError = class extends Error {
930
912
  }
931
913
  };
932
914
  function executeProcess(cfg) {
933
- const { observer, cwd } = cfg;
934
- const { onStdout, onError, onComplete } = observer || {};
915
+ const { observer, cwd, command, args } = cfg;
916
+ const { onStdout, onError, onComplete } = observer ?? {};
935
917
  const date = (/* @__PURE__ */ new Date()).toISOString();
936
918
  const start = performance.now();
937
919
  return new Promise((resolve, reject) => {
938
- const process2 = spawn(cfg.command, cfg.args, { cwd, shell: true });
920
+ const process2 = spawn(command, args, { cwd, shell: true });
939
921
  let stdout = "";
940
922
  let stderr = "";
941
923
  process2.stdout.on("data", (data) => {
@@ -1069,7 +1051,7 @@ function style(text, styles = ["b"]) {
1069
1051
 
1070
1052
  // packages/utils/src/lib/reports/md/headline.ts
1071
1053
  function headline(text, hierarchy = 1) {
1072
- return `${new Array(hierarchy).fill("#").join("")} ${text}`;
1054
+ return `${"#".repeat(hierarchy)} ${text}`;
1073
1055
  }
1074
1056
  function h2(text) {
1075
1057
  return headline(text, 2);
@@ -1099,45 +1081,50 @@ function tableMd(data, align) {
1099
1081
  if (data.length === 0) {
1100
1082
  throw new Error("Data can't be empty");
1101
1083
  }
1102
- align = align || data[0]?.map(() => "c");
1103
- const _data = data.map((arr) => "|" + arr.join("|") + "|");
1104
- const secondRow = "|" + align?.map((s) => alignString.get(s)).join("|") + "|";
1105
- return _data.shift() + NEW_LINE + secondRow + NEW_LINE + _data.join(NEW_LINE);
1084
+ align ??= data[0]?.map(() => "c");
1085
+ const tableContent = data.map((arr) => `|${arr.join("|")}|`);
1086
+ const secondRow = `|${align?.map((s) => alignString.get(s)).join("|")}|`;
1087
+ return tableContent.shift() + NEW_LINE + secondRow + NEW_LINE + tableContent.join(NEW_LINE);
1106
1088
  }
1107
1089
  function tableHtml(data) {
1108
1090
  if (data.length === 0) {
1109
1091
  throw new Error("Data can't be empty");
1110
1092
  }
1111
- const _data = data.map((arr, index) => {
1093
+ const tableContent = data.map((arr, index) => {
1112
1094
  if (index === 0) {
1113
- return "<tr>" + arr.map((s) => `<th>${s}</th>`).join("") + "</tr>";
1095
+ const headerRow = arr.map((s) => `<th>${s}</th>`).join("");
1096
+ return `<tr>${headerRow}</tr>`;
1114
1097
  }
1115
- return "<tr>" + arr.map((s) => `<td>${s}</td>`).join("") + "</tr>";
1098
+ const row = arr.map((s) => `<td>${s}</td>`).join("");
1099
+ return `<tr>${row}</tr>`;
1116
1100
  });
1117
- return "<table>" + _data.join("") + "</table>";
1101
+ return `<table>${tableContent.join("")}</table>`;
1118
1102
  }
1119
1103
 
1120
1104
  // packages/utils/src/lib/reports/generate-md-report.ts
1121
1105
  function generateMdReport(report, commitData) {
1122
- let md = reportToHeaderSection() + NEW_LINE;
1123
- md += reportToOverviewSection(report) + NEW_LINE + NEW_LINE;
1124
- md += reportToCategoriesSection(report) + NEW_LINE + NEW_LINE;
1125
- md += reportToAuditsSection(report) + NEW_LINE + NEW_LINE;
1126
- md += reportToAboutSection(report, commitData) + NEW_LINE + NEW_LINE;
1127
- md += `${FOOTER_PREFIX} ${link(README_LINK, "Code PushUp")}`;
1128
- return md;
1106
+ return (
1107
+ // header section
1108
+ // eslint-disable-next-line prefer-template
1109
+ reportToHeaderSection() + NEW_LINE + // overview section
1110
+ reportToOverviewSection(report) + NEW_LINE + NEW_LINE + // categories section
1111
+ reportToCategoriesSection(report) + NEW_LINE + NEW_LINE + // audits section
1112
+ reportToAuditsSection(report) + NEW_LINE + NEW_LINE + // about section
1113
+ reportToAboutSection(report, commitData) + NEW_LINE + NEW_LINE + // footer section
1114
+ `${FOOTER_PREFIX} ${link(README_LINK, "Code PushUp")}`
1115
+ );
1129
1116
  }
1130
1117
  function reportToHeaderSection() {
1131
1118
  return headline(reportHeadlineText) + NEW_LINE;
1132
1119
  }
1133
1120
  function reportToOverviewSection(report) {
1134
- const { categories } = report;
1121
+ const { categories, plugins } = report;
1135
1122
  const tableContent = [
1136
1123
  reportOverviewTableHeaders,
1137
1124
  ...categories.map(({ title, refs, score }) => [
1138
1125
  link(`#${slugify(title)}`, title),
1139
1126
  `${getRoundScoreMarker(score)} ${style(formatReportScore(score))}`,
1140
- countCategoryAudits(refs, report.plugins).toString()
1127
+ countCategoryAudits(refs, plugins).toString()
1141
1128
  ])
1142
1129
  ];
1143
1130
  return tableMd(tableContent, ["l", "c", "c"]);
@@ -1273,7 +1260,10 @@ function reportToAboutSection(report, commitData) {
1273
1260
  formatDuration(duration2)
1274
1261
  ])
1275
1262
  ];
1276
- 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"]);
1263
+ return (
1264
+ // eslint-disable-next-line prefer-template
1265
+ 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"])
1266
+ );
1277
1267
  }
1278
1268
  function getDocsAndDescription({
1279
1269
  docsUrl,
@@ -1307,13 +1297,7 @@ function addLine(line = "") {
1307
1297
  return line + NEW_LINE;
1308
1298
  }
1309
1299
  function generateStdoutSummary(report) {
1310
- let output = "";
1311
- output += addLine(reportToHeaderSection2(report));
1312
- output += addLine();
1313
- output += addLine(reportToDetailSection(report));
1314
- output += addLine(reportToOverviewSection2(report));
1315
- output += addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
1316
- return output;
1300
+ return addLine(reportToHeaderSection2(report)) + addLine() + addLine(reportToDetailSection(report)) + addLine(reportToOverviewSection2(report)) + addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
1317
1301
  }
1318
1302
  function reportToHeaderSection2(report) {
1319
1303
  const { packageName, version: version2 } = report;
@@ -1321,12 +1305,9 @@ function reportToHeaderSection2(report) {
1321
1305
  }
1322
1306
  function reportToDetailSection(report) {
1323
1307
  const { plugins } = report;
1324
- let output = "";
1325
- plugins.forEach(({ title, audits }) => {
1326
- output += addLine();
1327
- output += addLine(chalk3.magentaBright.bold(`${title} audits`));
1328
- output += addLine();
1329
- const ui = cliui({ width: 80 });
1308
+ return plugins.reduce((acc, plugin) => {
1309
+ const { title, audits } = plugin;
1310
+ const ui = cliui({ width: TERMINAL_WIDTH });
1330
1311
  audits.forEach(({ score, title: title2, displayValue, value }) => {
1331
1312
  ui.div(
1332
1313
  {
@@ -1336,6 +1317,7 @@ function reportToDetailSection(report) {
1336
1317
  },
1337
1318
  {
1338
1319
  text: title2,
1320
+ // eslint-disable-next-line no-magic-numbers
1339
1321
  padding: [0, 3, 0, 0]
1340
1322
  },
1341
1323
  {
@@ -1345,17 +1327,13 @@ function reportToDetailSection(report) {
1345
1327
  }
1346
1328
  );
1347
1329
  });
1348
- output += addLine(ui.toString());
1349
- output += addLine();
1350
- });
1351
- return output;
1330
+ return acc + addLine() + addLine(chalk3.magentaBright.bold(`${title} audits`)) + addLine() + addLine(ui.toString()) + addLine();
1331
+ }, "");
1352
1332
  }
1353
1333
  function reportToOverviewSection2({
1354
1334
  categories,
1355
1335
  plugins
1356
1336
  }) {
1357
- let output = addLine(chalk3.magentaBright.bold("Categories"));
1358
- output += addLine();
1359
1337
  const table = new Table({
1360
1338
  head: reportRawOverviewTableHeaders,
1361
1339
  colAligns: ["left", "right", "right"],
@@ -1370,8 +1348,7 @@ function reportToOverviewSection2({
1370
1348
  countCategoryAudits(refs, plugins)
1371
1349
  ])
1372
1350
  );
1373
- output += addLine(table.toString());
1374
- return output;
1351
+ return addLine(chalk3.magentaBright.bold("Categories")) + addLine() + addLine(table.toString());
1375
1352
  }
1376
1353
  function withColor({ score, text }) {
1377
1354
  const formattedScore = text ?? formatReportScore(score);
@@ -1425,28 +1402,28 @@ function scoreReport(report) {
1425
1402
  const scoredReport = deepClone(report);
1426
1403
  const allScoredAuditsAndGroups = /* @__PURE__ */ new Map();
1427
1404
  scoredReport.plugins?.forEach((plugin) => {
1428
- const { audits } = plugin;
1405
+ const { slug, audits } = plugin;
1429
1406
  const groups = plugin.groups || [];
1430
1407
  audits.forEach((audit) => {
1431
- const key = `${plugin.slug}-${audit.slug}-audit`;
1432
- audit.plugin = plugin.slug;
1408
+ const key = `${slug}-${audit.slug}-audit`;
1409
+ audit.plugin = slug;
1433
1410
  allScoredAuditsAndGroups.set(key, audit);
1434
1411
  });
1435
1412
  function groupScoreFn(ref) {
1436
1413
  const score = allScoredAuditsAndGroups.get(
1437
- `${plugin.slug}-${ref.slug}-audit`
1414
+ `${slug}-${ref.slug}-audit`
1438
1415
  )?.score;
1439
1416
  if (score == null) {
1440
1417
  throw new Error(
1441
- `Group has invalid ref - audit with slug ${plugin.slug}-${ref.slug}-audit not found`
1418
+ `Group has invalid ref - audit with slug ${slug}-${ref.slug}-audit not found`
1442
1419
  );
1443
1420
  }
1444
1421
  return score;
1445
1422
  }
1446
1423
  groups.forEach((group) => {
1447
- const key = `${plugin.slug}-${group.slug}-group`;
1424
+ const key = `${slug}-${group.slug}-group`;
1448
1425
  group.score = calculateScore(group.refs, groupScoreFn);
1449
- group.plugin = plugin.slug;
1426
+ group.plugin = slug;
1450
1427
  allScoredAuditsAndGroups.set(key, group);
1451
1428
  });
1452
1429
  plugin.groups = groups;
@@ -1466,7 +1443,7 @@ function scoreReport(report) {
1466
1443
  category.score = calculateScore(category.refs, catScoreFn);
1467
1444
  scoredCategoriesMap.set(category.slug, category);
1468
1445
  }
1469
- scoredReport.categories = Array.from(scoredCategoriesMap.values());
1446
+ scoredReport.categories = [...scoredCategoriesMap.values()];
1470
1447
  return scoredReport;
1471
1448
  }
1472
1449
 
@@ -1492,7 +1469,7 @@ function sortReport(report) {
1492
1469
  ...groups,
1493
1470
  ...audits.sort(compareCategoryAudits)
1494
1471
  ];
1495
- const sortedRefs = category.refs.slice().sort((a, b) => {
1472
+ const sortedRefs = [...category.refs].sort((a, b) => {
1496
1473
  const aIndex = sortedAuditsAndGroups.findIndex(
1497
1474
  (ref) => ref.slug === a.slug
1498
1475
  );
@@ -1505,13 +1482,15 @@ function sortReport(report) {
1505
1482
  });
1506
1483
  const sortedPlugins = plugins.map((plugin) => ({
1507
1484
  ...plugin,
1508
- audits: plugin.audits.sort(compareAudits).map((audit) => ({
1509
- ...audit,
1510
- details: {
1511
- ...audit.details,
1512
- issues: audit?.details?.issues.slice().sort(compareIssues) || []
1513
- }
1514
- }))
1485
+ audits: [...plugin.audits].sort(compareAudits).map(
1486
+ (audit) => audit.details?.issues ? {
1487
+ ...audit,
1488
+ details: {
1489
+ ...audit.details,
1490
+ issues: [...audit.details.issues].sort(compareIssues)
1491
+ }
1492
+ } : audit
1493
+ )
1515
1494
  }));
1516
1495
  return {
1517
1496
  ...report,
@@ -1717,7 +1696,7 @@ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits)
1717
1696
 
1718
1697
  // packages/core/package.json
1719
1698
  var name = "@code-pushup/core";
1720
- var version = "0.8.20";
1699
+ var version = "0.8.22";
1721
1700
 
1722
1701
  // packages/core/src/lib/implementation/collect.ts
1723
1702
  async function collect(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/core",
3
- "version": "0.8.20",
3
+ "version": "0.8.22",
4
4
  "dependencies": {
5
5
  "@code-pushup/models": "*",
6
6
  "@code-pushup/utils": "*",