@code-pushup/js-packages-plugin 0.44.2 → 0.44.4

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/README.md CHANGED
@@ -59,7 +59,7 @@ It supports the following package managers:
59
59
  // ...
60
60
  plugins: [
61
61
  // ...
62
- await jsPackagesPlugin({ packageManager: ['yarn'], checks: ['audit'] }),
62
+ await jsPackagesPlugin({ packageManager: ['yarn-classic'], checks: ['audit'], dependencyGroups: ['prod'] }),
63
63
  ],
64
64
  };
65
65
  ```
@@ -112,11 +112,12 @@ The plugin accepts the following parameters:
112
112
 
113
113
  - `packageManager`: The package manager you are using. Supported values: `npm`, `yarn-classic` (v1), `yarn-modern` (v2+), `pnpm`.
114
114
  - (optional) `checks`: Array of checks to be run. Supported commands: `audit`, `outdated`. Both are configured by default.
115
+ - (optional) `dependencyGroups`: Array of dependency groups to be checked. `prod` and `dev` are configured by default. `optional` are opt-in.
115
116
  - (optional) `auditLevelMapping`: If you wish to set a custom level of issue severity based on audit vulnerability level, you may do so here. Any omitted values will be filled in by defaults. Audit levels are: `critical`, `high`, `moderate`, `low` and `info`. Issue severities are: `error`, `warn` and `info`. By default the mapping is as follows: `critical` and `high` → `error`; `moderate` and `low` → `warning`; `info` → `info`.
116
117
 
117
118
  ### Audits and group
118
119
 
119
- This plugin provides a group per check for a convenient declaration in your config. Each group contains audits for all supported groups of dependencies (`prod`, `dev` and `optional`).
120
+ This plugin provides a group per check for a convenient declaration in your config. Each group contains audits for all selected groups of dependencies that are supported (`prod`, `dev` or `optional`).
120
121
 
121
122
  ```ts
122
123
  // ...
@@ -144,7 +145,7 @@ This plugin provides a group per check for a convenient declaration in your conf
144
145
  ],
145
146
  ```
146
147
 
147
- Each dependency group has its own audit. If you want to check only a subset of dependencies (e.g. run audit and outdated for production dependencies) or assign different weights to them, you can do so in the following way:
148
+ Each dependency group has its own audit. If you want to assign different weights to the audits or record different dependency groups for different checks (the bigger set needs to be included in the plugin configuration), you can do so in the following way:
148
149
 
149
150
  ```ts
150
151
  // ...
