@code-pushup/core 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 (40) hide show
  1. package/package.json +10 -8
  2. package/src/index.d.ts +11 -11
  3. package/src/index.js +10 -0
  4. package/src/index.js.map +1 -0
  5. package/src/lib/collect-and-persist.d.ts +1 -1
  6. package/src/lib/collect-and-persist.js +21 -0
  7. package/src/lib/collect-and-persist.js.map +1 -0
  8. package/src/lib/compare.js +96 -0
  9. package/src/lib/compare.js.map +1 -0
  10. package/src/lib/history.d.ts +1 -1
  11. package/src/lib/history.js +38 -0
  12. package/src/lib/history.js.map +1 -0
  13. package/src/lib/implementation/collect.d.ts +1 -1
  14. package/src/lib/implementation/collect.js +25 -0
  15. package/src/lib/implementation/collect.js.map +1 -0
  16. package/src/lib/implementation/compare-scorables.js +117 -0
  17. package/src/lib/implementation/compare-scorables.js.map +1 -0
  18. package/src/lib/implementation/execute-plugin.js +126 -0
  19. package/src/lib/implementation/execute-plugin.js.map +1 -0
  20. package/src/lib/implementation/persist.js +56 -0
  21. package/src/lib/implementation/persist.js.map +1 -0
  22. package/src/lib/implementation/read-rc-file.d.ts +3 -0
  23. package/src/lib/implementation/read-rc-file.js +54 -0
  24. package/src/lib/implementation/read-rc-file.js.map +1 -0
  25. package/src/lib/implementation/report-to-gql.js +133 -0
  26. package/src/lib/implementation/report-to-gql.js.map +1 -0
  27. package/src/lib/implementation/runner.js +34 -0
  28. package/src/lib/implementation/runner.js.map +1 -0
  29. package/src/lib/load-portal-client.js +11 -0
  30. package/src/lib/load-portal-client.js.map +1 -0
  31. package/src/lib/merge-diffs.js +33 -0
  32. package/src/lib/merge-diffs.js.map +1 -0
  33. package/src/lib/normalize.js +31 -0
  34. package/src/lib/normalize.js.map +1 -0
  35. package/src/lib/types.js +2 -0
  36. package/src/lib/types.js.map +1 -0
  37. package/src/lib/upload.d.ts +1 -1
  38. package/src/lib/upload.js +34 -0
  39. package/src/lib/upload.js.map +1 -0
  40. package/index.js +0 -3249
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/core",
3
- "version": "0.55.0",
3
+ "version": "0.57.0",
4
4
  "license": "MIT",
5
5
  "description": "Core business logic for the used by the Code PushUp CLI",
6
6
  "homepage": "https://github.com/code-pushup/cli/tree/main/packages/core#readme",
@@ -38,12 +38,11 @@
38
38
  "access": "public"
39
39
  },
40
40
  "type": "module",
41
- "main": "./index.js",
42
- "types": "./src/index.d.ts",
43
41
  "dependencies": {
44
- "@code-pushup/models": "0.55.0",
45
- "@code-pushup/utils": "0.55.0",
46
- "ansis": "^3.3.0"
42
+ "@code-pushup/models": "0.57.0",
43
+ "@code-pushup/utils": "0.57.0",
44
+ "ansis": "^3.3.0",
45
+ "zod-validation-error": "^3.4.0"
47
46
  },
