@cyclonedx/cdxgen 8.6.0 → 9.0.1

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/utils.js CHANGED
@@ -1,28 +1,66 @@
1
- const glob = require("glob");
2
- const os = require("os");
3
- const path = require("path");
4
- const parsePackageJsonName = require("parse-packagejson-name");
5
- const fs = require("fs");
6
- const got = require("got");
7
- const convert = require("xml-js");
8
- const licenseMapping = require("./data/lic-mapping.json");
9
- const vendorAliases = require("./data/vendor-alias.json");
10
- const spdxLicenses = require("./data/spdx-licenses.json");
11
- const knownLicenses = require("./data/known-licenses.json");
12
- const cheerio = require("cheerio");
13
- const yaml = require("js-yaml");
14
- const { spawnSync } = require("child_process");
15
- const propertiesReader = require("properties-reader");
16
- const semver = require("semver");
17
- const StreamZip = require("node-stream-zip");
18
- const ednDataLib = require("edn-data");
19
- const { PackageURL } = require("packageurl-js");
1
+ import { globSync } from "glob";
2
+ import { tmpdir, platform, freemem } from "node:os";
3
+ import {
4
+ dirname,
5
+ sep as _sep,
6
+ basename,
7
+ join,
8
+ resolve,
9
+ delimiter as _delimiter
10
+ } from "node:path";
11
+ import {
12
+ existsSync,
13
+ readFileSync,
14
+ mkdtempSync,
15
+ rmSync,
16
+ copyFileSync,
17
+ constants,
18
+ writeFileSync,
19
+ unlinkSync,
20
+ chmodSync
21
+ } from "node:fs";
22
+ import got from "got";
23
+ import { xml2js } from "xml-js";
24
+ import { fileURLToPath } from "node:url";
25
+ let url = import.meta.url;
26
+ if (!url.startsWith("file://")) {
27
+ url = new URL(`file://${import.meta.url}`).toString();
28
+ }
29
+ const dirName = import.meta ? dirname(fileURLToPath(url)) : __dirname;
30
+
31
+ const licenseMapping = JSON.parse(
32
+ readFileSync(join(dirName, "data", "lic-mapping.json"))
33
+ );
34
+ const vendorAliases = JSON.parse(
35
+ readFileSync(join(dirName, "data", "vendor-alias.json"))
36
+ );
37
+ const spdxLicenses = JSON.parse(
38
+ readFileSync(join(dirName, "data", "spdx-licenses.json"))
39
+ );
40
+ const knownLicenses = JSON.parse(
41
+ readFileSync(join(dirName, "data", "known-licenses.json"))
42
+ );
43
+ import { load } from "cheerio";
44
+ import { load as _load } from "js-yaml";
45
+ import { spawnSync } from "node:child_process";
46
+ import propertiesReader from "properties-reader";
47
+ import { satisfies, coerce, maxSatisfying, clean, valid } from "semver";
48
+ import StreamZip from "node-stream-zip";
49
+ import { parseEDNString } from "edn-data";
50
+ import { PackageURL } from "packageurl-js";
51
+
52
+ const selfPJson = JSON.parse(readFileSync(join(dirName, "package.json")));
53
+ const _version = selfPJson.version;
20
54
 
21
55
  // Refer to contrib/py-modules.py for a script to generate this list
22
56
  // The script needs to be used once every few months to update this list
23
- const PYTHON_STD_MODULES = require("./data/python-stdlib.json");
57
+ const PYTHON_STD_MODULES = JSON.parse(
58
+ readFileSync(join(dirName, "data", "python-stdlib.json"))
59
+ );
24
60
  // Mapping between modules and package names
25
- const PYPI_MODULE_PACKAGE_MAPPING = require("./data/pypi-pkg-aliases.json");
61
+ const PYPI_MODULE_PACKAGE_MAPPING = JSON.parse(
62
+ readFileSync(join(dirName, "data", "pypi-pkg-aliases.json"))
63
+ );
26
64
 
27
65
  // Debug mode flag
28
66
  const DEBUG_MODE =
@@ -37,10 +75,9 @@ const TIMEOUT_MS = parseInt(process.env.CDXGEN_TIMEOUT_MS) || 10 * 60 * 1000;
37
75
  let metadata_cache = {};
38
76
 
39
77
  // Whether test scope shall be included for java/maven projects; default, if unset shall be 'true'
40
- const includeMavenTestScope =
78
+ export const includeMavenTestScope =
41
79
  !process.env.CDX_MAVEN_INCLUDE_TEST_SCOPE ||
42
80
  ["true", "1"].includes(process.env.CDX_MAVEN_INCLUDE_TEST_SCOPE);
43
- exports.includeMavenTestScope = includeMavenTestScope;
44
81
 
45
82
  // Whether license information should be fetched
46
83
  const fetchLicenses =
@@ -54,13 +91,20 @@ if (process.env.PYTHON_CMD) {
54
91
  PYTHON_CMD = process.env.PYTHON_CMD;
55
92
  }
56
93
 
94
+ // Custom user-agent for cdxgen
95
+ const cdxgenAgent = got.extend({
96
+ headers: {
97
+ "user-agent": `@CycloneDX/cdxgen ${_version}`
98
+ }
99
+ });
100
+
57
101
  /**
58
102
  * Method to get files matching a pattern
59
103
  *
60
104
  * @param {string} dirPath Root directory for search
61
105
  * @param {string} pattern Glob pattern (eg: *.gradle)
62
106
  */
