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