@code-pushup/js-packages-plugin 0.30.0-alpha → 0.35.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 (34) hide show
  1. package/CONTRIBUTING.md +15 -5
  2. package/bin.js +288 -131
  3. package/index.js +490 -94
  4. package/package.json +3 -3
  5. package/src/lib/config.d.ts +2 -2
  6. package/src/lib/constants.d.ts +3 -8
  7. package/src/lib/package-managers/constants.d.ts +2 -0
  8. package/src/lib/package-managers/index.d.ts +2 -0
  9. package/src/lib/{runner/audit/unify-type.d.ts → package-managers/npm/audit-result.d.ts} +2 -3
  10. package/src/lib/package-managers/npm/npm.d.ts +2 -0
  11. package/src/lib/package-managers/npm/outdated-result.d.ts +2 -0
  12. package/src/lib/package-managers/npm/types.d.ts +38 -0
  13. package/src/lib/package-managers/package-managers.d.ts +3 -0
  14. package/src/lib/package-managers/pnpm/audit-result.d.ts +3 -0
  15. package/src/lib/package-managers/pnpm/outdated-result.d.ts +2 -0
  16. package/src/lib/package-managers/pnpm/pnpm.d.ts +2 -0
  17. package/src/lib/package-managers/pnpm/types.d.ts +26 -0
  18. package/src/lib/package-managers/types.d.ts +26 -0
  19. package/src/lib/package-managers/yarn-classic/audit-result.d.ts +2 -0
  20. package/src/lib/package-managers/yarn-classic/outdated-result.d.ts +2 -0
  21. package/src/lib/package-managers/yarn-classic/types.d.ts +49 -0
  22. package/src/lib/package-managers/yarn-classic/yarn-classic.d.ts +2 -0
  23. package/src/lib/package-managers/yarn-modern/audit-result.d.ts +2 -0
  24. package/src/lib/package-managers/yarn-modern/outdated-result.d.ts +2 -0
  25. package/src/lib/package-managers/yarn-modern/types.d.ts +26 -0
  26. package/src/lib/package-managers/yarn-modern/yarn-modern.d.ts +2 -0
  27. package/src/lib/runner/audit/constants.d.ts +1 -4
  28. package/src/lib/runner/audit/transform.d.ts +2 -2
  29. package/src/lib/runner/audit/types.d.ts +0 -69
  30. package/src/lib/runner/audit/utils.d.ts +2 -0
  31. package/src/lib/runner/outdated/constants.d.ts +2 -5
  32. package/src/lib/runner/outdated/transform.d.ts +2 -2
  33. package/src/lib/runner/outdated/types.d.ts +0 -37
  34. package/src/lib/runner/outdated/unify-type.d.ts +0 -4
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.29.0";
7
+ var version = "0.35.0";
8
8
 
9
9
  // packages/plugin-js-packages/src/lib/config.ts
10
10
  import { z as z15 } from "zod";
@@ -663,35 +663,16 @@ var defaultAuditLevelMapping = {
663
663
  low: "warning",
664
664
  info: "info"
665
665
  };