63
- const getAllFiles = function (dirPath, pattern) {
107
+ export const getAllFiles = function (dirPath, pattern) {
64
108
  try {
65
109
  const ignoreList = [
66
110
  "**/.hg/**",
@@ -74,9 +118,8 @@ const getAllFiles = function (dirPath, pattern) {
74
118
  if (!pattern.includes("package.json")) {
75
119
  ignoreList.push("**/node_modules/**");
76
120
  }
77
- return glob.sync(pattern, {
121
+ return globSync(pattern, {
78
122
  cwd: dirPath,
79
- silent: true,
80
123
  absolute: true,
81
124
  nocase: true,
82
125
  nodir: true,
@@ -92,7 +135,6 @@ const getAllFiles = function (dirPath, pattern) {
92
135
  return [];
93
136
  }
94
137
  };
95
- exports.getAllFiles = getAllFiles;
96
138
 
97
139
  const toBase64 = (hexString) => {
98
140
  return Buffer.from(hexString, "hex").toString("base64");
@@ -104,7 +146,7 @@ const toBase64 = (hexString) => {
104
146
  * and url of the license object, otherwise, set the 'name' of the license
105
147
  * object.
106
148
  */
107
- function getLicenses(pkg, format = "xml") {
149
+ export function getLicenses(pkg, format = "xml") {
108
150
  let license = pkg.license && (pkg.license.type || pkg.license);
109
151
  if (license) {
110
152
  if (!Array.isArray(license)) {
@@ -146,14 +188,13 @@ function getLicenses(pkg, format = "xml") {
146
188
  }
147
189
  return [];
148
190
  }
149
- exports.getLicenses = getLicenses;
150
191
 
151
192
  /**
152
193
  * Tries to find a file containing the license text based on commonly
153
194
  * used naming and content types. If a candidate file is found, add
154
195
  * the text to the license text object and stop.
155
196
  */
156
- function addLicenseText(pkg, l, licenseContent, format = "xml") {
197
+ export function addLicenseText(pkg, l, licenseContent, format = "xml") {
157
198
  let licenseFilenames = [
158
199
  "LICENSE",
159
200
  "License",
@@ -179,7 +220,7 @@ function addLicenseText(pkg, l, licenseContent, format = "xml") {
179
220
  licenseContentTypes
180
221
  )) {
181
222
  let licenseFilepath = `${pkg.realPath}/${licenseFilename}${licenseName}${fileExtension}`;
182
- if (fs.existsSync(licenseFilepath)) {
223
+ if (existsSync(licenseFilepath)) {
183
224
  licenseContent.text = readLicenseText(
184
225
  licenseFilepath,
185
226
  licenseContentType,
@@ -196,8 +237,12 @@ function addLicenseText(pkg, l, licenseContent, format = "xml") {
196
237
  * Read the file from the given path to the license text object and includes
197
238
  * content-type attribute, if not default. Returns the license text object.
198
239
  */
199
- function readLicenseText(licenseFilepath, licenseContentType, format = "xml") {
200
- let licenseText = fs.readFileSync(licenseFilepath, "utf8");
240
+ export function readLicenseText(
241
+ licenseFilepath,
242
+ licenseContentType,
243
+ format = "xml"
244
+ ) {
245
+ let licenseText = readFileSync(licenseFilepath, "utf8");
201
246
  if (licenseText) {
202
247
  if (format === "xml") {
203
248
  let licenseContentText = { "#cdata": licenseText };
@@ -221,7 +266,7 @@ function readLicenseText(licenseFilepath, licenseContentType, format = "xml") {
221
266
  *
222
267
  * @param {Array} pkgList Package list
223
268
  */
224
- const getNpmMetadata = async function (pkgList) {
269
+ export const getNpmMetadata = async function (pkgList) {
225
270
  const NPM_URL = "https://registry.npmjs.org/";
226
271
  const cdepList = [];
227
272
  for (const p of pkgList) {
@@ -238,7 +283,7 @@ const getNpmMetadata = async function (pkgList) {
238
283
  if (metadata_cache[key]) {
239
284
  body = metadata_cache[key];
240
285
  } else {
241
- const res = await got.get(NPM_URL + key, {
286
+ const res = await cdxgenAgent.get(NPM_URL + key, {
242
287
  responseType: "json"
243
288
  });
244
289
  body = res.body;
@@ -262,7 +307,6 @@ const getNpmMetadata = async function (pkgList) {
262
307
  }
263
308
  return cdepList;
264
309
  };
265
- exports.getNpmMetadata = getNpmMetadata;
266
310
 
267
311
  const _getDepPkgList = async function (
268
312
  pkgLockFile,
@@ -363,11 +407,11 @@ const _getDepPkgList = async function (
363
407
  *
364
408
  * @param {string} pkgJsonFile package.json file
365
409
  */
366
- const parsePkgJson = async (pkgJsonFile) => {
410
+ export const parsePkgJson = async (pkgJsonFile) => {
367
411
  const pkgList = [];
368
- if (fs.existsSync(pkgJsonFile)) {
412
+ if (existsSync(pkgJsonFile)) {
369
413
  try {
370
- const pkgData = JSON.parse(fs.readFileSync(pkgJsonFile, "utf8"));
414
+ const pkgData = JSON.parse(readFileSync(pkgJsonFile, "utf8"));
371
415
  const pkgIdentifier = parsePackageJsonName(pkgData.name);
372
416
  pkgList.push({
373
417
  name: pkgIdentifier.fullName || pkgData.name,
@@ -394,20 +438,19 @@ const parsePkgJson = async (pkgJsonFile) => {
394
438
  }
395
439
  return pkgList;
396
440
  };
397
- exports.parsePkgJson = parsePkgJson;
398
441
 
399
442
  /**
400
443
  * Parse nodejs package lock file
401
444
  *
402
445
  * @param {string} pkgLockFile package-lock.json file
403
446
  */
404
- const parsePkgLock = async (pkgLockFile) => {
447
+ export const parsePkgLock = async (pkgLockFile) => {
405
448
  let pkgList = [];
406
449
  let dependenciesList = [];
407
450
  let depKeys = {};
408
451
  let rootPkg = {};
409
- if (fs.existsSync(pkgLockFile)) {
410
- const lockData = JSON.parse(fs.readFileSync(pkgLockFile, "utf8"));
452
+ if (existsSync(pkgLockFile)) {
453
+ const lockData = JSON.parse(readFileSync(pkgLockFile, "utf8"));
411
454
  rootPkg.name = lockData.name || "";
412
455
  // lockfile v2 onwards
413
456
  if (lockData.name && lockData.packages && lockData.packages[""]) {
@@ -419,8 +462,8 @@ const parsePkgLock = async (pkgLockFile) => {
419
462
  type: "application"
420
463
  };
421
464
  } else if (lockData.lockfileVersion === 1) {
422
- let dirName = path.dirname(pkgLockFile);
423
- const tmpA = dirName.split(path.sep);
465
+ let dirName = dirname(pkgLockFile);
466
+ const tmpA = dirName.split(_sep);
424
467
  dirName = tmpA[tmpA.length - 1];
425
468
  // v1 lock file
426
469
  rootPkg = {
@@ -505,7 +548,6 @@ const parsePkgLock = async (pkgLockFile) => {
505
548
  dependenciesList
506
549
  };
507
550
  };
508
- exports.parsePkgLock = parsePkgLock;
509
551
 
510
552
  /**
511
553
  * Given a lock file this method would return an Object with the identiy as the key and parsed name and value
@@ -515,7 +557,7 @@ exports.parsePkgLock = parsePkgLock;
515
557
  *
516
558
  * @param {string} lockData Yarn Lockfile data
517
559
  */
518
- const yarnLockToIdentMap = function (lockData) {
560
+ export const yarnLockToIdentMap = function (lockData) {
519
561
  const identMap = {};
520
562
  let currentIdents = [];
521
563
  lockData.split("\n").forEach((l) => {
@@ -558,19 +600,18 @@ const yarnLockToIdentMap = function (lockData) {
558
600
  });
559
601
  return identMap;
560
602
  };
561
- exports.yarnLockToIdentMap = yarnLockToIdentMap;
562
603
 
563
604
  /**
564
605
  * Parse nodejs yarn lock file
565
606
  *
566
607
  * @param {string} yarnLockFile yarn.lock file
567
608
  */
568
- const parseYarnLock = async function (yarnLockFile) {
609
+ export const parseYarnLock = async function (yarnLockFile) {
569
610
  let pkgList = [];
570
611
  const dependenciesList = [];
571
612
  const depKeys = {};
572
- if (fs.existsSync(yarnLockFile)) {
573
- const lockData = fs.readFileSync(yarnLockFile, "utf8");
613
+ if (existsSync(yarnLockFile)) {
614
+ const lockData = readFileSync(yarnLockFile, "utf8");
574
615
  let name = "";
575
616
  let group = "";
576
617
  let version = "";
@@ -714,17 +755,16 @@ const parseYarnLock = async function (yarnLockFile) {
714
755
  dependenciesList
715
756
  };
716
757
  };
717
- exports.parseYarnLock = parseYarnLock;
718
758
 
719
759
  /**
720
760
  * Parse nodejs shrinkwrap deps file
721
761
  *
722
762
  * @param {string} swFile shrinkwrap-deps.json file
723
763
  */
724
- const parseNodeShrinkwrap = async function (swFile) {
764
+ export const parseNodeShrinkwrap = async function (swFile) {
725
765
  const pkgList = [];
726
- if (fs.existsSync(swFile)) {
727
- const lockData = JSON.parse(fs.readFileSync(swFile, "utf8"));
766
+ if (existsSync(swFile)) {
767
+ const lockData = JSON.parse(readFileSync(swFile, "utf8"));
728
768
  const pkgKeys = Object.keys(lockData);
729
769
  for (var k in pkgKeys) {
730
770
  const fullName = pkgKeys[k];
@@ -774,14 +814,13 @@ const parseNodeShrinkwrap = async function (swFile) {
774
814
  }
775
815
  return pkgList;
776
816
  };
777
- exports.parseNodeShrinkwrap = parseNodeShrinkwrap;
778
817
 
779
818
  /**
780
819
  * Parse nodejs pnpm lock file
781
820
  *
782
821
  * @param {string} pnpmLock pnpm-lock.yaml file
783
822
  */
784
- const parsePnpmLock = async function (pnpmLock, parentComponent = null) {
823
+ export const parsePnpmLock = async function (pnpmLock, parentComponent = null) {
785
824
  let pkgList = [];
786
825
  const dependenciesList = [];
787
826
  let ppurl = "";
@@ -797,9 +836,9 @@ const parsePnpmLock = async function (pnpmLock, parentComponent = null) {
797
836
  null
798
837
  ).toString();
799
838
  }
800
- if (fs.existsSync(pnpmLock)) {
801
- const lockData = fs.readFileSync(pnpmLock, "utf8");
802
- const yamlObj = yaml.load(lockData);
839
+ if (existsSync(pnpmLock)) {
840
+ const lockData = readFileSync(pnpmLock, "utf8");
841
+ const yamlObj = _load(lockData);
803
842
  if (!yamlObj) {
804
843
  return {};
805
844
  }
@@ -936,18 +975,17 @@ const parsePnpmLock = async function (pnpmLock, parentComponent = null) {
936
975
  dependenciesList
937
976
  };
938
977
  };
939
- exports.parsePnpmLock = parsePnpmLock;
940
978
 
941
979
  /**
942
980
  * Parse bower json file
943
981
  *
944
982
  * @param {string} bowerJsonFile bower.json file
945
983
  */
946
- const parseBowerJson = async (bowerJsonFile) => {
984
+ export const parseBowerJson = async (bowerJsonFile) => {
947
985
  const pkgList = [];
948
- if (fs.existsSync(bowerJsonFile)) {
986
+ if (existsSync(bowerJsonFile)) {
949
987
  try {
950
- const pkgData = JSON.parse(fs.readFileSync(bowerJsonFile, "utf8"));
988
+ const pkgData = JSON.parse(readFileSync(bowerJsonFile, "utf8"));
951
989
  const pkgIdentifier = parsePackageJsonName(pkgData.name);
952
990
  pkgList.push({
953
991
  name: pkgIdentifier.fullName || pkgData.name,
@@ -976,18 +1014,17 @@ const parseBowerJson = async (bowerJsonFile) => {
976
1014
  }
977
1015
  return pkgList;
978
1016
  };
979
- exports.parseBowerJson = parseBowerJson;
980
1017
 
981
1018
  /**
982
1019
  * Parse minified js file
983
1020
  *
984
1021
  * @param {string} minJsFile min.js file
985
1022
  */
986
- const parseMinJs = async (minJsFile) => {
1023
+ export const parseMinJs = async (minJsFile) => {
987
1024
  const pkgList = [];
988
- if (fs.existsSync(minJsFile)) {
1025
+ if (existsSync(minJsFile)) {
989
1026
  try {
990
- const rawData = fs.readFileSync(minJsFile, { encoding: "utf-8" });
1027
+ const rawData = readFileSync(minJsFile, { encoding: "utf-8" });
991
1028
  const tmpA = rawData.split("\n");
992
1029
  tmpA.forEach((l) => {
993
1030
  if ((l.startsWith("/*!") || l.startsWith(" * ")) && l.length < 500) {
@@ -1050,17 +1087,16 @@ const parseMinJs = async (minJsFile) => {
1050
1087
  }
1051
1088
  return pkgList;
1052
1089
  };
1053
- exports.parseMinJs = parseMinJs;
1054
1090
 
1055
1091
  /**
1056
1092
  * Parse pom file
1057
1093
  *
1058
1094
  * @param {string} pom file to parse
1059
1095
  */
1060
- const parsePom = function (pomFile) {
1096
+ export const parsePom = function (pomFile) {
1061
1097
  const deps = [];
1062
- const xmlData = fs.readFileSync(pomFile);
1063
- const project = convert.xml2js(xmlData, {
1098
+ const xmlData = readFileSync(pomFile);
1099
+ const project = xml2js(xmlData, {
1064
1100
  compact: true,
1065
1101
  spaces: 4,
1066
1102
  textKey: "_",
@@ -1098,13 +1134,12 @@ const parsePom = function (pomFile) {
1098
1134
  }
1099
1135
  return deps;
1100
1136
  };
1101
- exports.parsePom = parsePom;
1102
1137
 
1103
1138
  /**
1104
1139
  * Parse maven tree output
1105
1140
  * @param {string} rawOutput Raw string output
1106
1141
  */
1107
- const parseMavenTree = function (rawOutput) {
1142
+ export const parseMavenTree = function (rawOutput) {
1108
1143
  if (!rawOutput) {
1109
1144
  return {};
1110
1145
  }
@@ -1190,7 +1225,6 @@ const parseMavenTree = function (rawOutput) {
1190
1225
  dependenciesList
1191
1226
  };
1192
1227
  };
1193
- exports.parseMavenTree = parseMavenTree;
1194
1228
 
1195
1229
  /**
1196
1230
  * Parse gradle dependencies output
@@ -1199,7 +1233,7 @@ exports.parseMavenTree = parseMavenTree;
1199
1233
  * @param {string} rootProjectName Root project name
1200
1234
  * @param {string} rootProjectVersion Root project version
1201
1235
  */
1202
- const parseGradleDep = function (
1236
+ export const parseGradleDep = function (
1203
1237
  rawOutput,
1204
1238
  rootProjectGroup = "",
1205
1239
  rootProjectName = "root",
@@ -1387,13 +1421,12 @@ const parseGradleDep = function (
1387
1421
  }
1388
1422
  return {};
1389
1423
  };
1390
- exports.parseGradleDep = parseGradleDep;
1391
1424
 
1392
1425
  /**
1393
1426
  * Parse clojure cli dependencies output
1394
1427
  * @param {string} rawOutput Raw string output
1395
1428
  */
1396
- const parseCljDep = function (rawOutput) {
1429
+ export const parseCljDep = function (rawOutput) {
1397
1430
  if (typeof rawOutput === "string") {
1398
1431
  const deps = [];
1399
1432
  const keys_cache = {};
@@ -1406,11 +1439,11 @@ const parseCljDep = function (rawOutput) {
1406
1439
  }
1407
1440
  const tmpArr = l.split(" ");
1408
1441
  if (tmpArr.length == 2) {
1409
- let group = path.dirname(tmpArr[0]);
1442
+ let group = dirname(tmpArr[0]);
1410
1443
  if (group === ".") {
1411
1444
  group = "";
1412
1445
  }
1413
- const name = path.basename(tmpArr[0]);
1446
+ const name = basename(tmpArr[0]);
1414
1447
  const version = tmpArr[1];
1415
1448
  const cacheKey = group + "-" + name + "-" + version;
1416
1449
  if (!keys_cache[cacheKey]) {
@@ -1428,38 +1461,36 @@ const parseCljDep = function (rawOutput) {
1428
1461
  }
1429
1462
  return [];
1430
1463
  };
1431
- exports.parseCljDep = parseCljDep;
1432
1464
 
1433
1465
  /**
1434
1466
  * Parse lein dependency tree output
1435
1467
  * @param {string} rawOutput Raw string output
1436
1468
  */
1437
- const parseLeinDep = function (rawOutput) {
1469
+ export const parseLeinDep = function (rawOutput) {
1438
1470
  if (typeof rawOutput === "string") {
1439
1471
  const deps = [];
1440
1472
  const keys_cache = {};
1441
1473
  if (rawOutput.includes("{[") && !rawOutput.startsWith("{[")) {
1442
1474
  rawOutput = "{[" + rawOutput.split("{[")[1];
1443
1475
  }
1444
- const ednData = ednDataLib.parseEDNString(rawOutput);
1476
+ const ednData = parseEDNString(rawOutput);
1445
1477
  return parseLeinMap(ednData, keys_cache, deps);
1446
1478
  }
1447
1479
  return [];
1448
1480
  };
1449
- exports.parseLeinDep = parseLeinDep;
1450
1481
 
1451
- const parseLeinMap = function (node, keys_cache, deps) {
1482
+ export const parseLeinMap = function (node, keys_cache, deps) {
1452
1483
  if (node["map"]) {
1453
1484
  for (let n of node["map"]) {
1454
1485
  if (n.length === 2) {
1455
1486
  const rootNode = n[0];
1456
1487
  let psym = rootNode[0].sym;
1457
1488
  let version = rootNode[1];
1458
- let group = path.dirname(psym);
1489
+ let group = dirname(psym);
1459
1490
  if (group === ".") {
1460
1491
  group = "";
1461
1492
  }
1462
- let name = path.basename(psym);
1493
+ let name = basename(psym);
1463
1494
  let cacheKey = group + "-" + name + "-" + version;
1464
1495
  if (!keys_cache[cacheKey]) {
1465
1496
  keys_cache[cacheKey] = true;
@@ -1473,14 +1504,13 @@ const parseLeinMap = function (node, keys_cache, deps) {
1473
1504
  }
1474
1505
  return deps;
1475
1506
  };
1476
- exports.parseLeinMap = parseLeinMap;
1477
1507
 
1478
1508
  /**
1479
1509
  * Parse gradle projects output
1480
1510
  *
1481
1511
  * @param {string} rawOutput Raw string output
1482
1512
  */
1483
- const parseGradleProjects = function (rawOutput) {
1513
+ export const parseGradleProjects = function (rawOutput) {
1484
1514
  let rootProject = "root";
1485
1515
  const projects = new Set();
1486
1516
  if (typeof rawOutput === "string") {
@@ -1516,14 +1546,13 @@ const parseGradleProjects = function (rawOutput) {
1516
1546
  projects: Array.from(projects)
1517
1547
  };
1518
1548
  };
1519
- exports.parseGradleProjects = parseGradleProjects;
1520
1549
 
1521
1550
  /**
1522
1551
  * Parse gradle properties output
1523
1552
  *
1524
1553
  * @param {string} rawOutput Raw string output
1525
1554
  */
1526
- const parseGradleProperties = function (rawOutput) {
1555
+ export const parseGradleProperties = function (rawOutput) {
1527
1556
  let rootProject = "root";
1528
1557
  let projects = new Set();
1529
1558
  const metadata = { group: "", version: "latest", properties: [] };
@@ -1559,7 +1588,6 @@ const parseGradleProperties = function (rawOutput) {
1559
1588
  metadata
1560
1589
  };
1561
1590
  };
1562
- exports.parseGradleProperties = parseGradleProperties;
1563
1591
 
1564
1592
  /**
1565
1593
  * Execute gradle properties command and return parsed output
@@ -1568,7 +1596,7 @@ exports.parseGradleProperties = parseGradleProperties;
1568
1596
  * @param {string} rootPath Root directory
1569
1597
  * @param {string} subProject Sub project name
1570
1598
  */
1571
- const executeGradleProperties = function (dir, rootPath, subProject) {
1599
+ export const executeGradleProperties = function (dir, rootPath, subProject) {
1572
1600
  const defaultProps = {
1573
1601
  rootProject: subProject,
1574
1602
  projects: [],
@@ -1623,13 +1651,12 @@ const executeGradleProperties = function (dir, rootPath, subProject) {
1623
1651
  }
1624
1652
  return {};
1625
1653
  };
1626
- exports.executeGradleProperties = executeGradleProperties;
1627
1654
 
1628
1655
  /**
1629
1656
  * Parse bazel skyframe state output
1630
1657
  * @param {string} rawOutput Raw string output
1631
1658
  */
1632
- const parseBazelSkyframe = function (rawOutput) {
1659
+ export const parseBazelSkyframe = function (rawOutput) {
1633
1660
  if (typeof rawOutput === "string") {
1634
1661
  const deps = [];
1635
1662
  const keys_cache = {};
@@ -1680,13 +1707,12 @@ const parseBazelSkyframe = function (rawOutput) {
1680
1707
  }
1681
1708
  return [];
1682
1709
  };
1683
- exports.parseBazelSkyframe = parseBazelSkyframe;
1684
1710
 
1685
1711
  /**
1686
1712
  * Parse bazel BUILD file
1687
1713
  * @param {string} rawOutput Raw string output
1688
1714
  */
1689
- const parseBazelBuild = function (rawOutput) {
1715
+ export const parseBazelBuild = function (rawOutput) {
1690
1716
  if (typeof rawOutput === "string") {
1691
1717
  const projs = [];
1692
1718
  const tmpA = rawOutput.split("\n");
@@ -1702,12 +1728,11 @@ const parseBazelBuild = function (rawOutput) {
1702
1728
  }
1703
1729
  return [];
1704
1730
  };
1705
- exports.parseBazelBuild = parseBazelBuild;
1706
1731
 
1707
1732
  /**
1708
1733
  * Parse dependencies in Key:Value format
1709
1734
  */
1710
- const parseKVDep = function (rawOutput) {
1735
+ export const parseKVDep = function (rawOutput) {
1711
1736
  if (typeof rawOutput === "string") {
1712
1737
  const deps = [];
1713
1738
  rawOutput.split("\n").forEach((l) => {
@@ -1732,14 +1757,13 @@ const parseKVDep = function (rawOutput) {
1732
1757
  }
1733
1758
  return [];
1734
1759
  };
1735
- exports.parseKVDep = parseKVDep;
1736
1760
 
1737
1761
  /**
1738
1762
  * Method to find the spdx license id from name
1739
1763
  *
1740
1764
  * @param {string} name License full name
1741
1765
  */
1742
- const findLicenseId = function (name) {
1766
+ export const findLicenseId = function (name) {
1743
1767
  for (let l of licenseMapping) {
1744
1768
  if (l.names.includes(name)) {
1745
1769
  return l.exp;
@@ -1749,14 +1773,13 @@ const findLicenseId = function (name) {
1749
1773
  ? guessLicenseId(name)
1750
1774
  : name;
1751
1775
  };
1752
- exports.findLicenseId = findLicenseId;
1753
1776
 
1754
1777
  /**
1755
1778
  * Method to guess the spdx license id from license contents
1756
1779
  *
1757
1780
  * @param {string} name License file contents
1758
1781
  */
1759
- const guessLicenseId = function (content) {
1782
+ export const guessLicenseId = function (content) {
1760
1783
  content = content.replace(/\n/g, " ");
1761
1784
  for (let l of licenseMapping) {
1762
1785
  for (let j in l.names) {
@@ -1767,14 +1790,13 @@ const guessLicenseId = function (content) {
1767
1790
  }
1768
1791
  return undefined;
1769
1792
  };
1770
- exports.guessLicenseId = guessLicenseId;
1771
1793
 
1772
1794
  /**
1773
1795
  * Method to retrieve metadata for maven packages by querying maven central
1774
1796
  *
1775
1797
  * @param {Array} pkgList Package list
1776
1798
  */
1777
- const getMvnMetadata = async function (pkgList) {
1799
+ export const getMvnMetadata = async function (pkgList) {
1778
1800
  const MAVEN_CENTRAL_URL = "https://repo1.maven.org/maven2/";
1779
1801
  const ANDROID_MAVEN = "https://maven.google.com/";
1780
1802
  const cdepList = [];
@@ -1817,8 +1839,8 @@ const getMvnMetadata = async function (pkgList) {
1817
1839
  if (DEBUG_MODE) {
1818
1840
  console.log(`Querying ${fullUrl}`);
1819
1841
  }
1820
- const res = await got.get(fullUrl);
1821
- const bodyJson = convert.xml2js(res.body, {
1842
+ const res = await cdxgenAgent.get(fullUrl);
1843
+ const bodyJson = xml2js(res.body, {
1822
1844
  compact: true,
1823
1845
  spaces: 4,
1824
1846
  textKey: "_",
@@ -1859,14 +1881,13 @@ const getMvnMetadata = async function (pkgList) {
1859
1881
  }
1860
1882
  return cdepList;
1861
1883
  };
1862
- exports.getMvnMetadata = getMvnMetadata;
1863
1884
 
1864
1885
  /**
1865
1886
  * Method to parse python requires_dist attribute found in pypi setup.py
1866
1887
  *
1867
1888
  * @param requires_dist string
1868
1889
  */
1869
- const parsePyRequiresDist = function (dist_string) {
1890
+ export const parsePyRequiresDist = function (dist_string) {
1870
1891
  if (!dist_string) {
1871
1892
  return undefined;
1872
1893
  }
@@ -1887,7 +1908,6 @@ const parsePyRequiresDist = function (dist_string) {
1887
1908
  version
1888
1909
  };
1889
1910
  };
1890
- exports.parsePyRequiresDist = parsePyRequiresDist;
1891
1911
 
1892
1912
  /**
1893
1913
  * Method to mimic pip version solver using node-semver
@@ -1895,22 +1915,18 @@ exports.parsePyRequiresDist = parsePyRequiresDist;
1895
1915
  * @param {Array} versionsList List of version numbers available
1896
1916
  * @param {*} versionSpecifiers pip version specifier
1897
1917
  */
1898
- const guessPypiMatchingVersion = (versionsList, versionSpecifiers) => {
1918
+ export const guessPypiMatchingVersion = (versionsList, versionSpecifiers) => {
1899
1919
  versionSpecifiers = versionSpecifiers.replace(/,/g, " ").split(";")[0];
1900
1920
  // Iterate in the reverse order
1901
1921
  for (let i = versionsList.length - 1; i > 0; i--) {
1902
1922
  let rv = versionsList[i];
1903
- if (semver.satisfies(semver.coerce(rv), versionSpecifiers, true)) {
1923
+ if (satisfies(coerce(rv), versionSpecifiers, true)) {
1904
1924
  return rv;
1905
1925
  }
1906
1926
  }
1907
1927
  // Let's try to clean and have another go
1908
- return semver.maxSatisfying(
1909
- versionsList,
1910
- semver.clean(versionSpecifiers, { loose: true })
1911
- );
1928
+ return maxSatisfying(versionsList, clean(versionSpecifiers, { loose: true }));
1912
1929
  };
1913
- exports.guessPypiMatchingVersion = guessPypiMatchingVersion;
1914
1930
 
1915
1931
  /**
1916
1932
  * Method to retrieve metadata for python packages by querying pypi
@@ -1918,7 +1934,7 @@ exports.guessPypiMatchingVersion = guessPypiMatchingVersion;
1918
1934
  * @param {Array} pkgList Package list
1919
1935
  * @param {Boolean} fetchDepsInfo Fetch dependencies info from pypi
1920
1936
  */
1921
- const getPyMetadata = async function (pkgList, fetchDepsInfo) {
1937
+ export const getPyMetadata = async function (pkgList, fetchDepsInfo) {
1922
1938
  if (!fetchLicenses && !fetchDepsInfo) {
1923
1939
  return pkgList;
1924
1940
  }
@@ -1938,7 +1954,7 @@ const getPyMetadata = async function (pkgList, fetchDepsInfo) {
1938
1954
  if (p.name.includes("[")) {
1939
1955
  p.name = p.name.split("[")[0];
1940
1956
  }
1941
- const res = await got.get(PYPI_URL + p.name + "/json", {
1957
+ const res = await cdxgenAgent.get(PYPI_URL + p.name + "/json", {
1942
1958
  responseType: "json"
1943
1959
  });
1944
1960
  const body = res.body;
@@ -2030,6 +2046,7 @@ const getPyMetadata = async function (pkgList, fetchDepsInfo) {
2030
2046
  p.version = "latest";
2031
2047
  }
2032
2048
  // Add a property to let the downstream tools know about this assumption
2049
+ // FIXME: Do this correctly with 1.5
2033
2050
  if (!p.properties) {
2034
2051
  p.properties = [];
2035
2052
  }
@@ -2042,14 +2059,13 @@ const getPyMetadata = async function (pkgList, fetchDepsInfo) {
2042
2059
  }
2043
2060
  return cdepList;
2044
2061
  };
2045
- exports.getPyMetadata = getPyMetadata;
2046
2062
 
2047
2063
  /**
2048
2064
  * Method to parse bdist_wheel metadata
2049
2065
  *
2050
2066
  * @param {Object} mData bdist_wheel metadata
2051
2067
  */
2052
- const parseBdistMetadata = function (mData) {
2068
+ export const parseBdistMetadata = function (mData) {
2053
2069
  const pkg = {};
2054
2070
  mData.split("\n").forEach((l) => {
2055
2071
  if (l.indexOf("Name: ") > -1) {
@@ -2068,14 +2084,13 @@ const parseBdistMetadata = function (mData) {
2068
2084
  });
2069
2085
  return [pkg];
2070
2086
  };
2071
- exports.parseBdistMetadata = parseBdistMetadata;
2072
2087
 
2073
2088
  /**
2074
2089
  * Method to parse pipfile.lock data
2075
2090
  *
2076
2091
  * @param {Object} lockData JSON data from Pipfile.lock
2077
2092
  */
2078
- const parsePiplockData = async function (lockData) {
2093
+ export const parsePiplockData = async function (lockData) {
2079
2094
  const pkgList = [];
2080
2095
  Object.keys(lockData)
2081
2096
  .filter((i) => i !== "_meta")
@@ -2091,14 +2106,13 @@ const parsePiplockData = async function (lockData) {
2091
2106
  });
2092
2107
  return await getPyMetadata(pkgList, false);
2093
2108
  };
2094
- exports.parsePiplockData = parsePiplockData;
2095
2109
 
2096
2110
  /**
2097
2111
  * Method to parse poetry.lock data
2098
2112
  *
2099
2113
  * @param {Object} lockData JSON data from poetry.lock
2100
2114
  */
2101
- const parsePoetrylockData = async function (lockData) {
2115
+ export const parsePoetrylockData = async function (lockData) {
2102
2116
  const pkgList = [];
2103
2117
  let pkg = null;
2104
2118
  if (!lockData) {
@@ -2133,7 +2147,6 @@ const parsePoetrylockData = async function (lockData) {
2133
2147
  });
2134
2148
  return await getPyMetadata(pkgList, false);
2135
2149
  };
2136
- exports.parsePoetrylockData = parsePoetrylockData;
2137
2150
 
2138
2151
  /**
2139
2152
  * Method to parse requirements.txt data
@@ -2141,7 +2154,7 @@ exports.parsePoetrylockData = parsePoetrylockData;
2141
2154
  * @param {Object} reqData Requirements.txt data
2142
2155
  * @param {Boolean} fetchDepsInfo Fetch dependencies info from pypi
2143
2156
  */
2144
- async function parseReqFile(reqData, fetchDepsInfo) {
2157
+ export async function parseReqFile(reqData, fetchDepsInfo) {
2145
2158
  const pkgList = [];
2146
2159
  let compScope = undefined;
2147
2160
  reqData.split("\n").forEach((l) => {
@@ -2263,7 +2276,6 @@ async function parseReqFile(reqData, fetchDepsInfo) {
2263
2276
  });
2264
2277
  return await getPyMetadata(pkgList, fetchDepsInfo);
2265
2278
  }
2266
- exports.parseReqFile = parseReqFile;
2267
2279
 
2268
2280
  /**
2269
2281
  * Method to find python modules by parsing the imports and then checking with PyPI to obtain the latest version
@@ -2272,7 +2284,7 @@ exports.parseReqFile = parseReqFile;
2272
2284
  * @param {Array} epkgList Existing package list
2273
2285
  * @returns List of packages
2274
2286
  */
2275
- const getPyModules = async (src, epkgList) => {
2287
+ export const getPyModules = async (src, epkgList) => {
2276
2288
  const allImports = {};
2277
2289
  const modList = findAppModules(src, "python");
2278
2290
  const pyDefaultModules = new Set(PYTHON_STD_MODULES);
@@ -2300,27 +2312,26 @@ const getPyModules = async (src, epkgList) => {
2300
2312
  pkgList = pkgList.filter(
2301
2313
  (obj, index) => pkgList.findIndex((i) => i.name === obj.name) === index
2302
2314
  );
2303
- if (epkgList && epkgList.length) {
2304
- const pkgMaps = epkgList.map((p) => p.name);
2305
- pkgList = pkgList.filter((p) => !pkgMaps.includes(p.name));
2306
- }
2307
- pkgList = await getPyMetadata(pkgList, true);
2308
2315
  // Populate the imports list
2309
2316
  if (pkgList && pkgList.length) {
2310
2317
  pkgList.forEach((p) => {
2311
2318
  allImports[p.name] = true;
2312
2319
  });
2313
2320
  }
2321
+ if (epkgList && epkgList.length) {
2322
+ const pkgMaps = epkgList.map((p) => p.name);
2323
+ pkgList = pkgList.filter((p) => !pkgMaps.includes(p.name));
2324
+ }
2325
+ pkgList = await getPyMetadata(pkgList, true);
2314
2326
  return { allImports, pkgList };
2315
2327
  };
2316
- exports.getPyModules = getPyModules;
2317
2328
 
2318
2329
  /**
2319
2330
  * Method to parse setup.py data
2320
2331
  *
2321
2332
  * @param {Object} setupPyData Contents of setup.py
2322
2333
  */
2323
- const parseSetupPyFile = async function (setupPyData) {
2334
+ export const parseSetupPyFile = async function (setupPyData) {
2324
2335
  let lines = [];
2325
2336
  let requires_found = false;
2326
2337
  let should_break = false;
@@ -2342,13 +2353,12 @@ const parseSetupPyFile = async function (setupPyData) {
2342
2353
  });
2343
2354
  return await parseReqFile(lines.join("\n"), false);
2344
2355
  };
2345
- exports.parseSetupPyFile = parseSetupPyFile;
2346
2356
 
2347
2357
  /**
2348
2358
  * Method to construct a github url for the given repo
2349
2359
  * @param {Object} repoMetadata Repo metadata with group and name
2350
2360
  */
2351
- const toGitHubUrl = function (repoMetadata) {
2361
+ export const toGitHubUrl = function (repoMetadata) {
2352
2362
  if (repoMetadata) {
2353
2363
  const group = repoMetadata.group;
2354
2364
  const name = repoMetadata.name;
@@ -2362,7 +2372,6 @@ const toGitHubUrl = function (repoMetadata) {
2362
2372
  return undefined;
2363
2373
  }
2364
2374
  };
2365
- exports.toGitHubUrl = toGitHubUrl;
2366
2375
 
2367
2376
  /**
2368
2377
  * Method to retrieve repo license by querying github api
@@ -2371,7 +2380,7 @@ exports.toGitHubUrl = toGitHubUrl;
2371
2380
  * @param {Object} repoMetadata Object containing group and package name strings
2372
2381
  * @return {String} SPDX license id
2373
2382
  */
2374
- const getRepoLicense = async function (repoUrl, repoMetadata) {
2383
+ export const getRepoLicense = async function (repoUrl, repoMetadata) {
2375
2384
  if (!repoUrl) {
2376
2385
  repoUrl = toGitHubUrl(repoMetadata);
2377
2386
  }
@@ -2387,7 +2396,7 @@ const getRepoLicense = async function (repoUrl, repoMetadata) {
2387
2396
  headers["Authorization"] = "Bearer " + process.env.GITHUB_TOKEN;
2388
2397
  }
2389
2398
  try {
2390
- const res = await got.get(apiUrl, {
2399
+ const res = await cdxgenAgent.get(apiUrl, {
2391
2400
  responseType: "json",
2392
2401
  headers: headers
2393
2402
  });
@@ -2434,14 +2443,13 @@ const getRepoLicense = async function (repoUrl, repoMetadata) {
2434
2443
  }
2435
2444
  return undefined;
2436
2445
  };
2437
- exports.getRepoLicense = getRepoLicense;
2438
2446
 
2439
2447
  /**
2440
2448
  * Method to get go pkg license from go.dev site.
2441
2449
  *
2442
2450
  * @param {Object} repoMetadata Repo metadata
2443
2451
  */
2444
- const getGoPkgLicense = async function (repoMetadata) {
2452
+ export const getGoPkgLicense = async function (repoMetadata) {
2445
2453
  const group = repoMetadata.group;
2446
2454
  const name = repoMetadata.name;
2447
2455
  let pkgUrlPrefix = "https://pkg.go.dev/";
@@ -2454,9 +2462,9 @@ const getGoPkgLicense = async function (repoMetadata) {
2454
2462
  return metadata_cache[pkgUrlPrefix];
2455
2463
  }
2456
2464
  try {
2457
- const res = await got.get(pkgUrlPrefix);
2465
+ const res = await cdxgenAgent.get(pkgUrlPrefix);
2458
2466
  if (res && res.body) {
2459
- const $ = cheerio.load(res.body);
2467
+ const $ = load(res.body);
2460
2468
  let licenses = $("#LICENSE > h2").text().trim();
2461
2469
  if (licenses === "") {
2462
2470
  licenses = $("section.License > h2").text().trim();
@@ -2481,9 +2489,8 @@ const getGoPkgLicense = async function (repoMetadata) {
2481
2489
  }
2482
2490
  return undefined;
2483
2491
  };
2484
- exports.getGoPkgLicense = getGoPkgLicense;
2485
2492
 
2486
- const getGoPkgComponent = async function (group, name, version, hash) {
2493
+ export const getGoPkgComponent = async function (group, name, version, hash) {
2487
2494
  let pkg = {};
2488
2495
  let license = undefined;
2489
2496
  if (fetchLicenses) {
@@ -2506,9 +2513,8 @@ const getGoPkgComponent = async function (group, name, version, hash) {
2506
2513
  };
2507
2514
  return pkg;
2508
2515
  };
2509
- exports.getGoPkgComponent = getGoPkgComponent;
2510
2516
 
2511
- const parseGoModData = async function (goModData, gosumMap) {
2517
+ export const parseGoModData = async function (goModData, gosumMap) {
2512
2518
  const pkgComponentsList = [];
2513
2519
  let isModReplacement = false;
2514
2520
 
@@ -2572,7 +2578,6 @@ const parseGoModData = async function (goModData, gosumMap) {
2572
2578
  metadata_cache = {};
2573
2579
  return pkgComponentsList;
2574
2580
  };
2575
- exports.parseGoModData = parseGoModData;
2576
2581
 
2577
2582
  /**
2578
2583
  * Parse go list output
@@ -2580,7 +2585,7 @@ exports.parseGoModData = parseGoModData;
2580
2585
  * @param {string} rawOutput Output from go list invocation
2581
2586
  * @returns List of packages
2582
2587
  */
2583
- const parseGoListDep = async function (rawOutput, gosumMap) {
2588
+ export const parseGoListDep = async function (rawOutput, gosumMap) {
2584
2589
  if (typeof rawOutput === "string") {
2585
2590
  const deps = [];
2586
2591
  const keys_cache = {};
@@ -2624,14 +2629,13 @@ const parseGoListDep = async function (rawOutput, gosumMap) {
2624
2629
  }
2625
2630
  return [];
2626
2631
  };
2627
- exports.parseGoListDep = parseGoListDep;
2628
2632
 
2629
2633
  /**
2630
2634
  * Parse go mod why output
2631
2635
  * @param {string} rawOutput Output from go mod why
2632
2636
  * @returns package name or none
2633
2637
  */
2634
- const parseGoModWhy = function (rawOutput) {
2638
+ export const parseGoModWhy = function (rawOutput) {
2635
2639
  if (typeof rawOutput === "string") {
2636
2640
  let pkg_name = undefined;
2637
2641
  const tmpA = rawOutput.split("\n");
@@ -2644,9 +2648,8 @@ const parseGoModWhy = function (rawOutput) {
2644
2648
  }
2645
2649
  return undefined;
2646
2650
  };
2647
- exports.parseGoModWhy = parseGoModWhy;
2648
2651
 
2649
- const parseGosumData = async function (gosumData) {
2652
+ export const parseGosumData = async function (gosumData) {
2650
2653
  const pkgList = [];
2651
2654
  if (!gosumData) {
2652
2655
  return pkgList;
@@ -2682,9 +2685,8 @@ const parseGosumData = async function (gosumData) {
2682
2685
  }
2683
2686
  return pkgList;
2684
2687
  };
2685
- exports.parseGosumData = parseGosumData;
2686
2688
 
2687
- const parseGopkgData = async function (gopkgData) {
2689
+ export const parseGopkgData = async function (gopkgData) {
2688
2690
  const pkgList = [];
2689
2691
  if (!gopkgData) {
2690
2692
  return pkgList;
@@ -2732,9 +2734,8 @@ const parseGopkgData = async function (gopkgData) {
2732
2734
  }
2733
2735
  return pkgList;
2734
2736
  };
2735
- exports.parseGopkgData = parseGopkgData;
2736
2737
 
2737
- const parseGoVersionData = async function (buildInfoData) {
2738
+ export const parseGoVersionData = async function (buildInfoData) {
2738
2739
  const pkgList = [];
2739
2740
  if (!buildInfoData) {
2740
2741
  return pkgList;
@@ -2759,14 +2760,13 @@ const parseGoVersionData = async function (buildInfoData) {
2759
2760
  }
2760
2761
  return pkgList;
2761
2762
  };
2762
- exports.parseGoVersionData = parseGoVersionData;
2763
2763
 
2764
2764
  /**
2765
2765
  * Method to query rubygems api for gems details
2766
2766
  *
2767
2767
  * @param {*} pkgList List of packages with metadata
2768
2768
  */
2769
- const getRubyGemsMetadata = async function (pkgList) {
2769
+ export const getRubyGemsMetadata = async function (pkgList) {
2770
2770
  const RUBYGEMS_URL = "https://rubygems.org/api/v1/versions/";
2771
2771
  const rdepList = [];
2772
2772
  for (const p of pkgList) {
@@ -2774,7 +2774,7 @@ const getRubyGemsMetadata = async function (pkgList) {
2774
2774
  if (DEBUG_MODE) {
2775
2775
  console.log(`Querying rubygems.org for ${p.name}`);
2776
2776
  }
2777
- const res = await got.get(RUBYGEMS_URL + p.name + ".json", {
2777
+ const res = await cdxgenAgent.get(RUBYGEMS_URL + p.name + ".json", {
2778
2778
  responseType: "json"
2779
2779
  });
2780
2780
  let body = res.body;
@@ -2810,14 +2810,13 @@ const getRubyGemsMetadata = async function (pkgList) {
2810
2810
  }
2811
2811
  return rdepList;
2812
2812
  };
2813
- exports.getRubyGemsMetadata = getRubyGemsMetadata;
2814
2813
 
2815
2814
  /**
2816
2815
  * Method to parse Gemspec
2817
2816
  *
2818
2817
  * @param {*} gemspecData Gemspec data
2819
2818
  */
2820
- const parseGemspecData = async function (gemspecData) {
2819
+ export const parseGemspecData = async function (gemspecData) {
2821
2820
  let pkgList = [];
2822
2821
  const pkg = {};
2823
2822
  if (!gemspecData) {
@@ -2849,14 +2848,13 @@ const parseGemspecData = async function (gemspecData) {
2849
2848
  return pkgList;
2850
2849
  }
2851
2850
  };
2852
- exports.parseGemspecData = parseGemspecData;
2853
2851
 
2854
2852
  /**
2855
2853
  * Method to parse Gemfile.lock
2856
2854
  *
2857
2855
  * @param {*} gemLockData Gemfile.lock data
2858
2856
  */
2859
- const parseGemfileLockData = async function (gemLockData) {
2857
+ export const parseGemfileLockData = async function (gemLockData) {
2860
2858
  const pkgList = [];
2861
2859
  const pkgnames = {};
2862
2860
  if (!gemLockData) {
@@ -2898,14 +2896,13 @@ const parseGemfileLockData = async function (gemLockData) {
2898
2896
  return pkgList;
2899
2897
  }
2900
2898
  };
2901
- exports.parseGemfileLockData = parseGemfileLockData;
2902
2899
 
2903
2900
  /**
2904
2901
  * Method to retrieve metadata for rust packages by querying crates
2905
2902
  *
2906
2903
  * @param {Array} pkgList Package list
2907
2904
  */
2908
- const getCratesMetadata = async function (pkgList) {
2905
+ export const getCratesMetadata = async function (pkgList) {
2909
2906
  const CRATES_URL = "https://crates.io/api/v1/crates/";
2910
2907
  const cdepList = [];
2911
2908
  for (const p of pkgList) {
@@ -2913,7 +2910,9 @@ const getCratesMetadata = async function (pkgList) {
2913
2910
  if (DEBUG_MODE) {
2914
2911
  console.log(`Querying crates.io for ${p.name}`);
2915
2912
  }
2916
- const res = await got.get(CRATES_URL + p.name, { responseType: "json" });
2913
+ const res = await cdxgenAgent.get(CRATES_URL + p.name, {
2914
+ responseType: "json"
2915
+ });
2917
2916
  const body = res.body.crate;
2918
2917
  p.description = body.description;
2919
2918
  if (res.body.versions) {
@@ -2937,14 +2936,13 @@ const getCratesMetadata = async function (pkgList) {
2937
2936
  }
2938
2937
  return cdepList;
2939
2938
  };
2940
- exports.getCratesMetadata = getCratesMetadata;
2941
2939
 
2942
2940
  /**
2943
2941
  * Method to retrieve metadata for dart packages by querying pub.dev
2944
2942
  *
2945
2943
  * @param {Array} pkgList Package list
2946
2944
  */
2947
- const getDartMetadata = async function (pkgList) {
2945
+ export const getDartMetadata = async function (pkgList) {
2948
2946
  const PUB_DEV_URL = "https://pub.dev/api/packages/";
2949
2947
  const cdepList = [];
2950
2948
  for (const p of pkgList) {
@@ -2952,9 +2950,11 @@ const getDartMetadata = async function (pkgList) {
2952
2950
  if (DEBUG_MODE) {
2953
2951
  console.log(`Querying pub.dev for ${p.name}`);
2954
2952
  }
2955
- const res = await got.get(PUB_DEV_URL + p.name, {
2953
+ const res = await cdxgenAgent.get(PUB_DEV_URL + p.name, {
2956
2954
  responseType: "json",
2957
- Accept: "application/vnd.pub.v2+json"
2955
+ headers: {
2956
+ Accept: "application/vnd.pub.v2+json"
2957
+ }
2958
2958
  });
2959
2959
  if (res && res.body) {
2960
2960
  const versions = res.body.versions;
@@ -2980,9 +2980,8 @@ const getDartMetadata = async function (pkgList) {
2980
2980
  }
2981
2981
  return cdepList;
2982
2982
  };
2983
- exports.getDartMetadata = getDartMetadata;
2984
2983
 
2985
- const parseCargoTomlData = async function (cargoData) {
2984
+ export const parseCargoTomlData = async function (cargoData) {
2986
2985
  let pkgList = [];
2987
2986
  if (!cargoData) {
2988
2987
  return pkgList;
@@ -3017,11 +3016,11 @@ const parseCargoTomlData = async function (cargoData) {
3017
3016
  pkg._integrity = "sha384-" + value;
3018
3017
  break;
3019
3018
  case "name":
3020
- pkg.group = path.dirname(value);
3019
+ pkg.group = dirname(value);
3021
3020
  if (pkg.group === ".") {
3022
3021
  pkg.group = "";
3023
3022
  }
3024
- pkg.name = path.basename(value);
3023
+ pkg.name = basename(value);
3025
3024
  break;
3026
3025
  case "version":
3027
3026
  pkg.version = value;
@@ -3065,9 +3064,8 @@ const parseCargoTomlData = async function (cargoData) {
3065
3064
  return pkgList;
3066
3065
  }
3067
3066
  };
3068
- exports.parseCargoTomlData = parseCargoTomlData;
3069
3067
 
3070
- const parseCargoData = async function (cargoData) {
3068
+ export const parseCargoData = async function (cargoData) {
3071
3069
  const pkgList = [];
3072
3070
  if (!cargoData) {
3073
3071
  return pkgList;
@@ -3095,11 +3093,11 @@ const parseCargoData = async function (cargoData) {
3095
3093
  pkg._integrity = "sha384-" + value;
3096
3094
  break;
3097
3095
  case "name":
3098
- pkg.group = path.dirname(value);
3096
+ pkg.group = dirname(value);
3099
3097
  if (pkg.group === ".") {
3100
3098
  pkg.group = "";
3101
3099
  }
3102
- pkg.name = path.basename(value);
3100
+ pkg.name = basename(value);
3103
3101
  break;
3104
3102
  case "version":
3105
3103
  pkg.version = value;
@@ -3113,9 +3111,8 @@ const parseCargoData = async function (cargoData) {
3113
3111
  return pkgList;
3114
3112
  }
3115
3113
  };
3116
- exports.parseCargoData = parseCargoData;
3117
3114
 
3118
- const parseCargoAuditableData = async function (cargoData) {
3115
+ export const parseCargoAuditableData = async function (cargoData) {
3119
3116
  const pkgList = [];
3120
3117
  if (!cargoData) {
3121
3118
  return pkgList;
@@ -3123,8 +3120,8 @@ const parseCargoAuditableData = async function (cargoData) {
3123
3120
  cargoData.split("\n").forEach((l) => {
3124
3121
  const tmpA = l.split("\t");
3125
3122
  if (tmpA && tmpA.length > 2) {
3126
- let group = path.dirname(tmpA[0].trim());
3127
- const name = path.basename(tmpA[0].trim());
3123
+ let group = dirname(tmpA[0].trim());
3124
+ const name = basename(tmpA[0].trim());
3128
3125
  if (group === ".") {
3129
3126
  group = "";
3130
3127
  }
@@ -3142,9 +3139,8 @@ const parseCargoAuditableData = async function (cargoData) {
3142
3139
  return pkgList;
3143
3140
  }
3144
3141
  };
3145
- exports.parseCargoAuditableData = parseCargoAuditableData;
3146
3142
 
3147
- const parsePubLockData = async function (pubLockData) {
3143
+ export const parsePubLockData = async function (pubLockData) {
3148
3144
  const pkgList = [];
3149
3145
  if (!pubLockData) {
3150
3146
  return pkgList;
@@ -3182,13 +3178,12 @@ const parsePubLockData = async function (pubLockData) {
3182
3178
  return pkgList;
3183
3179
  }
3184
3180
  };
3185
- exports.parsePubLockData = parsePubLockData;
3186
3181
 
3187
- const parsePubYamlData = async function (pubYamlData) {
3182
+ export const parsePubYamlData = async function (pubYamlData) {
3188
3183
  const pkgList = [];
3189
3184
  let yamlObj = undefined;
3190
3185
  try {
3191
- yamlObj = yaml.load(pubYamlData);
3186
+ yamlObj = _load(pubYamlData);
3192
3187
  } catch (err) {
3193
3188
  // continue regardless of error
3194
3189
  }
@@ -3203,13 +3198,12 @@ const parsePubYamlData = async function (pubYamlData) {
3203
3198
  });
3204
3199
  return pkgList;
3205
3200
  };
3206
- exports.parsePubYamlData = parsePubYamlData;
3207
3201
 
3208
- const parseHelmYamlData = async function (helmData) {
3202
+ export const parseHelmYamlData = async function (helmData) {
3209
3203
  const pkgList = [];
3210
3204
  let yamlObj = undefined;
3211
3205
  try {
3212
- yamlObj = yaml.load(helmData);
3206
+ yamlObj = _load(helmData);
3213
3207
  } catch (err) {
3214
3208
  // continue regardless of error
3215
3209
  }
@@ -3269,9 +3263,8 @@ const parseHelmYamlData = async function (helmData) {
3269
3263
  }
3270
3264
  return pkgList;
3271
3265
  };
3272
- exports.parseHelmYamlData = parseHelmYamlData;
3273
3266
 
3274
- const recurseImageNameLookup = (keyValueObj, pkgList, imgList) => {
3267
+ export const recurseImageNameLookup = (keyValueObj, pkgList, imgList) => {
3275
3268
  if (typeof keyValueObj === "string" || keyValueObj instanceof String) {
3276
3269
  return imgList;
3277
3270
  }
@@ -3333,9 +3326,8 @@ const recurseImageNameLookup = (keyValueObj, pkgList, imgList) => {
3333
3326
  }
3334
3327
  return imgList;
3335
3328
  };
3336
- exports.recurseImageNameLookup = recurseImageNameLookup;
3337
3329
 
3338
- const parseContainerSpecData = async function (dcData) {
3330
+ export const parseContainerSpecData = async function (dcData) {
3339
3331
  const pkgList = [];
3340
3332
  const imgList = [];
3341
3333
  if (!dcData.includes("image") && !dcData.includes("kind")) {
@@ -3348,7 +3340,7 @@ const parseContainerSpecData = async function (dcData) {
3348
3340
  for (const dcData of dcDataList) {
3349
3341
  let yamlObj = undefined;
3350
3342
  try {
3351
- yamlObj = yaml.load(dcData);
3343
+ yamlObj = _load(dcData);
3352
3344
  } catch (err) {
3353
3345
  // ignore errors
3354
3346
  }
@@ -3401,9 +3393,8 @@ const parseContainerSpecData = async function (dcData) {
3401
3393
  }
3402
3394
  return pkgList;
3403
3395
  };
3404
- exports.parseContainerSpecData = parseContainerSpecData;
3405
3396
 
3406
- const identifyFlow = function (processingObj) {
3397
+ export const identifyFlow = function (processingObj) {
3407
3398
  let flow = "unknown";
3408
3399
  if (processingObj.sinkId) {
3409
3400
  let sinkId = processingObj.sinkId.toLowerCase();
@@ -3429,8 +3420,8 @@ const convertProcessing = function (processing_list) {
3429
3420
  return data_list;
3430
3421
  };
3431
3422
 
3432
- const parsePrivadoFile = function (f) {
3433
- const pData = fs.readFileSync(f, { encoding: "utf-8" });
3423
+ export const parsePrivadoFile = function (f) {
3424
+ const pData = readFileSync(f, { encoding: "utf-8" });
3434
3425
  const servlist = [];
3435
3426
  if (!pData) {
3436
3427
  return servlist;
@@ -3513,16 +3504,15 @@ const parsePrivadoFile = function (f) {
3513
3504
  }
3514
3505
  return servlist;
3515
3506
  };
3516
- exports.parsePrivadoFile = parsePrivadoFile;
3517
3507
 
3518
- const parseOpenapiSpecData = async function (oaData) {
3508
+ export const parseOpenapiSpecData = async function (oaData) {
3519
3509
  const servlist = [];
3520
3510
  if (!oaData) {
3521
3511
  return servlist;
3522
3512
  }
3523
3513
  try {
3524
3514
  if (oaData.startsWith("openapi:")) {
3525
- oaData = yaml.load(oaData);
3515
+ oaData = _load(oaData);
3526
3516
  } else {
3527
3517
  oaData = JSON.parse(oaData);
3528
3518
  }
@@ -3564,9 +3554,8 @@ const parseOpenapiSpecData = async function (oaData) {
3564
3554
  servlist.push(aservice);
3565
3555
  return servlist;
3566
3556
  };
3567
- exports.parseOpenapiSpecData = parseOpenapiSpecData;
3568
3557
 
3569
- const parseCabalData = async function (cabalData) {
3558
+ export const parseCabalData = async function (cabalData) {
3570
3559
  const pkgList = [];
3571
3560
  if (!cabalData) {
3572
3561
  return pkgList;
@@ -3592,9 +3581,8 @@ const parseCabalData = async function (cabalData) {
3592
3581
  });
3593
3582
  return pkgList;
3594
3583
  };
3595
- exports.parseCabalData = parseCabalData;
3596
3584
 
3597
- const parseMixLockData = async function (mixData) {
3585
+ export const parseMixLockData = async function (mixData) {
3598
3586
  const pkgList = [];
3599
3587
  if (!mixData) {
3600
3588
  return pkgList;
@@ -3619,15 +3607,14 @@ const parseMixLockData = async function (mixData) {
3619
3607
  });
3620
3608
  return pkgList;
3621
3609
  };
3622
- exports.parseMixLockData = parseMixLockData;
3623
3610
 
3624
- const parseGitHubWorkflowData = async function (ghwData) {
3611
+ export const parseGitHubWorkflowData = async function (ghwData) {
3625
3612
  const pkgList = [];
3626
3613
  const keys_cache = {};
3627
3614
  if (!ghwData) {
3628
3615
  return pkgList;
3629
3616
  }
3630
- const yamlObj = yaml.load(ghwData);
3617
+ const yamlObj = _load(ghwData);
3631
3618
  if (!yamlObj) {
3632
3619
  return pkgList;
3633
3620
  }
@@ -3662,15 +3649,14 @@ const parseGitHubWorkflowData = async function (ghwData) {
3662
3649
  }
3663
3650
  return pkgList;
3664
3651
  };
3665
- exports.parseGitHubWorkflowData = parseGitHubWorkflowData;
3666
3652
 
3667
- const parseCloudBuildData = async function (cbwData) {
3653
+ export const parseCloudBuildData = async function (cbwData) {
3668
3654
  const pkgList = [];
3669
3655
  const keys_cache = {};
3670
3656
  if (!cbwData) {
3671
3657
  return pkgList;
3672
3658
  }
3673
- const yamlObj = yaml.load(cbwData);
3659
+ const yamlObj = _load(cbwData);
3674
3660
  if (!yamlObj) {
3675
3661
  return pkgList;
3676
3662
  }
@@ -3679,8 +3665,8 @@ const parseCloudBuildData = async function (cbwData) {
3679
3665
  if (step.name) {
3680
3666
  const tmpA = step.name.split(":");
3681
3667
  if (tmpA.length === 2) {
3682
- let group = path.dirname(tmpA[0]);
3683
- let name = path.basename(tmpA[0]);
3668
+ let group = dirname(tmpA[0]);
3669
+ let name = basename(tmpA[0]);
3684
3670
  if (group === ".") {
3685
3671
  group = "";
3686
3672
  }
@@ -3700,9 +3686,8 @@ const parseCloudBuildData = async function (cbwData) {
3700
3686
  }
3701
3687
  return pkgList;
3702
3688
  };
3703
- exports.parseCloudBuildData = parseCloudBuildData;
3704
3689
 
3705
- const parseConanLockData = async function (conanLockData) {
3690
+ export const parseConanLockData = async function (conanLockData) {
3706
3691
  const pkgList = [];
3707
3692
  if (!conanLockData) {
3708
3693
  return pkgList;
@@ -3722,9 +3707,8 @@ const parseConanLockData = async function (conanLockData) {
3722
3707
  }
3723
3708
  return pkgList;
3724
3709
  };
3725
- exports.parseConanLockData = parseConanLockData;
3726
3710
 
3727
- const parseConanData = async function (conanData) {
3711
+ export const parseConanData = async function (conanData) {
3728
3712
  const pkgList = [];
3729
3713
  if (!conanData) {
3730
3714
  return pkgList;
@@ -3742,9 +3726,8 @@ const parseConanData = async function (conanData) {
3742
3726
  });
3743
3727
  return pkgList;
3744
3728
  };
3745
- exports.parseConanData = parseConanData;
3746
3729
 
3747
- const parseLeiningenData = function (leinData) {
3730
+ export const parseLeiningenData = function (leinData) {
3748
3731
  const pkgList = [];
3749
3732
  if (!leinData) {
3750
3733
  return pkgList;
@@ -3753,7 +3736,7 @@ const parseLeiningenData = function (leinData) {
3753
3736
  if (tmpArr.length > 1) {
3754
3737
  leinData = "(defproject" + tmpArr[1];
3755
3738
  }
3756
- const ednData = ednDataLib.parseEDNString(leinData);
3739
+ const ednData = parseEDNString(leinData);
3757
3740
  for (let k of Object.keys(ednData)) {
3758
3741
  if (k === "list") {
3759
3742
  ednData[k].forEach((jk) => {
@@ -3762,11 +3745,11 @@ const parseLeiningenData = function (leinData) {
3762
3745
  if (Array.isArray(pobjl) && pobjl.length > 1) {
3763
3746
  const psym = pobjl[0].sym;
3764
3747
  if (psym) {
3765
- let group = path.dirname(psym) || "";
3748
+ let group = dirname(psym) || "";
3766
3749
  if (group === ".") {
3767
3750
  group = "";
3768
3751
  }
3769
- const name = path.basename(psym);
3752
+ const name = basename(psym);
3770
3753
  pkgList.push({ group, name, version: pobjl[1] });
3771
3754
  }
3772
3755
  }
@@ -3777,14 +3760,13 @@ const parseLeiningenData = function (leinData) {
3777
3760
  }
3778
3761
  return pkgList;
3779
3762
  };
3780
- exports.parseLeiningenData = parseLeiningenData;
3781
3763
 
3782
- const parseEdnData = function (rawEdnData) {
3764
+ export const parseEdnData = function (rawEdnData) {
3783
3765
  const pkgList = [];
3784
3766
  if (!rawEdnData) {
3785
3767
  return pkgList;
3786
3768
  }
3787
- const ednData = ednDataLib.parseEDNString(rawEdnData);
3769
+ const ednData = parseEDNString(rawEdnData);
3788
3770
  const pkgCache = {};
3789
3771
  for (let k of Object.keys(ednData)) {
3790
3772
  if (k === "map") {
@@ -3805,11 +3787,11 @@ const parseEdnData = function (rawEdnData) {
3805
3787
  if (e["map"]) {
3806
3788
  if (e["map"][0].length > 1) {
3807
3789
  const version = e["map"][0][1];
3808
- let group = path.dirname(psym) || "";
3790
+ let group = dirname(psym) || "";
3809
3791
  if (group === ".") {
3810
3792
  group = "";
3811
3793
  }
3812
- const name = path.basename(psym);
3794
+ const name = basename(psym);
3813
3795
  const cacheKey = group + "-" + name + "-" + version;
3814
3796
  if (!pkgCache[cacheKey]) {
3815
3797
  pkgList.push({ group, name, version });
@@ -3830,9 +3812,8 @@ const parseEdnData = function (rawEdnData) {
3830
3812
  }
3831
3813
  return pkgList;
3832
3814
  };
3833
- exports.parseEdnData = parseEdnData;
3834
3815
 
3835
- const parseNupkg = async function (nupkgFile) {
3816
+ export const parseNupkg = async function (nupkgFile) {
3836
3817
  const pkgList = [];
3837
3818
  let pkg = { group: "" };
3838
3819
  let nuspecData = await readZipEntry(nupkgFile, ".nuspec");
@@ -3842,7 +3823,7 @@ const parseNupkg = async function (nupkgFile) {
3842
3823
  }
3843
3824
  let npkg = undefined;
3844
3825
  try {
3845
- npkg = convert.xml2js(nuspecData, {
3826
+ npkg = xml2js(nuspecData, {
3846
3827
  compact: true,
3847
3828
  alwaysArray: false,
3848
3829
  spaces: 4,
@@ -3876,14 +3857,13 @@ const parseNupkg = async function (nupkgFile) {
3876
3857
  return pkgList;
3877
3858
  }
3878
3859
  };
3879
- exports.parseNupkg = parseNupkg;
3880
3860
 
3881
- const parseCsPkgData = async function (pkgData) {
3861
+ export const parseCsPkgData = async function (pkgData) {
3882
3862
  const pkgList = [];
3883
3863
  if (!pkgData) {
3884
3864
  return pkgList;
3885
3865
  }
3886
- let packages = convert.xml2js(pkgData, {
3866
+ let packages = xml2js(pkgData, {
3887
3867
  compact: true,
3888
3868
  alwaysArray: true,
3889
3869
  spaces: 4,
@@ -3908,14 +3888,13 @@ const parseCsPkgData = async function (pkgData) {
3908
3888
  return pkgList;
3909
3889
  }
3910
3890
  };
3911
- exports.parseCsPkgData = parseCsPkgData;
3912
3891
 
3913
- const parseCsProjData = async function (csProjData) {
3892
+ export const parseCsProjData = async function (csProjData) {
3914
3893
  const pkgList = [];
3915
3894
  if (!csProjData) {
3916
3895
  return pkgList;
3917
3896
  }
3918
- const projects = convert.xml2js(csProjData, {
3897
+ const projects = xml2js(csProjData, {
3919
3898
  compact: true,
3920
3899
  alwaysArray: true,
3921
3900
  spaces: 4,
@@ -3963,9 +3942,8 @@ const parseCsProjData = async function (csProjData) {
3963
3942
  return pkgList;
3964
3943
  }
3965
3944
  };
3966
- exports.parseCsProjData = parseCsProjData;
3967
3945
 
3968
- const parseCsProjAssetsData = async function (csProjData) {
3946
+ export const parseCsProjAssetsData = async function (csProjData) {
3969
3947
  const pkgList = [];
3970
3948
  let pkg = null;
3971
3949
  if (!csProjData) {
@@ -4003,9 +3981,8 @@ const parseCsProjAssetsData = async function (csProjData) {
4003
3981
  return pkgList;
4004
3982
  }
4005
3983
  };
4006
- exports.parseCsProjAssetsData = parseCsProjAssetsData;
4007
3984
 
4008
- const parseCsPkgLockData = async function (csLockData) {
3985
+ export const parseCsPkgLockData = async function (csLockData) {
4009
3986
  const pkgList = [];
4010
3987
  let pkg = null;
4011
3988
  if (!csLockData) {
@@ -4032,81 +4009,127 @@ const parseCsPkgLockData = async function (csLockData) {
4032
4009
  return pkgList;
4033
4010
  }
4034
4011
  };
4035
- exports.parseCsPkgLockData = parseCsPkgLockData;
4036
4012
 
4037
4013
  /**
4038
4014
  * Method to retrieve metadata for nuget packages
4039
4015
  *
4040
4016
  * @param {Array} pkgList Package list
4041
4017
  */
4042
- const getNugetMetadata = async function (pkgList) {
4018
+ export const getNugetMetadata = async function (pkgList) {
4043
4019
  const NUGET_URL = "https://api.nuget.org/v3/registration3/";
4044
4020
  const cdepList = [];
4045
4021
  for (const p of pkgList) {
4022
+ let cacheKey = undefined;
4046
4023
  try {
4047
- if (DEBUG_MODE) {
4048
- console.log(`Querying nuget for ${p.name}`);
4049
- }
4050
- const res = await got.get(
4051
- NUGET_URL +
4052
- p.group.toLowerCase() +
4053
- (p.group !== "" ? "." : "") +
4054
- p.name.toLowerCase() +
4055
- "/index.json",
4056
- { responseType: "json" }
4057
- );
4058
- const items = res.body.items;
4059
- if (!items || !items[0] || !items[0].items) {
4060
- continue;
4061
- }
4062
- const firstItem = items[0];
4063
- const body = firstItem.items[firstItem.items.length - 1];
4064
- // Set the latest version in case it is missing
4065
- if (!p.version && body.catalogEntry.version) {
4066
- p.version = body.catalogEntry.version;
4067
- }
4068
- p.description = body.catalogEntry.description;
4069
4024
  if (
4070
- body.catalogEntry.licenseExpression &&
4071
- body.catalogEntry.licenseExpression !== ""
4025
+ (p.group && p.group.toLowerCase() === "system") ||
4026
+ p.name.toLowerCase().startsWith("system")
4072
4027
  ) {
4073
- p.license = findLicenseId(body.catalogEntry.licenseExpression);
4074
- } else if (body.catalogEntry.licenseUrl) {
4075
- p.license = body.catalogEntry.licenseUrl;
4076
- }
4077
- if (body.catalogEntry.projectUrl) {
4078
- p.repository = { url: body.catalogEntry.projectUrl };
4079
- p.homepage = {
4080
- url:
4081
- "https://www.nuget.org/packages/" +
4082
- p.group +
4083
- (p.group !== "" ? "." : "") +
4084
- p.name +
4085
- "/" +
4086
- p.version +
4087
- "/"
4088
- };
4028
+ p.license = "http://go.microsoft.com/fwlink/?LinkId=329770";
4029
+ } else if (
4030
+ (p.group && p.group.toLowerCase() === "microsoft") ||
4031
+ p.name.toLowerCase().startsWith("microsoft")
4032
+ ) {
4033
+ p.license =
4034
+ "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm";
4035
+ } else if (
4036
+ (p.group && p.group.toLowerCase() === "nuget") ||
4037
+ p.name.toLowerCase().startsWith("nuget")
4038
+ ) {
4039
+ p.license = "Apache-2.0";
4040
+ } else {
4041
+ // If there is a version, we can safely use the cache to retrieve the license
4042
+ // See: https://github.com/CycloneDX/cdxgen/issues/352
4043
+ const twoPartName = p.name.split(".").slice(0, 2).join(".");
4044
+ cacheKey = `${p.group}|${twoPartName}`;
4045
+ let body = metadata_cache[cacheKey];
4046
+ if (body && body.error) {
4047
+ cdepList.push(p);
4048
+ continue;
4049
+ }
4050
+ if (!body) {
4051
+ if (DEBUG_MODE) {
4052
+ console.log(`Querying nuget for ${p.name}`);
4053
+ }
4054
+ const res = await cdxgenAgent.get(
4055
+ NUGET_URL +
4056
+ p.group.toLowerCase() +
4057
+ (p.group !== "" ? "." : "") +
4058
+ p.name.toLowerCase() +
4059
+ "/index.json",
4060
+ { responseType: "json" }
4061
+ );
4062
+ const items = res.body.items;
4063
+ if (!items || !items[0] || !items[0].items) {
4064
+ continue;
4065
+ }
4066
+ const firstItem = items[0];
4067
+ // Work backwards to find the body for the matching version
4068
+ body = firstItem.items[firstItem.items.length - 1];
4069
+ if (p.version) {
4070
+ const newBody = firstItem.items
4071
+ .reverse()
4072
+ .filter(
4073
+ (i) => i.catalogEntry && i.catalogEntry.version === p.version
4074
+ );
4075
+ if (newBody && newBody.length) {
4076
+ body = newBody[0];
4077
+ }
4078
+ }
4079
+ metadata_cache[cacheKey] = body;
4080
+ }
4081
+ // Set the latest version in case it is missing
4082
+ if (!p.version && body.catalogEntry.version) {
4083
+ p.version = body.catalogEntry.version;
4084
+ }
4085
+ p.description = body.catalogEntry.description;
4086
+ if (body.catalogEntry.authors) {
4087
+ p.author = body.catalogEntry.authors.trim();
4088
+ }
4089
+ if (
4090
+ body.catalogEntry.licenseExpression &&
4091
+ body.catalogEntry.licenseExpression !== ""
4092
+ ) {
4093
+ p.license = findLicenseId(body.catalogEntry.licenseExpression);
4094
+ } else if (body.catalogEntry.licenseUrl) {
4095
+ p.license = findLicenseId(body.catalogEntry.licenseUrl);
4096
+ }
4097
+ if (body.catalogEntry.projectUrl) {
4098
+ p.repository = { url: body.catalogEntry.projectUrl };
4099
+ p.homepage = {
4100
+ url:
4101
+ "https://www.nuget.org/packages/" +
4102
+ p.group +
4103
+ (p.group !== "" ? "." : "") +
4104
+ p.name +
4105
+ "/" +
4106
+ p.version +
4107
+ "/"
4108
+ };
4109
+ }
4089
4110
  }
4090
4111
  cdepList.push(p);
4091
4112
  } catch (err) {
4113
+ if (cacheKey) {
4114
+ metadata_cache[cacheKey] = { error: err.code };
4115
+ }
4092
4116
  cdepList.push(p);
4093
4117
  }
4094
4118
  }
4095
4119
  return cdepList;
4096
4120
  };
4097
- exports.getNugetMetadata = getNugetMetadata;
4098
4121
 
4099
4122
  /**
4100
4123
  * Parse composer lock file
4101
4124
  *
4102
4125
  * @param {string} pkgLockFile composer.lock file
4103
4126
  */
4104
- const parseComposerLock = function (pkgLockFile) {
4127
+ export const parseComposerLock = function (pkgLockFile) {
4105
4128
  const pkgList = [];
4106
- if (fs.existsSync(pkgLockFile)) {
4129
+ if (existsSync(pkgLockFile)) {
4107
4130
  let lockData = {};
4108
4131
  try {
4109
- lockData = JSON.parse(fs.readFileSync(pkgLockFile, "utf8"));
4132
+ lockData = JSON.parse(readFileSync(pkgLockFile, "utf8"));
4110
4133
  } catch (e) {
4111
4134
  console.error("Invalid composer.lock file:", pkgLockFile);
4112
4135
  return [];
@@ -4126,11 +4149,11 @@ const parseComposerLock = function (pkgLockFile) {
4126
4149
  if (!pkg || !pkg.name || !pkg.version) {
4127
4150
  continue;
4128
4151
  }
4129
- let group = path.dirname(pkg.name);
4152
+ let group = dirname(pkg.name);
4130
4153
  if (group === ".") {
4131
4154
  group = "";
4132
4155
  }
4133
- let name = path.basename(pkg.name);
4156
+ let name = basename(pkg.name);
4134
4157
  pkgList.push({
4135
4158
  group: group,
4136
4159
  name: name,
@@ -4156,17 +4179,16 @@ const parseComposerLock = function (pkgLockFile) {
4156
4179
  }
4157
4180
  return pkgList;
4158
4181
  };
4159
- exports.parseComposerLock = parseComposerLock;
4160
4182
 
4161
4183
  /**
4162
4184
  * Parse sbt lock file
4163
4185
  *
4164
4186
  * @param {string} pkgLockFile build.sbt.lock file
4165
4187
  */
4166
- const parseSbtLock = function (pkgLockFile) {
4188
+ export const parseSbtLock = function (pkgLockFile) {
4167
4189
  const pkgList = [];
4168
- if (fs.existsSync(pkgLockFile)) {
4169
- const lockData = JSON.parse(fs.readFileSync(pkgLockFile, "utf8"));
4190
+ if (existsSync(pkgLockFile)) {
4191
+ const lockData = JSON.parse(readFileSync(pkgLockFile, "utf8"));
4170
4192
  if (lockData && lockData.dependencies) {
4171
4193
  for (let pkg of lockData.dependencies) {
4172
4194
  const artifacts = pkg.artifacts || undefined;
@@ -4200,7 +4222,6 @@ const parseSbtLock = function (pkgLockFile) {
4200
4222
  }
4201
4223
  return pkgList;
4202
4224
  };
4203
- exports.parseSbtLock = parseSbtLock;
4204
4225
 
4205
4226
  /**
4206
4227
  * Convert OS query results
@@ -4208,7 +4229,11 @@ exports.parseSbtLock = parseSbtLock;
4208
4229
  * @param {Object} queryObj Query Object from the queries.json configuration
4209
4230
  * @param {Array} results Query Results
4210
4231
  */
4211
- const convertOSQueryResults = function (queryCategory, queryObj, results) {
4232
+ export const convertOSQueryResults = function (
4233
+ queryCategory,
4234
+ queryObj,
4235
+ results
4236
+ ) {
4212
4237
  const pkgList = [];
4213
4238
  if (results && results.length) {
4214
4239
  for (const res of results) {
@@ -4260,9 +4285,13 @@ const convertOSQueryResults = function (queryCategory, queryObj, results) {
4260
4285
  }
4261
4286
  return pkgList;
4262
4287
  };
4263
- exports.convertOSQueryResults = convertOSQueryResults;
4264
4288
 
4265
- const _swiftDepPkgList = (pkgList, dependenciesList, depKeys, jsonData) => {
4289
+ export const _swiftDepPkgList = (
4290
+ pkgList,
4291
+ dependenciesList,
4292
+ depKeys,
4293
+ jsonData
4294
+ ) => {
4266
4295
  if (jsonData && jsonData.dependencies) {
4267
4296
  for (let adep of jsonData.dependencies) {
4268
4297
  const urlOrPath = adep.url || adep.path;
@@ -4345,7 +4374,7 @@ const _swiftDepPkgList = (pkgList, dependenciesList, depKeys, jsonData) => {
4345
4374
  * @param {string} rawOutput Swift dependencies json output
4346
4375
  * @param {string} pkgFile Package.swift file
4347
4376
  */
4348
- const parseSwiftJsonTree = (rawOutput, pkgFile) => {
4377
+ export const parseSwiftJsonTree = (rawOutput, pkgFile) => {
4349
4378
  if (!rawOutput) {
4350
4379
  return {};
4351
4380
  }
@@ -4420,17 +4449,16 @@ const parseSwiftJsonTree = (rawOutput, pkgFile) => {
4420
4449
  dependenciesList
4421
4450
  };
4422
4451
  };
4423
- exports.parseSwiftJsonTree = parseSwiftJsonTree;
4424
4452
 
4425
4453
  /**
4426
4454
  * Parse swift package resolved file
4427
4455
  * @param {string} resolvedFile Package.resolved file
4428
4456
  */
4429
- const parseSwiftResolved = (resolvedFile) => {
4457
+ export const parseSwiftResolved = (resolvedFile) => {
4430
4458
  const pkgList = [];
4431
- if (fs.existsSync(resolvedFile)) {
4459
+ if (existsSync(resolvedFile)) {
4432
4460
  try {
4433
- const pkgData = JSON.parse(fs.readFileSync(resolvedFile, "utf8"));
4461
+ const pkgData = JSON.parse(readFileSync(resolvedFile, "utf8"));
4434
4462
  let resolvedList = [];
4435
4463
  if (pkgData.pins) {
4436
4464
  resolvedList = pkgData.pins;
@@ -4461,7 +4489,6 @@ const parseSwiftResolved = (resolvedFile) => {
4461
4489
  }
4462
4490
  return pkgList;
4463
4491
  };
4464
- exports.parseSwiftResolved = parseSwiftResolved;
4465
4492
 
4466
4493
  /**
4467
4494
  * Collect maven dependencies
@@ -4469,8 +4496,8 @@ exports.parseSwiftResolved = parseSwiftResolved;
4469
4496
  * @param {string} mavenCmd Maven command to use
4470
4497
  * @param {string} basePath Path to the maven project
4471
4498
  */
4472
- const collectMvnDependencies = function (mavenCmd, basePath) {
4473
- let tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "mvn-deps-"));
4499
+ export const collectMvnDependencies = function (mavenCmd, basePath) {
4500
+ let tempDir = mkdtempSync(join(tmpdir(), "mvn-deps-"));
4474
4501
  console.log(
4475
4502
  `Executing 'mvn dependency:copy-dependencies -DoutputDirectory=${tempDir} -DexcludeTransitive=true -DincludeScope=runtime' in ${basePath}`
4476
4503
  );
@@ -4506,13 +4533,12 @@ const collectMvnDependencies = function (mavenCmd, basePath) {
4506
4533
  jarNSMapping = collectJarNS(tempDir);
4507
4534
  }
4508
4535
  // Clean up
4509
- if (tempDir && tempDir.startsWith(os.tmpdir()) && fs.rmSync) {
4536
+ if (tempDir && tempDir.startsWith(tmpdir()) && rmSync) {
4510
4537
  console.log(`Cleaning up ${tempDir}`);
4511
- fs.rmSync(tempDir, { recursive: true, force: true });
4538
+ rmSync(tempDir, { recursive: true, force: true });
4512
4539
  }
4513
4540
  return jarNSMapping;
4514
4541
  };
4515
- exports.collectMvnDependencies = collectMvnDependencies;
4516
4542
 
4517
4543
  /**
4518
4544
  * Method to collect class names from all jars in a directory
@@ -4521,7 +4547,7 @@ exports.collectMvnDependencies = collectMvnDependencies;
4521
4547
  *
4522
4548
  * @return object containing jar name and class list
4523
4549
  */
4524
- const collectJarNS = function (jarPath) {
4550
+ export const collectJarNS = function (jarPath) {
4525
4551
  const jarNSMapping = {};
4526
4552
  console.log(
4527
4553
  `About to identify class names for all jars in the path ${jarPath}`
@@ -4530,7 +4556,7 @@ const collectJarNS = function (jarPath) {
4530
4556
  const jarFiles = getAllFiles(jarPath, "**/*.jar");
4531
4557
  if (jarFiles && jarFiles.length) {
4532
4558
  for (let jf of jarFiles) {
4533
- const jarname = path.basename(jf);
4559
+ const jarname = basename(jf);
4534
4560
  if (DEBUG_MODE) {
4535
4561
  console.log(`Executing 'jar tf ${jf}'`);
4536
4562
  }
@@ -4567,13 +4593,12 @@ const collectJarNS = function (jarPath) {
4567
4593
  }
4568
4594
  return jarNSMapping;
4569
4595
  };
4570
- exports.collectJarNS = collectJarNS;
4571
4596
 
4572
- const parsePomXml = function (pomXmlData) {
4597
+ export const parsePomXml = function (pomXmlData) {
4573
4598
  if (!pomXmlData) {
4574
4599
  return undefined;
4575
4600
  }
4576
- const project = convert.xml2js(pomXmlData, {
4601
+ const project = xml2js(pomXmlData, {
4577
4602
  compact: true,
4578
4603
  spaces: 4,
4579
4604
  textKey: "_",
@@ -4600,9 +4625,8 @@ const parsePomXml = function (pomXmlData) {
4600
4625
  }
4601
4626
  return undefined;
4602
4627
  };
4603
- exports.parsePomXml = parsePomXml;
4604
4628
 
4605
- const parseJarManifest = function (jarMetadata) {
4629
+ export const parseJarManifest = function (jarMetadata) {
4606
4630
  const metadata = {};
4607
4631
  if (!jarMetadata) {
4608
4632
  return metadata;
@@ -4617,14 +4641,14 @@ const parseJarManifest = function (jarMetadata) {
4617
4641
  });
4618
4642
  return metadata;
4619
4643
  };
4620
- exports.parseJarManifest = parseJarManifest;
4621
4644
 
4622
4645
  const encodeForPurl = (s) => {
4623
4646
  return s
4624
4647
  ? encodeURIComponent(s).replace(/%3A/g, ":").replace(/%2F/g, "/")
4625
4648
  : s;
4626
4649
  };
4627
- exports.encodeForPurl = encodeForPurl;
4650
+ const _encodeForPurl = encodeForPurl;
4651
+ export { _encodeForPurl as encodeForPurl };
4628
4652
 
4629
4653
  /**
4630
4654
  * Method to extract a war or ear file
@@ -4634,27 +4658,23 @@ exports.encodeForPurl = encodeForPurl;
4634
4658
  *
4635
4659
  * @return pkgList Package list
4636
4660
  */
4637
- const extractJarArchive = function (jarFile, tempDir) {
4661
+ export const extractJarArchive = function (jarFile, tempDir) {
4638
4662
  let pkgList = [];
4639
4663
  let jarFiles = [];
4640
- const fname = path.basename(jarFile);
4664
+ const fname = basename(jarFile);
4641
4665
  let pomname = undefined;
4642
4666
  // If there is a pom file in the same directory, try to use it
4643
4667
  if (jarFile.endsWith(".jar")) {
4644
4668
  pomname = jarFile.replace(".jar", ".pom");
4645
4669
  }
4646
- if (pomname && fs.existsSync(pomname)) {
4647
- tempDir = path.dirname(jarFile);
4648
- } else if (!fs.existsSync(path.join(tempDir, fname))) {
4670
+ if (pomname && existsSync(pomname)) {
4671
+ tempDir = dirname(jarFile);
4672
+ } else if (!existsSync(join(tempDir, fname))) {
4649
4673
  // Only copy if the file doesn't exist
4650
- fs.copyFileSync(
4651
- jarFile,
4652
- path.join(tempDir, fname),
4653
- fs.constants.COPYFILE_FICLONE
4654
- );
4674
+ copyFileSync(jarFile, join(tempDir, fname), constants.COPYFILE_FICLONE);
4655
4675
  }
4656
4676
  if (jarFile.endsWith(".war") || jarFile.endsWith(".hpi")) {
4657
- let jarResult = spawnSync("jar", ["-xf", path.join(tempDir, fname)], {
4677
+ let jarResult = spawnSync("jar", ["-xf", join(tempDir, fname)], {
4658
4678
  encoding: "utf-8",
4659
4679
  cwd: tempDir
4660
4680
  });
@@ -4665,17 +4685,17 @@ const extractJarArchive = function (jarFile, tempDir) {
4665
4685
  );
4666
4686
  return pkgList;
4667
4687
  }
4668
- jarFiles = getAllFiles(path.join(tempDir, "WEB-INF", "lib"), "**/*.jar");
4688
+ jarFiles = getAllFiles(join(tempDir, "WEB-INF", "lib"), "**/*.jar");
4669
4689
  if (jarFile.endsWith(".hpi")) {
4670
4690
  jarFiles.push(jarFile);
4671
4691
  }
4672
4692
  } else {
4673
- jarFiles = [path.join(tempDir, fname)];
4693
+ jarFiles = [join(tempDir, fname)];
4674
4694
  }
4675
4695
  if (jarFiles && jarFiles.length) {
4676
4696
  for (let jf of jarFiles) {
4677
4697
  pomname = jf.replace(".jar", ".pom");
4678
- const jarname = path.basename(jf);
4698
+ const jarname = basename(jf);
4679
4699
  // Ignore test jars
4680
4700
  if (
4681
4701
  jarname.endsWith("-tests.jar") ||
@@ -4683,12 +4703,12 @@ const extractJarArchive = function (jarFile, tempDir) {
4683
4703
  ) {
4684
4704
  continue;
4685
4705
  }
4686
- let manifestDir = path.join(tempDir, "META-INF");
4687
- const manifestFile = path.join(manifestDir, "MANIFEST.MF");
4706
+ let manifestDir = join(tempDir, "META-INF");
4707
+ const manifestFile = join(manifestDir, "MANIFEST.MF");
4688
4708
  let jarResult = {
4689
4709
  status: 1
4690
4710
  };
4691
- if (fs.existsSync(pomname)) {
4711
+ if (existsSync(pomname)) {
4692
4712
  jarResult = { status: 0 };
4693
4713
  } else {
4694
4714
  jarResult = spawnSync("jar", ["-xf", jf], {
@@ -4699,9 +4719,9 @@ const extractJarArchive = function (jarFile, tempDir) {
4699
4719
  if (jarResult.status !== 0) {
4700
4720
  console.error(jarResult.stdout, jarResult.stderr);
4701
4721
  } else {
4702
- if (fs.existsSync(manifestFile)) {
4722
+ if (existsSync(manifestFile)) {
4703
4723
  const jarMetadata = parseJarManifest(
4704
- fs.readFileSync(manifestFile, {
4724
+ readFileSync(manifestFile, {
4705
4725
  encoding: "utf-8"
4706
4726
  })
4707
4727
  );
@@ -4732,9 +4752,9 @@ const extractJarArchive = function (jarFile, tempDir) {
4732
4752
  version = version.split(" ")[0];
4733
4753
  }
4734
4754
  if (!name && group) {
4735
- name = path.basename(group.replace(/\./g, "/"));
4755
+ name = basename(group.replace(/\./g, "/"));
4736
4756
  if (!group.startsWith("javax")) {
4737
- group = path.dirname(group.replace(/\./g, "/"));
4757
+ group = dirname(group.replace(/\./g, "/"));
4738
4758
  group = group.replace(/\//g, ".");
4739
4759
  }
4740
4760
  }
@@ -4794,9 +4814,9 @@ const extractJarArchive = function (jarFile, tempDir) {
4794
4814
  }
4795
4815
  }
4796
4816
  try {
4797
- if (fs.rmSync && fs.existsSync(path.join(tempDir, "META-INF"))) {
4817
+ if (rmSync && existsSync(join(tempDir, "META-INF"))) {
4798
4818
  // Clean up META-INF
4799
- fs.rmSync(path.join(tempDir, "META-INF"), {
4819
+ rmSync(join(tempDir, "META-INF"), {
4800
4820
  recursive: true,
4801
4821
  force: true
4802
4822
  });
@@ -4809,7 +4829,6 @@ const extractJarArchive = function (jarFile, tempDir) {
4809
4829
  } // if
4810
4830
  return pkgList;
4811
4831
  };
4812
- exports.extractJarArchive = extractJarArchive;
4813
4832
 
4814
4833
  /**
4815
4834
  * Determine the version of SBT used in compilation of this project.
@@ -4819,18 +4838,17 @@ exports.extractJarArchive = extractJarArchive;
4819
4838
  *
4820
4839
  * @param {string} projectPath Path to the SBT project
4821
4840
  */
4822
- const determineSbtVersion = function (projectPath) {
4823
- const buildPropFile = path.join(projectPath, "project", "build.properties");
4824
- if (fs.existsSync(buildPropFile)) {
4841
+ export const determineSbtVersion = function (projectPath) {
4842
+ const buildPropFile = join(projectPath, "project", "build.properties");
4843
+ if (existsSync(buildPropFile)) {
4825
4844
  let properties = propertiesReader(buildPropFile);
4826
4845
  let property = properties.get("sbt.version");
4827
- if (property != null && semver.valid(property)) {
4846
+ if (property != null && valid(property)) {
4828
4847
  return property;
4829
4848
  }
4830
4849
  }
4831
4850
  return null;
4832
4851
  };
4833
- exports.determineSbtVersion = determineSbtVersion;
4834
4852
 
4835
4853
  /**
4836
4854
  * Adds a new plugin to the SBT project by amending its plugins list.
@@ -4844,22 +4862,17 @@ exports.determineSbtVersion = determineSbtVersion;
4844
4862
  * @param {string} projectPath Path to the SBT project
4845
4863
  * @param {string} plugin Name of the plugin to add
4846
4864
  */
4847
- const addPlugin = function (projectPath, plugin) {
4865
+ export const addPlugin = function (projectPath, plugin) {
4848
4866
  const pluginsFile = sbtPluginsPath(projectPath);
4849
4867
  var originalPluginsFile = null;
4850
- if (fs.existsSync(pluginsFile)) {
4868
+ if (existsSync(pluginsFile)) {
4851
4869
  originalPluginsFile = pluginsFile + ".cdxgen";
4852
- fs.copyFileSync(
4853
- pluginsFile,
4854
- originalPluginsFile,
4855
- fs.constants.COPYFILE_FICLONE
4856
- );
4870
+ copyFileSync(pluginsFile, originalPluginsFile, constants.COPYFILE_FICLONE);
4857
4871
  }
4858
4872
 
4859
- fs.writeFileSync(pluginsFile, plugin, { flag: "a" });
4873
+ writeFileSync(pluginsFile, plugin, { flag: "a" });
4860
4874
  return originalPluginsFile;
4861
4875
  };
4862
- exports.addPlugin = addPlugin;
4863
4876
 
4864
4877
  /**
4865
4878
  * Cleans up modifications to the project's plugins' file made by the
@@ -4868,38 +4881,36 @@ exports.addPlugin = addPlugin;
4868
4881
  * @param {string} projectPath Path to the SBT project
4869
4882
  * @param {string} originalPluginsFile Location of the original plugins file, if any
4870
4883
  */
4871
- const cleanupPlugin = function (projectPath, originalPluginsFile) {
4884
+ export const cleanupPlugin = function (projectPath, originalPluginsFile) {
4872
4885
  const pluginsFile = sbtPluginsPath(projectPath);
4873
- if (fs.existsSync(pluginsFile)) {
4886
+ if (existsSync(pluginsFile)) {
4874
4887
  if (!originalPluginsFile) {
4875
4888
  // just remove the file, it was never there
4876
- fs.unlinkSync(pluginsFile);
4877
- return !fs.existsSync(pluginsFile);
4889
+ unlinkSync(pluginsFile);
4890
+ return !existsSync(pluginsFile);
4878
4891
  } else {
4879
4892
  // Bring back the original file
4880
- fs.copyFileSync(
4893
+ copyFileSync(
4881
4894
  originalPluginsFile,
4882
4895
  pluginsFile,
4883
- fs.constants.COPYFILE_FICLONE
4896
+ constants.COPYFILE_FICLONE
4884
4897
  );
4885
- fs.unlinkSync(originalPluginsFile);
4898
+ unlinkSync(originalPluginsFile);
4886
4899
  return true;
4887
4900
  }
4888
4901
  } else {
4889
4902
  return false;
4890
4903
  }
4891
4904
  };
4892
- exports.cleanupPlugin = cleanupPlugin;
4893
4905
 
4894
4906
  /**
4895
4907
  * Returns a default location of the plugins file.
4896
4908
  *
4897
4909
  * @param {string} projectPath Path to the SBT project
4898
4910
  */
4899
- const sbtPluginsPath = function (projectPath) {
4900
- return path.join(projectPath, "project", "plugins.sbt");
4911
+ export const sbtPluginsPath = function (projectPath) {
4912
+ return join(projectPath, "project", "plugins.sbt");
4901
4913
  };
4902
- exports.sbtPluginsPath = sbtPluginsPath;
4903
4914
 
4904
4915
  /**
4905
4916
  * Method to read a single file entry from a zip file
@@ -4909,7 +4920,7 @@ exports.sbtPluginsPath = sbtPluginsPath;
4909
4920
  *
4910
4921
  * @returns File contents
4911
4922
  */
4912
- const readZipEntry = async function (zipFile, filePattern) {
4923
+ export const readZipEntry = async function (zipFile, filePattern) {
4913
4924
  let retData = undefined;
4914
4925
  try {
4915
4926
  const zip = new StreamZip.async({ file: zipFile });
@@ -4934,7 +4945,6 @@ const readZipEntry = async function (zipFile, filePattern) {
4934
4945
  }
4935
4946
  return retData;
4936
4947
  };
4937
- exports.readZipEntry = readZipEntry;
4938
4948
 
4939
4949
  /**
4940
4950
  * Method to return the gradle command to use.
@@ -4942,39 +4952,38 @@ exports.readZipEntry = readZipEntry;
4942
4952
  * @param {string} srcPath Path to look for gradlew wrapper
4943
4953
  * @param {string} rootPath Root directory to look for gradlew wrapper
4944
4954
  */
4945
- const getGradleCommand = (srcPath, rootPath) => {
4955
+ export const getGradleCommand = (srcPath, rootPath) => {
4946
4956
  let gradleCmd = "gradle";
4947
4957
 
4948
4958
  let findGradleFile = "gradlew";
4949
- if (os.platform() == "win32") {
4959
+ if (platform() == "win32") {
4950
4960
  findGradleFile = "gradlew.bat";
4951
4961
  }
4952
4962
 
4953
- if (fs.existsSync(path.join(srcPath, findGradleFile))) {
4963
+ if (existsSync(join(srcPath, findGradleFile))) {
4954
4964
  // Use local gradle wrapper if available
4955
4965
  // Enable execute permission
4956
4966
  try {
4957
- fs.chmodSync(path.join(srcPath, findGradleFile), 0o775);
4967
+ chmodSync(join(srcPath, findGradleFile), 0o775);
4958
4968
  } catch (e) {
4959
4969
  // continue regardless of error
4960
4970
  }
4961
- gradleCmd = path.resolve(path.join(srcPath, findGradleFile));
4962
- } else if (rootPath && fs.existsSync(path.join(rootPath, findGradleFile))) {
4971
+ gradleCmd = resolve(join(srcPath, findGradleFile));
4972
+ } else if (rootPath && existsSync(join(rootPath, findGradleFile))) {
4963
4973
  // Check if the root directory has a wrapper script
4964
4974
  try {
4965
- fs.chmodSync(path.join(rootPath, findGradleFile), 0o775);
4975
+ chmodSync(join(rootPath, findGradleFile), 0o775);
4966
4976
  } catch (e) {
4967
4977
  // continue regardless of error
4968
4978
  }
4969
- gradleCmd = path.resolve(path.join(rootPath, findGradleFile));
4979
+ gradleCmd = resolve(join(rootPath, findGradleFile));
4970
4980
  } else if (process.env.GRADLE_CMD) {
4971
4981
  gradleCmd = process.env.GRADLE_CMD;
4972
4982
  } else if (process.env.GRADLE_HOME) {
4973
- gradleCmd = path.join(process.env.GRADLE_HOME, "bin", "gradle");
4983
+ gradleCmd = join(process.env.GRADLE_HOME, "bin", "gradle");
4974
4984
  }
4975
4985
  return gradleCmd;
4976
4986
  };
4977
- exports.getGradleCommand = getGradleCommand;
4978
4987
 
4979
4988
  /**
4980
4989
  * Method to return the maven command to use.
@@ -4982,65 +4991,64 @@ exports.getGradleCommand = getGradleCommand;
4982
4991
  * @param {string} srcPath Path to look for maven wrapper
4983
4992
  * @param {string} rootPath Root directory to look for maven wrapper
4984
4993
  */
4985
- const getMavenCommand = (srcPath, rootPath) => {
4994
+ export const getMavenCommand = (srcPath, rootPath) => {
4986
4995
  let mavenCmd = "mvn";
4987
4996
 
4988
4997
  let findMavenFile = "mvnw";
4989
- if (os.platform() == "win32") {
4998
+ if (platform() == "win32") {
4990
4999
  findMavenFile = "mvnw.bat";
4991
5000
  }
4992
5001
 
4993
- if (fs.existsSync(path.join(srcPath, findMavenFile))) {
5002
+ if (existsSync(join(srcPath, findMavenFile))) {
4994
5003
  // Use local maven wrapper if available
4995
5004
  // Enable execute permission
4996
5005
  try {
4997
- fs.chmodSync(path.join(srcPath, findMavenFile), 0o775);
5006
+ chmodSync(join(srcPath, findMavenFile), 0o775);
4998
5007
  } catch (e) {
4999
5008
  // continue regardless of error
5000
5009
  }
5001
- mavenCmd = path.resolve(path.join(srcPath, findMavenFile));
5002
- } else if (rootPath && fs.existsSync(path.join(rootPath, findMavenFile))) {
5010
+ mavenCmd = resolve(join(srcPath, findMavenFile));
5011
+ } else if (rootPath && existsSync(join(rootPath, findMavenFile))) {
5003
5012
  // Check if the root directory has a wrapper script
5004
5013
  try {
5005
- fs.chmodSync(path.join(rootPath, findMavenFile), 0o775);
5014
+ chmodSync(join(rootPath, findMavenFile), 0o775);
5006
5015
  } catch (e) {
5007
5016
  // continue regardless of error
5008
5017
  }
5009
- mavenCmd = path.resolve(path.join(rootPath, findMavenFile));
5018
+ mavenCmd = resolve(join(rootPath, findMavenFile));
5010
5019
  } else if (process.env.MVN_CMD || process.env.MAVEN_CMD) {
5011
5020
  mavenCmd = process.env.MVN_CMD || process.env.MAVEN_CMD;
5012
5021
  } else if (process.env.MAVEN_HOME) {
5013
- mavenCmd = path.join(process.env.MAVEN_HOME, "bin", "mvn");
5022
+ mavenCmd = join(process.env.MAVEN_HOME, "bin", "mvn");
5014
5023
  }
5015
5024
  return mavenCmd;
5016
5025
  };
5017
- exports.getMavenCommand = getMavenCommand;
5018
5026
 
5019
5027
  /**
5020
5028
  * Retrieves the atom command by referring to various environment variables
5021
5029
  */
5022
- const getAtomCommand = () => {
5030
+ export const getAtomCommand = () => {
5023
5031
  if (process.env.ATOM_CMD) {
5024
5032
  return process.env.ATOM_CMD;
5025
5033
  }
5026
5034
  if (process.env.ATOM_HOME) {
5027
- return path.join(process.env.ATOM_HOME, "bin", "atom");
5035
+ return join(process.env.ATOM_HOME, "bin", "atom");
5028
5036
  }
5029
5037
  const NODE_CMD = process.env.NODE_CMD || "node";
5030
- const localAtom = path.join(
5031
- __dirname,
5038
+ const localAtom = join(
5039
+ dirName,
5032
5040
  "node_modules",
5033
5041
  "@appthreat",
5034
5042
  "atom",
5035
5043
  "index.js"
5036
5044
  );
5037
- if (fs.existsSync(localAtom)) {
5045
+ if (existsSync(localAtom)) {
5038
5046
  return `${NODE_CMD} ${localAtom}`;
5039
5047
  }
5040
5048
  return "atom";
5041
5049
  };
5042
5050
 
5043
- const executeAtom = (src, args) => {
5051
+ export const executeAtom = (src, args) => {
5044
5052
  let ATOM_BIN = getAtomCommand();
5045
5053
  if (ATOM_BIN.includes(" ")) {
5046
5054
  const tmpA = ATOM_BIN.split(" ");
@@ -5049,7 +5057,7 @@ const executeAtom = (src, args) => {
5049
5057
  args.unshift(tmpA[1]);
5050
5058
  }
5051
5059
  }
5052
- const freeMemoryGB = Math.floor(os.freemem() / 1024 / 1024 / 1024);
5060
+ const freeMemoryGB = Math.floor(freemem() / 1024 / 1024 / 1024);
5053
5061
  if (DEBUG_MODE) {
5054
5062
  console.log("Execuing", ATOM_BIN, args.join(" "));
5055
5063
  }
@@ -5073,7 +5081,6 @@ const executeAtom = (src, args) => {
5073
5081
  }
5074
5082
  return true;
5075
5083
  };
5076
- exports.executeAtom = executeAtom;
5077
5084
 
5078
5085
  /**
5079
5086
  * Find the imported modules in the application with atom parsedeps command
@@ -5082,35 +5089,34 @@ exports.executeAtom = executeAtom;
5082
5089
  * @param {string} language
5083
5090
  * @returns List of imported modules
5084
5091
  */
5085
- const findAppModules = function (src, language) {
5086
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "atom-deps-"));
5087
- const atomFile = path.join(tempDir, "app.atom");
5088
- const slicesFile = path.join(tempDir, "slices.json");
5092
+ export const findAppModules = function (src, language) {
5093
+ const tempDir = mkdtempSync(join(tmpdir(), "atom-deps-"));
5094
+ const atomFile = join(tempDir, "app.atom");
5095
+ const slicesFile = join(tempDir, "slices.json");
5089
5096
  let retList = [];
5090
5097
  const args = [
5091
5098
  "parsedeps",
5092
5099
  "-l",
5093
5100
  language,
5094
5101
  "-o",
5095
- path.resolve(atomFile),
5102
+ resolve(atomFile),
5096
5103
  "--slice-outfile",
5097
- path.resolve(slicesFile),
5098
- path.resolve(src)
5104
+ resolve(slicesFile),
5105
+ resolve(src)
5099
5106
  ];
5100
5107
  executeAtom(src, args);
5101
- if (fs.existsSync(slicesFile)) {
5102
- const slicesData = JSON.parse(fs.readFileSync(slicesFile), "utf8");
5108
+ if (existsSync(slicesFile)) {
5109
+ const slicesData = JSON.parse(readFileSync(slicesFile), "utf8");
5103
5110
  if (slicesData && Object.keys(slicesData) && slicesData.modules) {
5104
5111
  retList = slicesData.modules;
5105
5112
  }
5106
5113
  }
5107
5114
  // Clean up
5108
- if (tempDir && tempDir.startsWith(os.tmpdir()) && fs.rmSync) {
5109
- fs.rmSync(tempDir, { recursive: true, force: true });
5115
+ if (tempDir && tempDir.startsWith(tmpdir()) && rmSync) {
5116
+ rmSync(tempDir, { recursive: true, force: true });
5110
5117
  }
5111
5118
  return retList;
5112
5119
  };
5113
- exports.findAppModules = findAppModules;
5114
5120
 
5115
5121
  /**
5116
5122
  * Execute pip freeze by creating a virtual env in a temp directory
@@ -5119,10 +5125,10 @@ exports.findAppModules = findAppModules;
5119
5125
  * @param {string} reqOrSetupFile Requirements or setup.py file
5120
5126
  * @returns List of packages from the virtual env
5121
5127
  */
5122
- const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5128
+ export const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5123
5129
  let pkgList = [];
5124
5130
  let result = undefined;
5125
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cdxgen-venv-"));
5131
+ const tempDir = mkdtempSync(join(tmpdir(), "cdxgen-venv-"));
5126
5132
  const env = {
5127
5133
  ...process.env
5128
5134
  };
@@ -5139,7 +5145,7 @@ const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5139
5145
  }
5140
5146
  } else {
5141
5147
  env.VIRTUAL_ENV = tempDir;
5142
- env.PATH = `${path.join(tempDir, "bin")}${path.delimiter}${
5148
+ env.PATH = `${join(tempDir, "bin")}${_delimiter}${
5143
5149
  process.env.PATH || ""
5144
5150
  }`;
5145
5151
  }
@@ -5163,9 +5169,9 @@ const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5163
5169
  !reqOrSetupFile.endsWith("pyproject.toml")
5164
5170
  ) {
5165
5171
  pipInstallArgs.push("-r");
5166
- pipInstallArgs.push(path.resolve(reqOrSetupFile));
5172
+ pipInstallArgs.push(resolve(reqOrSetupFile));
5167
5173
  } else {
5168
- pipInstallArgs.push(path.resolve(basePath));
5174
+ pipInstallArgs.push(resolve(basePath));
5169
5175
  }
5170
5176
  // Attempt to perform pip install
5171
5177
  result = spawnSync(PYTHON_CMD, pipInstallArgs, {
@@ -5175,12 +5181,26 @@ const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5175
5181
  env
5176
5182
  });
5177
5183
  if (result.status !== 0 || result.error) {
5178
- if (DEBUG_MODE) {
5179
- console.log(result.stderr, "args used:", pipInstallArgs);
5184
+ let versionRelatedError = false;
5185
+ if (
5186
+ result.stderr &&
5187
+ (result.stderr.includes(
5188
+ "Could not find a version that satisfies the requirement"
5189
+ ) ||
5190
+ result.stderr.includes("No matching distribution found for"))
5191
+ ) {
5192
+ versionRelatedError = true;
5193
+ console.log(
5194
+ "The version or the version specifiers used for a dependency is invalid. Resolve the below error to improve SBoM accuracy."
5195
+ );
5196
+ console.log(result.stderr);
5197
+ }
5198
+ if (!versionRelatedError && DEBUG_MODE) {
5199
+ console.log("args used:", pipInstallArgs);
5180
5200
  console.log(
5181
5201
  "Possible build errors detected. The resulting list in the SBoM would therefore be incomplete.\nTry installing any missing build tools or development libraries to improve the accuracy."
5182
5202
  );
5183
- if (os.platform() == "win32") {
5203
+ if (platform() == "win32") {
5184
5204
  console.log(
5185
5205
  "- Install the appropriate compilers and build tools on Windows by following this documentation - https://wiki.python.org/moin/WindowsCompilers"
5186
5206
  );
@@ -5212,7 +5232,7 @@ const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5212
5232
  !reqOrSetupFile.endsWith("pyproject.toml")
5213
5233
  ) {
5214
5234
  pipFreezeArgs.push("-r");
5215
- pipFreezeArgs.push(path.resolve(reqOrSetupFile));
5235
+ pipFreezeArgs.push(resolve(reqOrSetupFile));
5216
5236
  }
5217
5237
  result = spawnSync(PYTHON_CMD, pipFreezeArgs, {
5218
5238
  cwd: basePath,
@@ -5241,9 +5261,29 @@ const executePipFreezeInVenv = async (basePath, reqOrSetupFile) => {
5241
5261
  }
5242
5262
  }
5243
5263
  // Clean up
5244
- if (tempDir && tempDir.startsWith(os.tmpdir()) && fs.rmSync) {
5245
- fs.rmSync(tempDir, { recursive: true, force: true });
5264
+ if (tempDir && tempDir.startsWith(tmpdir()) && rmSync) {
5265
+ rmSync(tempDir, { recursive: true, force: true });
5246
5266
  }
5247
5267
  return pkgList;
5248
5268
  };
5249
- exports.executePipFreezeInVenv = executePipFreezeInVenv;
5269
+
5270
+ // taken from a very old package https://github.com/keithamus/parse-packagejson-name/blob/master/index.js
5271
+ export const parsePackageJsonName = (name) => {
5272
+ const nameRegExp = /^(?:@([^/]+)\/)?(([^.]+)(?:\.(.*))?)$/;
5273
+ const returnObject = {
5274
+ scope: null,
5275
+ fullName: "",
5276
+ projectName: "",
5277
+ moduleName: ""
5278
+ };
5279
+ const match = (typeof name === "object" ? name.name || "" : name || "").match(
5280
+ nameRegExp
5281
+ );
5282
+ if (match) {
5283
+ returnObject.scope = match[1] || null;
5284
+ returnObject.fullName = match[2] || match[0];
5285
+ returnObject.projectName = match[3] === match[2] ? null : match[3];
5286
+ returnObject.moduleName = match[4] || match[2] || null;
5287
+ }
5288
+ return returnObject;
5289
+ };