@code-pushup/lighthouse-plugin 0.56.0 → 0.57.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.
Files changed (41) hide show
  1. package/package.json +8 -7
  2. package/src/index.d.ts +6 -6
  3. package/src/index.js +7 -0
  4. package/src/index.js.map +1 -0
  5. package/src/lib/constants.js +8 -0
  6. package/src/lib/constants.js.map +1 -0
  7. package/src/lib/lighthouse-plugin.d.ts +1 -1
  8. package/src/lib/lighthouse-plugin.js +27 -0
  9. package/src/lib/lighthouse-plugin.js.map +1 -0
  10. package/src/lib/normalize-flags.d.ts +2 -2
  11. package/src/lib/normalize-flags.js +55 -0
  12. package/src/lib/normalize-flags.js.map +1 -0
  13. package/src/lib/runner/constants.js +78 -0
  14. package/src/lib/runner/constants.js.map +1 -0
  15. package/src/lib/runner/details/details.js +40 -0
  16. package/src/lib/runner/details/details.js.map +1 -0
  17. package/src/lib/runner/details/item-value.js +120 -0
  18. package/src/lib/runner/details/item-value.js.map +1 -0
  19. package/src/lib/runner/details/opportunity.type.js +49 -0
  20. package/src/lib/runner/details/opportunity.type.js.map +1 -0
  21. package/src/lib/runner/details/table.type.js +42 -0
  22. package/src/lib/runner/details/table.type.js.map +1 -0
  23. package/src/lib/runner/details/utils.js +7 -0
  24. package/src/lib/runner/details/utils.js.map +1 -0
  25. package/src/lib/runner/runner.d.ts +1 -1
  26. package/src/lib/runner/runner.js +28 -0
  27. package/src/lib/runner/runner.js.map +1 -0
  28. package/src/lib/runner/types.d.ts +1 -1
  29. package/src/lib/runner/types.js +2 -0
  30. package/src/lib/runner/types.js.map +1 -0
  31. package/src/lib/runner/utils.d.ts +2 -2
  32. package/src/lib/runner/utils.js +98 -0
  33. package/src/lib/runner/utils.js.map +1 -0
  34. package/src/lib/types.d.ts +2 -2
  35. package/src/lib/types.js +2 -0
  36. package/src/lib/types.js.map +1 -0
  37. package/src/lib/utils.d.ts +1 -1
  38. package/src/lib/utils.js +77 -0
  39. package/src/lib/utils.js.map +1 -0
  40. package/index.js +0 -1632
  41. package/src/lib/runner/index.d.ts +0 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/lighthouse-plugin",
3
- "version": "0.56.0",
3
+ "version": "0.57.0",
4
4
  "license": "MIT",
5
5
  "description": "Code PushUp plugin for measuring web performance and quality with Lighthouse 🔥",
6
6
  "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-lighthouse#readme",
@@ -35,14 +35,15 @@
35
35
  "access": "public"
36
36
  },
37
37
  "type": "module",
