@code-pushup/lighthouse-plugin 0.47.0 → 0.49.0

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
@@ -1,6 +1,6 @@
1
1
  // packages/plugin-lighthouse/package.json
2
2
  var name = "@code-pushup/lighthouse-plugin";
3
- var version = "0.47.0";
3
+ var version = "0.49.0";
4
4
 
5
5
  // packages/plugin-lighthouse/src/lib/constants.ts
6
6
  import { join } from "node:path";
@@ -711,11 +711,18 @@ var LIGHTHOUSE_OUTPUT_PATH = join(
711
711
  );
712
712
 
713
713
  // packages/plugin-lighthouse/src/lib/normalize-flags.ts
714
- import chalk8 from "chalk";
714
+ import { bold as bold9, yellow as yellow2 } from "ansis";
715
+
716
+ // packages/utils/src/lib/reports/utils.ts
717
+ import ansis from "ansis";
718
+ import { md } from "build-md";
719
+
720
+ // packages/utils/src/lib/reports/constants.ts
721
+ var TERMINAL_WIDTH = 80;
715
722
 
716
723
  // packages/utils/src/lib/file-system.ts
724
+ import { bold, gray } from "ansis";
717
725
  import { bundleRequire } from "bundle-require";
718
- import chalk2 from "chalk";
719
726
  import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
720
727
 
721
728
  // packages/utils/src/lib/formatting.ts