48
47
  "peerDependencies": {
49
48
  "@code-pushup/portal-client": "^0.9.0"
@@ -52,5 +51,8 @@
52
51
  "@code-pushup/portal-client": {
53
52
  "optional": true
54
53
  }
55
- }
56
- }
54
+ },
55
+ "module": "./src/index.js",
56
+ "main": "./src/index.js",
57
+ "types": "./src/index.d.ts"
58
+ }
package/src/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export { type CollectAndPersistReportsOptions, collectAndPersistReports, } from './lib/collect-and-persist';
2
- export { compareReportFiles, compareReports } from './lib/compare';
3
- export { type CollectOptions, collect } from './lib/implementation/collect';
4
- export type { ReportsToCompare } from './lib/implementation/compare-scorables';
5
- export { PluginOutputMissingAuditError, executePlugin, executePlugins, } from './lib/implementation/execute-plugin';
6
- export { PersistDirError, PersistError, persistReport, } from './lib/implementation/persist';
7
- export { history, type HistoryOptions, type HistoryOnlyOptions, } from './lib/history';
8
- export { ConfigPathError, autoloadRc, readRcByPath, } from './lib/implementation/read-rc-file';
9
- export type { GlobalOptions } from './lib/types';
10
- export { type UploadOptions, upload } from './lib/upload';
11
- export { mergeDiffs } from './lib/merge-diffs';
1
+ export { type CollectAndPersistReportsOptions, collectAndPersistReports, } from './lib/collect-and-persist.js';
2
+ export { compareReportFiles, compareReports } from './lib/compare.js';
3
+ export { type CollectOptions, collect } from './lib/implementation/collect.js';
4
+ export type { ReportsToCompare } from './lib/implementation/compare-scorables.js';
5
+ export { PluginOutputMissingAuditError, executePlugin, executePlugins, } from './lib/implementation/execute-plugin.js';
6
+ export { PersistDirError, PersistError, persistReport, } from './lib/implementation/persist.js';
7
+ export { history, type HistoryOptions, type HistoryOnlyOptions, } from './lib/history.js';
8
+ export { ConfigPathError, autoloadRc, readRcByPath, } from './lib/implementation/read-rc-file.js';
9
+ export type { GlobalOptions } from './lib/types.js';
10
+ export { type UploadOptions, upload } from './lib/upload.js';
11
+ export { mergeDiffs } from './lib/merge-diffs.js';
package/src/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { collectAndPersistReports, } from './lib/collect-and-persist.js';
2
+ export { compareReportFiles, compareReports } from './lib/compare.js';
3
+ export { collect } from './lib/implementation/collect.js';
4
+ export { PluginOutputMissingAuditError, executePlugin, executePlugins, } from './lib/implementation/execute-plugin.js';
5
+ export { PersistDirError, PersistError, persistReport, } from './lib/implementation/persist.js';
6
+ export { history, } from './lib/history.js';
7
+ export { ConfigPathError, autoloadRc, readRcByPath, } from './lib/implementation/read-rc-file.js';
8
+ export { upload } from './lib/upload.js';
9
+ export { mergeDiffs } from './lib/merge-diffs.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/core/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAuB,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAE/E,OAAO,EACL,6BAA6B,EAC7B,aAAa,EACb,cAAc,GACf,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,eAAe,EACf,YAAY,EACZ,aAAa,GACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,OAAO,GAGR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,GACb,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAsB,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { type CoreConfig, type PersistConfig } from '@code-pushup/models';
2
- import type { GlobalOptions } from './types';
2
+ import type { GlobalOptions } from './types.js';
3
3
  export type CollectAndPersistReportsOptions = Pick<CoreConfig, 'plugins' | 'categories'> & {
4
4
  persist: Required<PersistConfig>;
5
5
  } & Partial<GlobalOptions>;
