@code-pushup/lighthouse-plugin 0.47.0 → 0.48.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.48.0";
4
4
 
5
5
  // packages/plugin-lighthouse/src/lib/constants.ts
6
6
  import { join } from "node:path";
@@ -711,7 +711,7 @@ 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 chalk9 from "chalk";
715
715
 
716
716
  // packages/utils/src/lib/file-system.ts
717
717
  import { bundleRequire } from "bundle-require";
@@ -1232,14 +1232,14 @@ var DEFAULT_CLI_FLAGS = {
1232
1232
  };
1233
1233
 
1234
1234
  // packages/plugin-lighthouse/src/lib/runner/utils.ts
1235
- import chalk7 from "chalk";
1235
+ import chalk8 from "chalk";
1236
1236
  import log from "lighthouse-logger";
1237
1237
  import desktopConfig from "lighthouse/core/config/desktop-config.js";
1238
1238
  import experimentalConfig from "lighthouse/core/config/experimental-config.js";
1239
1239
  import perfConfig from "lighthouse/core/config/perf-config.js";
1240
1240
 
1241
1241
  // packages/plugin-lighthouse/src/lib/runner/details/details.ts
1242
- import chalk6 from "chalk";
1242
+ import chalk7 from "chalk";
1243
1243
 
1244
1244
  // packages/plugin-lighthouse/src/lib/runner/details/item-value.ts
1245
1245
  import chalk5 from "chalk";
@@ -1301,11 +1301,8 @@ function formatTableItemPropertyValue(itemValue, itemValueFormat) {
1301
1301
  `Format type ${chalk5.bold("thumbnail")} is not implemented`
1302
1302
  );
1303
1303
  return "";
1304
- case null:
1305
- return "";
1306
- default:
1307
- return itemValue;
1308
1304
  }
1305
+ return itemValue;
1309
1306
  }