package/bin.js CHANGED
@@ -1186,6 +1186,7 @@ var dependencyGroupToLong = {
1186
1186
 
1187
1187
  // packages/plugin-js-packages/src/lib/config.ts
1188
1188
  var dependencyGroups = ["prod", "dev", "optional"];
1189
+ var dependencyGroupSchema = z16.enum(dependencyGroups);
1189
1190
  var packageCommandSchema = z16.enum(["audit", "outdated"]);
1190
1191
  var packageManagerIdSchema = z16.enum([
1191
1192
  "npm",
@@ -1217,6 +1218,7 @@ var jsPackagesPluginConfigSchema = z16.object({
1217
1218
  packageManager: packageManagerIdSchema.describe(
1218
1219
  "Package manager to be used."
1219
1220
  ),
1221
+ dependencyGroups: z16.array(dependencyGroupSchema).min(1).default(["prod", "dev"]),
1220
1222
  auditLevelMapping: z16.record(packageAuditLevelSchema, issueSeveritySchema, {
1221
1223
  description: "Mapping of audit levels to issue severity. Custom mapping or overrides may be entered manually, otherwise has a default preset."
1222
1224
  }).default(defaultAuditLevelMapping).transform(fillAuditLevelMapping)
@@ -1354,11 +1356,16 @@ var npmPackageManager = {
1354
1356
  ],
1355
1357
  unifyResult: npmToAuditResult,
1356
1358
  // prod dependencies need to be filtered out manually since v10
1357
- postProcessResult: (results) => ({
1358
- prod: results.prod,
1359
- dev: filterAuditResult(results.dev, "name", results.prod),
1360
- optional: filterAuditResult(results.optional, "name", results.prod)
1361
- })
1359
+ postProcessResult: (results) => {
1360
+ const depGroups = objectToKeys(results);
1361
+ const devFilter = results.dev && results.prod ? filterAuditResult(results.dev, "name", results.prod) : results.dev;
1362
+ const optionalFilter = results.optional && results.prod ? filterAuditResult(results.optional, "name", results.prod) : results.optional;
1363
+ return {
1364
+ ...depGroups.includes("prod") && { prod: results.prod },
1365
+ ...depGroups.includes("dev") && { dev: devFilter },
1366
+ ...depGroups.includes("optional") && { optional: optionalFilter }
1367
+ };
1368
+ }
1362
1369
  },
1363
1370
  outdated: {
1364
1371
  commandArgs: [...COMMON_OUTDATED_ARGS, "--long"],
@@ -1451,15 +1458,16 @@ var pnpmPackageManager = {
1451
1458
  ignoreExitCode: true,
1452
1459
  unifyResult: pnpmToAuditResult,
1453
1460
  // optional dependencies don't have an exclusive option so they need duplicates filtered out
1454
- postProcessResult: (results) => ({
1455
- prod: results.prod,
1456
- dev: results.dev,
1457
- optional: filterAuditResult(
1458
- filterAuditResult(results.optional, "id", results.prod),
1459
- "id",
1460
- results.dev
1461
- )
1462
- })
1461
+ postProcessResult: (results) => {
1462
+ const depGroups = objectToKeys(results);
1463
+ const prodFilter = results.optional && results.prod ? filterAuditResult(results.optional, "id", results.prod) : results.optional;
1464
+ const devFilter = prodFilter && results.dev ? filterAuditResult(prodFilter, "id", results.dev) : results.optional;
1465
+ return {
1466
+ ...depGroups.includes("prod") && { prod: results.prod },
1467
+ ...depGroups.includes("dev") && { dev: results.dev },
1468
+ ...results.optional && { optional: devFilter }
1469
+ };
1470
+ }
1463
1471
  },
1464
1472
  outdated: {
1465
1473
  commandArgs: COMMON_OUTDATED_ARGS,
@@ -1853,14 +1861,19 @@ function outdatedToIssues(dependencies) {
1853
1861
 
1854
1862
  // packages/plugin-js-packages/src/lib/runner/index.ts
1855
1863
  async function executeRunner() {
1856
- const { packageManager, checks, auditLevelMapping } = await readJsonFile(PLUGIN_CONFIG_PATH);
1857
- const auditResults = checks.includes("audit") ? await processAudit(packageManager, auditLevelMapping) : [];
1858
- const outdatedResults = checks.includes("outdated") ? await processOutdated(packageManager) : [];
1864
+ const {
1865
+ packageManager,
1866
+ checks,
1867
+ auditLevelMapping,
1868
+ dependencyGroups: depGroups
1869
+ } = await readJsonFile(PLUGIN_CONFIG_PATH);
1870
+ const auditResults = checks.includes("audit") ? await processAudit(packageManager, auditLevelMapping, depGroups) : [];
1871
+ const outdatedResults = checks.includes("outdated") ? await processOutdated(packageManager, depGroups) : [];
1859
1872
  const checkResults = [...auditResults, ...outdatedResults];
1860
1873
  await ensureDirectoryExists(dirname(RUNNER_OUTPUT_PATH));
1861
1874
  await writeFile(RUNNER_OUTPUT_PATH, JSON.stringify(checkResults));
1862
1875
  }
1863
- async function processOutdated(id) {
1876
+ async function processOutdated(id, depGroups) {
1864
1877
  const pm = packageManagers[id];
1865
1878
  const { stdout } = await executeProcess({
1866
1879
  command: pm.command,
@@ -1870,15 +1883,18 @@ async function processOutdated(id) {
1870
1883
  // outdated returns exit code 1 when outdated dependencies are found
1871
1884
  });
1872
1885
  const normalizedResult = pm.outdated.unifyResult(stdout);
1873
- return dependencyGroups.map(
1886
+ return depGroups.map(
1874
1887
  (depGroup) => outdatedResultToAuditOutput(normalizedResult, id, depGroup)
1875
1888
  );
1876
1889
  }
1877
- async function processAudit(id, auditLevelMapping) {
1890
+ async function processAudit(id, auditLevelMapping, depGroups) {
1878
1891
  const pm = packageManagers[id];
1879
- const supportedDepGroups = pm.audit.supportedDepGroups ?? dependencyGroups;
1892
+ const supportedAuditDepGroups = pm.audit.supportedDepGroups ?? dependencyGroups;
1893
+ const compatibleAuditDepGroups = depGroups.filter(
1894
+ (group) => supportedAuditDepGroups.includes(group)
1895
+ );
1880
1896
  const auditResults = await Promise.allSettled(
1881
- supportedDepGroups.map(
1897
+ compatibleAuditDepGroups.map(
1882
1898
  async (depGroup) => {
1883
1899
  const { stdout } = await executeProcess({
1884
1900
  command: pm.command,
@@ -1901,8 +1917,9 @@ async function processAudit(id, auditLevelMapping) {
1901
1917
  auditResults.filter(isPromiseFulfilledResult).map((x) => x.value)
1902
1918
  );
1903
1919
  const uniqueResults = pm.audit.postProcessResult?.(fulfilled) ?? fulfilled;
1904
- return supportedDepGroups.map(
1920
+ return compatibleAuditDepGroups.map(
1905
1921
  (depGroup) => auditResultToAuditOutput(
1922
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1906
1923
  uniqueResults[depGroup],
1907
1924
  id,
1908
1925
  depGroup,
package/index.js CHANGED
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
4
4
 
5
5
  // packages/plugin-js-packages/package.json
6
6
  var name = "@code-pushup/js-packages-plugin";
7
- var version = "0.44.2";
7
+ var version = "0.44.4";
8
8
 
9
9
  // packages/plugin-js-packages/src/lib/config.ts
10
10
  import { z as z16 } from "zod";
@@ -717,10 +717,9 @@ var dependencyGroupToLong = {
717
717
  optional: "optionalDependencies"
718
718
  };
719
719
  var dependencyGroupWeights = {
720
- // eslint-disable-next-line no-magic-numbers
721
- prod: 3,
722
- dev: 1,
723
- optional: 1
720
+ prod: 80,
721
+ dev: 15,
722
+ optional: 5
724
723
  };
725
724
  var dependencyDocs = {
726
725
  prod: "https://classic.yarnpkg.com/docs/dependency-types#toc-dependencies",
@@ -730,6 +729,7 @@ var dependencyDocs = {
730
729
 
731
730
  // packages/plugin-js-packages/src/lib/config.ts
732
731
  var dependencyGroups = ["prod", "dev", "optional"];
732
+ var dependencyGroupSchema = z16.enum(dependencyGroups);
733
733
  var packageCommandSchema = z16.enum(["audit", "outdated"]);
734
734
  var packageManagerIdSchema = z16.enum([
735
735
  "npm",
@@ -761,47 +761,12 @@ var jsPackagesPluginConfigSchema = z16.object({
761
761
  packageManager: packageManagerIdSchema.describe(
762
762
  "Package manager to be used."
763
763
  ),
764
+ dependencyGroups: z16.array(dependencyGroupSchema).min(1).default(["prod", "dev"]),
764
765
  auditLevelMapping: z16.record(packageAuditLevelSchema, issueSeveritySchema, {
765
766
  description: "Mapping of audit levels to issue severity. Custom mapping or overrides may be entered manually, otherwise has a default preset."
766
767
  }).default(defaultAuditLevelMapping).transform(fillAuditLevelMapping)
767
768
  });
768
769
 
769
- // packages/plugin-js-packages/src/lib/runner/utils.ts
770
- function filterAuditResult(result, key, referenceResult) {
771
- if (result.vulnerabilities.length === 0) {
772
- return result;
773
- }
774
- const uniqueResult = result.vulnerabilities.reduce(
775
- (acc, ref) => {
776
- const matchReference = referenceResult ?? acc;
777
- const isMatch = matchReference.vulnerabilities.map((vulnerability) => vulnerability[key]).includes(ref[key]);
778
- if (isMatch) {
779
- return {
780
- vulnerabilities: acc.vulnerabilities,
781
- summary: {
782
- ...acc.summary,
783
- [ref.severity]: acc.summary[ref.severity] - 1,
784
- total: acc.summary.total - 1
785
- }
786
- };
787
- }
788
- return {
789
- vulnerabilities: [...acc.vulnerabilities, ref],
790
- summary: acc.summary
791
- };
792
- },
793
- { vulnerabilities: [], summary: result.summary }
794
- );
795
- return {
796
- vulnerabilities: uniqueResult.vulnerabilities,
797
- summary: uniqueResult.summary
798
- };
799
- }
800
-
801
- // packages/plugin-js-packages/src/lib/package-managers/constants.ts
802
- var COMMON_AUDIT_ARGS = ["audit", "--json"];
803
- var COMMON_OUTDATED_ARGS = ["outdated", "--json"];
804
-
805
770
  // packages/utils/src/lib/text-formats/constants.ts
806
771
  var NEW_LINE = "\n";
807
772
  var TAB = " ";
@@ -1187,6 +1152,42 @@ var { details: details3 } = html;
1187
1152
  // packages/utils/src/lib/reports/log-stdout-summary.ts
1188
1153
  import chalk4 from "chalk";
1189
1154
 
1155
+ // packages/plugin-js-packages/src/lib/runner/utils.ts
1156
+ function filterAuditResult(result, key, referenceResult) {
1157
+ if (result.vulnerabilities.length === 0) {
1158
+ return result;
1159
+ }
1160
+ const uniqueResult = result.vulnerabilities.reduce(
1161
+ (acc, ref) => {
1162
+ const matchReference = referenceResult ?? acc;
1163
+ const isMatch = matchReference.vulnerabilities.map((vulnerability) => vulnerability[key]).includes(ref[key]);
1164
+ if (isMatch) {
1165
+ return {
1166
+ vulnerabilities: acc.vulnerabilities,
1167
+ summary: {
1168
+ ...acc.summary,
1169
+ [ref.severity]: acc.summary[ref.severity] - 1,
1170
+ total: acc.summary.total - 1
1171
+ }
1172
+ };
1173
+ }
1174
+ return {
1175
+ vulnerabilities: [...acc.vulnerabilities, ref],
1176
+ summary: acc.summary
1177
+ };
1178
+ },
1179
+ { vulnerabilities: [], summary: result.summary }
1180
+ );
1181
+ return {
1182
+ vulnerabilities: uniqueResult.vulnerabilities,
1183
+ summary: uniqueResult.summary
1184
+ };
1185
+ }
1186
+
1187
+ // packages/plugin-js-packages/src/lib/package-managers/constants.ts
1188
+ var COMMON_AUDIT_ARGS = ["audit", "--json"];
1189
+ var COMMON_OUTDATED_ARGS = ["outdated", "--json"];
1190
+
1190
1191
  // packages/plugin-js-packages/src/lib/package-managers/npm/audit-result.ts
1191
1192
  function npmToAuditResult(output) {
1192
1193
  const npmAudit = JSON.parse(output);
@@ -1283,11 +1284,16 @@ var npmPackageManager = {
1283
1284
  ],
1284
1285
  unifyResult: npmToAuditResult,
1285
1286
  // prod dependencies need to be filtered out manually since v10
1286
- postProcessResult: (results) => ({
1287
- prod: results.prod,
1288
- dev: filterAuditResult(results.dev, "name", results.prod),
1289
- optional: filterAuditResult(results.optional, "name", results.prod)
1290
- })
1287
+ postProcessResult: (results) => {
1288
+ const depGroups = objectToKeys(results);
1289
+ const devFilter = results.dev && results.prod ? filterAuditResult(results.dev, "name", results.prod) : results.dev;
1290
+ const optionalFilter = results.optional && results.prod ? filterAuditResult(results.optional, "name", results.prod) : results.optional;
1291
+ return {
1292
+ ...depGroups.includes("prod") && { prod: results.prod },
1293
+ ...depGroups.includes("dev") && { dev: devFilter },
1294
+ ...depGroups.includes("optional") && { optional: optionalFilter }
1295
+ };
1296
+ }
1291
1297
  },
1292
1298
  outdated: {
1293
1299
  commandArgs: [...COMMON_OUTDATED_ARGS, "--long"],
@@ -1380,15 +1386,16 @@ var pnpmPackageManager = {
1380
1386
  ignoreExitCode: true,
1381
1387
  unifyResult: pnpmToAuditResult,
1382
1388
  // optional dependencies don't have an exclusive option so they need duplicates filtered out
1383
- postProcessResult: (results) => ({
1384
- prod: results.prod,
1385
- dev: results.dev,
1386
- optional: filterAuditResult(
1387
- filterAuditResult(results.optional, "id", results.prod),
1388
- "id",
1389
- results.dev
1390
- )
1391
- })
1389
+ postProcessResult: (results) => {
1390
+ const depGroups = objectToKeys(results);
1391
+ const prodFilter = results.optional && results.prod ? filterAuditResult(results.optional, "id", results.prod) : results.optional;
1392
+ const devFilter = prodFilter && results.dev ? filterAuditResult(prodFilter, "id", results.dev) : results.optional;
1393
+ return {
1394
+ ...depGroups.includes("prod") && { prod: results.prod },
1395
+ ...depGroups.includes("dev") && { dev: results.dev },
1396
+ ...results.optional && { optional: devFilter }
1397
+ };
1398
+ }
1392
1399
  },
1393
1400
  outdated: {
1394
1401
  commandArgs: COMMON_OUTDATED_ARGS,
@@ -1669,6 +1676,7 @@ async function createRunnerConfig(scriptPath, config) {
1669
1676
  async function jsPackagesPlugin(config) {
1670
1677
  const jsPackagesPluginConfig = jsPackagesPluginConfigSchema.parse(config);
1671
1678
  const checks = [...new Set(jsPackagesPluginConfig.checks)];
1679
+ const depGroups = [...new Set(jsPackagesPluginConfig.dependencyGroups)];
1672
1680
  const id = jsPackagesPluginConfig.packageManager;
1673
1681
  const pm = packageManagers[id];
1674
1682
  const runnerScriptPath = join3(
@@ -1683,21 +1691,24 @@ async function jsPackagesPlugin(config) {
1683
1691
  docsUrl: pm.docs.homepage,
1684
1692
  packageName: name,
1685
1693
  version,
1686
- audits: createAudits(id, checks),
1687
- groups: createGroups(id, checks),
1694
+ audits: createAudits(id, checks, depGroups),
1695
+ groups: createGroups(id, checks, depGroups),
1688
1696
  runner: await createRunnerConfig(runnerScriptPath, jsPackagesPluginConfig)
1689
1697
  };
1690
1698
  }
1691
- function createGroups(id, checks) {
1699
+ function createGroups(id, checks, depGroups) {
1692
1700
  const pm = packageManagers[id];
1693
1701
  const supportedAuditDepGroups = pm.audit.supportedDepGroups ?? dependencyGroups;
1702
+ const compatibleAuditDepGroups = depGroups.filter(
1703
+ (group) => supportedAuditDepGroups.includes(group)
1704
+ );
1694
1705
  const groups = {
1695
1706
  audit: {
1696
1707
  slug: `${pm.slug}-audit`,
1697
1708
  title: `${pm.name} audit`,
1698
1709
  description: `Group containing ${pm.name} vulnerabilities.`,
1699
1710
  docsUrl: pm.docs.audit,
1700
- refs: supportedAuditDepGroups.map((depGroup) => ({
1711
+ refs: compatibleAuditDepGroups.map((depGroup) => ({
1701
1712
  slug: `${pm.slug}-audit-${depGroup}`,
1702
1713
  weight: dependencyGroupWeights[depGroup]
1703
1714
  }))
@@ -1707,7 +1718,7 @@ function createGroups(id, checks) {
1707
1718
  title: `${pm.name} outdated dependencies`,
1708
1719
  description: `Group containing outdated ${pm.name} dependencies.`,
1709
1720
  docsUrl: pm.docs.outdated,
1710
- refs: dependencyGroups.map((depGroup) => ({
1721
+ refs: depGroups.map((depGroup) => ({
1711
1722
  slug: `${pm.slug}-outdated-${depGroup}`,
1712
1723
  weight: dependencyGroupWeights[depGroup]
1713
1724
  }))
@@ -1715,11 +1726,12 @@ function createGroups(id, checks) {
1715
1726
  };
1716
1727
  return checks.map((check) => groups[check]);
1717
1728
  }
1718
- function createAudits(id, checks) {
1729
+ function createAudits(id, checks, depGroups) {
1719
1730
  const { slug } = packageManagers[id];
1720
1731
  return checks.flatMap((check) => {
1721
- const supportedDepGroups = check === "audit" ? packageManagers[id].audit.supportedDepGroups ?? dependencyGroups : dependencyGroups;
1722
- return supportedDepGroups.map((depGroup) => ({
1732
+ const supportedAuditDepGroups = packageManagers[id].audit.supportedDepGroups ?? dependencyGroups;
1733
+ const compatibleDepGroups = check === "audit" ? depGroups.filter((group) => supportedAuditDepGroups.includes(group)) : depGroups;
1734
+ return compatibleDepGroups.map((depGroup) => ({
1723
1735
  slug: `${slug}-${check}-${depGroup}`,
1724
1736
  title: getAuditTitle(slug, check, depGroup),
1725
1737
  description: getAuditDescription(check, depGroup),
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@code-pushup/js-packages-plugin",
3
- "version": "0.44.2",
3
+ "version": "0.44.4",
4
4
  "dependencies": {
5
- "@code-pushup/models": "0.44.2",
6
- "@code-pushup/utils": "0.44.2",
5
+ "@code-pushup/models": "0.44.4",
6
+ "@code-pushup/utils": "0.44.4",
7
7
  "semver": "^7.6.0",
8
8
  "zod": "^3.22.4"
9
9
  },
@@ -14,14 +14,17 @@ export declare function fillAuditLevelMapping(mapping: Partial<AuditSeverity>):
14
14
  export declare const jsPackagesPluginConfigSchema: z.ZodObject<{
15
15
  checks: z.ZodDefault<z.ZodArray<z.ZodEnum<["audit", "outdated"]>, "many">>;
16
16
  packageManager: z.ZodEnum<["npm", "yarn-classic", "yarn-modern", "pnpm"]>;
17
+ dependencyGroups: z.ZodDefault<z.ZodArray<z.ZodEnum<["prod", "dev", "optional"]>, "many">>;
17
18
  auditLevelMapping: z.ZodEffects<z.ZodDefault<z.ZodRecord<z.ZodEnum<["critical", "high", "moderate", "low", "info"]>, z.ZodEnum<["info", "warning", "error"]>>>, AuditSeverity, Partial<Record<"info" | "critical" | "high" | "moderate" | "low", "error" | "info" | "warning">> | undefined>;
18
19
  }, "strip", z.ZodTypeAny, {
19
20
  checks: ("audit" | "outdated")[];
20
21
  packageManager: "npm" | "pnpm" | "yarn-classic" | "yarn-modern";
22
+ dependencyGroups: ("prod" | "dev" | "optional")[];
21
23
  auditLevelMapping: AuditSeverity;
22
24
  }, {
23
25
  packageManager: "npm" | "pnpm" | "yarn-classic" | "yarn-modern";
24
26
  checks?: ("audit" | "outdated")[] | undefined;
27
+ dependencyGroups?: ("prod" | "dev" | "optional")[] | undefined;
25
28
  auditLevelMapping?: Partial<Record<"info" | "critical" | "high" | "moderate" | "low", "error" | "info" | "warning">> | undefined;
26
29
  }>;
27
30
  export type JSPackagesPluginConfig = z.input<typeof jsPackagesPluginConfigSchema>;
@@ -2,6 +2,7 @@ import type { MaterialIcon } from '@code-pushup/models';
2
2
  import { DependencyGroup, PackageManagerId } from '../config';
3
3
  import { AuditResult } from '../runner/audit/types';
4
4
  import { OutdatedResult } from '../runner/outdated/types';
5
+ export type AuditResults = Partial<Record<DependencyGroup, AuditResult>>;
5
6
  export type PackageManager = {
6
7
  slug: PackageManagerId;
7
8
  name: string;
@@ -17,7 +18,7 @@ export type PackageManager = {
17
18
  ignoreExitCode?: boolean;
18
19
  supportedDepGroups?: DependencyGroup[];
19
20
  unifyResult: (output: string) => AuditResult;
20
- postProcessResult?: (result: Record<DependencyGroup, AuditResult>) => Record<DependencyGroup, AuditResult>;
21
+ postProcessResult?: (result: AuditResults) => AuditResults;
21
22
  };
22
23
  outdated: {
23
24
  commandArgs: string[];