38
- "main": "./index.js",
39
- "types": "./src/index.d.ts",
40
38
  "dependencies": {
41
- "@code-pushup/models": "0.56.0",
42
- "@code-pushup/utils": "0.56.0",
39
+ "@code-pushup/models": "0.57.0",
40
+ "@code-pushup/utils": "0.57.0",
43
41
  "ansis": "^3.3.0",
44
42
  "chrome-launcher": "^1.1.1",
45
43
  "lighthouse": "^12.0.0",
46
44
  "lighthouse-logger": "2.0.1"
47
- }
48
- }
45
+ },
46
+ "module": "./src/index.js",
47
+ "main": "./src/index.js",
48
+ "types": "./src/index.d.ts"
49
+ }
package/src/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { lighthousePlugin } from './lib/lighthouse-plugin';
2
- export { LIGHTHOUSE_REPORT_NAME } from './lib/runner';
3
- export { DEFAULT_CHROME_FLAGS, LIGHTHOUSE_PLUGIN_SLUG, LIGHTHOUSE_OUTPUT_PATH, } from './lib/constants';
4
- export { lighthouseAuditRef, lighthouseGroupRef, type LighthouseGroupSlugs, } from './lib/utils';
5
- export type { LighthouseOptions } from './lib/types';
6
- export { lighthousePlugin } from './lib/lighthouse-plugin';
1
+ import { lighthousePlugin } from './lib/lighthouse-plugin.js';
2
+ export { LIGHTHOUSE_REPORT_NAME } from './lib/runner/constants.js';
3
+ export { DEFAULT_CHROME_FLAGS, LIGHTHOUSE_PLUGIN_SLUG, LIGHTHOUSE_OUTPUT_PATH, } from './lib/constants.js';
4
+ export { lighthouseAuditRef, lighthouseGroupRef, type LighthouseGroupSlugs, } from './lib/utils.js';
5
+ export type { LighthouseOptions } from './lib/types.js';
6
+ export { lighthousePlugin } from './lib/lighthouse-plugin.js';
7
7
  export default lighthousePlugin;
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import { lighthousePlugin } from './lib/lighthouse-plugin.js';
2
+ export { LIGHTHOUSE_REPORT_NAME } from './lib/runner/constants.js';
3
+ export { DEFAULT_CHROME_FLAGS, LIGHTHOUSE_PLUGIN_SLUG, LIGHTHOUSE_OUTPUT_PATH, } from './lib/constants.js';
4
+ export { lighthouseAuditRef, lighthouseGroupRef, } from './lib/utils.js';
5
+ export { lighthousePlugin } from './lib/lighthouse-plugin.js';
6
+ export default lighthousePlugin;
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/plugin-lighthouse/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { DEFAULT_FLAGS } from 'chrome-launcher/dist/flags.js';
2
+ import path from 'node:path';
3
+ import { DEFAULT_PERSIST_OUTPUT_DIR } from '@code-pushup/models';
4
+ // headless is needed to pass CI on Linux and Windows (locally it works without headless too)
5
+ export const DEFAULT_CHROME_FLAGS = [...DEFAULT_FLAGS, '--headless'];
6
+ export const LIGHTHOUSE_PLUGIN_SLUG = 'lighthouse';
7
+ export const LIGHTHOUSE_OUTPUT_PATH = path.join(DEFAULT_PERSIST_OUTPUT_DIR, LIGHTHOUSE_PLUGIN_SLUG);
8
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../packages/plugin-lighthouse/src/lib/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,6FAA6F;AAC7F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,aAAa,EAAE,YAAY,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC;AACnD,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAC7C,0BAA0B,EAC1B,sBAAsB,CACvB,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import type { PluginConfig } from '@code-pushup/models';
2
- import type { LighthouseOptions } from './types';
2
+ import type { LighthouseOptions } from './types.js';
3
3
  export declare function lighthousePlugin(url: string, flags?: LighthouseOptions): PluginConfig;
