@code-pushup/lighthouse-plugin 0.45.1 → 0.47.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,3 +1,7 @@
1
+ // packages/plugin-lighthouse/package.json
2
+ var name = "@code-pushup/lighthouse-plugin";
3
+ var version = "0.47.0";
4
+
1
5
  // packages/plugin-lighthouse/src/lib/constants.ts
2
6
  import { join } from "node:path";
3
7
 
@@ -66,7 +70,7 @@ function missingRefsForCategoriesErrorMsg(categories2, plugins) {
66
70
  }
67
71
 
68
72
  // packages/models/src/lib/implementation/schemas.ts
69
- var primitiveValueSchema = z.union([z.string(), z.number()]);
73
+ var tableCellValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]).default(null);
70
74
  function executionMetaSchema(options = {
71
75
  descriptionDate: "Execution start date and time",
72
76
  descriptionDuration: "Execution duration in ms"
@@ -230,10 +234,10 @@ var tableColumnObjectSchema = z4.object({
230
234
  label: z4.string().optional(),
231
235
  align: tableAlignmentSchema.optional()
232
236
  });
233
- var tableRowObjectSchema = z4.record(primitiveValueSchema, {
237
+ var tableRowObjectSchema = z4.record(tableCellValueSchema, {
234
238
  description: "Object row"
235
239
  });
236
- var tableRowPrimitiveSchema = z4.array(primitiveValueSchema, {
240
+ var tableRowPrimitiveSchema = z4.array(tableCellValueSchema, {
237
241
  description: "Primitive row"
238
242
  });
239
243
  var tableSharedSchema = z4.object({
@@ -707,13 +711,52 @@ var LIGHTHOUSE_OUTPUT_PATH = join(
707
711
  );
708
712
 
709
713
  // packages/plugin-lighthouse/src/lib/normalize-flags.ts
710
- import chalk6 from "chalk";
714
+ import chalk8 from "chalk";
711
715
 
712
716
  // packages/utils/src/lib/file-system.ts
713
717
  import { bundleRequire } from "bundle-require";
714
718
  import chalk2 from "chalk";
715
719
  import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
716
720
 
721
+ // packages/utils/src/lib/formatting.ts
722
+ function formatBytes(bytes, decimals = 2) {
723
+ const positiveBytes = Math.max(bytes, 0);
724
+ if (positiveBytes === 0) {
725
+ return "0 B";
726
+ }
727
+ const k = 1024;
728
+ const dm = decimals < 0 ? 0 : decimals;
729
+ const sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
730
+ const i = Math.floor(Math.log(positiveBytes) / Math.log(k));
731
+ return `${Number.parseFloat((positiveBytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
732
+ }
733
+ function formatDuration(duration, granularity = 0) {
734
+ if (duration < 1e3) {
735
+ return `${granularity ? duration.toFixed(granularity) : duration} ms`;
736
+ }
737
+ return `${(duration / 1e3).toFixed(2)} s`;
738
+ }
739
+ function truncateText(text, options) {
740
+ const {
741
+ maxChars,
742
+ position = "end",
743
+ ellipsis = "..."
744
+ } = typeof options === "number" ? { maxChars: options } : options;
745
+ if (text.length <= maxChars) {
746
+ return text;
747
+ }
748
+ const maxLength = maxChars - ellipsis.length;
749
+ switch (position) {
750
+ case "start":
751
+ return ellipsis + text.slice(-maxLength).trim();
752
+ case "middle":
753
+ const halfMaxChars = Math.floor(maxLength / 2);
754
+ return text.slice(0, halfMaxChars).trim() + ellipsis + text.slice(-halfMaxChars).trim();
755
+ case "end":
756
+ return text.slice(0, maxLength).trim() + ellipsis;
757
+ }
758
+ }
759
+
717
760
  // packages/utils/src/lib/logging.ts
718
761
  import isaacs_cliui from "@isaacs/cliui";
719
762
  import { cliui } from "@poppinss/cliui";
@@ -766,20 +809,12 @@ async function ensureDirectoryExists(baseDir) {
766
809
  }
767
810
  }
768
811
  }
769
- var NoExportError = class extends Error {
770
- constructor(filepath) {
771
- super(`No default export found in ${filepath}`);
772
- }
773
- };
774
- async function importEsmModule(options) {
775
- const { mod } = await bundleRequire({
776
- format: "esm",
777
- ...options
778
- });
779
- if (!("default" in mod)) {
780
- throw new NoExportError(options.filepath);
812
+ async function importModule(options) {
813
+ const { mod } = await bundleRequire(options);
814
+ if (typeof mod === "object" && "default" in mod) {
815
+ return mod.default;
781
816
  }
782
- return mod.default;
817
+ return mod;
783
818
  }
784
819
 
785
820
  // packages/utils/src/lib/text-formats/constants.ts
@@ -811,7 +846,7 @@ function code(text) {
811
846
 
812
847
  // packages/utils/src/lib/text-formats/html/link.ts
813
848
  function link(href, text) {
814
- return `<a href="${href}">${text || href}"</a>`;
849
+ return `<a href="${href}">${text || href}</a>`;
815
850
  }
816
851
 
817
852
  // packages/utils/src/lib/transform.ts
@@ -824,7 +859,7 @@ function capitalize(text) {
824
859
  )}`;
825
860
  }
826
861
 
827
- // packages/utils/src/lib/table.ts
862
+ // packages/utils/src/lib/text-formats/table.ts
828
863
  function rowToStringArray({ rows, columns = [] }) {
829
864
  if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
830
865
  throw new TypeError(
@@ -837,14 +872,19 @@ function rowToStringArray({ rows, columns = [] }) {
837
872
  }
838
873
  const objectRow = row;
839
874
  if (columns.length === 0 || typeof columns.at(0) === "string") {
840
- return Object.values(objectRow).map(String);
875
+ return Object.values(objectRow).map(
876
+ (value) => value == null ? "" : String(value)
877
+ );
841
878
  }
842
879
  return columns.map(
843
- ({ key }) => String(objectRow[key])
880
+ ({ key }) => objectRow[key] == null ? "" : String(objectRow[key])
844
881
  );
845
882
  });
846
883
  }
847
- function columnsToStringArray({ rows, columns = [] }) {
884
+ function columnsToStringArray({
885
+ rows,
886
+ columns = []
887
+ }) {
848
888
  const firstRow = rows.at(0);
849
889
  const primitiveRows = Array.isArray(firstRow);
850
890
  if (typeof columns.at(0) === "string" && !primitiveRows) {
@@ -884,10 +924,8 @@ function getColumnAlignmentForIndex(targetIdx, columns = []) {
884
924
  return "center";
885
925
  }
886
926
  }
887
- function getColumnAlignments({
888
- rows,
889
- columns = []
890
- }) {
927
+ function getColumnAlignments(tableData) {
928
+ const { rows, columns = [] } = tableData;
891
929
  if (rows.at(0) == null) {
892
930
  throw new Error("first row can`t be undefined.");
893
931
  }
@@ -897,10 +935,17 @@ function getColumnAlignments({
897
935
  (_, idx) => getColumnAlignmentForIndex(idx, columns)
898
936
  );
899
937
  }
900
- const firstObject = rows.at(0);
901
- return Object.keys(firstObject).map(
902
- (key, idx) => getColumnAlignmentForKeyAndIndex(key, idx, columns)
903
- );
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");
904
949
  }
905
950
 
906
951
  // packages/utils/src/lib/text-formats/html/table.ts
@@ -997,7 +1042,10 @@ function section(...contents) {
997
1042
  return `${lines(...contents)}${NEW_LINE}`;
998
1043
  }
999
1044
  function lines(...contents) {
1000
- return `${contents.filter(Boolean).join(NEW_LINE)}`;
1045
+ const filteredContent = contents.filter(
1046
+ (value) => value != null && value !== "" && value !== false
1047
+ );
1048
+ return `${filteredContent.join(NEW_LINE)}`;
1001
1049
  }
1002
1050
 
1003
1051
  // packages/utils/src/lib/text-formats/md/table.ts
@@ -1166,7 +1214,6 @@ var DEFAULT_CLI_FLAGS = {
1166
1214
  // default values extracted from
1167
1215
  // https://github.com/GoogleChrome/lighthouse/blob/7d80178c37a1b600ea8f092fc0b098029799a659/cli/cli-flags.js#L80
1168
1216
  verbose: false,
1169
- quiet: false,
1170
1217
  saveAssets: false,
1171
1218
  // needed to pass CI on linux and windows (locally it works without headless too)
1172
1219
  chromeFlags: ["--headless=shell"],
@@ -1175,6 +1222,8 @@ var DEFAULT_CLI_FLAGS = {
1175
1222
  view: false,
1176
1223
  channel: "cli",
1177
1224
  // custom overwrites in favour of the plugin
1225
+ // hide logs by default
1226
+ quiet: true,
1178
1227
  onlyAudits: [],
1179
1228
  skipAudits: [],
1180
1229
  onlyCategories: [],
@@ -1183,20 +1232,235 @@ var DEFAULT_CLI_FLAGS = {
1183
1232
  };
1184
1233
 
1185
1234
  // packages/plugin-lighthouse/src/lib/runner/utils.ts
1186
- import chalk5 from "chalk";
1235
+ import chalk7 from "chalk";
1187
1236
  import log from "lighthouse-logger";
1188
1237
  import desktopConfig from "lighthouse/core/config/desktop-config.js";
1189
1238
  import experimentalConfig from "lighthouse/core/config/experimental-config.js";
1190
1239
  import perfConfig from "lighthouse/core/config/perf-config.js";
1240
+
1241
+ // packages/plugin-lighthouse/src/lib/runner/details/details.ts
1242
+ import chalk6 from "chalk";
1243
+
1244
+ // packages/plugin-lighthouse/src/lib/runner/details/item-value.ts
1245
+ import chalk5 from "chalk";
1246
+ function trimSlice(item, maxLength = 0) {
1247
+ const str = String(item).trim();
1248
+ return maxLength > 0 ? str.slice(0, maxLength) : str;
1249
+ }
1250
+ function parseNodeValue(node) {
1251
+ const { selector = "" } = node ?? {};
1252
+ return selector;
1253
+ }
1254
+ function formatTableItemPropertyValue(itemValue, itemValueFormat) {
1255
+ if (itemValue == null) {
1256
+ return "";
1257
+ }
1258
+ if (itemValueFormat == null) {
1259
+ if (typeof itemValue === "string") {
1260
+ return trimSlice(itemValue);
1261
+ }
1262
+ if (typeof itemValue === "number") {
1263
+ return Number(itemValue);
1264
+ }
1265
+ if (typeof itemValue === "boolean") {
1266
+ return itemValue;
1267
+ }
1268
+ }
1269
+ const parsedItemValue = parseTableItemPropertyValue(itemValue);
1270
+ switch (itemValueFormat) {
1271
+ case "bytes":
1272
+ return formatBytes(Number(parsedItemValue));
1273
+ case "code":
1274
+ return html.code(trimSlice(parsedItemValue));
1275
+ case "link":
1276
+ const link8 = parsedItemValue;
1277
+ return html.link(link8.url, link8.text);
1278
+ case "url":
1279
+ const url = parsedItemValue;
1280
+ return html.link(url);
1281
+ case "timespanMs":
1282
+ case "ms":
1283
+ return formatDuration(Number(parsedItemValue));
1284
+ case "node":
1285
+ return parseNodeValue(itemValue);
1286
+ case "source-location":
1287
+ return truncateText(String(parsedItemValue), 200);
1288
+ case "numeric":
1289
+ const num = Number(parsedItemValue);
1290
+ if (num.toFixed(3).toString().endsWith(".000")) {
1291
+ return String(num);
1292
+ }
1293
+ return String(num.toFixed(3));
1294
+ case "text":
1295
+ return truncateText(String(parsedItemValue), 500);
1296
+ case "multi":
1297
+ ui().logger.info(`Format type ${chalk5.bold("multi")} is not implemented`);
1298
+ return "";
1299
+ case "thumbnail":
1300
+ ui().logger.info(
1301
+ `Format type ${chalk5.bold("thumbnail")} is not implemented`
1302
+ );
1303
+ return "";
1304
+ case null:
1305
+ return "";
1306
+ default:
1307
+ return itemValue;
1308
+ }
1309
+ }
1310
+ function parseSimpleItemValue(item) {
1311
+ if (typeof item === "object") {
1312
+ const value = item.value;
1313
+ if (typeof value === "object") {
1314
+ return value.formattedDefault;
1315
+ }
1316
+ return value;
1317
+ }
1318
+ return item;
1319
+ }
1320
+ function parseTableItemPropertyValue(itemValue) {
1321
+ if (itemValue == null) {
1322
+ return "";
1323
+ }
1324
+ if (typeof itemValue === "string" || typeof itemValue === "number" || typeof itemValue === "boolean") {
1325
+ return parseSimpleItemValue(itemValue);
1326
+ }
1327
+ const objectValue = itemValue;
1328
+ const { type } = objectValue;
1329
+ switch (type) {
1330
+ case "code":
1331
+ case "url":
1332
+ return String(parseSimpleItemValue(objectValue));
1333
+ case "node":
1334
+ return parseNodeValue(objectValue);
1335
+ case "link":
1336
+ return objectValue;
1337
+ case "numeric":
1338
+ return Number(parseSimpleItemValue(objectValue));
1339
+ case "source-location":
1340
+ const { url } = objectValue;
1341
+ return String(url);
1342
+ case "subitems":
1343
+ ui().logger.info(
1344
+ `Value type ${chalk5.bold("subitems")} is not implemented`
1345
+ );
1346
+ return "";
1347
+ case "debugdata":
1348
+ ui().logger.info(
1349
+ `Value type ${chalk5.bold("debugdata")} is not implemented`,
1350
+ { silent: true }
1351
+ );
1352
+ return "";
1353
+ }
1354
+ return parseSimpleItemValue(objectValue);
1355
+ }
1356
+
1357
+ // packages/plugin-lighthouse/src/lib/runner/details/table.type.ts
1358
+ function parseTableToAuditDetailsTable(details4) {
1359
+ const { headings: rawHeadings, items } = details4;
1360
+ if (items.length === 0) {
1361
+ return void 0;
1362
+ }
1363
+ return {
1364
+ columns: parseTableColumns(rawHeadings),
1365
+ rows: items.map((row) => parseTableRow(row, rawHeadings))
1366
+ };
1367
+ }
1368
+ function parseTableColumns(rawHeadings) {
1369
+ return rawHeadings.map(({ key, label }) => ({
1370
+ key: key ?? "",
1371
+ label: typeof label === "string" ? label : void 0,
1372
+ align: "left"
1373
+ }));
1374
+ }
1375
+ function parseTableRow(tableItem, headings) {
1376
+ const keys = new Set(headings.map(({ key }) => key));
1377
+ const valueTypesByKey = new Map(
1378
+ headings.map(({ key, valueType }) => [key, valueType])
1379
+ );
1380
+ return Object.fromEntries(
1381
+ Object.entries(tableItem).filter(([key]) => keys.has(key)).map(([key, value]) => {
1382
+ const valueType = valueTypesByKey.get(key);
1383
+ return parseTableEntry([key, value], valueType);
1384
+ })
1385
+ );
1386
+ }
1387
+ function parseTableEntry([key, value], valueType) {
1388
+ if (value == null) {
1389
+ return [key, value];
1390
+ }
1391
+ return [key, formatTableItemPropertyValue(value, valueType)];
1392
+ }
1393
+
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") {
1401
+ return void 0;
1402
+ }
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()}`
1422
+ );
1423
+ }
1424
+ return void 0;
1425
+ }
1426
+ var unsupportedDetailTypes = /* @__PURE__ */ new Set([
1427
+ "opportunity",
1428
+ "debugdata",
1429
+ "treemap-data",
1430
+ "screenshot",
1431
+ "filmstrip",
1432
+ "criticalrequestchain"
1433
+ ]);
1434
+ function logUnsupportedDetails(lhrAudits, { displayCount = 3 } = {}) {
1435
+ const slugsWithDetailParsingErrors = [
1436
+ ...new Set(
1437
+ lhrAudits.filter(
1438
+ ({ details: details4 }) => unsupportedDetailTypes.has(details4?.type)
1439
+ ).map(({ details: details4 }) => details4?.type)
1440
+ )
1441
+ ];
1442
+ if (slugsWithDetailParsingErrors.length > 0) {
1443
+ const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1444
+ ui().logger.debug(
1445
+ `${chalk6.yellow("\u26A0")} Plugin ${chalk6.bold(
1446
+ PLUGIN_SLUG
1447
+ )} skipped parsing of unsupported audit details: ${chalk6.bold(
1448
+ slugsWithDetailParsingErrors.slice(0, displayCount).join(", ")
1449
+ )}${postFix(slugsWithDetailParsingErrors.length)}`
1450
+ );
1451
+ }
1452
+ }
1453
+
1454
+ // packages/plugin-lighthouse/src/lib/runner/utils.ts
1191
1455
  function normalizeAuditOutputs(auditOutputs, flags = { skipAudits: [] }) {
1192
1456
  const toSkip = new Set(flags.skipAudits ?? []);
1193
1457
  return auditOutputs.filter(({ slug }) => {
1194
1458
  const doSkip = toSkip.has(slug);
1195
1459
  if (doSkip) {
1196
1460
  ui().logger.info(
1197
- `Audit ${chalk5.bold(
1461
+ `Audit ${chalk7.bold(
1198
1462
  slug
1199
- )} was included in audit outputs of lighthouse but listed under ${chalk5.bold(
1463
+ )} was included in audit outputs of lighthouse but listed under ${chalk7.bold(
1200
1464
  "skipAudits"
1201
1465
  )}.`
1202
1466
  );
@@ -1221,63 +1485,45 @@ function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
1221
1485
  slug,
1222
1486
  score: score ?? 1,
1223
1487
  // score can be null
1224
- value: Number.parseInt(value.toString(), 10),
1488
+ value,
1225
1489
  displayValue
1226
1490
  };
1227
- if (details4 == null) {
1228
- return auditOutput;
1491
+ if (details4 != null) {
1492
+ try {
1493
+ const parsedDetails = toAuditDetails(details4);
1494
+ return parsedDetails ? { ...auditOutput, details: parsedDetails } : auditOutput;
1495
+ } catch (error) {
1496
+ throw new Error(
1497
+ `
1498
+ Audit ${chalk7.bold(slug)} failed parsing details:
1499
+ ${error.message}`
1500
+ );
1501
+ }
1229
1502
  }
1230
1503
  return auditOutput;
1231
1504
  }
1232
1505
  );
1233
1506
  }
1234
- var unsupportedDetailTypes = /* @__PURE__ */ new Set([
1235
- "opportunity",
1236
- "table",
1237
- "treemap-data",
1238
- "screenshot",
1239
- "filmstrip",
1240
- "debugdata",
1241
- "criticalrequestchain"
1242
- ]);
1243
- function logUnsupportedDetails(lhrAudits, { displayCount = 3 } = {}) {
1244
- const slugsWithDetailParsingErrors = [
1245
- ...new Set(
1246
- lhrAudits.filter(
1247
- ({ details: details4 }) => unsupportedDetailTypes.has(details4?.type)
1248
- ).map(({ details: details4 }) => details4?.type)
1249
- )
1250
- ];
1251
- if (slugsWithDetailParsingErrors.length > 0) {
1252
- const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1253
- ui().logger.debug(
1254
- `${chalk5.yellow("\u26A0")} Plugin ${chalk5.bold(
1255
- PLUGIN_SLUG
1256
- )} skipped parsing of unsupported audit details: ${chalk5.bold(
1257
- slugsWithDetailParsingErrors.slice(0, displayCount).join(", ")
1258
- )}${postFix(slugsWithDetailParsingErrors.length)}`
1259
- );
1260
- }
1261
- }
1262
- function setLogLevel({
1507
+ function determineAndSetLogLevel({
1263
1508
  verbose,
1264
1509
  quiet
1265
1510
  } = {}) {
1511
+ let logLevel = "info";
1266
1512
  if (verbose) {
1267
- log.setLevel("verbose");
1513
+ logLevel = "verbose";
1268
1514
  } else if (quiet) {
1269
- log.setLevel("silent");
1270
- } else {
1271
- log.setLevel("info");
1515
+ logLevel = "silent";
1272
1516
  }
1517
+ log.setLevel(logLevel);
1518
+ return logLevel;
1273
1519
  }
1274
1520
  async function getConfig(options = {}) {
1275
1521
  const { configPath: filepath, preset } = options;
1276
- if (typeof filepath === "string") {
1522
+ if (filepath != null) {
1277
1523
  if (filepath.endsWith(".json")) {
1278
1524
  return readJsonFile(filepath);
1279
1525
  } else if (/\.(ts|js|mjs)$/.test(filepath)) {
1280
- return importEsmModule({ filepath });
1526
+ return importModule({ filepath, format: "esm" });
1281
1527
  } else {
1282
1528
  ui().logger.info(`Format of file ${filepath} not supported`);
1283
1529
  }
@@ -1305,13 +1551,14 @@ function createRunnerFunction(urlUnderTest, flags = DEFAULT_CLI_FLAGS) {
1305
1551
  outputPath,
1306
1552
  ...parsedFlags
1307
1553
  } = flags;
1308
- setLogLevel(parsedFlags);
1554
+ const logLevel = determineAndSetLogLevel(parsedFlags);
1309
1555
  const config = await getConfig({ configPath, preset });
1310
1556
  if (outputPath) {
1311
1557
  await ensureDirectoryExists(dirname(outputPath));
1312
1558
  }
1313
1559
  const enrichedFlags = {
1314
1560
  ...parsedFlags,
1561
+ logLevel,
1315
1562
  outputPath
1316
1563
  };
1317
1564
  const runnerResult = await runLighthouse(
@@ -1382,9 +1629,9 @@ function logUnsupportedFlagsInUse(flags, displayCount = 3) {
1382
1629
  if (unsupportedFlagsInUse.length > 0) {
1383
1630
  const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1384
1631
  ui().logger.debug(
1385
- `${chalk6.yellow("\u26A0")} Plugin ${chalk6.bold(
1632
+ `${chalk8.yellow("\u26A0")} Plugin ${chalk8.bold(
1386
1633
  LIGHTHOUSE_PLUGIN_SLUG
1387
- )} used unsupported flags: ${chalk6.bold(
1634
+ )} used unsupported flags: ${chalk8.bold(
1388
1635
  unsupportedFlagsInUse.slice(0, displayCount).join(", ")
1389
1636
  )}${postFix(unsupportedFlagsInUse.length)}`
1390
1637
  );
@@ -1491,6 +1738,8 @@ function lighthousePlugin(url, flags) {
1491
1738
  );
1492
1739
  return {
1493
1740
  slug: LIGHTHOUSE_PLUGIN_SLUG,
1741
+ packageName: name,
1742
+ version,
1494
1743
  title: "Lighthouse",
1495
1744
  icon: "lighthouse",
1496
1745
  audits: audits2,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@code-pushup/lighthouse-plugin",
3
- "version": "0.45.1",
3
+ "version": "0.47.0",
4
4
  "license": "MIT",
5
5
  "dependencies": {
6
- "@code-pushup/models": "0.45.1",
6
+ "@code-pushup/models": "0.47.0",
7
7
  "lighthouse": "^12.0.0",
8
- "@code-pushup/utils": "0.45.1",
8
+ "@code-pushup/utils": "0.47.0",
9
9
  "lighthouse-logger": "2.0.1",
10
10
  "chalk": "^5.3.0"
11
11
  },
@@ -3,13 +3,13 @@ import type { LighthouseOptions } from './types';
3
3
  export declare const DEFAULT_LIGHTHOUSE_OPTIONS: {
4
4
  onlyGroups: never[];
5
5
  verbose: false;
6
- quiet: false;
7
6
  saveAssets: false;
8
7
  chromeFlags: string[];
9
8
  port: number;
10
9
  hostname: string;
11
10
  view: false;
12
11
  channel: string;
12
+ quiet: true;
13
13
  onlyAudits: never[];
14
14
  skipAudits: never[];
15
15
  output: "json"[];
@@ -5,13 +5,13 @@ export declare const LIGHTHOUSE_GROUPS: Group[];
5
5
  export declare const LIGHTHOUSE_REPORT_NAME = "lighthouse-report.json";
6
6
  export declare const DEFAULT_CLI_FLAGS: {
7
7
  verbose: false;
8
- quiet: false;
9
8
  saveAssets: false;
10
9
  chromeFlags: string[];
11
10
  port: number;
12
11
  hostname: string;
13
12
  view: false;
14
13
  channel: string;
14
+ quiet: true;
15
15
  onlyAudits: never[];
16
16
  skipAudits: never[];
17
17
  onlyCategories: never[];
@@ -0,0 +1,9 @@
1
+ import type { FormattedIcu } from 'lighthouse';
2
+ import type Details from 'lighthouse/types/lhr/audit-details';
3
+ import { Result } from 'lighthouse/types/lhr/audit-result';
4
+ import { AuditDetails } from '@code-pushup/models';
5
+ export declare function toAuditDetails<T extends FormattedIcu<Details>>(details: T | undefined): AuditDetails | undefined;
6
+ export declare const unsupportedDetailTypes: Set<string>;
7
+ export declare function logUnsupportedDetails(lhrAudits: Result[], { displayCount }?: {
8
+ displayCount?: number;
9
+ }): void;
@@ -0,0 +1,10 @@
1
+ import type { IcuMessage } from 'lighthouse';
2
+ import type Details from 'lighthouse/types/lhr/audit-details';
3
+ export type PrimitiveItemValue = string | number | boolean;
4
+ export type ObjectItemValue = Exclude<Details.ItemValue, PrimitiveItemValue | IcuMessage>;
5
+ export type SimpleItemValue = Extract<ObjectItemValue, Details.NumericValue | Details.CodeValue | Details.UrlValue> | PrimitiveItemValue;
6
+ export declare function trimSlice(item?: PrimitiveItemValue, maxLength?: number): string;
7
+ export declare function parseNodeValue(node?: Details.NodeValue): string;
8
+ export declare function formatTableItemPropertyValue(itemValue?: Details.ItemValue, itemValueFormat?: Details.ItemValueType): Details.ItemValue;
9
+ export declare function parseSimpleItemValue(item: SimpleItemValue): PrimitiveItemValue;
10
+ export declare function parseTableItemPropertyValue(itemValue?: Details.ItemValue): PrimitiveItemValue | Details.LinkValue;
@@ -0,0 +1,6 @@
1
+ import type Details from 'lighthouse/types/lhr/audit-details';
2
+ import { Table, TableColumnObject, TableRowObject } from '@code-pushup/models';
3
+ export declare function parseTableToAuditDetailsTable(details: Details.Table): Table | undefined;
4
+ export declare function parseTableColumns(rawHeadings: Details.TableColumnHeading[]): TableColumnObject[];
5
+ export declare function parseTableRow(tableItem: Details.TableItem, headings: Details.TableColumnHeading[]): TableRowObject;
6
+ export declare function parseTableEntry<T extends Details.TableItem>([key, value]: [keyof T, T[keyof T]], valueType?: Details.ItemValueType): [keyof T, Details.ItemValue | undefined];
@@ -0,0 +1,4 @@
1
+ export type DOM = {
2
+ append: (v: string) => string;
3
+ createComponent: (type: 'crcChain', opt: Record<string, unknown>) => string;
4
+ };
@@ -8,12 +8,10 @@ export declare function toAuditOutputs(lhrAudits: Result[], { verbose }?: {
8
8
  verbose?: boolean;
9
9
  }): AuditOutputs;
10
10
  export declare const unsupportedDetailTypes: Set<string>;
11
- export declare function logUnsupportedDetails(lhrAudits: Result[], { displayCount }?: {
12
- displayCount?: number;
13
- }): void;
14
- export declare function setLogLevel({ verbose, quiet, }?: {
11
+ export type LighthouseLogLevel = 'verbose' | 'error' | 'info' | 'silent' | 'warn' | undefined;
12
+ export declare function determineAndSetLogLevel({ verbose, quiet, }?: {
15
13
  verbose?: boolean;
16
14
  quiet?: boolean;
17
- }): void;
15
+ }): LighthouseLogLevel;
18
16
  export type ConfigOptions = Partial<Pick<LighthouseCliFlags, 'configPath' | 'preset'>>;
19
17
  export declare function getConfig(options?: ConfigOptions): Promise<Config | undefined>;