@@ -760,12 +767,7 @@ function truncateText(text, options) {
760
767
  // packages/utils/src/lib/logging.ts
761
768
  import isaacs_cliui from "@isaacs/cliui";
762
769
  import { cliui } from "@poppinss/cliui";
763
- import chalk from "chalk";
764
-
765
- // packages/utils/src/lib/reports/constants.ts
766
- var TERMINAL_WIDTH = 80;
767
-
768
- // packages/utils/src/lib/logging.ts
770
+ import { underline } from "ansis";
769
771
  var singletonUiInstance;
770
772
  function ui() {
771
773
  if (singletonUiInstance === void 0) {
@@ -817,9 +819,42 @@ async function importModule(options) {
817
819
  return mod;
818
820
  }
819
821
 
822
+ // packages/utils/src/lib/filter.ts
823
+ function filterItemRefsBy(items, refFilterFn) {
824
+ return items.map((item) => ({
825
+ ...item,
826
+ refs: item.refs.filter(refFilterFn)
827
+ })).filter((item) => item.refs.length);
828
+ }
829
+
830
+ // packages/utils/src/lib/git/git.ts
831
+ import { simpleGit } from "simple-git";
832
+
833
+ // packages/utils/src/lib/transform.ts
834
+ function toArray(val) {
835
+ return Array.isArray(val) ? val : [val];
836
+ }
837
+ function capitalize(text) {
838
+ return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
839
+ 1
840
+ )}`;
841
+ }
842
+
843
+ // packages/utils/src/lib/git/git.commits-and-tags.ts
844
+ import { simpleGit as simpleGit2 } from "simple-git";
845
+
846
+ // packages/utils/src/lib/semver.ts
847
+ import { rcompare, valid } from "semver";
848
+
849
+ // packages/utils/src/lib/progress.ts
850
+ import { black, bold as bold2, gray as gray2, green } from "ansis";
851
+ import { MultiProgressBars } from "multi-progress-bars";
852
+
853
+ // packages/utils/src/lib/reports/generate-md-report.ts
854
+ import { MarkdownDocument as MarkdownDocument3, md as md4 } from "build-md";
855
+
820
856
  // packages/utils/src/lib/text-formats/constants.ts
821
857
  var NEW_LINE = "\n";
822
- var TAB = " ";
823
858
 
824
859
  // packages/utils/src/lib/text-formats/html/details.ts
825
860
  function details(title, content, cfg = { open: false }) {
@@ -832,7 +867,7 @@ function details(title, content, cfg = { open: false }) {
832
867
 
833
868
  // packages/utils/src/lib/text-formats/html/font-style.ts
834
869
  var boldElement = "b";
835
- function bold(text) {
870
+ function bold3(text) {
836
871
  return `<${boldElement}>${text}</${boldElement}>`;
837
872
  }
838
873
  var italicElement = "i";
@@ -849,16 +884,6 @@ function link(href, text) {
849
884
  return `<a href="${href}">${text || href}</a>`;
850
885
  }
851
886
 
852
- // packages/utils/src/lib/transform.ts
853
- function toArray(val) {
854
- return Array.isArray(val) ? val : [val];
855
- }
856
- function capitalize(text) {
857
- return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
858
- 1
859
- )}`;
860
- }
861
-
862
887
  // packages/utils/src/lib/text-formats/table.ts
863
888
  function rowToStringArray({ rows, columns = [] }) {
864
889
  if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
@@ -902,51 +927,6 @@ function columnsToStringArray({
902
927
  const cols = columns;
903
928
  return cols.map(({ label, key }) => label ?? capitalize(key));
904
929
  }
905
- function getColumnAlignmentForKeyAndIndex(targetKey, targetIdx, columns = []) {
906
- const column = columns.at(targetIdx) ?? columns.find((col) => col.key === targetKey);
907
- if (typeof column === "string") {
908
- return column;
909
- } else if (typeof column === "object") {
910
- return column.align ?? "center";
911
- } else {
912
- return "center";
913
- }
914
- }
915
- function getColumnAlignmentForIndex(targetIdx, columns = []) {
916
- const column = columns.at(targetIdx);
917
- if (column == null) {
918
- return "center";
919
- } else if (typeof column === "string") {
920
- return column;
921
- } else if (typeof column === "object") {
922
- return column.align ?? "center";
923
- } else {
924
- return "center";
925
- }
926
- }
927
- function getColumnAlignments(tableData) {
928
- const { rows, columns = [] } = tableData;
929
- if (rows.at(0) == null) {
930
- throw new Error("first row can`t be undefined.");
931
- }
932
- if (Array.isArray(rows.at(0))) {
933
- const firstPrimitiveRow = rows.at(0);
934
- return Array.from({ length: firstPrimitiveRow.length }).map(
935
- (_, idx) => getColumnAlignmentForIndex(idx, columns)
936
- );
937
- }
938
- const biggestRow = [...rows].sort((a, b) => Object.keys(a).length - Object.keys(b).length).at(-1);
939
- if (columns.length > 0) {
940
- return columns.map(
941
- (column, idx) => typeof column === "string" ? column : getColumnAlignmentForKeyAndIndex(
942
- column.key,
943
- idx,
944
- columns
945
- )
946
- );
947
- }
948
- return Object.keys(biggestRow ?? {}).map((_) => "center");
949
- }
950
930
 
951
931
  // packages/utils/src/lib/text-formats/html/table.ts
952
932
  function wrap(elem, content) {
@@ -969,135 +949,9 @@ function table(tableData) {
969
949
  return wrap("table", `${NEW_LINE}${tableHeaderRow}${tableBody}`);
970
950
  }
971
951
 
972
- // packages/utils/src/lib/text-formats/md/font-style.ts
973
- var boldWrap = "**";
974
- function bold2(text) {
975
- return `${boldWrap}${text}${boldWrap}`;
976
- }
977
- var italicWrap = "_";
978
- function italic2(text) {
979
- return `${italicWrap}${text}${italicWrap}`;
980
- }
981
- var strikeThroughWrap = "~";
982
- function strikeThrough(text) {
983
- return `${strikeThroughWrap}${text}${strikeThroughWrap}`;
984
- }
985
- var codeWrap = "`";
986
- function code2(text) {
987
- return `${codeWrap}${text}${codeWrap}`;
988
- }
989
-
990
- // packages/utils/src/lib/text-formats/md/headline.ts
991
- function headline(text, hierarchy = 1) {
992
- return `${"#".repeat(hierarchy)} ${text}${NEW_LINE}`;
993
- }
994
- function h(text, hierarchy = 1) {
995
- return headline(text, hierarchy);
996
- }
997
- function h1(text) {
998
- return headline(text, 1);
999
- }
1000
- function h2(text) {
1001
- return headline(text, 2);
1002
- }
1003
- function h3(text) {
1004
- return headline(text, 3);
1005
- }
1006
- function h4(text) {
1007
- return headline(text, 4);
1008
- }
1009
- function h5(text) {
1010
- return headline(text, 5);
1011
- }
1012
- function h6(text) {
1013
- return headline(text, 6);
1014
- }
1015
-
1016
- // packages/utils/src/lib/text-formats/md/image.ts
1017
- function image(src, alt) {
1018
- return `![${alt}](${src})`;
1019
- }
1020
-
1021
- // packages/utils/src/lib/text-formats/md/link.ts
1022
- function link2(href, text) {
1023
- return `[${text || href}](${href})`;
1024
- }
1025
-
1026
- // packages/utils/src/lib/text-formats/md/list.ts
1027
- function li(text, order = "unordered") {
1028
- const style = order === "unordered" ? "-" : "- [ ]";
1029
- return `${style} ${text}`;
1030
- }
1031
- function indentation(text, level = 1) {
1032
- return `${TAB.repeat(level)}${text}`;
1033
- }
1034
-
1035
- // packages/utils/src/lib/text-formats/md/paragraphs.ts
1036
- function paragraphs(...sections) {
1037
- return sections.filter(Boolean).join(`${NEW_LINE}${NEW_LINE}`);
1038
- }
1039
-
1040
- // packages/utils/src/lib/text-formats/md/section.ts
1041
- function section(...contents) {
1042
- return `${lines(...contents)}${NEW_LINE}`;
1043
- }
1044
- function lines(...contents) {
1045
- const filteredContent = contents.filter(
1046
- (value) => value != null && value !== "" && value !== false
1047
- );
1048
- return `${filteredContent.join(NEW_LINE)}`;
1049
- }
1050
-
1051
- // packages/utils/src/lib/text-formats/md/table.ts
1052
- var alignString = /* @__PURE__ */ new Map([
1053
- ["left", ":--"],
1054
- ["center", ":--:"],
1055
- ["right", "--:"]
1056
- ]);
1057
- function tableRow(rows) {
1058
- return `|${rows.join("|")}|`;
1059
- }
1060
- function table2(data) {
1061
- if (data.rows.length === 0) {
1062
- throw new Error("Data can't be empty");
1063
- }
1064
- const alignmentRow = getColumnAlignments(data).map(
1065
- (s) => alignString.get(s) ?? String(alignString.get("center"))
1066
- );
1067
- return section(
1068
- `${lines(
1069
- tableRow(columnsToStringArray(data)),
1070
- tableRow(alignmentRow),
1071
- ...rowToStringArray(data).map(tableRow)
1072
- )}`
1073
- );
1074
- }
1075
-
1076
952
  // packages/utils/src/lib/text-formats/index.ts
1077
- var md = {
1078
- bold: bold2,
1079
- italic: italic2,
1080
- strikeThrough,
1081
- code: code2,
1082
- link: link2,
1083
- image,
1084
- headline,
1085
- h,
1086
- h1,
1087
- h2,
1088
- h3,
1089
- h4,
1090
- h5,
1091
- h6,
1092
- indentation,
1093
- lines,
1094
- li,
1095
- section,
1096
- paragraphs,
1097
- table: table2
1098
- };
1099
953
  var html = {
1100
- bold,
954
+ bold: bold3,
1101
955
  italic,
1102
956
  code,
1103
957
  link,
@@ -1105,55 +959,20 @@ var html = {
1105
959
  table
1106
960
  };
1107
961
 
1108
- // packages/utils/src/lib/reports/utils.ts
1109
- var { image: image2, bold: boldMd } = md;
1110
-
1111
- // packages/utils/src/lib/filter.ts
1112
- function filterItemRefsBy(items, refFilterFn) {
1113
- return items.map((item) => ({
1114
- ...item,
1115
- refs: item.refs.filter(refFilterFn)
1116
- })).filter((item) => item.refs.length);
1117
- }
1118
-
1119
- // packages/utils/src/lib/git/git.ts
1120
- import { simpleGit } from "simple-git";
1121
-
1122
- // packages/utils/src/lib/git/git.commits-and-tags.ts
1123
- import { simpleGit as simpleGit2 } from "simple-git";
1124
-
1125
- // packages/utils/src/lib/semver.ts
1126
- import { rcompare, valid } from "semver";
1127
-
1128
- // packages/utils/src/lib/progress.ts
1129
- import chalk3 from "chalk";
1130
- import { MultiProgressBars } from "multi-progress-bars";
1131
-
1132
962
  // packages/utils/src/lib/reports/formatting.ts
1133
- var { headline: headline2, lines: lines2, link: link3, section: section2, table: table3 } = md;
963
+ import { MarkdownDocument, md as md2 } from "build-md";
1134
964
 
1135
965
  // packages/utils/src/lib/reports/generate-md-report-categoy-section.ts
1136
- var { link: link4, section: section3, h2: h22, lines: lines3, li: li2, bold: boldMd2, h3: h32, indentation: indentation2 } = md;
1137
-
1138
- // packages/utils/src/lib/reports/generate-md-report.ts
1139
- var { h1: h12, h2: h23, h3: h33, lines: lines4, link: link5, section: section4, code: codeMd } = md;
1140
- var { bold: boldHtml, details: details2 } = html;
966
+ import { MarkdownDocument as MarkdownDocument2, md as md3 } from "build-md";
1141
967
 
1142
968
  // packages/utils/src/lib/reports/generate-md-reports-diff.ts
1143
- var {
1144
- h1: h13,
1145
- h2: h24,
1146
- lines: lines5,
1147
- link: link6,
1148
- bold: boldMd3,
1149
- italic: italicMd,
1150
- table: table4,
1151
- section: section5
1152
- } = md;
1153
- var { details: details3 } = html;
969
+ import {
970
+ MarkdownDocument as MarkdownDocument4,
971
+ md as md5
972
+ } from "build-md";
1154
973
 
1155
974
  // packages/utils/src/lib/reports/log-stdout-summary.ts
1156
- import chalk4 from "chalk";
975
+ import { bold as bold4, cyan, cyanBright, green as green2, red } from "ansis";
1157
976
 
1158
977
  // packages/plugin-lighthouse/src/lib/runner/runner.ts
1159
978
  import { runLighthouse } from "lighthouse/cli/run.js";
@@ -1232,17 +1051,17 @@ var DEFAULT_CLI_FLAGS = {
1232
1051
  };
1233
1052
 
1234
1053
  // packages/plugin-lighthouse/src/lib/runner/utils.ts
1235
- import chalk7 from "chalk";
1054
+ import { bold as bold8 } from "ansis";
1236
1055
  import log from "lighthouse-logger";
1237
1056
  import desktopConfig from "lighthouse/core/config/desktop-config.js";
1238
1057
  import experimentalConfig from "lighthouse/core/config/experimental-config.js";
1239
1058
  import perfConfig from "lighthouse/core/config/perf-config.js";
1240
1059
 
1241
1060
  // packages/plugin-lighthouse/src/lib/runner/details/details.ts
1242
- import chalk6 from "chalk";
1061
+ import { bold as bold7, yellow } from "ansis";
1243
1062
 
1244
1063
  // packages/plugin-lighthouse/src/lib/runner/details/item-value.ts
1245
- import chalk5 from "chalk";
1064
+ import { bold as bold5 } from "ansis";
1246
1065
  function trimSlice(item, maxLength = 0) {
1247
1066
  const str = String(item).trim();
1248
1067
  return maxLength > 0 ? str.slice(0, maxLength) : str;
@@ -1273,8 +1092,8 @@ function formatTableItemPropertyValue(itemValue, itemValueFormat) {
1273
1092
  case "code":
1274
1093
  return html.code(trimSlice(parsedItemValue));
1275
1094
  case "link":
1276
- const link8 = parsedItemValue;
1277
- return html.link(link8.url, link8.text);
1095
+ const link3 = parsedItemValue;
1096
+ return html.link(link3.url, link3.text);
1278
1097
  case "url":
1279
1098
  const url = parsedItemValue;
1280
1099
  return html.link(url);
@@ -1294,18 +1113,13 @@ function formatTableItemPropertyValue(itemValue, itemValueFormat) {
1294
1113
  case "text":
1295
1114
  return truncateText(String(parsedItemValue), 500);
1296
1115
  case "multi":
1297
- ui().logger.info(`Format type ${chalk5.bold("multi")} is not implemented`);
1116
+ ui().logger.info(`Format type ${bold5("multi")} is not implemented`);
1298
1117
  return "";
1299
1118
  case "thumbnail":
1300
- ui().logger.info(
1301
- `Format type ${chalk5.bold("thumbnail")} is not implemented`
1302
- );
1303
- return "";
1304
- case null:
1119
+ ui().logger.info(`Format type ${bold5("thumbnail")} is not implemented`);
1305
1120
  return "";
1306
- default:
1307
- return itemValue;
1308
1121
  }
1122
+ return itemValue;
1309
1123
  }
1310
1124
  function parseSimpleItemValue(item) {
1311
1125
  if (typeof item === "object") {
@@ -1340,35 +1154,56 @@ function parseTableItemPropertyValue(itemValue) {
1340
1154
  const { url } = objectValue;
1341
1155
  return String(url);
1342
1156
  case "subitems":
1343
- ui().logger.info(
1344
- `Value type ${chalk5.bold("subitems")} is not implemented`
1345
- );
1157
+ ui().logger.info(`Value type ${bold5("subitems")} is not implemented`);
1346
1158
  return "";
1347
1159
  case "debugdata":
1348
- ui().logger.info(
1349
- `Value type ${chalk5.bold("debugdata")} is not implemented`,
1350
- { silent: true }
1351
- );
1160
+ ui().logger.info(`Value type ${bold5("debugdata")} is not implemented`, {
1161
+ silent: true
1162
+ });
1352
1163
  return "";
1353
1164
  }
1354
1165
  return parseSimpleItemValue(objectValue);
1355
1166
  }
1356
1167
 
1168
+ // packages/plugin-lighthouse/src/lib/runner/details/utils.ts
1169
+ import { bold as bold6 } from "ansis";
1170
+ var LighthouseAuditDetailsParsingError = class extends Error {
1171
+ constructor(type, rawTable, error) {
1172
+ super(
1173
+ `Parsing lighthouse report details ${bold6(
1174
+ type
1175
+ )} failed:
1176
+ Raw data:
1177
+ ${JSON.stringify(rawTable, null, 2)}
1178
+ ${error}`
1179
+ );
1180
+ }
1181
+ };
1182
+
1357
1183
  // packages/plugin-lighthouse/src/lib/runner/details/table.type.ts
1358
- function parseTableToAuditDetailsTable(details4) {
1359
- const { headings: rawHeadings, items } = details4;
1184
+ function parseTableToAuditDetailsTable(details2) {
1185
+ const { headings: rawHeadings, items } = details2;
1360
1186
  if (items.length === 0) {
1361
1187
  return void 0;
1362
1188
  }
1363
- return {
1364
- columns: parseTableColumns(rawHeadings),
1365
- rows: items.map((row) => parseTableRow(row, rawHeadings))
1366
- };
1189
+ try {
1190
+ return tableSchema().parse({
1191
+ title: "Table",
1192
+ columns: parseTableColumns(rawHeadings),
1193
+ rows: items.map((row) => parseTableRow(row, rawHeadings))
1194
+ });
1195
+ } catch (error) {
1196
+ throw new LighthouseAuditDetailsParsingError(
1197
+ "table",
1198
+ { items, headings: rawHeadings },
1199
+ error.message.toString()
1200
+ );
1201
+ }
1367
1202
  }
1368
1203
  function parseTableColumns(rawHeadings) {
1369
1204
  return rawHeadings.map(({ key, label }) => ({
1370
1205
  key: key ?? "",
1371
- label: typeof label === "string" ? label : void 0,
1206
+ ...typeof label === "string" && label.length > 0 ? { label } : {},
1372
1207
  align: "left"
1373
1208
  }));
1374
1209
  }
@@ -1391,40 +1226,73 @@ function parseTableEntry([key, value], valueType) {
1391
1226
  return [key, formatTableItemPropertyValue(value, valueType)];
1392
1227
  }
1393
1228
 
1394
- // packages/plugin-lighthouse/src/lib/runner/details/details.ts
1395
- function toAuditDetails(details4) {
1396
- if (details4 == null) {
1397
- return void 0;
1398
- }
1399
- const { type } = details4;
1400
- if (type !== "table") {
1229
+ // packages/plugin-lighthouse/src/lib/runner/details/opportunity.type.ts
1230
+ function parseOpportunityToAuditDetailsTable(details2) {
1231
+ const { headings: rawHeadings, items } = details2;
1232
+ if (items.length === 0) {
1401
1233
  return void 0;
1402
1234
  }
1403
- const rawTable = parseTableToAuditDetailsTable(details4);
1404
- if (rawTable != null) {
1405
- const result = tableSchema().safeParse(rawTable);
1406
- if (result.success) {
1407
- return {
1408
- table: result.data
1409
- };
1410
- }
1411
- throw new Error(
1412
- `Parsing details ${chalk6.bold(
1413
- type
1414
- )} failed:
1415
- Raw data:
1416
- ${JSON.stringify(
1417
- rawTable,
1418
- null,
1419
- 2
1420
- )}
1421
- ${result.error.toString()}`
1235
+ try {
1236
+ return tableSchema().parse({
1237
+ title: "Opportunity",
1238
+ columns: parseTableColumns(rawHeadings),
1239
+ rows: items.map((row) => parseOpportunityItemToTableRow(row, rawHeadings))
1240
+ });
1241
+ } catch (error) {
1242
+ throw new LighthouseAuditDetailsParsingError(
1243
+ "opportunity",
1244
+ { items, headings: rawHeadings },
1245
+ error.message.toString()
1422
1246
  );
1423
1247
  }
1424
- return void 0;
1248
+ }
1249
+ function parseOpportunityItemToTableRow(opportunityItem, headings) {
1250
+ const keys = new Set(headings.map(({ key }) => key));
1251
+ const valueTypesByKey = new Map(
1252
+ headings.map(({ key, valueType }) => [key, valueType])
1253
+ );
1254
+ return {
1255
+ ...Object.fromEntries(
1256
+ Object.entries(opportunityItem).filter(([key]) => keys.has(key)).map(([key, value]) => {
1257
+ const valueType = valueTypesByKey.get(key);
1258
+ return parseOpportunityEntry([key, value], valueType);
1259
+ })
1260
+ )
1261
+ };
1262
+ }
1263
+ function parseOpportunityEntry([key, value], valueType) {
1264
+ switch (key) {
1265
+ case "url":
1266
+ return [key, html.link(String(value))];
1267
+ case "wastedPercent":
1268
+ return [key, `${Number(value).toFixed(2)} %`];
1269
+ case "totalBytes":
1270
+ case "wastedBytes":
1271
+ return [key, formatBytes(Number(value))];
1272
+ case "wastedMs":
1273
+ return [key, formatDuration(Number(value))];
1274
+ default:
1275
+ return parseTableEntry([key, value], valueType);
1276
+ }
1277
+ }
1278
+
1279
+ // packages/plugin-lighthouse/src/lib/runner/details/details.ts
1280
+ function toAuditDetails(details2) {
1281
+ if (details2 == null) {
1282
+ return {};
1283
+ }
1284
+ const { type } = details2;
1285
+ switch (type) {
1286
+ case "table":
1287
+ const table2 = parseTableToAuditDetailsTable(details2);
1288
+ return table2 ? { table: table2 } : {};
1289
+ case "opportunity":
1290
+ const opportunity = parseOpportunityToAuditDetailsTable(details2);
1291
+ return opportunity ? { table: opportunity } : {};
1292
+ }
1293
+ return {};
1425
1294
  }
1426
1295
  var unsupportedDetailTypes = /* @__PURE__ */ new Set([
1427
- "opportunity",
1428
1296
  "debugdata",
1429
1297
  "treemap-data",
1430
1298
  "screenshot",
@@ -1435,16 +1303,16 @@ function logUnsupportedDetails(lhrAudits, { displayCount = 3 } = {}) {
1435
1303
  const slugsWithDetailParsingErrors = [
1436
1304
  ...new Set(
1437
1305
  lhrAudits.filter(
1438
- ({ details: details4 }) => unsupportedDetailTypes.has(details4?.type)
1439
- ).map(({ details: details4 }) => details4?.type)
1306
+ ({ details: details2 }) => unsupportedDetailTypes.has(details2?.type)
1307
+ ).map(({ details: details2 }) => details2?.type)
1440
1308
  )
1441
1309
  ];
1442
1310
  if (slugsWithDetailParsingErrors.length > 0) {
1443
1311
  const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1444
1312
  ui().logger.debug(
1445
- `${chalk6.yellow("\u26A0")} Plugin ${chalk6.bold(
1313
+ `${yellow("\u26A0")} Plugin ${bold7(
1446
1314
  PLUGIN_SLUG
1447
- )} skipped parsing of unsupported audit details: ${chalk6.bold(
1315
+ )} skipped parsing of unsupported audit details: ${bold7(
1448
1316
  slugsWithDetailParsingErrors.slice(0, displayCount).join(", ")
1449
1317
  )}${postFix(slugsWithDetailParsingErrors.length)}`
1450
1318
  );
@@ -1458,9 +1326,9 @@ function normalizeAuditOutputs(auditOutputs, flags = { skipAudits: [] }) {
1458
1326
  const doSkip = toSkip.has(slug);
1459
1327
  if (doSkip) {
1460
1328
  ui().logger.info(
1461
- `Audit ${chalk7.bold(
1329
+ `Audit ${bold8(
1462
1330
  slug
1463
- )} was included in audit outputs of lighthouse but listed under ${chalk7.bold(
1331
+ )} was included in audit outputs of lighthouse but listed under ${bold8(
1464
1332
  "skipAudits"
1465
1333
  )}.`
1466
1334
  );
@@ -1468,6 +1336,13 @@ function normalizeAuditOutputs(auditOutputs, flags = { skipAudits: [] }) {
1468
1336
  return !doSkip;
1469
1337
  });
1470
1338
  }
1339
+ var LighthouseAuditParsingError = class extends Error {
1340
+ constructor(slug, error) {
1341
+ super(`
1342
+ Audit ${bold8(slug)} failed parsing details:
1343
+ ${error.message}`);
1344
+ }
1345
+ };
1471
1346
  function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
1472
1347
  if (verbose) {
1473
1348
  logUnsupportedDetails(lhrAudits);
@@ -1478,7 +1353,7 @@ function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
1478
1353
  score,
1479
1354
  numericValue: value = 0,
1480
1355
  // not every audit has a numericValue
1481
- details: details4,
1356
+ details: details2,
1482
1357
  displayValue
1483
1358
  }) => {
1484
1359
  const auditOutput = {
@@ -1488,16 +1363,12 @@ function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
1488
1363
  value,
1489
1364
  displayValue
1490
1365
  };
1491
- if (details4 != null) {
1366
+ if (details2 != null) {
1492
1367
  try {
1493
- const parsedDetails = toAuditDetails(details4);
1494
- return parsedDetails ? { ...auditOutput, details: parsedDetails } : auditOutput;
1368
+ const parsedDetails = toAuditDetails(details2);
1369
+ return Object.keys(parsedDetails).length > 0 ? { ...auditOutput, details: parsedDetails } : auditOutput;
1495
1370
  } catch (error) {
1496
- throw new Error(
1497
- `
1498
- Audit ${chalk7.bold(slug)} failed parsing details:
1499
- ${error.message}`
1500
- );
1371
+ throw new LighthouseAuditParsingError(slug, error);
1501
1372
  }
1502
1373
  }
1503
1374
  return auditOutput;
@@ -1629,9 +1500,9 @@ function logUnsupportedFlagsInUse(flags, displayCount = 3) {
1629
1500
  if (unsupportedFlagsInUse.length > 0) {
1630
1501
  const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1631
1502
  ui().logger.debug(
1632
- `${chalk8.yellow("\u26A0")} Plugin ${chalk8.bold(
1503
+ `${yellow2("\u26A0")} Plugin ${bold9(
1633
1504
  LIGHTHOUSE_PLUGIN_SLUG
1634
- )} used unsupported flags: ${chalk8.bold(
1505
+ )} used unsupported flags: ${bold9(
1635
1506
  unsupportedFlagsInUse.slice(0, displayCount).join(", ")
1636
1507
  )}${postFix(unsupportedFlagsInUse.length)}`
1637
1508
  );
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@code-pushup/lighthouse-plugin",
3
- "version": "0.47.0",
3
+ "version": "0.49.0",
4
4
  "license": "MIT",
5
5
  "dependencies": {
6
- "@code-pushup/models": "0.47.0",
6
+ "@code-pushup/models": "0.49.0",
7
+ "@code-pushup/utils": "0.49.0",
8
+ "ansis": "^3.3.0",
7
9
  "lighthouse": "^12.0.0",
8
- "@code-pushup/utils": "0.47.0",
9
- "lighthouse-logger": "2.0.1",
10
- "chalk": "^5.3.0"
10
+ "lighthouse-logger": "2.0.1"
11
11
  },
12
12
  "homepage": "https://github.com/code-pushup/cli#readme",
13
13
  "bugs": {
@@ -2,7 +2,7 @@ import type { FormattedIcu } from 'lighthouse';
2
2
  import type Details from 'lighthouse/types/lhr/audit-details';
3
3
  import { Result } from 'lighthouse/types/lhr/audit-result';
4
4
  import { AuditDetails } from '@code-pushup/models';
5
- export declare function toAuditDetails<T extends FormattedIcu<Details>>(details: T | undefined): AuditDetails | undefined;
5
+ export declare function toAuditDetails<T extends FormattedIcu<Details>>(details: T | undefined): AuditDetails;
6
6
  export declare const unsupportedDetailTypes: Set<string>;
7
7
  export declare function logUnsupportedDetails(lhrAudits: Result[], { displayCount }?: {
8
8
  displayCount?: number;
@@ -0,0 +1,8 @@
1
+ import type Details from 'lighthouse/types/lhr/audit-details';
2
+ import { Table, TableRowObject } from '@code-pushup/models';
3
+ export declare function parseOpportunityToAuditDetailsTable(details: Details.Opportunity): Table | undefined;
4
+ export declare function parseOpportunityItemToTableRow(opportunityItem: Details.OpportunityItem, headings: Details.TableColumnHeading[]): TableRowObject;
5
+ export declare function parseOpportunityEntry([key, value]: [
6
+ keyof Details.OpportunityItem,
7
+ Details.OpportunityItem[string]
8
+ ], valueType: Details.ItemValueType): string[] | [keyof Details.TableItem, Details.ItemValue | undefined];
@@ -0,0 +1,4 @@
1
+ import Details from 'lighthouse/types/lhr/audit-details';
2
+ export declare class LighthouseAuditDetailsParsingError extends Error {
3
+ constructor(type: Details['type'], rawTable: Record<string, unknown>, error: string);
4
+ }
@@ -4,10 +4,12 @@ import { AuditOutputs } from '@code-pushup/models';
4
4
  import type { LighthouseOptions } from '../types';
5
5
  import { LighthouseCliFlags } from './types';
6
6
  export declare function normalizeAuditOutputs(auditOutputs: AuditOutputs, flags?: LighthouseOptions): AuditOutputs;
7
+ export declare class LighthouseAuditParsingError extends Error {
8
+ constructor(slug: string, error: Error);
9
+ }
7
10
  export declare function toAuditOutputs(lhrAudits: Result[], { verbose }?: {
8
11
  verbose?: boolean;
9
12
  }): AuditOutputs;
10
- export declare const unsupportedDetailTypes: Set<string>;
11
13
  export type LighthouseLogLevel = 'verbose' | 'error' | 'info' | 'silent' | 'warn' | undefined;
12
14
  export declare function determineAndSetLogLevel({ verbose, quiet, }?: {
13
15
  verbose?: boolean;