@code-pushup/lighthouse-plugin 0.55.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
@@ -1,8 +1,8 @@
1
1
  import type { Config } from 'lighthouse';
2
2
  import type { Result } from 'lighthouse/types/lhr/audit-result';
3
3
  import type { AuditOutputs } from '@code-pushup/models';
4
- import type { LighthouseOptions } from '../types';
5
- import type { LighthouseCliFlags } from './types';
4
+ import type { LighthouseOptions } from '../types.js';
5
+ import type { LighthouseCliFlags } from './types.js';
6
6
  export declare function normalizeAuditOutputs(auditOutputs: AuditOutputs, flags?: LighthouseOptions): AuditOutputs;
7
7
  export declare class LighthouseAuditParsingError extends Error {
8
8
  constructor(slug: string, error: Error);
@@ -0,0 +1,98 @@
1
+ import { bold } from 'ansis';
2
+ import log from 'lighthouse-logger';
3
+ import desktopConfig from 'lighthouse/core/config/desktop-config.js';
4
+ import experimentalConfig from 'lighthouse/core/config/experimental-config.js';
5
+ import perfConfig from 'lighthouse/core/config/perf-config.js';
6
+ import { formatReportScore, importModule, readJsonFile, ui, } from '@code-pushup/utils';
7
+ import { logUnsupportedDetails, toAuditDetails } from './details/details.js';
8
+ export function normalizeAuditOutputs(auditOutputs, flags = { skipAudits: [] }) {
9
+ const toSkip = new Set(flags.skipAudits ?? []);
10
+ return auditOutputs.filter(({ slug }) => !toSkip.has(slug));
11
+ }
12
+ export class LighthouseAuditParsingError extends Error {
13
+ constructor(slug, error) {
14
+ super(`\nAudit ${bold(slug)} failed parsing details: \n${error.message}`);
15
+ }
16
+ }
17
+ function formatBaseAuditOutput(lhrAudit) {
18
+ const { id: slug, score, numericValue, displayValue, scoreDisplayMode, } = lhrAudit;
19
+ return {
20
+ slug,
21
+ score: score ?? 1,
22
+ value: numericValue ?? score ?? 0,
23
+ displayValue: displayValue ??
24
+ (scoreDisplayMode === 'binary'
25
+ ? score === 1
26
+ ? 'passed'
27
+ : 'failed'
28
+ : score
29
+ ? `${formatReportScore(score)}%`
30
+ : undefined),
31
+ };
32
+ }
33
+ function processAuditDetails(auditOutput, details) {
34
+ try {
35
+ const parsedDetails = toAuditDetails(details);
36
+ return Object.keys(parsedDetails).length > 0
37
+ ? { ...auditOutput, details: parsedDetails }
38
+ : auditOutput;
39
+ }
40
+ catch (error) {
41
+ throw new LighthouseAuditParsingError(auditOutput.slug, error);
42
+ }
43
+ }
44
+ export function toAuditOutputs(lhrAudits, { verbose = false } = {}) {
45
+ if (verbose) {
46
+ logUnsupportedDetails(lhrAudits);
47
+ }
48
+ return lhrAudits.map(audit => {
49
+ const auditOutput = formatBaseAuditOutput(audit);
50
+ return audit.details == null
51
+ ? auditOutput
52
+ : processAuditDetails(auditOutput, audit.details);
53
+ });
54
+ }
55
+ export function determineAndSetLogLevel({ verbose, quiet, } = {}) {
56
+ // eslint-disable-next-line functional/no-let
57
+ let logLevel = 'info';
58
+ // set logging preferences
59
+ if (verbose) {
60
+ logLevel = 'verbose';
61
+ }
62
+ else if (quiet) {
63
+ logLevel = 'silent';
64
+ }
65
+ log.setLevel(logLevel);
66
+ return logLevel;
67
+ }
68
+ export async function getConfig(options = {}) {
69
+ const { configPath: filepath, preset } = options;
70
+ if (filepath != null) {
71
+ if (filepath.endsWith('.json')) {
72
+ // Resolve the config file path relative to where cli was called.
73
+ return readJsonFile(filepath);
74
+ }
75
+ else if (/\.(ts|js|mjs)$/.test(filepath)) {
76
+ return importModule({ filepath, format: 'esm' });
77
+ }
78
+ else {
79
+ ui().logger.info(`Format of file ${filepath} not supported`);
80
+ }
81
+ }
82
+ else if (preset != null) {
83
+ switch (preset) {
84
+ case 'desktop':
85
+ return desktopConfig;
86
+ case 'perf':
87
+ return perfConfig;
88
+ case 'experimental':
89
+ return experimentalConfig;
90
+ default:
91
+ // as preset is a string literal the default case here is normally caught by TS and not possible to happen. Now in reality it can happen and preset could be a string not included in the literal.
92
+ // Therefore, we have to use `as string`. Otherwise, it will consider preset as type never
93
+ ui().logger.info(`Preset "${preset}" is not supported`);
94
+ }
95
+ }
96
+ return undefined;
97
+ }
98
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../../packages/plugin-lighthouse/src/lib/runner/utils.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { CliFlags } from 'lighthouse';
2
- import type { ExcludeNullFromPropertyTypes } from '@code-pushup/utils';
3
- export type LighthouseOptions = ExcludeNullFromPropertyTypes<Partial<Omit<CliFlags, '_' | 'precomputedLanternDataPath' | 'enableErrorReporting' | 'list-all-audits' | 'list-locales' | 'list-trace-categories' | 'chromeIgnoreDefaultFlags' | 'onlyCategories' | 'onlyAudits' | 'skipAudits'>>> & {
2
+ import type { ExcludeNullableProps } from '@code-pushup/utils';
3
+ export type LighthouseOptions = ExcludeNullableProps<Partial<Omit<CliFlags, '_' | 'precomputedLanternDataPath' | 'enableErrorReporting' | 'list-all-audits' | 'list-locales' | 'list-trace-categories' | 'chromeIgnoreDefaultFlags' | 'onlyCategories' | 'onlyAudits' | 'skipAudits'>>> & {
4
4
  onlyGroups?: string | string[];
5
5
  onlyAudits?: string | string[];
6
6
  skipAudits?: string | 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/types.ts"],"names":[],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  import type { Audit, CategoryRef, Group } from '@code-pushup/models';
2
- import type { LighthouseCliFlags } from './runner';
2
+ import type { LighthouseCliFlags } from './runner/types.js';
3
3
  export type LighthouseGroupSlugs = 'performance' | 'accessibility' | 'best-practices' | 'seo' | 'pwa';
4
4
  export declare function lighthouseGroupRef(groupSlug: LighthouseGroupSlugs, weight?: number): CategoryRef;
5
5
  export declare function lighthouseAuditRef(auditSlug: string, weight?: number): CategoryRef;
@@ -0,0 +1,77 @@
1
+ import { filterItemRefsBy, toArray } from '@code-pushup/utils';
2
+ import { LIGHTHOUSE_PLUGIN_SLUG } from './constants.js';
3
+ export function lighthouseGroupRef(groupSlug, weight = 1) {
4
+ return {
5
+ plugin: LIGHTHOUSE_PLUGIN_SLUG,
6
+ slug: groupSlug,
7
+ type: 'group',
8
+ weight,
9
+ };
10
+ }
11
+ export function lighthouseAuditRef(auditSlug, weight = 1) {
12
+ return {
13
+ plugin: LIGHTHOUSE_PLUGIN_SLUG,
14
+ slug: auditSlug,
15
+ type: 'audit',
16
+ weight,
17
+ };
18
+ }
19
+ export class AuditsNotImplementedError extends Error {
20
+ constructor(auditSlugs) {
21
+ super(`audits: "${auditSlugs.join(', ')}" not implemented`);
22
+ }
23
+ }
24
+ export function validateAudits(audits, onlyAudits) {
25
+ const missingAudtis = toArray(onlyAudits).filter(slug => !audits.some(audit => audit.slug === slug));
26
+ if (missingAudtis.length > 0) {
27
+ throw new AuditsNotImplementedError(missingAudtis);
28
+ }
29
+ return true;
30
+ }
31
+ export class CategoriesNotImplementedError extends Error {
32
+ constructor(categorySlugs) {
33
+ super(`categories: "${categorySlugs.join(', ')}" not implemented`);
34
+ }
35
+ }
36
+ export function validateOnlyCategories(groups, onlyCategories) {
37
+ const missingCategories = toArray(onlyCategories).filter(slug => groups.every(group => group.slug !== slug));
38
+ if (missingCategories.length > 0) {
39
+ throw new CategoriesNotImplementedError(missingCategories);
40
+ }
41
+ return true;
42
+ }
43
+ export function filterAuditsAndGroupsByOnlyOptions(audits, groups, options) {
44
+ const { onlyAudits = [], skipAudits = [], onlyCategories = [], } = options ?? {};
45
+ // category wins over audits
46
+ if (onlyCategories.length > 0) {
47
+ validateOnlyCategories(groups, onlyCategories);
48
+ const categorySlugs = new Set(onlyCategories);
49
+ const filteredGroups = groups.filter(({ slug }) => categorySlugs.has(slug));
50
+ const auditSlugsFromRemainingGroups = new Set(filteredGroups.flatMap(({ refs }) => refs.map(({ slug }) => slug)));
51
+ return {
52
+ audits: audits.filter(({ slug }) => auditSlugsFromRemainingGroups.has(slug)),
53
+ groups: filteredGroups,
54
+ };
55
+ }
56
+ else if (onlyAudits.length > 0 || skipAudits.length > 0) {
57
+ validateAudits(audits, onlyAudits);
58
+ validateAudits(audits, skipAudits);
59
+ const onlyAuditSlugs = new Set(onlyAudits);
60
+ const skipAuditSlugs = new Set(skipAudits);
61
+ const filterAudits = ({ slug }) => !(
62
+ // audit is NOT in given onlyAuditSlugs
63
+ ((onlyAudits.length > 0 && !onlyAuditSlugs.has(slug)) ||
64
+ // audit IS in given skipAuditSlugs
65
+ (skipAudits.length > 0 && skipAuditSlugs.has(slug))));
66
+ return {
67
+ audits: audits.filter(filterAudits),
68
+ groups: filterItemRefsBy(groups, filterAudits),
69
+ };
70
+ }
71
+ // return unchanged
72
+ return {
73
+ audits,
74
+ groups,
75
+ };
76
+ }
77
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../packages/plugin-lighthouse/src/lib/utils.ts"],"names":[],"mappings":"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"}