@@ -0,0 +1,27 @@
1
+ import { createRequire } from 'node:module';
2
+ import { LIGHTHOUSE_PLUGIN_SLUG } from './constants.js';
3
+ import { normalizeFlags } from './normalize-flags.js';
4
+ import { LIGHTHOUSE_GROUPS, LIGHTHOUSE_NAVIGATION_AUDITS, } from './runner/constants.js';
5
+ import { createRunnerFunction } from './runner/runner.js';
6
+ import { filterAuditsAndGroupsByOnlyOptions } from './utils.js';
7
+ export function lighthousePlugin(url, flags) {
8
+ const { skipAudits, onlyAudits, onlyCategories, ...unparsedFlags } = normalizeFlags(flags ?? {});
9
+ const { audits, groups } = filterAuditsAndGroupsByOnlyOptions(LIGHTHOUSE_NAVIGATION_AUDITS, LIGHTHOUSE_GROUPS, { skipAudits, onlyAudits, onlyCategories });
10
+ const packageJson = createRequire(import.meta.url)('../../package.json');
11
+ return {
12
+ slug: LIGHTHOUSE_PLUGIN_SLUG,
13
+ packageName: packageJson.name,
14
+ version: packageJson.version,
15
+ title: 'Lighthouse',
16
+ icon: 'lighthouse',
17
+ audits,
18
+ groups,
19
+ runner: createRunnerFunction(url, {
20
+ skipAudits,
21
+ onlyAudits,
22
+ onlyCategories,
23
+ ...unparsedFlags,
24
+ }),
25
+ };
26
+ }
27
+ //# sourceMappingURL=lighthouse-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lighthouse-plugin.js","sourceRoot":"","sources":["../../../../../packages/plugin-lighthouse/src/lib/lighthouse-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,KAAyB;IAEzB,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,aAAa,EAAE,GAChE,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAE9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,kCAAkC,CAC3D,4BAA4B,EAC5B,iBAAiB,EACjB,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,CAC3C,CAAC;IAEF,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAChD,oBAAoB,CACkB,CAAC;IAEzC,OAAO;QACL,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,WAAW,CAAC,IAAI;QAC7B,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,YAAY;QAClB,MAAM;QACN,MAAM;QACN,MAAM,EAAE,oBAAoB,CAAC,GAAG,EAAE;YAChC,UAAU;YACV,UAAU;YACV,cAAc;YACd,GAAG,aAAa;SACjB,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -1,5 +1,5 @@
1
- import { type LighthouseCliFlags } from './runner';
2
- import type { LighthouseOptions } from './types';
1
+ import type { LighthouseCliFlags } from './runner/types.js';
2
+ import type { LighthouseOptions } from './types.js';
3
3
  export declare const DEFAULT_LIGHTHOUSE_OPTIONS: {
4
4
  onlyGroups: never[];
5
5
  verbose: false;
@@ -0,0 +1,55 @@
1
+ import { bold, yellow } from 'ansis';
2
+ import { ui } from '@code-pushup/utils';
3
+ import { LIGHTHOUSE_PLUGIN_SLUG } from './constants.js';
4
+ import { DEFAULT_CLI_FLAGS } from './runner/constants.js';
5
+ const { onlyCategories, ...originalDefaultCliFlags } = DEFAULT_CLI_FLAGS;
6
+ export const DEFAULT_LIGHTHOUSE_OPTIONS = {
7
+ ...originalDefaultCliFlags,
8
+ onlyGroups: onlyCategories,
9
+ };
10
+ // NOTE:
11
+ // This is an intermediate variable to get `UnsupportedCliFlags`. For unknown reasons `typescript@5.3.3` doesn't work otherwise.
12
+ const lighthouseUnsupportedCliFlags = [
13
+ 'precomputedLanternDataPath', // Path to the file where precomputed lantern data should be read from.
14
+ 'chromeIgnoreDefaultFlags', // ignore default flags from Lighthouse CLI
15
+ // No error reporting implemented as in the source Sentry was involved
16
+ // See: https://github.com/GoogleChrome/lighthouse/blob/d8ccf70692216b7fa047a4eaa2d1277b0b7fe947/cli/bin.js#L124
17
+ 'enableErrorReporting', // enable error reporting
18
+ // lighthouse CLI specific debug logs
19
+ 'list-all-audits', // Prints a list of all available audits and exits.
20
+ 'list-locales', // Prints a list of all supported locales and exits.
21
+ 'list-trace-categories', // Prints a list of all required trace categories and exits.
22
+ ];
23
+ const LIGHTHOUSE_UNSUPPORTED_CLI_FLAGS = new Set(lighthouseUnsupportedCliFlags);
24
+ const REFINED_STRING_OR_STRING_ARRAY = new Set([
25
+ 'onlyAudits',
26
+ 'onlyCategories',
27
+ 'skipAudits',
28
+ 'budgets',
29
+ 'chromeFlags',
30
+ ]);
31
+ export function normalizeFlags(flags) {
32
+ const prefilledFlags = { ...DEFAULT_LIGHTHOUSE_OPTIONS, ...flags };
33
+ logUnsupportedFlagsInUse(prefilledFlags);
34
+ return Object.fromEntries(Object.entries(prefilledFlags)
35
+ .filter(([flagName]) => !LIGHTHOUSE_UNSUPPORTED_CLI_FLAGS.has(flagName))
36
+ // in code-pushup lighthouse categories are mapped as groups, therefor we had to rename "onlyCategories" to "onlyGroups" for the user of the plugin as it was confusing
37
+ .map(([key, v]) => [key === 'onlyGroups' ? 'onlyCategories' : key, v])
38
+ // onlyAudits and onlyCategories cannot be empty arrays, otherwise skipAudits is ignored by lighthouse
39
+ .filter(([_, v]) => !(Array.isArray(v) && v.length === 0))
40
+ // undefined | string | string[] => string[] (empty for undefined)
41
+ .map(([key, v]) => {
42
+ if (!REFINED_STRING_OR_STRING_ARRAY.has(key)) {
43
+ return [key, v];
44
+ }
45
+ return [key, Array.isArray(v) ? v : v == null ? [] : [v]];
46
+ }));
47
+ }
48
+ export function logUnsupportedFlagsInUse(flags, displayCount = 3) {
49
+ const unsupportedFlagsInUse = Object.keys(flags).filter(flag => LIGHTHOUSE_UNSUPPORTED_CLI_FLAGS.has(flag));
50
+ if (unsupportedFlagsInUse.length > 0) {
51
+ const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : '';
52
+ ui().logger.debug(`${yellow('⚠')} Plugin ${bold(LIGHTHOUSE_PLUGIN_SLUG)} used unsupported flags: ${bold(unsupportedFlagsInUse.slice(0, displayCount).join(', '))}${postFix(unsupportedFlagsInUse.length)}`);
53
+ }
54
+ }
55
+ //# sourceMappingURL=normalize-flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-flags.js","sourceRoot":"","sources":["../../../../../packages/plugin-lighthouse/src/lib/normalize-flags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { defaultConfig, } from 'lighthouse';
2
+ import path from 'node:path';
3
+ import { DEFAULT_CHROME_FLAGS, LIGHTHOUSE_OUTPUT_PATH } from '../constants.js';
4
+ const { audits, categories } = defaultConfig;
5
+ // internal intermediate variable to derive the relevant audits
6
+ const allRawLighthouseAudits = await Promise.all((audits ?? []).map(loadLighthouseAudit));
7
+ export const PLUGIN_SLUG = 'lighthouse';
8
+ export const LIGHTHOUSE_NAVIGATION_AUDITS = allRawLighthouseAudits
9
+ // This plugin only supports the "navigation" mode of Lighthouse in the current implementation
10
+ // If we don't exclude other audits we throw in the plugin output validation as some of the provided audits are not included in `lighthouse-report.json`
11
+ .filter(audit => audit.meta.supportedModes == null ||
12
+ (Array.isArray(audit.meta.supportedModes) &&
13
+ audit.meta.supportedModes.includes('navigation')))
14
+ .map(audit => ({
15
+ slug: audit.meta.id,
16
+ title: getMetaString(audit.meta.title),
17
+ description: getMetaString(audit.meta.description),
18
+ }));
19
+ const navigationAuditSlugs = new Set(LIGHTHOUSE_NAVIGATION_AUDITS.map(({ slug }) => slug));
20
+ export const LIGHTHOUSE_GROUPS = Object.entries(categories ?? {}).map(([id, category]) => ({
21
+ slug: id,
22
+ title: getMetaString(category.title),
23
+ ...(category.description && {
24
+ description: getMetaString(category.description),
25
+ }),
26
+ refs: category.auditRefs
27
+ .filter(({ id: auditSlug }) => navigationAuditSlugs.has(auditSlug))
28
+ .map(ref => ({
29
+ slug: ref.id,
30
+ weight: ref.weight,
31
+ })),
32
+ }));
33
+ function getMetaString(value) {
34
+ if (typeof value === 'string') {
35
+ return value;
36
+ }
37
+ return value.formattedDefault;
38
+ }
39
+ async function loadLighthouseAudit(value) {
40
+ // the passed value directly includes the implementation as JS object
41
+ // shape: { implementation: typeof LHAudit; options?: {}; }
42
+ if (typeof value === 'object' && 'implementation' in value) {
43
+ return value.implementation;
44
+ }
45
+ // the passed value is a `LH.Audit` class instance
46
+ // shape: LHAudit
47
+ if (typeof value === 'function') {
48
+ return value;
49
+ }
50
+ // the passed value is the path directly
51
+ // shape: string
52
+ // otherwise it is a JS object maintaining a `path` property
53
+ // shape: { path: string, options?: {}; }
54
+ const file = typeof value === 'string' ? value : value.path;
55
+ const module = (await import(`lighthouse/core/audits/${file}.js`));
56
+ return module.default;
57
+ }
58
+ export const LIGHTHOUSE_REPORT_NAME = 'lighthouse-report.json';
59
+ export const DEFAULT_CLI_FLAGS = {
60
+ // default values extracted from
61
+ // https://github.com/GoogleChrome/lighthouse/blob/7d80178c37a1b600ea8f092fc0b098029799a659/cli/cli-flags.js#L80
62
+ verbose: false,
63
+ saveAssets: false,
64
+ chromeFlags: DEFAULT_CHROME_FLAGS,
65
+ port: 0,
66
+ hostname: '127.0.0.1',
67
+ view: false,
68
+ channel: 'cli',
69
+ // custom overwrites in favour of the plugin
70
+ // hide logs by default
71
+ quiet: true,
72
+ onlyAudits: [],
73
+ skipAudits: [],
74
+ onlyCategories: [],
75
+ output: ['json'],
76
+ outputPath: path.join(LIGHTHOUSE_OUTPUT_PATH, LIGHTHOUSE_REPORT_NAME),
77
+ };
78
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../../packages/plugin-lighthouse/src/lib/runner/constants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { bold, yellow } from 'ansis';
2
+ import { ui } from '@code-pushup/utils';
3
+ import { PLUGIN_SLUG } from '../constants.js';
4
+ import { parseOpportunityToAuditDetailsTable } from './opportunity.type.js';
5
+ import { parseTableToAuditDetailsTable } from './table.type.js';
6
+ export function toAuditDetails(details) {
7
+ if (details == null) {
8
+ return {};
9
+ }
10
+ const { type } = details;
11
+ switch (type) {
12
+ case 'table':
13
+ const table = parseTableToAuditDetailsTable(details);
14
+ return table ? { table } : {};
15
+ case 'opportunity':
16
+ const opportunity = parseOpportunityToAuditDetailsTable(details);
17
+ return opportunity ? { table: opportunity } : {};
18
+ }
19
+ return {};
20
+ }
21
+ // @TODO implement all details
22
+ export const unsupportedDetailTypes = new Set([
23
+ 'debugdata',
24
+ 'treemap-data',
25
+ 'screenshot',
26
+ 'filmstrip',
27
+ 'criticalrequestchain',
28
+ ]);
29
+ export function logUnsupportedDetails(lhrAudits, { displayCount = 3 } = {}) {
30
+ const slugsWithDetailParsingErrors = [
31
+ ...new Set(lhrAudits
32
+ .filter(({ details }) => unsupportedDetailTypes.has(details?.type))
33
+ .map(({ details }) => details?.type)),
34
+ ];
35
+ if (slugsWithDetailParsingErrors.length > 0) {
36
+ const postFix = (count) => count > displayCount ? ` and ${count - displayCount} more.` : '';
37
+ ui().logger.debug(`${yellow('⚠')} Plugin ${bold(PLUGIN_SLUG)} skipped parsing of unsupported audit details: ${bold(slugsWithDetailParsingErrors.slice(0, displayCount).join(', '))}${postFix(slugsWithDetailParsingErrors.length)}`);
38
+ }
39
+ }
40
+ //# sourceMappingURL=details.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"details.js","sourceRoot":"","sources":["../../../../../../../packages/plugin-lighthouse/src/lib/runner/details/details.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAKrC,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,mCAAmC,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,UAAU,cAAc,CAC5B,OAAsB;IAEtB,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,MAAM,KAAK,GAAsB,6BAA6B,CAAC,OAAO,CAAC,CAAC;YACxE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,KAAK,aAAa;YAChB,MAAM,WAAW,GACf,mCAAmC,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IAC5C,WAAW;IACX,cAAc;IACd,YAAY;IACZ,WAAW;IACX,sBAAsB;CACvB,CAAC,CAAC;AAEH,MAAM,UAAU,qBAAqB,CACnC,SAAmB,EACnB,EAAE,YAAY,GAAG,CAAC,KAAgC,EAAE;IAEpD,MAAM,4BAA4B,GAAG;QACnC,GAAG,IAAI,GAAG,CACR,SAAS;aACN,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CACtB,sBAAsB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAc,CAAC,CACpD;aACA,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CACvC;KACF,CAAC;IACF,IAAI,4BAA4B,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAChC,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CACf,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,IAAI,CAC3B,WAAW,CACZ,kDAAkD,IAAI,CACrD,4BAA4B,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/D,GAAG,OAAO,CAAC,4BAA4B,CAAC,MAAM,CAAC,EAAE,CACnD,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,120 @@
1
+ import { bold } from 'ansis';
2
+ import { formatBytes, formatDuration, html, truncateText, ui, } from '@code-pushup/utils';
3
+ export function trimSlice(item, maxLength = 0) {
4
+ const str = String(item).trim();
5
+ return maxLength > 0 ? str.slice(0, maxLength) : str;
6
+ }
7
+ export function parseNodeValue(node) {
8
+ const { selector = '' } = node ?? {};
9
+ return selector;
10
+ }
11
+ // eslint-disable-next-line max-lines-per-function
12
+ export function formatTableItemPropertyValue(itemValue, itemValueFormat) {
13
+ // null
14
+ if (itemValue == null) {
15
+ return '';
16
+ }
17
+ // Primitive Values
18
+ if (itemValueFormat == null) {
19
+ if (typeof itemValue === 'string') {
20
+ return trimSlice(itemValue);
21
+ }
22
+ if (typeof itemValue === 'number') {
23
+ return Number(itemValue);
24
+ }
25
+ if (typeof itemValue === 'boolean') {
26
+ return itemValue;
27
+ }
28
+ }
29
+ const parsedItemValue = parseTableItemPropertyValue(itemValue);
30
+ /* eslint-disable @typescript-eslint/no-magic-numbers */
31
+ switch (itemValueFormat) {
32
+ case 'bytes':
33
+ return formatBytes(Number(parsedItemValue));
34
+ case 'code':
35
+ return html.code(trimSlice(parsedItemValue));
36
+ case 'link':
37
+ const link = parsedItemValue;
38
+ return html.link(link.url, link.text);
39
+ case 'url':
40
+ const url = parsedItemValue;
41
+ return html.link(url);
42
+ case 'timespanMs':
43
+ case 'ms':
44
+ return formatDuration(Number(parsedItemValue));
45
+ case 'node':
46
+ return parseNodeValue(itemValue);
47
+ case 'source-location':
48
+ return truncateText(String(parsedItemValue), 200);
49
+ case 'numeric':
50
+ const num = Number(parsedItemValue);
51
+ if (num.toFixed(3).toString().endsWith('.000')) {
52
+ return String(num);
53
+ }
54
+ return String(num.toFixed(3));
55
+ case 'text':
56
+ return truncateText(String(parsedItemValue), 500);
57
+ case 'multi': // @TODO
58
+ // @TODO log verbose first, then implement data type
59
+ ui().logger.info(`Format type ${bold('multi')} is not implemented`);
60
+ return '';
61
+ case 'thumbnail': // @TODO
62
+ // @TODO log verbose first, then implement data type
63
+ ui().logger.info(`Format type ${bold('thumbnail')} is not implemented`);
64
+ return '';
65
+ }
66
+ /* eslint-enable @typescript-eslint/no-magic-numbers */
67
+ return itemValue;
68
+ }
69
+ export function parseSimpleItemValue(item) {
70
+ if (typeof item === 'object') {
71
+ const value = item.value;
72
+ if (typeof value === 'object') {
73
+ return value.formattedDefault;
74
+ }
75
+ return value;
76
+ }
77
+ return item;
78
+ }
79
+ // @TODO extract Link type from logic
80
+ export function parseTableItemPropertyValue(itemValue) {
81
+ if (itemValue == null) {
82
+ return '';
83
+ }
84
+ // Primitive Values
85
+ if (typeof itemValue === 'string' ||
86
+ typeof itemValue === 'number' ||
87
+ typeof itemValue === 'boolean') {
88
+ return parseSimpleItemValue(itemValue);
89
+ }
90
+ // Object Values
91
+ const objectValue = itemValue;
92
+ const { type } = objectValue;
93
+ switch (type) {
94
+ case 'code':
95
+ case 'url':
96
+ return String(parseSimpleItemValue(objectValue));
97
+ case 'node':
98
+ return parseNodeValue(objectValue);
99
+ case 'link':
100
+ return objectValue;
101
+ case 'numeric':
102
+ return Number(parseSimpleItemValue(objectValue));
103
+ case 'source-location':
104
+ const { url } = objectValue;
105
+ return String(url);
106
+ case 'subitems':
107
+ // @TODO log verbose first, then implement data type
108
+ ui().logger.info(`Value type ${bold('subitems')} is not implemented`);
109
+ return '';
110
+ case 'debugdata':
111
+ // @TODO log verbose first, then implement data type
112
+ ui().logger.info(`Value type ${bold('debugdata')} is not implemented`, {
113
+ silent: true,
114
+ });
115
+ return '';
116
+ }
117
+ // IcuMessage
118
+ return parseSimpleItemValue(objectValue);
119
+ }
120
+ //# sourceMappingURL=item-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-value.js","sourceRoot":"","sources":["../../../../../../../packages/plugin-lighthouse/src/lib/runner/details/item-value.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { tableSchema, } from '@code-pushup/models';
2
+ import { formatBytes, formatDuration, html } from '@code-pushup/utils';
3
+ import { parseTableColumns, parseTableEntry } from './table.type.js';
4
+ import { LighthouseAuditDetailsParsingError } from './utils.js';
5
+ export function parseOpportunityToAuditDetailsTable(details) {
6
+ const { headings: rawHeadings, items } = details;
7
+ if (items.length === 0) {
8
+ return undefined;
9
+ }
10
+ try {
11
+ return tableSchema().parse({
12
+ title: 'Opportunity',
13
+ columns: parseTableColumns(rawHeadings),
14
+ rows: items.map(row => parseOpportunityItemToTableRow(row, rawHeadings)),
15
+ });
16
+ }
17
+ catch (error) {
18
+ throw new LighthouseAuditDetailsParsingError('opportunity', { items, headings: rawHeadings }, error.message.toString());
19
+ }
20
+ }
21
+ export function parseOpportunityItemToTableRow(opportunityItem, headings) {
22
+ const keys = new Set(headings.map(({ key }) => key));
23
+ const valueTypesByKey = new Map(headings.map(({ key, valueType }) => [key, valueType]));
24
+ return {
25
+ ...Object.fromEntries(Object.entries(opportunityItem)
26
+ // forward only properties with a given value
27
+ .filter(([key]) => keys.has(key))
28
+ .map(([key, value]) => {
29
+ const valueType = valueTypesByKey.get(key);
30
+ return parseOpportunityEntry([key, value], valueType);
31
+ })),
32
+ };
33
+ }
34
+ export function parseOpportunityEntry([key, value], valueType) {
35
+ switch (key) {
36
+ case 'url':
37
+ return [key, html.link(String(value))];
38
+ case 'wastedPercent':
39
+ return [key, `${Number(value).toFixed(2)} %`];
40
+ case 'totalBytes':
41
+ case 'wastedBytes':
42
+ return [key, formatBytes(Number(value))];
43
+ case 'wastedMs':
44
+ return [key, formatDuration(Number(value))];
45
+ default:
46
+ return parseTableEntry([key, value], valueType);
47
+ }
48
+ }
49
+ //# sourceMappingURL=opportunity.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opportunity.type.js","sourceRoot":"","sources":["../../../../../../../packages/plugin-lighthouse/src/lib/runner/details/opportunity.type.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { tableSchema, } from '@code-pushup/models';
2
+ import { formatTableItemPropertyValue } from './item-value.js';
3
+ import { LighthouseAuditDetailsParsingError } from './utils.js';
4
+ export function parseTableToAuditDetailsTable(details) {
5
+ const { headings: rawHeadings, items } = details;
6
+ if (items.length === 0) {
7
+ return undefined;
8
+ }
9
+ try {
10
+ return tableSchema().parse({
11
+ columns: parseTableColumns(rawHeadings),
12
+ rows: items.map(row => parseTableRow(row, rawHeadings)),
13
+ });
14
+ }
15
+ catch (error) {
16
+ throw new LighthouseAuditDetailsParsingError('table', { items, headings: rawHeadings }, error.message.toString());
17
+ }
18
+ }
19
+ export function parseTableColumns(rawHeadings) {
20
+ return rawHeadings.map(({ key, label }) => ({
21
+ key: key ?? '',
22
+ ...(typeof label === 'string' && label.length > 0 ? { label } : {}),
23
+ align: 'left',
24
+ }));
25
+ }
26
+ export function parseTableRow(tableItem, headings) {
27
+ const keys = new Set(headings.map(({ key }) => key));
28
+ const valueTypesByKey = new Map(headings.map(({ key, valueType }) => [key, valueType]));
29
+ return Object.fromEntries(Object.entries(tableItem)
30
+ .filter(([key]) => keys.has(key))
31
+ .map(([key, value]) => {
32
+ const valueType = valueTypesByKey.get(key);
33
+ return parseTableEntry([key, value], valueType);
34
+ }));
35
+ }
36
+ export function parseTableEntry([key, value], valueType) {
37
+ if (value == null) {
38
+ return [key, value];
39
+ }
40
+ return [key, formatTableItemPropertyValue(value, valueType)];
41
+ }
42
+ //# sourceMappingURL=table.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.type.js","sourceRoot":"","sources":["../../../../../../../packages/plugin-lighthouse/src/lib/runner/details/table.type.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,UAAU,6BAA6B,CAC3C,OAAsB;IAEtB,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,WAAW,EAAE,CAAC,KAAK,CAAC;YACzB,OAAO,EAAE,iBAAiB,CAAC,WAAW,CAAC;YACvC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;SACxD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,kCAAkC,CAC1C,OAAO,EACP,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,EAC/B,KAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,CACpC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,WAAyC;IAEzC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1C,GAAG,EAAE,GAAG,IAAI,EAAE;QACd,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,KAAK,EAAE,MAAM;KACd,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,SAA4B,EAC5B,QAAsC;IAEtC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CACvD,CAAC;IAEF,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SACtB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,OAAO,eAAe,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC,CAAC,CACa,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,CAAC,GAAG,EAAE,KAAK,CAAwB,EACnC,SAAiC;IAEjC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,4BAA4B,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { bold } from 'ansis';
2
+ export class LighthouseAuditDetailsParsingError extends Error {
3
+ constructor(type, rawTable, error) {
4
+ super(`Parsing lighthouse report details ${bold(type)} failed: \nRaw data:\n ${JSON.stringify(rawTable, null, 2)}\n${error}`);
5
+ }
6
+ }
7
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../../../packages/plugin-lighthouse/src/lib/runner/details/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAG7B,MAAM,OAAO,kCAAmC,SAAQ,KAAK;IAC3D,YACE,IAAqB,EACrB,QAAiC,EACjC,KAAa;QAEb,KAAK,CACH,qCAAqC,IAAI,CACvC,IAAI,CACL,0BAA0B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,KAAK,EAAE,CACzE,CAAC;IACJ,CAAC;CACF"}
@@ -1,3 +1,3 @@
1
1
  import type { RunnerFunction } from '@code-pushup/models';
2
- import type { LighthouseCliFlags } from './types';
2
+ import type { LighthouseCliFlags } from './types.js';
3
3
  export declare function createRunnerFunction(urlUnderTest: string, flags?: LighthouseCliFlags): RunnerFunction;
@@ -0,0 +1,28 @@
1
+ import { runLighthouse } from 'lighthouse/cli/run.js';
2
+ import path from 'node:path';
3
+ import { ensureDirectoryExists } from '@code-pushup/utils';
4
+ import { DEFAULT_CLI_FLAGS } from './constants.js';
5
+ import { determineAndSetLogLevel, getConfig, normalizeAuditOutputs, toAuditOutputs, } from './utils.js';
6
+ export function createRunnerFunction(urlUnderTest, flags = DEFAULT_CLI_FLAGS) {
7
+ return async () => {
8
+ const { configPath, preset, outputPath, ...parsedFlags } = flags;
9
+ const logLevel = determineAndSetLogLevel(parsedFlags);
10
+ const config = await getConfig({ configPath, preset });
11
+ if (outputPath) {
12
+ await ensureDirectoryExists(path.dirname(outputPath));
13
+ }
14
+ const enrichedFlags = {
15
+ ...parsedFlags,
16
+ logLevel,
17
+ outputPath,
18
+ };
19
+ const runnerResult = await runLighthouse(urlUnderTest, enrichedFlags, config);
20
+ if (runnerResult == null) {
21
+ throw new Error('Lighthouse did not produce a result.');
22
+ }
23
+ const { lhr } = runnerResult;
24
+ const auditOutputs = toAuditOutputs(Object.values(lhr.audits), flags);
25
+ return normalizeAuditOutputs(auditOutputs, enrichedFlags);
26
+ };
27
+ }
28
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../../../packages/plugin-lighthouse/src/lib/runner/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,qBAAqB,EACrB,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,QAA4B,iBAAiB;IAE7C,OAAO,KAAK,IAA2B,EAAE;QACvC,MAAM,EACJ,UAAU,EACV,MAAM,EACN,UAAU,EACV,GAAG,WAAW,EACf,GAAgC,KAAK,CAAC;QAEvC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAEtD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,aAAa,GAAG;YACpB,GAAG,WAAW;YACd,QAAQ;YACR,UAAU;SACX,CAAC;QAEF,MAAM,YAAY,GAAY,MAAM,aAAa,CAC/C,YAAY,EACZ,aAAa,EACb,MAAM,CACP,CAAC;QAEF,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,GAAG,YAA4B,CAAC;QAC7C,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAEtE,OAAO,qBAAqB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { LighthouseOptions } from '../types';
1
+ import type { LighthouseOptions } from '../types.js';
2
2
  export type NormalizedFlags = {
3
3
  chromeFlags: string[];
4
4
  onlyAudits: string[];
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../packages/plugin-lighthouse/src/lib/runner/types.ts"],"names":[],"mappings":""}