666
- var pkgManagerNames = {
667
- npm: "NPM",
668
- "yarn-classic": "Yarn v1",
669
- "yarn-modern": "Yarn v2+",
670
- pnpm: "PNPM"
666
+ var dependencyGroupToLong = {
667
+ prod: "dependencies",
668
+ dev: "devDependencies",
669
+ optional: "optionalDependencies"
671
670
  };
672
- var pkgManagerIcons = {
673
- npm: "npm",
674
- "yarn-classic": "yarn",
675
- "yarn-modern": "yarn",
676
- pnpm: "pnpm"
677
- };
678
- var pkgManagerDocs = {
679
- npm: "https://docs.npmjs.com/",
680
- "yarn-classic": "https://classic.yarnpkg.com/docs/",
681
- "yarn-modern": "https://yarnpkg.com/getting-started",
682
- pnpm: "https://pnpm.io/pnpm-cli"
683
- };
684
- var auditDocs = {
685
- npm: "https://docs.npmjs.com/cli/commands/npm-audit",
686
- "yarn-classic": "https://classic.yarnpkg.com/docs/cli/audit",
687
- "yarn-modern": "https://yarnpkg.com/cli/npm/audit",
688
- pnpm: "https://pnpm.io/cli/audit/"
689
- };
690
- var outdatedDocs = {
691
- npm: "https://docs.npmjs.com/cli/commands/npm-outdated",
692
- "yarn-classic": "https://classic.yarnpkg.com/docs/cli/outdated/",
693
- "yarn-modern": "https://github.com/mskelton/yarn-plugin-outdated",
694
- pnpm: "https://pnpm.io/cli/outdated"
671
+ var dependencyGroupWeights = {
672
+ // eslint-disable-next-line no-magic-numbers
673
+ prod: 3,
674
+ dev: 1,
675
+ optional: 1
695
676
  };
696
677
  var dependencyDocs = {
697
678
  prod: "https://classic.yarnpkg.com/docs/dependency-types#toc-dependencies",
@@ -700,8 +681,9 @@ var dependencyDocs = {
700
681
  };
701
682
 
702
683
  // packages/plugin-js-packages/src/lib/config.ts
684
+ var dependencyGroups = ["prod", "dev", "optional"];
703
685
  var packageCommandSchema = z15.enum(["audit", "outdated"]);
704
- var packageManagerSchema = z15.enum([
686
+ var packageManagerIdSchema = z15.enum([
705
687
  "npm",
706
688
  "yarn-classic",
707
689
  "yarn-modern",
@@ -728,15 +710,49 @@ var jsPackagesPluginConfigSchema = z15.object({
728
710
  checks: z15.array(packageCommandSchema, {
729
711
  description: "Package manager commands to be run. Defaults to both audit and outdated."
730
712
  }).min(1).default(["audit", "outdated"]),
731
- packageManager: packageManagerSchema.describe("Package manager to be used."),
713
+ packageManager: packageManagerIdSchema.describe(
714
+ "Package manager to be used."
715
+ ),
732
716
  auditLevelMapping: z15.record(packageAuditLevelSchema, issueSeveritySchema, {
733
717
  description: "Mapping of audit levels to issue severity. Custom mapping or overrides may be entered manually, otherwise has a default preset."
734
718
  }).default(defaultAuditLevelMapping).transform(fillAuditLevelMapping)
735
719
  });
736
720
 
737
- // packages/plugin-js-packages/src/lib/runner/index.ts
738
- import { writeFile } from "node:fs/promises";
739
- import { dirname } from "node:path";
721
+ // packages/plugin-js-packages/src/lib/runner/utils.ts
722
+ function filterAuditResult(result, key, referenceResult) {
723
+ if (result.vulnerabilities.length === 0) {
724
+ return result;
725
+ }
726
+ const uniqueResult = result.vulnerabilities.reduce(
727
+ (acc, ref) => {
728
+ const matchReference = referenceResult ?? acc;
729
+ const isMatch = matchReference.vulnerabilities.map((vulnerability) => vulnerability[key]).includes(ref[key]);
730
+ if (isMatch) {
731
+ return {
732
+ vulnerabilities: acc.vulnerabilities,
733
+ summary: {
734
+ ...acc.summary,
735
+ [ref.severity]: acc.summary[ref.severity] - 1,
736
+ total: acc.summary.total - 1
737
+ }
738
+ };
739
+ }
740
+ return {
741
+ vulnerabilities: [...acc.vulnerabilities, ref],
742
+ summary: acc.summary
743
+ };
744
+ },
745
+ { vulnerabilities: [], summary: result.summary }
746
+ );
747
+ return {
748
+ vulnerabilities: uniqueResult.vulnerabilities,
749
+ summary: uniqueResult.summary
750
+ };
751
+ }
752
+
753
+ // packages/plugin-js-packages/src/lib/package-managers/constants.ts
754
+ var COMMON_AUDIT_ARGS = ["audit", "--json"];
755
+ var COMMON_OUTDATED_ARGS = ["outdated", "--json"];
740
756
 
741
757
  // packages/utils/src/lib/file-system.ts
742
758
  import { bundleRequire } from "bundle-require";
@@ -795,6 +811,19 @@ function pluginWorkDir(slug) {
795
811
  // packages/utils/src/lib/git.ts
796
812
  import { simpleGit } from "simple-git";
797
813
 
814
+ // packages/utils/src/lib/transform.ts
815
+ import { platform } from "node:os";
816
+ function objectToEntries(obj) {
817
+ return Object.entries(obj);
818
+ }
819
+ function toUnixNewlines(text) {
820
+ return platform() === "win32" ? text.replace(/\r\n/g, "\n") : text;
821
+ }
822
+ function fromJsonLines(jsonLines) {
823
+ const unifiedNewLines = toUnixNewlines(jsonLines).trim();
824
+ return JSON.parse(`[${unifiedNewLines.split("\n").join(",")}]`);
825
+ }
826
+
798
827
  // packages/utils/src/lib/progress.ts
799
828
  import chalk3 from "chalk";
800
829
  import { MultiProgressBars } from "multi-progress-bars";
@@ -802,6 +831,392 @@ import { MultiProgressBars } from "multi-progress-bars";
802
831
  // packages/utils/src/lib/reports/log-stdout-summary.ts
803
832
  import chalk4 from "chalk";
804
833
 
834
+ // packages/plugin-js-packages/src/lib/package-managers/npm/audit-result.ts
835
+ function npmToAuditResult(output) {
836
+ const npmAudit = JSON.parse(output);
837
+ const vulnerabilities = objectToEntries(npmAudit.vulnerabilities).map(
838
+ ([name2, detail]) => {
839
+ const advisory = npmToAdvisory(name2, npmAudit.vulnerabilities);
840
+ return {
841
+ name: name2.toString(),
842
+ severity: detail.severity,
843
+ versionRange: detail.range,
844
+ directDependency: detail.isDirect ? true : detail.effects[0] ?? "",
845
+ fixInformation: npmToFixInformation(detail.fixAvailable),
846
+ ...advisory != null && {
847
+ title: advisory.title,
848
+ url: advisory.url
849
+ }
850
+ };
851
+ }
852
+ );
853
+ return {
854
+ vulnerabilities,
855
+ summary: npmAudit.metadata.vulnerabilities
856
+ };
857
+ }
858
+ function npmToFixInformation(fixAvailable) {
859
+ if (typeof fixAvailable === "boolean") {
860
+ return fixAvailable ? "Fix is available." : "";
861
+ }
862
+ return `Fix available: Update \`${fixAvailable.name}\` to version **${fixAvailable.version}**${fixAvailable.isSemVerMajor ? " (breaking change)." : "."}`;
863
+ }
864
+ function npmToAdvisory(name2, vulnerabilities, prevNodes = /* @__PURE__ */ new Set()) {
865
+ const advisory = vulnerabilities[name2]?.via;
866
+ if (Array.isArray(advisory) && advisory.length > 0 && typeof advisory[0] === "object") {
867
+ return { title: advisory[0].title, url: advisory[0].url };
868
+ }
869
+ if (Array.isArray(advisory) && advisory.length > 0 && advisory.every((value) => typeof value === "string")) {
870
+ let advisoryInfo = null;
871
+ let newReferences = [];
872
+ let advisoryInfoFound = false;
873
+ for (const via of advisory) {
874
+ if (!prevNodes.has(via)) {
875
+ newReferences.push(via);
876
+ }
877
+ }
878
+ while (newReferences.length > 0 && !advisoryInfoFound) {
879
+ const ref = newReferences.pop();
880
+ prevNodes.add(ref);
881
+ const result = npmToAdvisory(ref, vulnerabilities, prevNodes);
882
+ if (result != null) {
883
+ advisoryInfo = { title: result.title, url: result.url };
884
+ advisoryInfoFound = true;
885
+ }
886
+ }
887
+ return advisoryInfo;
888
+ }
889
+ return null;
890
+ }
891
+
892
+ // packages/plugin-js-packages/src/lib/package-managers/npm/outdated-result.ts
893
+ function npmToOutdatedResult(output) {
894
+ const npmOutdated = JSON.parse(output);
895
+ return objectToEntries(npmOutdated).filter(
896
+ (entry) => entry[1].current != null
897
+ ).map(([name2, overview]) => ({
898
+ name: name2,
899
+ current: overview.current,
900
+ latest: overview.latest,
901
+ type: overview.type,
902
+ ...overview.homepage != null && { url: overview.homepage }
903
+ }));
904
+ }
905
+
906
+ // packages/plugin-js-packages/src/lib/package-managers/npm/npm.ts
907
+ var npmDependencyOptions = {
908
+ prod: ["--omit=dev", "--omit=optional"],
909
+ dev: ["--include=dev", "--omit=optional"],
910
+ optional: ["--include=optional", "--omit=dev"]
911
+ };
912
+ var npmPackageManager = {
913
+ slug: "npm",
914
+ name: "NPM",
915
+ command: "npm",
916
+ icon: "npm",
917
+ docs: {
918
+ homepage: "https://docs.npmjs.com/",
919
+ audit: "https://docs.npmjs.com/cli/commands/npm-audit",
920
+ outdated: "https://docs.npmjs.com/cli/commands/npm-outdated"
921
+ },
922
+ audit: {
923
+ getCommandArgs: (groupDep) => [
924
+ ...COMMON_AUDIT_ARGS,
925
+ ...npmDependencyOptions[groupDep],
926
+ "--audit-level=none"
927
+ ],
928
+ unifyResult: npmToAuditResult,
929
+ // prod dependencies need to be filtered out manually since v10
930
+ postProcessResult: (results) => ({
931
+ prod: results.prod,
932
+ dev: filterAuditResult(results.dev, "name", results.prod),
933
+ optional: filterAuditResult(results.optional, "name", results.prod)
934
+ })
935
+ },
936
+ outdated: {
937
+ commandArgs: [...COMMON_OUTDATED_ARGS, "--long"],
938
+ unifyResult: npmToOutdatedResult
939
+ }
940
+ };
941
+
942
+ // packages/plugin-js-packages/src/lib/runner/audit/utils.ts
943
+ function getVulnerabilitiesTotal(summary) {
944
+ return Object.values(summary).reduce((acc, value) => acc + value, 0);
945
+ }
946
+
947
+ // packages/plugin-js-packages/src/lib/package-managers/pnpm/audit-result.ts
948
+ function pnpmToAuditResult(output) {
949
+ const pnpmResult = JSON.parse(output);
950
+ const vulnerabilities = Object.values(pnpmResult.advisories).map(
951
+ ({
952
+ module_name: name2,
953
+ id,
954
+ title,
955
+ url,
956
+ severity,
957
+ vulnerable_versions: versionRange,
958
+ recommendation: fixInformation,
959
+ findings
960
+ }) => {
961
+ const path = findings[0]?.paths[0];
962
+ return {
963
+ name: name2,
964
+ id,
965
+ title,
966
+ url,
967
+ severity,
968
+ versionRange,
969
+ directDependency: path == null ? true : pnpmToDirectDependency(path),
970
+ fixInformation
971
+ };
972
+ }
973
+ );
974
+ return {
975
+ vulnerabilities,
976
+ summary: {
977
+ ...pnpmResult.metadata.vulnerabilities,
978
+ total: getVulnerabilitiesTotal(pnpmResult.metadata.vulnerabilities)
979
+ }
980
+ };
981
+ }
982
+ function pnpmToDirectDependency(path) {
983
+ const deps = path.split(" > ").slice(1);
984
+ if (deps.length <= 1) {
985
+ return true;
986
+ }
987
+ return deps[0]?.split("@")[0] ?? true;
988
+ }
989
+
990
+ // packages/plugin-js-packages/src/lib/package-managers/pnpm/outdated-result.ts
991
+ function pnpmToOutdatedResult(output) {
992
+ const pnpmOutdated = JSON.parse(output);
993
+ return objectToEntries(pnpmOutdated).map(
994
+ ([name2, { current, latest, dependencyType: type }]) => ({
995
+ name: name2,
996
+ current,
997
+ latest,
998
+ type
999
+ })
1000
+ );
1001
+ }
1002
+
1003
+ // packages/plugin-js-packages/src/lib/package-managers/pnpm/pnpm.ts
1004
+ var pnpmDependencyOptions = {
1005
+ prod: ["--prod", "--no-optional"],
1006
+ dev: ["--dev", "--no-optional"],
1007
+ optional: []
1008
+ };
1009
+ var pnpmPackageManager = {
1010
+ slug: "pnpm",
1011
+ name: "pnpm",
1012
+ command: "pnpm",
1013
+ icon: "pnpm",
1014
+ docs: {
1015
+ homepage: "https://pnpm.io/pnpm-cli",
1016
+ audit: "https://pnpm.io/cli/audit/",
1017
+ outdated: "https://pnpm.io/cli/outdated"
1018
+ },
1019
+ audit: {
1020
+ getCommandArgs: (groupDep) => [
1021
+ ...COMMON_AUDIT_ARGS,
1022
+ ...pnpmDependencyOptions[groupDep]
1023
+ ],
1024
+ ignoreExitCode: true,
1025
+ unifyResult: pnpmToAuditResult,
1026
+ // optional dependencies don't have an exclusive option so they need duplicates filtered out
1027
+ postProcessResult: (results) => ({
1028
+ prod: results.prod,
1029
+ dev: results.dev,
1030
+ optional: filterAuditResult(
1031
+ filterAuditResult(results.optional, "id", results.prod),
1032
+ "id",
1033
+ results.dev
1034
+ )
1035
+ })
1036
+ },
1037
+ outdated: {
1038
+ commandArgs: COMMON_OUTDATED_ARGS,
1039
+ unifyResult: pnpmToOutdatedResult
1040
+ }
1041
+ };
1042
+
1043
+ // packages/plugin-js-packages/src/lib/package-managers/yarn-classic/audit-result.ts
1044
+ function yarnv1ToAuditResult(output) {
1045
+ const yarnv1Result = fromJsonLines(output);
1046
+ const [yarnv1Advisory, yarnv1Summary] = validateYarnv1Result(yarnv1Result);
1047
+ const vulnerabilities = yarnv1Advisory.map(
1048
+ ({ data: { resolution, advisory } }) => {
1049
+ const { id, path } = resolution;
1050
+ const directDependency = path.slice(0, path.indexOf(">"));
1051
+ const {
1052
+ module_name: name2,
1053
+ title,
1054
+ url,
1055
+ severity,
1056
+ vulnerable_versions: versionRange,
1057
+ recommendation: fixInformation
1058
+ } = advisory;
1059
+ return {
1060
+ name: name2,
1061
+ title,
1062
+ id,
1063
+ url,
1064
+ severity,
1065
+ versionRange,
1066
+ directDependency: name2 === directDependency ? true : directDependency,
1067
+ fixInformation
1068
+ };
1069
+ }
1070
+ );
1071
+ const summary = {
1072
+ ...yarnv1Summary.data.vulnerabilities,
1073
+ total: Object.values(yarnv1Summary.data.vulnerabilities).reduce(
1074
+ (acc, amount) => acc + amount,
1075
+ 0
1076
+ )
1077
+ };
1078
+ return filterAuditResult({ vulnerabilities, summary }, "id");
1079
+ }
1080
+ function validateYarnv1Result(result) {
1081
+ const summary = result.at(-1);
1082
+ if (summary?.type !== "auditSummary") {
1083
+ throw new Error("Invalid Yarn v1 audit result - no summary found.");
1084
+ }
1085
+ const vulnerabilities = result.filter(
1086
+ (item) => item.type === "auditAdvisory"
1087
+ );
1088
+ return [vulnerabilities, summary];
1089
+ }
1090
+
1091
+ // packages/plugin-js-packages/src/lib/package-managers/yarn-classic/outdated-result.ts
1092
+ function yarnv1ToOutdatedResult(output) {
1093
+ const yarnv1Outdated = fromJsonLines(output);
1094
+ const dependencies = yarnv1Outdated[1].data.body;
1095
+ return dependencies.map(([name2, current, _, latest, __, type, url]) => ({
1096
+ name: name2,
1097
+ current,
1098
+ latest,
1099
+ type,
1100
+ url
1101
+ }));
1102
+ }
1103
+
1104
+ // packages/plugin-js-packages/src/lib/package-managers/yarn-classic/yarn-classic.ts
1105
+ var yarnv1PackageManager = {
1106
+ slug: "yarn-classic",
1107
+ name: "Yarn v1",
1108
+ command: "yarn",
1109
+ icon: "yarn",
1110
+ docs: {
1111
+ homepage: "https://classic.yarnpkg.com/docs/",
1112
+ audit: "https://classic.yarnpkg.com/docs/cli/audit",
1113
+ outdated: "https://classic.yarnpkg.com/docs/cli/outdated/"
1114
+ },
1115
+ audit: {
1116
+ getCommandArgs: (groupDep) => [
1117
+ ...COMMON_AUDIT_ARGS,
1118
+ "--groups",
1119
+ dependencyGroupToLong[groupDep]
1120
+ ],
1121
+ ignoreExitCode: true,
1122
+ unifyResult: yarnv1ToAuditResult
1123
+ },
1124
+ outdated: {
1125
+ commandArgs: COMMON_OUTDATED_ARGS,
1126
+ unifyResult: yarnv1ToOutdatedResult
1127
+ }
1128
+ };
1129
+
1130
+ // packages/plugin-js-packages/src/lib/package-managers/yarn-modern/audit-result.ts
1131
+ function yarnv2ToAuditResult(output) {
1132
+ const yarnv2Audit = JSON.parse(output);
1133
+ const vulnerabilities = Object.values(yarnv2Audit.advisories).map(
1134
+ ({
1135
+ module_name: name2,
1136
+ severity,
1137
+ title,
1138
+ url,
1139
+ vulnerable_versions: versionRange,
1140
+ recommendation: fixInformation,
1141
+ findings
1142
+ }) => {
1143
+ const directDep = findings[0]?.paths[0];
1144
+ return {
1145
+ name: name2,
1146
+ severity,
1147
+ title,
1148
+ url,
1149
+ versionRange,
1150
+ fixInformation,
1151
+ directDependency: directDep != null && directDep !== name2 ? directDep : true
1152
+ };
1153
+ }
1154
+ );
1155
+ return {
1156
+ vulnerabilities,
1157
+ summary: {
1158
+ ...yarnv2Audit.metadata.vulnerabilities,
1159
+ total: getVulnerabilitiesTotal(yarnv2Audit.metadata.vulnerabilities)
1160
+ }
1161
+ };
1162
+ }
1163
+
1164
+ // packages/plugin-js-packages/src/lib/package-managers/yarn-modern/outdated-result.ts
1165
+ function yarnv2ToOutdatedResult(output) {
1166
+ const npmOutdated = JSON.parse(output);
1167
+ return npmOutdated.map(({ name: name2, current, latest, type }) => ({
1168
+ name: name2,
1169
+ current,
1170
+ latest,
1171
+ type
1172
+ }));
1173
+ }
1174
+
1175
+ // packages/plugin-js-packages/src/lib/package-managers/yarn-modern/yarn-modern.ts
1176
+ var yarnv2EnvironmentOptions = {
1177
+ prod: "production",
1178
+ dev: "development",
1179
+ optional: ""
1180
+ };
1181
+ var yarnv2PackageManager = {
1182
+ slug: "yarn-modern",
1183
+ name: "yarn-modern",
1184
+ command: "yarn",
1185
+ icon: "yarn",
1186
+ docs: {
1187
+ homepage: "https://yarnpkg.com/getting-started",
1188
+ audit: "https://yarnpkg.com/cli/npm/audit",
1189
+ outdated: "https://github.com/mskelton/yarn-plugin-outdated"
1190
+ },
1191
+ audit: {
1192
+ getCommandArgs: (groupDep) => [
1193
+ "npm",
1194
+ ...COMMON_AUDIT_ARGS,
1195
+ "--environment",
1196
+ yarnv2EnvironmentOptions[groupDep]
1197
+ ],
1198
+ supportedDepGroups: ["prod", "dev"],
1199
+ // Yarn v2 does not support audit for optional dependencies
1200
+ unifyResult: yarnv2ToAuditResult
1201
+ },
1202
+ outdated: {
1203
+ commandArgs: COMMON_OUTDATED_ARGS,
1204
+ unifyResult: yarnv2ToOutdatedResult
1205
+ }
1206
+ };
1207
+
1208
+ // packages/plugin-js-packages/src/lib/package-managers/package-managers.ts
1209
+ var packageManagers = {
1210
+ npm: npmPackageManager,
1211
+ "yarn-classic": yarnv1PackageManager,
1212
+ "yarn-modern": yarnv2PackageManager,
1213
+ pnpm: pnpmPackageManager
1214
+ };
1215
+
1216
+ // packages/plugin-js-packages/src/lib/runner/index.ts
1217
+ import { writeFile } from "node:fs/promises";
1218
+ import { dirname } from "node:path";
1219
+
805
1220
  // packages/plugin-js-packages/src/lib/runner/constants.ts
806
1221
  import { join as join2 } from "node:path";
807
1222
  var WORKDIR = pluginWorkDir("js-packages");
@@ -826,8 +1241,9 @@ async function createRunnerConfig(scriptPath, config) {
826
1241
  // packages/plugin-js-packages/src/lib/js-packages-plugin.ts
827
1242
  async function jsPackagesPlugin(config) {
828
1243
  const jsPackagesPluginConfig = jsPackagesPluginConfigSchema.parse(config);
829
- const pkgManager = jsPackagesPluginConfig.packageManager;
830
1244
  const checks = [...new Set(jsPackagesPluginConfig.checks)];
1245
+ const id = jsPackagesPluginConfig.packageManager;
1246
+ const pm = packageManagers[id];
831
1247
  const runnerScriptPath = join3(
832
1248
  fileURLToPath(dirname2(import.meta.url)),
833
1249
  "bin.js"
@@ -835,81 +1251,61 @@ async function jsPackagesPlugin(config) {
835
1251
  return {
836
1252
  slug: "js-packages",
837
1253
  title: "JS Packages",
838
- icon: pkgManagerIcons[pkgManager],
1254
+ icon: pm.icon,
839
1255
  description: "This plugin runs audit to uncover vulnerabilities and lists outdated dependencies. It supports npm, yarn classic, yarn modern, and pnpm package managers.",
840
- docsUrl: pkgManagerDocs[pkgManager],
1256
+ docsUrl: pm.docs.homepage,
841
1257
  packageName: name,
842
1258
  version,
843
- audits: createAudits(pkgManager, checks),
844
- groups: createGroups(pkgManager, checks),
1259
+ audits: createAudits(id, checks),
1260
+ groups: createGroups(id, checks),
845
1261
  runner: await createRunnerConfig(runnerScriptPath, jsPackagesPluginConfig)
846
1262
  };
847
1263
  }
848
- function createGroups(pkgManager, checks) {
1264
+ function createGroups(id, checks) {
1265
+ const pm = packageManagers[id];
1266
+ const supportedAuditDepGroups = pm.audit.supportedDepGroups ?? dependencyGroups;
849
1267
  const groups = {
850
1268
  audit: {
851
- slug: `${pkgManager}-audit`,
852
- title: `${pkgManagerNames[pkgManager]} audit`,
853
- description: `Group containing ${pkgManagerNames[pkgManager]} vulnerabilities.`,
854
- docsUrl: auditDocs[pkgManager],
855
- refs: [
856
- // eslint-disable-next-line no-magic-numbers
857
- { slug: `${pkgManager}-audit-prod`, weight: 3 },
858
- { slug: `${pkgManager}-audit-dev`, weight: 1 },
859
- // Yarn v2 does not support audit for optional dependencies
860
- ...pkgManager === "yarn-modern" ? [] : [
861
- {
862
- slug: `${pkgManager}-audit-optional`,
863
- weight: 1
864
- }
865
- ]
866
- ]
1269
+ slug: `${pm.slug}-audit`,
1270
+ title: `${pm.name} audit`,
1271
+ description: `Group containing ${pm.name} vulnerabilities.`,
1272
+ docsUrl: pm.docs.audit,
1273
+ refs: supportedAuditDepGroups.map((depGroup) => ({
1274
+ slug: `${pm.slug}-audit-${depGroup}`,
1275
+ weight: dependencyGroupWeights[depGroup]
1276
+ }))
867
1277
  },
868
1278
  outdated: {
869
- slug: `${pkgManager}-outdated`,
870
- title: `${pkgManagerNames[pkgManager]} outdated dependencies`,
871
- description: `Group containing outdated ${pkgManagerNames[pkgManager]} dependencies.`,
872
- docsUrl: outdatedDocs[pkgManager],
873
- refs: [
874
- // eslint-disable-next-line no-magic-numbers
875
- { slug: `${pkgManager}-outdated-prod`, weight: 3 },
876
- { slug: `${pkgManager}-outdated-dev`, weight: 1 },
877
- { slug: `${pkgManager}-outdated-optional`, weight: 1 }
878
- ]
1279
+ slug: `${pm.slug}-outdated`,
1280
+ title: `${pm.name} outdated dependencies`,
1281
+ description: `Group containing outdated ${pm.name} dependencies.`,
1282
+ docsUrl: pm.docs.outdated,
1283
+ refs: dependencyGroups.map((depGroup) => ({
1284
+ slug: `${pm.slug}-outdated-${depGroup}`,
1285
+ weight: dependencyGroupWeights[depGroup]
1286
+ }))
879
1287
  }
880
1288
  };
881
1289
  return checks.map((check) => groups[check]);
882
1290
  }
883
- function createAudits(pkgManager, checks) {
884
- return checks.flatMap((check) => [
885
- {
886
- slug: `${pkgManager}-${check}-prod`,
887
- title: getAuditTitle(pkgManager, check, "prod"),
888
- description: getAuditDescription(check, "prod"),
889
- docsUrl: dependencyDocs.prod
890
- },
891
- {
892
- slug: `${pkgManager}-${check}-dev`,
893
- title: getAuditTitle(pkgManager, check, "dev"),
894
- description: getAuditDescription(check, "dev"),
895
- docsUrl: dependencyDocs.dev
896
- },
897
- // Yarn v2 does not support audit for optional dependencies
898
- ...pkgManager === "yarn-modern" && check === "audit" ? [] : [
899
- {
900
- slug: `${pkgManager}-${check}-optional`,
901
- title: getAuditTitle(pkgManager, check, "optional"),
902
- description: getAuditDescription(check, "optional"),
903
- docsUrl: dependencyDocs.optional
904
- }
905
- ]
906
- ]);
1291
+ function createAudits(id, checks) {
1292
+ const { slug } = packageManagers[id];
1293
+ return checks.flatMap((check) => {
1294
+ const supportedDepGroups = check === "audit" ? packageManagers[id].audit.supportedDepGroups ?? dependencyGroups : dependencyGroups;
1295
+ return supportedDepGroups.map((depGroup) => ({
1296
+ slug: `${slug}-${check}-${depGroup}`,
1297
+ title: getAuditTitle(slug, check, depGroup),
1298
+ description: getAuditDescription(check, depGroup),
1299
+ docsUrl: dependencyDocs[depGroup]
1300
+ }));
1301
+ });
907
1302
  }
908
- function getAuditTitle(pkgManager, check, dependencyType) {
909
- return check === "audit" ? `Vulnerabilities for ${pkgManagerNames[pkgManager]} ${dependencyType} dependencies.` : `Outdated ${pkgManagerNames[pkgManager]} ${dependencyType} dependencies.`;
1303
+ function getAuditTitle(id, check, depGroup) {
1304
+ const pm = packageManagers[id];
1305
+ return check === "audit" ? `Vulnerabilities for ${pm.name} ${depGroup} dependencies.` : `Outdated ${pm.name} ${depGroup} dependencies.`;
910
1306
  }
911
- function getAuditDescription(check, dependencyType) {
912
- return check === "audit" ? `Runs security audit on ${dependencyType} dependencies.` : `Checks for outdated ${dependencyType} dependencies`;
1307
+ function getAuditDescription(check, depGroup) {
1308
+ return check === "audit" ? `Runs security audit on ${depGroup} dependencies.` : `Checks for outdated ${depGroup} dependencies`;
913
1309
  }
914
1310
 
915
1311
  // packages/plugin-js-packages/src/index.ts
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@code-pushup/js-packages-plugin",
3
- "version": "0.30.0-alpha",
3
+ "version": "0.35.0",
4
4
  "dependencies": {
5
- "@code-pushup/models": "*",
6
- "@code-pushup/utils": "*",
5
+ "@code-pushup/models": "0.35.0",
6
+ "@code-pushup/utils": "0.35.0",
7
7
  "zod": "^3.22.4"
8
8
  },
9
9
  "license": "MIT",
@@ -4,8 +4,8 @@ export declare const dependencyGroups: readonly ["prod", "dev", "optional"];
4
4
  export type DependencyGroup = (typeof dependencyGroups)[number];
5
5
  declare const packageCommandSchema: z.ZodEnum<["audit", "outdated"]>;
6
6
  export type PackageCommand = z.infer<typeof packageCommandSchema>;
7
- declare const packageManagerSchema: z.ZodEnum<["npm", "yarn-classic", "yarn-modern", "pnpm"]>;
8
- export type PackageManager = z.infer<typeof packageManagerSchema>;
7
+ declare const packageManagerIdSchema: z.ZodEnum<["npm", "yarn-classic", "yarn-modern", "pnpm"]>;
8
+ export type PackageManagerId = z.infer<typeof packageManagerIdSchema>;
9
9
  export declare const packageAuditLevels: readonly ["critical", "high", "moderate", "low", "info"];
10
10
  declare const packageAuditLevelSchema: z.ZodEnum<["critical", "high", "moderate", "low", "info"]>;
11
11
  export type PackageAuditLevel = z.infer<typeof packageAuditLevelSchema>;