@@ -0,0 +1,21 @@
1
+ import { pluginReportSchema, } from '@code-pushup/models';
2
+ import { logStdoutSummary, scoreReport, sortReport, verboseUtils, } from '@code-pushup/utils';
3
+ import { collect } from './implementation/collect.js';
4
+ import { logPersistedResults, persistReport, } from './implementation/persist.js';
5
+ export async function collectAndPersistReports(options) {
6
+ const { exec } = verboseUtils(options.verbose);
7
+ const report = await collect(options);
8
+ const sortedScoredReport = sortReport(scoreReport(report));
9
+ const persistResults = await persistReport(report, sortedScoredReport, options.persist);
10
+ // terminal output
11
+ logStdoutSummary(sortedScoredReport, options.verbose);
12
+ exec(() => {
13
+ logPersistedResults(persistResults);
14
+ });
15
+ // validate report and throw if invalid
16
+ report.plugins.forEach(plugin => {
17
+ // Running checks after persisting helps while debugging as you can check the invalid output after the error is thrown
18
+ pluginReportSchema.parse(plugin);
19
+ });
20
+ }
21
+ //# sourceMappingURL=collect-and-persist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect-and-persist.js","sourceRoot":"","sources":["../../../../../packages/core/src/lib/collect-and-persist.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,aAAa,GACd,MAAM,6BAA6B,CAAC;AAQrC,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAwC;IAExC,MAAM,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,kBAAkB,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,MAAM,aAAa,CACxC,MAAM,EACN,kBAAkB,EAClB,OAAO,CAAC,OAAO,CAChB,CAAC;IAEF,kBAAkB;IAClB,gBAAgB,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtD,IAAI,CAAC,GAAG,EAAE;QACR,mBAAmB,CAAC,cAAc,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,uCAAuC;IACvC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QAC9B,sHAAsH;QACtH,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { writeFile } from 'node:fs/promises';
2
+ import { createRequire } from 'node:module';
3
+ import path from 'node:path';
4
+ import { reportSchema, } from '@code-pushup/models';
5
+ import { calcDuration, ensureDirectoryExists, generateMdReportsDiff, readJsonFile, scoreReport, ui, } from '@code-pushup/utils';
6
+ import { compareAudits, compareCategories, compareGroups, } from './implementation/compare-scorables.js';
7
+ import { loadPortalClient } from './load-portal-client.js';
8
+ export async function compareReportFiles(inputPaths, persistConfig, uploadConfig, label) {
9
+ const { outputDir, filename, format } = persistConfig;
10
+ const [reportBefore, reportAfter] = await Promise.all([
11
+ readJsonFile(inputPaths.before),
12
+ readJsonFile(inputPaths.after),
13
+ ]);
14
+ const reports = {
15
+ before: reportSchema.parse(reportBefore),
16
+ after: reportSchema.parse(reportAfter),
17
+ };
18
+ const diff = compareReports(reports);
19
+ if (label) {
20
+ // eslint-disable-next-line functional/immutable-data
21
+ diff.label = label;
22
+ }
23
+ if (uploadConfig && diff.commits) {
24
+ // eslint-disable-next-line functional/immutable-data
25
+ diff.portalUrl = await fetchPortalComparisonLink(uploadConfig, diff.commits);
26
+ }
27
+ return Promise.all(format.map(async (fmt) => {
28
+ const outputPath = path.join(outputDir, `${filename}-diff.${fmt}`);
29
+ const content = reportsDiffToFileContent(diff, fmt);
30
+ await ensureDirectoryExists(outputDir);
31
+ await writeFile(outputPath, content);
32
+ return outputPath;
33
+ }));
34
+ }
35
+ export function compareReports(reports) {
36
+ const start = performance.now();
37
+ const date = new Date().toISOString();
38
+ const commits = reports.before.commit != null && reports.after.commit != null
39
+ ? { before: reports.before.commit, after: reports.after.commit }
40
+ : null;
41
+ const scoredReports = {
42
+ before: scoreReport(reports.before),
43
+ after: scoreReport(reports.after),
44
+ };
45
+ const categories = compareCategories(scoredReports);
46
+ const groups = compareGroups(scoredReports);
47
+ const audits = compareAudits(scoredReports);
48
+ const duration = calcDuration(start);
49
+ const packageJson = createRequire(import.meta.url)('../../package.json');
50
+ return {
51
+ commits,
52
+ categories,
53
+ groups,
54
+ audits,
55
+ packageName: packageJson.name,
56
+ version: packageJson.version,
57
+ date,
58
+ duration,
59
+ };
60
+ }
61
+ function reportsDiffToFileContent(reportsDiff, format) {
62
+ switch (format) {
63
+ case 'json':
64
+ return JSON.stringify(reportsDiff, null, 2);
65
+ case 'md':
66
+ return generateMdReportsDiff(reportsDiff);
67
+ }
68
+ }
69
+ async function fetchPortalComparisonLink(uploadConfig, commits) {
70
+ const { server, apiKey, organization, project } = uploadConfig;
71
+ const portalClient = await loadPortalClient();
72
+ if (!portalClient) {
73
+ return;
74
+ }
75
+ const { PortalOperationError, getPortalComparisonLink } = portalClient;
76
+ try {
77
+ return await getPortalComparisonLink({
78
+ server,
79
+ apiKey,
80
+ parameters: {
81
+ organization,
82
+ project,
83
+ before: commits.before.hash,
84
+ after: commits.after.hash,
85
+ },
86
+ });
87
+ }
88
+ catch (error) {
89
+ if (error instanceof PortalOperationError) {
90
+ ui().logger.warning(`Failed to fetch portal comparison link - ${error.message}`);
91
+ return undefined;
92
+ }
93
+ throw error;
94
+ }
95
+ }
96
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../../../packages/core/src/lib/compare.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models';
2
- import type { GlobalOptions } from './types';
2
+ import type { GlobalOptions } from './types.js';
3
3
  export type HistoryOnlyOptions = {
4
4
  targetBranch?: string;
5
5
  skipUploads?: boolean;
@@ -0,0 +1,38 @@
1
+ import { getCurrentBranchOrTag, safeCheckout, ui } from '@code-pushup/utils';
2
+ import { collectAndPersistReports } from './collect-and-persist.js';
3
+ import { upload } from './upload.js';
4
+ export async function history(config, commits) {
5
+ const initialBranch = await getCurrentBranchOrTag();
6
+ const { skipUploads = false, forceCleanStatus, persist } = config;
7
+ const reports = [];
8
+ // eslint-disable-next-line functional/no-loop-statements
9
+ for (const commit of commits) {
10
+ ui().logger.info(`Collect ${commit}`);
11
+ await safeCheckout(commit, forceCleanStatus);
12
+ const currentConfig = {
13
+ ...config,
14
+ persist: {
15
+ ...persist,
16
+ format: ['json'],
17
+ filename: `${commit}-report`,
18
+ },
19
+ };
20
+ await collectAndPersistReports(currentConfig);
21
+ if (skipUploads) {
22
+ ui().logger.info('Upload is skipped because skipUploads is set to true.');
23
+ }
24
+ else {
25
+ if (currentConfig.upload) {
26
+ await upload(currentConfig);
27
+ }
28
+ else {
29
+ ui().logger.info('Upload is skipped because upload config is undefined.');
30
+ }
31
+ }
32
+ // eslint-disable-next-line functional/immutable-data
33
+ reports.push(currentConfig.persist.filename);
34
+ }
35
+ await safeCheckout(initialBranch, forceCleanStatus);
36
+ return reports;
37
+ }
38
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../../../../packages/core/src/lib/history.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAarC,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAsB,EACtB,OAAiB;IAEjB,MAAM,aAAa,GAAW,MAAM,qBAAqB,EAAE,CAAC;IAE5D,MAAM,EAAE,WAAW,GAAG,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAElE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,yDAAyD;IACzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;QACtC,MAAM,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAE7C,MAAM,aAAa,GAAmB;YACpC,GAAG,MAAM;YACT,OAAO,EAAE;gBACP,GAAG,OAAO;gBACV,MAAM,EAAE,CAAC,MAAM,CAAC;gBAChB,QAAQ,EAAE,GAAG,MAAM,SAAS;aAC7B;SACF,CAAC;QAEF,MAAM,wBAAwB,CAAC,aAAa,CAAC,CAAC;QAE9C,IAAI,WAAW,EAAE,CAAC;YAChB,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;gBACzB,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CACd,uDAAuD,CACxD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,qDAAqD;QACrD,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,YAAY,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAEpD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { CoreConfig, Report } from '@code-pushup/models';
2
- import type { GlobalOptions } from '../types';
2
+ import type { GlobalOptions } from '../types.js';
3
3
  export type CollectOptions = Pick<CoreConfig, 'plugins' | 'categories'> & Partial<GlobalOptions>;
4
4
  /**
5
5
  * Run audits, collect plugin output and aggregate it into a JSON object
@@ -0,0 +1,25 @@
1
+ import { createRequire } from 'node:module';
2
+ import { calcDuration, getLatestCommit } from '@code-pushup/utils';
3
+ import { executePlugins } from './execute-plugin.js';
4
+ /**
5
+ * Run audits, collect plugin output and aggregate it into a JSON object
6
+ * @param options
7
+ */
8
+ export async function collect(options) {
9
+ const { plugins, categories } = options;
10
+ const date = new Date().toISOString();
11
+ const start = performance.now();
12
+ const commit = await getLatestCommit();
13
+ const pluginOutputs = await executePlugins(plugins, options);
14
+ const packageJson = createRequire(import.meta.url)('../../../package.json');
15
+ return {
16
+ commit,
17
+ packageName: packageJson.name,
18
+ version: packageJson.version,
19
+ date,
20
+ duration: calcDuration(start),
21
+ categories,
22
+ plugins: pluginOutputs,
23
+ };
24
+ }
25
+ //# sourceMappingURL=collect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../../../../packages/core/src/lib/implementation/collect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKrD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACnD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IACvC,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAChD,uBAAuB,CACkB,CAAC;IAC5C,OAAO;QACL,MAAM;QACN,WAAW,EAAE,WAAW,CAAC,IAAI;QAC7B,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,IAAI;QACJ,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC;QAC7B,UAAU;QACV,OAAO,EAAE,aAAa;KACvB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { comparePairs, listAuditsFromAllPlugins, listGroupsFromAllPlugins, matchArrayItemsByKey, } from '@code-pushup/utils';
2
+ export function compareCategories(reports) {
3
+ const { pairs, added, removed } = matchArrayItemsByKey({
4
+ before: reports.before.categories ?? [],
5
+ after: reports.after.categories ?? [],
6
+ key: 'slug',
7
+ });
8
+ const { changed, unchanged } = comparePairs(pairs, ({ before, after }) => before.score === after.score);
9
+ return {
10
+ changed: changed.map(categoryPairToDiff),
11
+ unchanged: unchanged.map(categoryToResult),
12
+ added: added.map(categoryToResult),
13
+ removed: removed.map(categoryToResult),
14
+ };
15
+ }
16
+ export function compareGroups(reports) {
17
+ const { pairs, added, removed } = matchArrayItemsByKey({
18
+ before: listGroupsFromAllPlugins(reports.before),
19
+ after: listGroupsFromAllPlugins(reports.after),
20
+ key: ({ plugin, group }) => `${plugin.slug}/${group.slug}`,
21
+ });
22
+ const { changed, unchanged } = comparePairs(pairs, ({ before, after }) => before.group.score === after.group.score);
23
+ return {
24
+ changed: changed.map(pluginGroupPairToDiff),
25
+ unchanged: unchanged.map(pluginGroupToResult),
26
+ added: added.map(pluginGroupToResult),
27
+ removed: removed.map(pluginGroupToResult),
28
+ };
29
+ }
30
+ export function compareAudits(reports) {
31
+ const { pairs, added, removed } = matchArrayItemsByKey({
32
+ before: listAuditsFromAllPlugins(reports.before),
33
+ after: listAuditsFromAllPlugins(reports.after),
34
+ key: ({ plugin, audit }) => `${plugin.slug}/${audit.slug}`,
35
+ });
36
+ const { changed, unchanged } = comparePairs(pairs, ({ before, after }) => before.audit.value === after.audit.value &&
37
+ before.audit.score === after.audit.score);
38
+ return {
39
+ changed: changed.map(pluginAuditPairToDiff),
40
+ unchanged: unchanged.map(pluginAuditToResult),
41
+ added: added.map(pluginAuditToResult),
42
+ removed: removed.map(pluginAuditToResult),
43
+ };
44
+ }
45
+ function categoryToResult(category) {
46
+ return {
47
+ ...selectMeta(category),
48
+ score: category.score,
49
+ };
50
+ }
51
+ function categoryPairToDiff({ before, after, }) {
52
+ return {
53
+ ...selectMeta(after),
54
+ scores: {
55
+ before: before.score,
56
+ after: after.score,
57
+ diff: after.score - before.score,
58
+ },
59
+ };
60
+ }
61
+ function pluginGroupToResult({ group, plugin }) {
62
+ return {
63
+ ...selectMeta(group),
64
+ plugin: selectMeta(plugin),
65
+ score: group.score,
66
+ };
67
+ }
68
+ function pluginGroupPairToDiff({ before, after, }) {
69
+ return {
70
+ ...selectMeta(after.group),
71
+ plugin: selectMeta(after.plugin),
72
+ scores: {
73
+ before: before.group.score,
74
+ after: after.group.score,
75
+ diff: after.group.score - before.group.score,
76
+ },
77
+ };
78
+ }
79
+ function pluginAuditToResult({ audit, plugin }) {
80
+ return {
81
+ ...selectMeta(audit),
82
+ plugin: selectMeta(plugin),
83
+ score: audit.score,
84
+ value: audit.value,
85
+ displayValue: audit.displayValue,
86
+ };
87
+ }
88
+ function pluginAuditPairToDiff({ before, after, }) {
89
+ return {
90
+ ...selectMeta(after.audit),
91
+ plugin: selectMeta(after.plugin),
92
+ scores: {
93
+ before: before.audit.score,
94
+ after: after.audit.score,
95
+ diff: after.audit.score - before.audit.score,
96
+ },
97
+ values: {
98
+ before: before.audit.value,
99
+ after: after.audit.value,
100
+ diff: after.audit.value - before.audit.value,
101
+ },
102
+ displayValues: {
103
+ before: before.audit.displayValue,
104
+ after: after.audit.displayValue,
105
+ },
106
+ };
107
+ }
108
+ function selectMeta(meta) {
109
+ return {
110
+ slug: meta.slug,
111
+ title: meta.title,
112
+ ...(meta.docsUrl && {
113
+ docsUrl: meta.docsUrl,
114
+ }),
115
+ };
116
+ }
117
+ //# sourceMappingURL=compare-scorables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-scorables.js","sourceRoot":"","sources":["../../../../../../packages/core/src/lib/implementation/compare-scorables.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import { bold } from 'ansis';
2
+ import { auditOutputsSchema, } from '@code-pushup/models';
3
+ import { getProgressBar, groupByStatus, logMultipleResults, pluralizeToken, } from '@code-pushup/utils';
4
+ import { normalizeAuditOutputs } from '../normalize.js';
5
+ import { executeRunnerConfig, executeRunnerFunction } from './runner.js';
6
+ /**
7
+ * Error thrown when plugin output is invalid.
8
+ */
9
+ export class PluginOutputMissingAuditError extends Error {
10
+ constructor(auditSlug) {
11
+ super(`Audit metadata not present in plugin config. Missing slug: ${bold(auditSlug)}`);
12
+ }
13
+ }
14
+ /**
15
+ * Execute a plugin.
16
+ *
17
+ * @public
18
+ * @param pluginConfig - {@link ProcessConfig} object with runner and meta
19
+ * @param onProgress - progress handler {@link OnProgress}
20
+ * @returns {Promise<AuditOutput[]>} - audit outputs from plugin runner
21
+ * @throws {PluginOutputMissingAuditError} - if plugin runner output is invalid
22
+ *
23
+ * @example
24
+ * // plugin execution
25
+ * const pluginCfg = pluginConfigSchema.parse({...});
26
+ * const output = await executePlugin(pluginCfg);
27
+ *
28
+ * @example
29
+ * // error handling
30
+ * try {
31
+ * await executePlugin(pluginCfg);
32
+ * } catch (e) {
33
+ * console.error(e.message);
34
+ * }
35
+ */
36
+ export async function executePlugin(pluginConfig, onProgress) {
37
+ const { runner, audits: pluginConfigAudits, description, docsUrl, groups, ...pluginMeta } = pluginConfig;
38
+ // execute plugin runner
39
+ const runnerResult = typeof runner === 'object'
40
+ ? await executeRunnerConfig(runner, onProgress)
41
+ : await executeRunnerFunction(runner, onProgress);
42
+ const { audits: unvalidatedAuditOutputs, ...executionMeta } = runnerResult;
43
+ // validate auditOutputs
44
+ const result = auditOutputsSchema.safeParse(unvalidatedAuditOutputs);
45
+ if (!result.success) {
46
+ throw new Error(`Audit output is invalid: ${result.error.message}`);
47
+ }
48
+ const auditOutputs = result.data;
49
+ auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits);
50
+ const normalizedAuditOutputs = await normalizeAuditOutputs(auditOutputs);
51
+ // enrich `AuditOutputs` to `AuditReport`
52
+ const auditReports = normalizedAuditOutputs.map((auditOutput) => ({
53
+ ...auditOutput,
54
+ ...pluginConfigAudits.find(audit => audit.slug === auditOutput.slug),
55
+ }));
56
+ // create plugin report
57
+ return {
58
+ ...pluginMeta,
59
+ ...executionMeta,
60
+ audits: auditReports,
61
+ ...(description && { description }),
62
+ ...(docsUrl && { docsUrl }),
63
+ ...(groups && { groups }),
64
+ };
65
+ }
66
+ const wrapProgress = async (pluginCfg, steps, progressBar) => {
67
+ progressBar?.updateTitle(`Executing ${bold(pluginCfg.title)}`);
68
+ try {
69
+ const pluginReport = await executePlugin(pluginCfg);
70
+ progressBar?.incrementInSteps(steps);
71
+ return pluginReport;
72
+ }
73
+ catch (error) {
74
+ progressBar?.incrementInSteps(steps);
75
+ throw new Error(error instanceof Error
76
+ ? `- Plugin ${bold(pluginCfg.title)} (${bold(pluginCfg.slug)}) produced the following error:\n - ${error.message}`
77
+ : String(error));
78
+ }
79
+ };
80
+ /**
81
+ * Execute multiple plugins and aggregates their output.
82
+ * @public
83
+ * @param plugins array of {@link PluginConfig} objects
84
+ * @param {Object} [options] execution options
85
+ * @param {boolean} options.progress show progress bar
86
+ * @returns {Promise<PluginReport[]>} plugin report
87
+ *
88
+ * @example
89
+ * // plugin execution
90
+ * const plugins = [pluginConfigSchema.parse({...})];
91
+ *
92
+ * @example
93
+ * // error handling
94
+ * try {
95
+ * await executePlugins(plugins);
96
+ * } catch (e) {
97
+ * console.error(e.message); // Plugin output is invalid
98
+ * }
99
+ *
100
+ */
101
+ export async function executePlugins(plugins, options) {
102
+ const { progress = false } = options ?? {};
103
+ const progressBar = progress ? getProgressBar('Run plugins') : null;
104
+ const pluginsResult = plugins.map(pluginCfg => wrapProgress(pluginCfg, plugins.length, progressBar));
105
+ const errorsTransform = ({ reason }) => String(reason);
106
+ const results = await Promise.allSettled(pluginsResult);
107
+ progressBar?.endProgress('Done running plugins');
108
+ logMultipleResults(results, 'Plugins', undefined, errorsTransform);
109
+ const { fulfilled, rejected } = groupByStatus(results);
110
+ if (rejected.length > 0) {
111
+ const errorMessages = rejected
112
+ .map(({ reason }) => String(reason))
113
+ .join('\n');
114
+ throw new Error(`Executing ${pluralizeToken('plugin', rejected.length)} failed.\n\n${errorMessages}\n\n`);
115
+ }
116
+ return fulfilled.map(result => result.value);
117
+ }
118
+ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits) {
119
+ auditOutputs.forEach(auditOutput => {
120
+ const auditMetadata = pluginConfigAudits.find(audit => audit.slug === auditOutput.slug);
121
+ if (!auditMetadata) {
122
+ throw new PluginOutputMissingAuditError(auditOutput.slug);
123
+ }
124
+ });
125
+ }
126
+ //# sourceMappingURL=execute-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-plugin.js","sourceRoot":"","sources":["../../../../../../packages/core/src/lib/implementation/execute-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { mkdir, stat, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { directoryExists, generateMdReport, logMultipleFileResults, ui, } from '@code-pushup/utils';
4
+ export class PersistDirError extends Error {
5
+ constructor(outputDir) {
6
+ super(`outPath: ${outputDir} is no directory.`);
7
+ }
8
+ }
9
+ export class PersistError extends Error {
10
+ constructor(reportPath) {
11
+ super(`fileName: ${reportPath} could not be saved.`);
12
+ }
13
+ }
14
+ export async function persistReport(report, sortedScoredReport, options) {
15
+ const { outputDir, filename, format } = options;
16
+ // collect physical format outputs
17
+ const results = format.map(reportType => {
18
+ switch (reportType) {
19
+ case 'json':
20
+ return {
21
+ format: 'json',
22
+ content: JSON.stringify(report, null, 2),
23
+ };
24
+ case 'md':
25
+ return {
26
+ format: 'md',
27
+ content: generateMdReport(sortedScoredReport, { outputDir }),
28
+ };
29
+ }
30
+ });
31
+ if (!(await directoryExists(outputDir))) {
32
+ try {
33
+ await mkdir(outputDir, { recursive: true });
34
+ }
35
+ catch (error) {
36
+ ui().logger.warning(error.toString());
37
+ throw new PersistDirError(outputDir);
38
+ }
39
+ }
40
+ // write relevant format outputs to file system
41
+ return Promise.allSettled(results.map(result => persistResult(path.join(outputDir, `${filename}.${result.format}`), result.content)));
42
+ }
43
+ async function persistResult(reportPath, content) {
44
+ return (writeFile(reportPath, content)
45
+ // return reportPath instead of void
46
+ .then(() => stat(reportPath))
47
+ .then(stats => [reportPath, stats.size])
48
+ .catch(error => {
49
+ ui().logger.warning(error.toString());
50
+ throw new PersistError(reportPath);
51
+ }));
52
+ }
53
+ export function logPersistedResults(persistResults) {
54
+ logMultipleFileResults(persistResults, 'Generated reports');
55
+ }
56
+ //# sourceMappingURL=persist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../../../../../packages/core/src/lib/implementation/persist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAGL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,EAAE,GACH,MAAM,oBAAoB,CAAC;AAE5B,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,SAAiB;QAC3B,KAAK,CAAC,YAAY,SAAS,mBAAmB,CAAC,CAAC;IAClD,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,UAAkB;QAC5B,KAAK,CAAC,aAAa,UAAU,sBAAsB,CAAC,CAAC;IACvD,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,kBAAgC,EAChC,OAAgC;IAEhC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEhD,kCAAkC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;QACtC,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,OAAO;oBACL,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACzC,CAAC;YACJ,KAAK,IAAI;gBACP,OAAO;oBACL,MAAM,EAAE,IAAI;oBACZ,OAAO,EAAE,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,CAAC;iBAC7D,CAAC;QACN,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAE,KAAe,CAAC,QAAQ,EAAE,CAAC,CAAC;YACjD,MAAM,IAAI,eAAe,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,OAAO,OAAO,CAAC,UAAU,CACvB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CACnB,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,EACpD,MAAM,CAAC,OAAO,CACf,CACF,CACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,UAAkB,EAAE,OAAe;IAC9D,OAAO,CACL,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC;QAC5B,oCAAoC;SACnC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SAC5B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAU,CAAC;SAChD,KAAK,CAAC,KAAK,CAAC,EAAE;QACb,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAE,KAAe,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjD,MAAM,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC,CAAC,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,cAAmC;IACrE,sBAAsB,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;AAC9D,CAAC"}
@@ -2,5 +2,8 @@ import { type CoreConfig } from '@code-pushup/models';
2
2
  export declare class ConfigPathError extends Error {
3
3
  constructor(configPath: string);
4
4
  }
5
+ export declare class ConfigValidationError extends Error {
6
+ constructor(configPath: string, message: string);
7
+ }
5
8
  export declare function readRcByPath(filepath: string, tsconfig?: string): Promise<CoreConfig>;
6
9
  export declare function autoloadRc(tsconfig?: string): Promise<CoreConfig>;