1310
1307
  function parseSimpleItemValue(item) {
1311
1308
  if (typeof item === "object") {
@@ -1354,21 +1351,45 @@ function parseTableItemPropertyValue(itemValue) {
1354
1351
  return parseSimpleItemValue(objectValue);
1355
1352
  }
1356
1353
 
1354
+ // packages/plugin-lighthouse/src/lib/runner/details/utils.ts
1355
+ import chalk6 from "chalk";
1356
+ var LighthouseAuditDetailsParsingError = class extends Error {
1357
+ constructor(type, rawTable, error) {
1358
+ super(
1359
+ `Parsing lighthouse report details ${chalk6.bold(
1360
+ type
1361
+ )} failed:
1362
+ Raw data:
1363
+ ${JSON.stringify(rawTable, null, 2)}
1364
+ ${error}`
1365
+ );
1366
+ }
1367
+ };
1368
+
1357
1369
  // packages/plugin-lighthouse/src/lib/runner/details/table.type.ts
1358
1370
  function parseTableToAuditDetailsTable(details4) {
1359
1371
  const { headings: rawHeadings, items } = details4;
1360
1372
  if (items.length === 0) {
1361
1373
  return void 0;
1362
1374
  }
1363
- return {
1364
- columns: parseTableColumns(rawHeadings),
1365
- rows: items.map((row) => parseTableRow(row, rawHeadings))
1366
- };
1375
+ try {
1376
+ return tableSchema().parse({
1377
+ title: "Table",
1378
+ columns: parseTableColumns(rawHeadings),
1379
+ rows: items.map((row) => parseTableRow(row, rawHeadings))
1380
+ });
1381
+ } catch (error) {
1382
+ throw new LighthouseAuditDetailsParsingError(
1383
+ "table",
1384
+ { items, headings: rawHeadings },
1385
+ error.message.toString()
1386
+ );
1387
+ }
1367
1388
  }
1368
1389
  function parseTableColumns(rawHeadings) {
1369
1390
  return rawHeadings.map(({ key, label }) => ({
1370
1391
  key: key ?? "",
1371
- label: typeof label === "string" ? label : void 0,
1392
+ ...typeof label === "string" && label.length > 0 ? { label } : {},
1372
1393
  align: "left"
1373
1394
  }));
1374
1395
  }
@@ -1391,40 +1412,73 @@ function parseTableEntry([key, value], valueType) {
1391
1412
  return [key, formatTableItemPropertyValue(value, valueType)];
1392
1413
  }
1393
1414
 
1415
+ // packages/plugin-lighthouse/src/lib/runner/details/opportunity.type.ts
1416
+ function parseOpportunityToAuditDetailsTable(details4) {
1417
+ const { headings: rawHeadings, items } = details4;
1418
+ if (items.length === 0) {
1419
+ return void 0;
1420
+ }
1421
+ try {
1422
+ return tableSchema().parse({
1423
+ title: "Opportunity",
1424
+ columns: parseTableColumns(rawHeadings),
1425
+ rows: items.map((row) => parseOpportunityItemToTableRow(row, rawHeadings))
1426
+ });
1427
+ } catch (error) {
1428
+ throw new LighthouseAuditDetailsParsingError(
1429
+ "opportunity",
1430
+ { items, headings: rawHeadings },
1431
+ error.message.toString()
1432
+ );
1433
+ }
1434
+ }
1435
+ function parseOpportunityItemToTableRow(opportunityItem, headings) {
1436
+ const keys = new Set(headings.map(({ key }) => key));
1437
+ const valueTypesByKey = new Map(
1438
+ headings.map(({ key, valueType }) => [key, valueType])
1439
+ );
1440
+ return {
1441
+ ...Object.fromEntries(
1442
+ Object.entries(opportunityItem).filter(([key]) => keys.has(key)).map(([key, value]) => {
1443
+ const valueType = valueTypesByKey.get(key);
1444
+ return parseOpportunityEntry([key, value], valueType);
1445
+ })
1446
+ )
1447
+ };
1448
+ }
1449
+ function parseOpportunityEntry([key, value], valueType) {
1450
+ switch (key) {
1451
+ case "url":
1452
+ return [key, html.link(String(value))];
1453
+ case "wastedPercent":
1454
+ return [key, `${Number(value).toFixed(2)} %`];
1455
+ case "totalBytes":
1456
+ case "wastedBytes":
1457
+ return [key, formatBytes(Number(value))];
1458
+ case "wastedMs":
1459
+ return [key, formatDuration(Number(value))];
1460
+ default:
1461
+ return parseTableEntry([key, value], valueType);
1462
+ }
1463
+ }
1464
+
1394
1465
  // packages/plugin-lighthouse/src/lib/runner/details/details.ts
1395
1466
  function toAuditDetails(details4) {
1396
1467
  if (details4 == null) {
1397
- return void 0;
1468
+ return {};
1398
1469
  }
1399
1470
  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
- );
1471
+ switch (type) {
1472
+ case "table":
1473
+ const table5 = parseTableToAuditDetailsTable(details4);
1474
+ return table5 ? { table: table5 } : {};
1475
+ case "opportunity":
1476
+ const opportunity = parseOpportunityToAuditDetailsTable(details4);
1477
+ return opportunity ? { table: opportunity } : {};
1423
1478
  }
1424
- return void 0;
1479
+ return {};
1425
1480
  }
1426
1481
  var unsupportedDetailTypes = /* @__PURE__ */ new Set([
1427
- "opportunity",
1428
1482
  "debugdata",
1429
1483
  "treemap-data",
1430
1484
  "screenshot",
@@ -1442,9 +1496,9 @@ function logUnsupportedDetails(lhrAudits, { displayCount = 3 } = {}) {
1442
1496
  if (slugsWithDetailParsingErrors.length > 0) {
1443
1497
  const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1444
1498
  ui().logger.debug(
1445
- `${chalk6.yellow("\u26A0")} Plugin ${chalk6.bold(
1499
+ `${chalk7.yellow("\u26A0")} Plugin ${chalk7.bold(
1446
1500
  PLUGIN_SLUG
1447
- )} skipped parsing of unsupported audit details: ${chalk6.bold(
1501
+ )} skipped parsing of unsupported audit details: ${chalk7.bold(
1448
1502
  slugsWithDetailParsingErrors.slice(0, displayCount).join(", ")
1449
1503
  )}${postFix(slugsWithDetailParsingErrors.length)}`
1450
1504
  );
@@ -1458,9 +1512,9 @@ function normalizeAuditOutputs(auditOutputs, flags = { skipAudits: [] }) {
1458
1512
  const doSkip = toSkip.has(slug);
1459
1513
  if (doSkip) {
1460
1514
  ui().logger.info(
1461
- `Audit ${chalk7.bold(
1515
+ `Audit ${chalk8.bold(
1462
1516
  slug
1463
- )} was included in audit outputs of lighthouse but listed under ${chalk7.bold(
1517
+ )} was included in audit outputs of lighthouse but listed under ${chalk8.bold(
1464
1518
  "skipAudits"
1465
1519
  )}.`
1466
1520
  );
@@ -1468,6 +1522,15 @@ function normalizeAuditOutputs(auditOutputs, flags = { skipAudits: [] }) {
1468
1522
  return !doSkip;
1469
1523
  });
1470
1524
  }
1525
+ var LighthouseAuditParsingError = class extends Error {
1526
+ constructor(slug, error) {
1527
+ super(
1528
+ `
1529
+ Audit ${chalk8.bold(slug)} failed parsing details:
1530
+ ${error.message}`
1531
+ );
1532
+ }
1533
+ };
1471
1534
  function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
1472
1535
  if (verbose) {
1473
1536
  logUnsupportedDetails(lhrAudits);
@@ -1491,13 +1554,9 @@ function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
1491
1554
  if (details4 != null) {
1492
1555
  try {
1493
1556
  const parsedDetails = toAuditDetails(details4);
1494
- return parsedDetails ? { ...auditOutput, details: parsedDetails } : auditOutput;
1557
+ return Object.keys(parsedDetails).length > 0 ? { ...auditOutput, details: parsedDetails } : auditOutput;
1495
1558
  } catch (error) {
1496
- throw new Error(
1497
- `
1498
- Audit ${chalk7.bold(slug)} failed parsing details:
1499
- ${error.message}`
1500
- );
1559
+ throw new LighthouseAuditParsingError(slug, error);
1501
1560
  }
1502
1561
  }
1503
1562
  return auditOutput;
@@ -1629,9 +1688,9 @@ function logUnsupportedFlagsInUse(flags, displayCount = 3) {
1629
1688
  if (unsupportedFlagsInUse.length > 0) {
1630
1689
  const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : "";
1631
1690
  ui().logger.debug(
1632
- `${chalk8.yellow("\u26A0")} Plugin ${chalk8.bold(
1691
+ `${chalk9.yellow("\u26A0")} Plugin ${chalk9.bold(
1633
1692
  LIGHTHOUSE_PLUGIN_SLUG
1634
- )} used unsupported flags: ${chalk8.bold(
1693
+ )} used unsupported flags: ${chalk9.bold(
1635
1694
  unsupportedFlagsInUse.slice(0, displayCount).join(", ")
1636
1695
  )}${postFix(unsupportedFlagsInUse.length)}`
1637
1696
  );
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@code-pushup/lighthouse-plugin",
3
- "version": "0.47.0",
3
+ "version": "0.48.0",
4
4
  "license": "MIT",
5
5
  "dependencies": {
6
- "@code-pushup/models": "0.47.0",
6
+ "@code-pushup/models": "0.48.0",
7
7
  "lighthouse": "^12.0.0",
8
- "@code-pushup/utils": "0.47.0",
8
+ "@code-pushup/utils": "0.48.0",
9
9
  "lighthouse-logger": "2.0.1",
10
10
  "chalk": "^5.3.0"
11
11
  },
@@ -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;