@code-pushup/js-packages-plugin 0.48.0 → 0.50.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/README.md +2 -2
  2. package/bin.js +104 -379
  3. package/index.js +200 -330
  4. package/package.json +6 -31
  5. package/src/lib/config.d.ts +5 -5
  6. package/src/lib/constants.d.ts +2 -2
  7. package/src/lib/js-packages-plugin.d.ts +2 -2
  8. package/src/lib/package-managers/derive-package-manager.d.ts +3 -0
  9. package/src/lib/package-managers/derive-yarn.d.ts +1 -0
  10. package/src/lib/package-managers/index.d.ts +1 -1
  11. package/src/lib/package-managers/npm/audit-result.d.ts +2 -2
  12. package/src/lib/package-managers/npm/npm.d.ts +1 -1
  13. package/src/lib/package-managers/npm/outdated-result.d.ts +1 -1
  14. package/src/lib/package-managers/npm/types.d.ts +3 -3
  15. package/src/lib/package-managers/package-managers.d.ts +2 -2
  16. package/src/lib/package-managers/pnpm/audit-result.d.ts +1 -1
  17. package/src/lib/package-managers/pnpm/outdated-result.d.ts +1 -1
  18. package/src/lib/package-managers/pnpm/pnpm.d.ts +1 -1
  19. package/src/lib/package-managers/pnpm/types.d.ts +2 -2
  20. package/src/lib/package-managers/types.d.ts +3 -3
  21. package/src/lib/package-managers/yarn-classic/audit-result.d.ts +1 -1
  22. package/src/lib/package-managers/yarn-classic/constants.d.ts +2 -2
  23. package/src/lib/package-managers/yarn-classic/outdated-result.d.ts +1 -1
  24. package/src/lib/package-managers/yarn-classic/types.d.ts +1 -1
  25. package/src/lib/package-managers/yarn-classic/yarn-classic.d.ts +1 -1
  26. package/src/lib/package-managers/yarn-modern/audit-result.d.ts +1 -1
  27. package/src/lib/package-managers/yarn-modern/outdated-result.d.ts +1 -1
  28. package/src/lib/package-managers/yarn-modern/types.d.ts +2 -2
  29. package/src/lib/package-managers/yarn-modern/yarn-modern.d.ts +1 -1
  30. package/src/lib/runner/audit/constants.d.ts +1 -1
  31. package/src/lib/runner/audit/transform.d.ts +2 -2
  32. package/src/lib/runner/audit/utils.d.ts +1 -1
  33. package/src/lib/runner/index.d.ts +1 -1
  34. package/src/lib/runner/outdated/transform.d.ts +3 -3
  35. package/src/lib/runner/utils.d.ts +2 -2
  36. package/src/lib/utils.d.ts +10 -0
package/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // packages/plugin-js-packages/src/lib/js-packages-plugin.ts
2
- import { dirname as dirname2, join as join3 } from "node:path";
2
+ import { dirname as dirname2, join as join4 } from "node:path";
3
3
  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.48.0";
7
+ var version = "0.50.0";
8
8
 
9
9
  // packages/plugin-js-packages/src/lib/config.ts
10
10
  import { z as z16 } from "zod";
@@ -677,6 +677,8 @@ var auditResultSchema = scorableWithPluginMetaSchema.merge(
677
677
  );
678
678
  var reportsDiffSchema = z15.object({
679
679
  commits: makeComparisonSchema(commitSchema).nullable().describe("Commits identifying compared reports"),
680
+ portalUrl: urlSchema.optional().describe("Link to comparison page in Code PushUp portal"),
681
+ label: z15.string().optional().describe("Label (e.g. project name)"),
680
682
  categories: makeArraysComparisonSchema(
681
683
  categoryDiffSchema,
682
684
  categoryResultSchema,
@@ -765,9 +767,7 @@ var jsPackagesPluginConfigSchema = z16.object({
765
767
  checks: z16.array(packageCommandSchema, {
766
768
  description: "Package manager commands to be run. Defaults to both audit and outdated."
767
769
  }).min(1).default(["audit", "outdated"]),
768
- packageManager: packageManagerIdSchema.describe(
769
- "Package manager to be used."
770
- ),
770
+ packageManager: packageManagerIdSchema.describe("Package manager to be used.").optional(),
771
771
  dependencyGroups: z16.array(dependencyGroupSchema).min(1).default(["prod", "dev"]),
772
772
  auditLevelMapping: z16.record(packageAuditLevelSchema, issueSeveritySchema, {
773
773
  description: "Mapping of audit levels to issue severity. Custom mapping or overrides may be entered manually, otherwise has a default preset."
@@ -775,21 +775,82 @@ var jsPackagesPluginConfigSchema = z16.object({
775
775
  packageJsonPaths: packageJsonPathSchema
776
776
  });
777
777
 
778
+ // packages/utils/src/lib/execute-process.ts
779
+ import {
780
+ spawn
781
+ } from "node:child_process";
782
+
783
+ // packages/utils/src/lib/reports/utils.ts
784
+ import ansis from "ansis";
785
+ import { md } from "build-md";
786
+
787
+ // packages/utils/src/lib/reports/constants.ts
788
+ var TERMINAL_WIDTH = 80;
789
+
790
+ // packages/utils/src/lib/reports/utils.ts
791
+ function calcDuration(start, stop) {
792
+ return Math.round((stop ?? performance.now()) - start);
793
+ }
794
+
795
+ // packages/utils/src/lib/execute-process.ts
796
+ var ProcessError = class extends Error {
797
+ code;
798
+ stderr;
799
+ stdout;
800
+ constructor(result) {
801
+ super(result.stderr);
802
+ this.code = result.code;
803
+ this.stderr = result.stderr;
804
+ this.stdout = result.stdout;
805
+ }
806
+ };
807
+ function executeProcess(cfg) {
808
+ const { command, args, observer, ignoreExitCode = false, ...options } = cfg;
809
+ const { onStdout, onStderr, onError, onComplete } = observer ?? {};
810
+ const date = (/* @__PURE__ */ new Date()).toISOString();
811
+ const start = performance.now();
812
+ return new Promise((resolve, reject) => {
813
+ const spawnedProcess = spawn(command, args ?? [], {
814
+ shell: true,
815
+ ...options
816
+ });
817
+ let stdout = "";
818
+ let stderr = "";
819
+ spawnedProcess.stdout.on("data", (data) => {
820
+ stdout += String(data);
821
+ onStdout?.(String(data), spawnedProcess);
822
+ });
823
+ spawnedProcess.stderr.on("data", (data) => {
824
+ stderr += String(data);
825
+ onStderr?.(String(data), spawnedProcess);
826
+ });
827
+ spawnedProcess.on("error", (err) => {
828
+ stderr += err.toString();
829
+ });
830
+ spawnedProcess.on("close", (code2) => {
831
+ const timings = { date, duration: calcDuration(start) };
832
+ if (code2 === 0 || ignoreExitCode) {
833
+ onComplete?.();
834
+ resolve({ code: code2, stdout, stderr, ...timings });
835
+ } else {
836
+ const errorMsg = new ProcessError({ code: code2, stdout, stderr, ...timings });
837
+ onError?.(errorMsg);
838
+ reject(errorMsg);
839
+ }
840
+ });
841
+ });
842
+ }
843
+
778
844
  // packages/utils/src/lib/file-system.ts
845
+ import { bold, gray } from "ansis";
779
846
  import { bundleRequire } from "bundle-require";
780
- import chalk2 from "chalk";
781
847
  import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
782
848
  import { join } from "node:path";
783
849
 
784
850
  // packages/utils/src/lib/logging.ts
785
851
  import isaacs_cliui from "@isaacs/cliui";
786
852
  import { cliui } from "@poppinss/cliui";
787
- import chalk from "chalk";
788
-
789
- // packages/utils/src/lib/reports/constants.ts
790
- var TERMINAL_WIDTH = 80;
791
-
792
- // packages/utils/src/lib/logging.ts
853
+ import { underline } from "ansis";
793
854
  var singletonUiInstance;
794
855
  function ui() {
795
856
  if (singletonUiInstance === void 0) {
@@ -814,6 +875,14 @@ function logListItem(args) {
814
875
  }
815
876
 
816
877
  // packages/utils/src/lib/file-system.ts
878
+ async function fileExists(path) {
879
+ try {
880
+ const stats = await stat(path);
881
+ return stats.isFile();
882
+ } catch {
883
+ return false;
884
+ }
885
+ }
817
886
  async function ensureDirectoryExists(baseDir) {
818
887
  try {
819
888
  await mkdir(baseDir, { recursive: true });
@@ -832,37 +901,8 @@ function filePathToCliArg(path) {
832
901
  return `"${path}"`;
833
902
  }
834
903
 
835
- // packages/utils/src/lib/text-formats/constants.ts
836
- var NEW_LINE = "\n";
837
- var TAB = " ";
838
-
839
- // packages/utils/src/lib/text-formats/html/details.ts
840
- function details(title, content, cfg = { open: false }) {
841
- return `<details${cfg.open ? " open" : ""}>${NEW_LINE}<summary>${title}</summary>${NEW_LINE}${// ⚠️ The blank line is needed to ensure Markdown in content is rendered correctly.
842
- NEW_LINE}${content}${NEW_LINE}${// @TODO in the future we could consider adding it only if the content ends with a code block
843
- // ⚠️ The blank line ensure Markdown in content is rendered correctly.
844
- NEW_LINE}</details>${// ⚠️ The blank line is needed to ensure Markdown after details is rendered correctly.
845
- NEW_LINE}`;
846
- }
847
-
848
- // packages/utils/src/lib/text-formats/html/font-style.ts
849
- var boldElement = "b";
850
- function bold(text) {
851
- return `<${boldElement}>${text}</${boldElement}>`;
852
- }
853
- var italicElement = "i";
854
- function italic(text) {
855
- return `<${italicElement}>${text}</${italicElement}>`;
856
- }
857
- var codeElement = "code";
858
- function code(text) {
859
- return `<${codeElement}>${text}</${codeElement}>`;
860
- }
861
-
862
- // packages/utils/src/lib/text-formats/html/link.ts
863
- function link(href, text) {
864
- return `<a href="${href}">${text || href}</a>`;
865
- }
904
+ // packages/utils/src/lib/git/git.ts
905
+ import { simpleGit } from "simple-git";
866
906
 
867
907
  // packages/utils/src/lib/transform.ts
868
908
  import { platform } from "node:os";
@@ -882,263 +922,6 @@ function fromJsonLines(jsonLines) {
882
922
  const unifiedNewLines = toUnixNewlines(jsonLines).trim();
883
923
  return JSON.parse(`[${unifiedNewLines.split("\n").join(",")}]`);
884
924
  }
885
- function capitalize(text) {
886
- return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
887
- 1
888
- )}`;
889
- }
890
-
891
- // packages/utils/src/lib/text-formats/table.ts
892
- function rowToStringArray({ rows, columns = [] }) {
893
- if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
894
- throw new TypeError(
895
- "Column can`t be object when rows are primitive values"
896
- );
897
- }
898
- return rows.map((row) => {
899
- if (Array.isArray(row)) {
900
- return row.map(String);
901
- }
902
- const objectRow = row;
903
- if (columns.length === 0 || typeof columns.at(0) === "string") {
904
- return Object.values(objectRow).map(
905
- (value) => value == null ? "" : String(value)
906
- );
907
- }
908
- return columns.map(
909
- ({ key }) => objectRow[key] == null ? "" : String(objectRow[key])
910
- );
911
- });
912
- }
913
- function columnsToStringArray({
914
- rows,
915
- columns = []
916
- }) {
917
- const firstRow = rows.at(0);
918
- const primitiveRows = Array.isArray(firstRow);
919
- if (typeof columns.at(0) === "string" && !primitiveRows) {
920
- throw new Error("invalid union type. Caught by model parsing.");
921
- }
922
- if (columns.length === 0) {
923
- if (Array.isArray(firstRow)) {
924
- return firstRow.map((_, idx) => String(idx));
925
- }
926
- return Object.keys(firstRow);
927
- }
928
- if (typeof columns.at(0) === "string") {
929
- return columns.map(String);
930
- }
931
- const cols = columns;
932
- return cols.map(({ label, key }) => label ?? capitalize(key));
933
- }
934
- function getColumnAlignmentForKeyAndIndex(targetKey, targetIdx, columns = []) {
935
- const column = columns.at(targetIdx) ?? columns.find((col) => col.key === targetKey);
936
- if (typeof column === "string") {
937
- return column;
938
- } else if (typeof column === "object") {
939
- return column.align ?? "center";
940
- } else {
941
- return "center";
942
- }
943
- }
944
- function getColumnAlignmentForIndex(targetIdx, columns = []) {
945
- const column = columns.at(targetIdx);
946
- if (column == null) {
947
- return "center";
948
- } else if (typeof column === "string") {
949
- return column;
950
- } else if (typeof column === "object") {
951
- return column.align ?? "center";
952
- } else {
953
- return "center";
954
- }
955
- }
956
- function getColumnAlignments(tableData) {
957
- const { rows, columns = [] } = tableData;
958
- if (rows.at(0) == null) {
959
- throw new Error("first row can`t be undefined.");
960
- }
961
- if (Array.isArray(rows.at(0))) {
962
- const firstPrimitiveRow = rows.at(0);
963
- return Array.from({ length: firstPrimitiveRow.length }).map(
964
- (_, idx) => getColumnAlignmentForIndex(idx, columns)
965
- );
966
- }
967
- const biggestRow = [...rows].sort((a, b) => Object.keys(a).length - Object.keys(b).length).at(-1);
968
- if (columns.length > 0) {
969
- return columns.map(
970
- (column, idx) => typeof column === "string" ? column : getColumnAlignmentForKeyAndIndex(
971
- column.key,
972
- idx,
973
- columns
974
- )
975
- );
976
- }
977
- return Object.keys(biggestRow ?? {}).map((_) => "center");
978
- }
979
-
980
- // packages/utils/src/lib/text-formats/html/table.ts
981
- function wrap(elem, content) {
982
- return `<${elem}>${content}</${elem}>${NEW_LINE}`;
983
- }
984
- function wrapRow(content) {
985
- const elem = "tr";
986
- return `<${elem}>${NEW_LINE}${content}</${elem}>${NEW_LINE}`;
987
- }
988
- function table(tableData) {
989
- if (tableData.rows.length === 0) {
990
- throw new Error("Data can't be empty");
991
- }
992
- const tableHeaderCols = columnsToStringArray(tableData).map((s) => wrap("th", s)).join("");
993
- const tableHeaderRow = wrapRow(tableHeaderCols);
994
- const tableBody = rowToStringArray(tableData).map((arr) => {
995
- const columns = arr.map((s) => wrap("td", s)).join("");
996
- return wrapRow(columns);
997
- }).join("");
998
- return wrap("table", `${NEW_LINE}${tableHeaderRow}${tableBody}`);
999
- }
1000
-
1001
- // packages/utils/src/lib/text-formats/md/font-style.ts
1002
- var boldWrap = "**";
1003
- function bold2(text) {
1004
- return `${boldWrap}${text}${boldWrap}`;
1005
- }
1006
- var italicWrap = "_";
1007
- function italic2(text) {
1008
- return `${italicWrap}${text}${italicWrap}`;
1009
- }
1010
- var strikeThroughWrap = "~";
1011
- function strikeThrough(text) {
1012
- return `${strikeThroughWrap}${text}${strikeThroughWrap}`;
1013
- }
1014
- var codeWrap = "`";
1015
- function code2(text) {
1016
- return `${codeWrap}${text}${codeWrap}`;
1017
- }
1018
-
1019
- // packages/utils/src/lib/text-formats/md/headline.ts
1020
- function headline(text, hierarchy = 1) {
1021
- return `${"#".repeat(hierarchy)} ${text}${NEW_LINE}`;
1022
- }
1023
- function h(text, hierarchy = 1) {
1024
- return headline(text, hierarchy);
1025
- }
1026
- function h1(text) {
1027
- return headline(text, 1);
1028
- }
1029
- function h2(text) {
1030
- return headline(text, 2);
1031
- }
1032
- function h3(text) {
1033
- return headline(text, 3);
1034
- }
1035
- function h4(text) {
1036
- return headline(text, 4);
1037
- }
1038
- function h5(text) {
1039
- return headline(text, 5);
1040
- }
1041
- function h6(text) {
1042
- return headline(text, 6);
1043
- }
1044
-
1045
- // packages/utils/src/lib/text-formats/md/image.ts
1046
- function image(src, alt) {
1047
- return `![${alt}](${src})`;
1048
- }
1049
-
1050
- // packages/utils/src/lib/text-formats/md/link.ts
1051
- function link2(href, text) {
1052
- return `[${text || href}](${href})`;
1053
- }
1054
-
1055
- // packages/utils/src/lib/text-formats/md/list.ts
1056
- function li(text, order = "unordered") {
1057
- const style = order === "unordered" ? "-" : "- [ ]";
1058
- return `${style} ${text}`;
1059
- }
1060
- function indentation(text, level = 1) {
1061
- return `${TAB.repeat(level)}${text}`;
1062
- }
1063
-
1064
- // packages/utils/src/lib/text-formats/md/paragraphs.ts
1065
- function paragraphs(...sections) {
1066
- return sections.filter(Boolean).join(`${NEW_LINE}${NEW_LINE}`);
1067
- }
1068
-
1069
- // packages/utils/src/lib/text-formats/md/section.ts
1070
- function section(...contents) {
1071
- return `${lines(...contents)}${NEW_LINE}`;
1072
- }
1073
- function lines(...contents) {
1074
- const filteredContent = contents.filter(
1075
- (value) => value != null && value !== "" && value !== false
1076
- );
1077
- return `${filteredContent.join(NEW_LINE)}`;
1078
- }
1079
-
1080
- // packages/utils/src/lib/text-formats/md/table.ts
1081
- var alignString = /* @__PURE__ */ new Map([
1082
- ["left", ":--"],
1083
- ["center", ":--:"],
1084
- ["right", "--:"]
1085
- ]);
1086
- function tableRow(rows) {
1087
- return `|${rows.join("|")}|`;
1088
- }
1089
- function table2(data) {
1090
- if (data.rows.length === 0) {
1091
- throw new Error("Data can't be empty");
1092
- }
1093
- const alignmentRow = getColumnAlignments(data).map(
1094
- (s) => alignString.get(s) ?? String(alignString.get("center"))
1095
- );
1096
- return section(
1097
- `${lines(
1098
- tableRow(columnsToStringArray(data)),
1099
- tableRow(alignmentRow),
1100
- ...rowToStringArray(data).map(tableRow)
1101
- )}`
1102
- );
1103
- }
1104
-
1105
- // packages/utils/src/lib/text-formats/index.ts
1106
- var md = {
1107
- bold: bold2,
1108
- italic: italic2,
1109
- strikeThrough,
1110
- code: code2,
1111
- link: link2,
1112
- image,
1113
- headline,
1114
- h,
1115
- h1,
1116
- h2,
1117
- h3,
1118
- h4,
1119
- h5,
1120
- h6,
1121
- indentation,
1122
- lines,
1123
- li,
1124
- section,
1125
- paragraphs,
1126
- table: table2
1127
- };
1128
- var html = {
1129
- bold,
1130
- italic,
1131
- code,
1132
- link,
1133
- details,
1134
- table
1135
- };
1136
-
1137
- // packages/utils/src/lib/reports/utils.ts
1138
- var { image: image2, bold: boldMd } = md;
1139
-
1140
- // packages/utils/src/lib/git/git.ts
1141
- import { simpleGit } from "simple-git";
1142
925
 
1143
926
  // packages/utils/src/lib/git/git.commits-and-tags.ts
1144
927
  import { simpleGit as simpleGit2 } from "simple-git";
@@ -1147,34 +930,32 @@ import { simpleGit as simpleGit2 } from "simple-git";
1147
930
  import { rcompare, valid } from "semver";
1148
931
 
1149
932
  // packages/utils/src/lib/progress.ts
1150
- import chalk3 from "chalk";
933
+ import { black, bold as bold2, gray as gray2, green } from "ansis";
1151
934
  import { MultiProgressBars } from "multi-progress-bars";
1152
935
 
936
+ // packages/utils/src/lib/reports/generate-md-report.ts
937
+ import { MarkdownDocument as MarkdownDocument3, md as md4 } from "build-md";
938
+
1153
939
  // packages/utils/src/lib/reports/formatting.ts
1154
- var { headline: headline2, lines: lines2, link: link3, section: section2, table: table3 } = md;
940
+ import {
941
+ MarkdownDocument,
942
+ md as md2
943
+ } from "build-md";
1155
944
 
1156
945
  // packages/utils/src/lib/reports/generate-md-report-categoy-section.ts
1157
- var { link: link4, section: section3, h2: h22, lines: lines3, li: li2, bold: boldMd2, h3: h32, indentation: indentation2 } = md;
1158
-
1159
- // packages/utils/src/lib/reports/generate-md-report.ts
1160
- var { h1: h12, h2: h23, h3: h33, lines: lines4, link: link5, section: section4, code: codeMd } = md;
1161
- var { bold: boldHtml, details: details2 } = html;
946
+ import { MarkdownDocument as MarkdownDocument2, md as md3 } from "build-md";
1162
947
 
1163
948
  // packages/utils/src/lib/reports/generate-md-reports-diff.ts
1164
- var {
1165
- h1: h13,
1166
- h2: h24,
1167
- lines: lines5,
1168
- link: link6,
1169
- bold: boldMd3,
1170
- italic: italicMd,
1171
- table: table4,
1172
- section: section5
1173
- } = md;
1174
- var { details: details3 } = html;
949
+ import {
950
+ MarkdownDocument as MarkdownDocument5,
951
+ md as md6
952
+ } from "build-md";
953
+
954
+ // packages/utils/src/lib/reports/generate-md-reports-diff-utils.ts
955
+ import { MarkdownDocument as MarkdownDocument4, md as md5 } from "build-md";
1175
956
 
1176
957
  // packages/utils/src/lib/reports/log-stdout-summary.ts
1177
- import chalk4 from "chalk";
958
+ import { bold as bold4, cyan, cyanBright, green as green2, red } from "ansis";
1178
959
 
1179
960
  // packages/plugin-js-packages/src/lib/runner/utils.ts
1180
961
  function filterAuditResult(result, key, referenceResult) {
@@ -1660,6 +1441,9 @@ var packageManagers = {
1660
1441
  import { writeFile } from "node:fs/promises";
1661
1442
  import { dirname } from "node:path";
1662
1443
 
1444
+ // packages/plugin-js-packages/src/lib/runner/audit/transform.ts
1445
+ import { md as md7 } from "build-md";
1446
+
1663
1447
  // packages/plugin-js-packages/src/lib/runner/constants.ts
1664
1448
  import { join as join2 } from "node:path";
1665
1449
  var WORKDIR = pluginWorkDir("js-packages");
@@ -1671,6 +1455,7 @@ var PLUGIN_CONFIG_PATH = join2(
1671
1455
  );
1672
1456
 
1673
1457
  // packages/plugin-js-packages/src/lib/runner/outdated/transform.ts
1458
+ import { md as md8 } from "build-md";
1674
1459
  import { clean, diff, neq } from "semver";
1675
1460
 
1676
1461
  // packages/plugin-js-packages/src/lib/runner/outdated/constants.ts
@@ -1696,28 +1481,113 @@ async function createRunnerConfig(scriptPath, config) {
1696
1481
  };
1697
1482
  }
1698
1483
 
1484
+ // packages/plugin-js-packages/src/lib/package-managers/derive-package-manager.ts
1485
+ import { readFile as readFile2 } from "node:fs/promises";
1486
+ import { join as join3 } from "node:path";
1487
+
1488
+ // packages/plugin-js-packages/src/lib/package-managers/derive-yarn.ts
1489
+ async function deriveYarnVersion() {
1490
+ const { stdout } = await executeProcess({
1491
+ command: "yarn",
1492
+ args: ["-v"]
1493
+ });
1494
+ const yarnVersion = Number.parseInt(stdout.toString().trim().at(0) ?? "", 10);
1495
+ if (yarnVersion >= 2) {
1496
+ return "yarn-modern";
1497
+ } else if (yarnVersion === 1) {
1498
+ return "yarn-classic";
1499
+ }
1500
+ return false;
1501
+ }
1502
+
1503
+ // packages/plugin-js-packages/src/lib/package-managers/derive-package-manager.ts
1504
+ async function derivePackageManagerInPackageJson(currentDir = process.cwd()) {
1505
+ if (await fileExists(join3(currentDir, "package.json"))) {
1506
+ const content = JSON.parse(
1507
+ (await readFile2(join3("package.json"))).toString()
1508
+ );
1509
+ const { packageManager: packageManagerData = "" } = content;
1510
+ const [manager = "", version2 = ""] = packageManagerData.split("@");
1511
+ if (manager === "npm") {
1512
+ return manager;
1513
+ }
1514
+ if (manager === "pnpm") {
1515
+ return manager;
1516
+ }
1517
+ if (manager === "yarn") {
1518
+ const majorVersion = Number(version2.split(".")[0]);
1519
+ return majorVersion > 1 ? "yarn-modern" : "yarn-classic";
1520
+ }
1521
+ }
1522
+ return false;
1523
+ }
1524
+ async function derivePackageManager(currentDir = process.cwd()) {
1525
+ const pkgManagerFromPackageJson = await derivePackageManagerInPackageJson(
1526
+ currentDir
1527
+ );
1528
+ if (pkgManagerFromPackageJson) {
1529
+ return pkgManagerFromPackageJson;
1530
+ }
1531
+ if (await fileExists(join3(currentDir, "package-lock.json"))) {
1532
+ return "npm";
1533
+ } else if (await fileExists(join3(currentDir, "pnpm-lock.yaml"))) {
1534
+ return "pnpm";
1535
+ } else if (await fileExists(join3(currentDir, "yarn.lock"))) {
1536
+ const yarnVersion = await deriveYarnVersion();
1537
+ if (yarnVersion) {
1538
+ return yarnVersion;
1539
+ }
1540
+ }
1541
+ throw new Error(
1542
+ "Could not detect package manager. Please provide it in the js-packages plugin config."
1543
+ );
1544
+ }
1545
+
1546
+ // packages/plugin-js-packages/src/lib/utils.ts
1547
+ async function normalizeConfig(config) {
1548
+ const jsPackagesPluginConfig = jsPackagesPluginConfigSchema.parse(
1549
+ config ?? {}
1550
+ );
1551
+ const {
1552
+ packageManager,
1553
+ dependencyGroups: dependencyGroupsCfg = [],
1554
+ checks: checksCfg = [],
1555
+ ...jsPackagesPluginConfigRest
1556
+ } = jsPackagesPluginConfig;
1557
+ const checks = [...new Set(checksCfg)];
1558
+ const depGroups = [...new Set(dependencyGroupsCfg)];
1559
+ const pm = packageManagers[packageManager ?? await derivePackageManager()];
1560
+ return {
1561
+ ...jsPackagesPluginConfigRest,
1562
+ packageManager: pm,
1563
+ checks,
1564
+ depGroups
1565
+ };
1566
+ }
1567
+
1699
1568
  // packages/plugin-js-packages/src/lib/js-packages-plugin.ts
1700
1569
  async function jsPackagesPlugin(config) {
1701
- const jsPackagesPluginConfig = jsPackagesPluginConfigSchema.parse(config);
1702
- const checks = [...new Set(jsPackagesPluginConfig.checks)];
1703
- const depGroups = [...new Set(jsPackagesPluginConfig.dependencyGroups)];
1704
- const id = jsPackagesPluginConfig.packageManager;
1705
- const pm = packageManagers[id];
1706
- const runnerScriptPath = join3(
1570
+ const { packageManager, checks, depGroups, ...jsPackagesPluginConfigRest } = await normalizeConfig(config);
1571
+ const runnerScriptPath = join4(
1707
1572
  fileURLToPath(dirname2(import.meta.url)),
1708
1573
  "bin.js"
1709
1574
  );
1710
1575
  return {
1711
1576
  slug: "js-packages",
1712
1577
  title: "JS Packages",
1713
- icon: pm.icon,
1578
+ icon: packageManager.icon,
1714
1579
  description: "This plugin runs audit to uncover vulnerabilities and lists outdated dependencies. It supports npm, yarn classic, yarn modern, and pnpm package managers.",
1715
- docsUrl: pm.docs.homepage,
1580
+ docsUrl: packageManager.docs.homepage,
1716
1581
  packageName: name,
1717
1582
  version,
1718
- audits: createAudits(id, checks, depGroups),
1719
- groups: createGroups(id, checks, depGroups),
1720
- runner: await createRunnerConfig(runnerScriptPath, jsPackagesPluginConfig)
1583
+ audits: createAudits(packageManager.slug, checks, depGroups),
1584
+ groups: createGroups(packageManager.slug, checks, depGroups),
1585
+ runner: await createRunnerConfig(runnerScriptPath, {
1586
+ ...jsPackagesPluginConfigRest,
1587
+ checks,
1588
+ packageManager: packageManager.slug,
1589
+ dependencyGroups: depGroups
1590
+ })
1721
1591
  };
1722
1592
  }
1723
1593
  function createGroups(id, checks, depGroups) {
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@code-pushup/js-packages-plugin",
3
- "version": "0.48.0",
3
+ "version": "0.50.0",
4
+ "description": "Code PushUp plugin for JavaScript packages 🛡️",
4
5
  "dependencies": {
5
- "@code-pushup/models": "0.48.0",
6
- "@code-pushup/utils": "0.48.0",
6
+ "@code-pushup/models": "0.50.0",
7
+ "@code-pushup/utils": "0.50.0",
8
+ "build-md": "^0.4.1",
7
9
  "semver": "^7.6.0",
8
10
  "zod": "^3.22.4"
9
11
  },
10
12
  "license": "MIT",
11
- "homepage": "https://github.com/code-pushup/cli#readme",
13
+ "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-js-packages#readme",
12
14
  "bugs": {
13
15
  "url": "https://github.com/code-pushup/cli/issues"
14
16
  },
@@ -17,33 +19,6 @@
17
19
  "url": "git+https://github.com/code-pushup/cli.git",
18
20
  "directory": "packages/plugin-js-packages"
19
21
  },
20
- "contributors": [
21
- {
22
- "name": "Igor Katsuba",
23
- "email": "igor@katsuba.dev",
24
- "url": "https://katsuba.dev"
25
- },
26
- {
27
- "name": "Kateřina Pilátová",
28
- "email": "katerina.pilatova@flowup.cz",
29
- "url": "https://github.com/Tlacenka"
30
- },
31
- {
32
- "name": "Matěj Chalk",
33
- "email": "matej.chalk@flowup.cz",
34
- "url": "https://github.com/matejchalk"
35
- },
36
- {
37
- "name": "Michael Hladky",
38
- "email": "michael.hladky@push-based.io",
39
- "url": "https://push-based.io"
40
- },
41
- {
42
- "name": "Michael Seredenko",
43
- "email": "misha.seredenko@push-based.io",
44
- "url": "https://github.com/MishaSeredenkoPushBased"
45
- }
46
- ],
47
22
  "type": "module",
48
23
  "main": "./index.js",
49
24
  "types": "./src/index.d.ts"